Conversation
CircleCI release pipeline is dead (Node 12 EOL). Replace with GitHub Actions workflow that runs lint + tests on PRs and publishes via semantic-release on master. Also bumps devDependencies (jest ^29, semantic-release ^24) and engines.node to >=18. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split the release job into a dedicated release.yml workflow that uses npm trusted publishing via OIDC instead of an NPM_TOKEN secret. The release job runs in a GitHub environment called "release" with id-token: write permission and NPM_CONFIG_PROVENANCE enabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ci.yml: run tests on PRs and master; dry-run semantic-release on PRs - release.yml: trigger via workflow_run after CI succeeds on master Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace NPM_TOKEN secret with OIDC trusted publishing. The id-token permission + release environment + NPM_CONFIG_PROVENANCE lets npm authenticate via GitHub's OIDC provider. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
This pull request adds a CI workflow whose 'test' job lacks an explicit job-level 'permissions' block, so it may inherit broad default GITHUB_TOKEN permissions (e.g., contents: write) and could allow untrusted PR code or compromised dependencies to perform unauthorized repository actions. To mitigate, the job should set minimal necessary permissions (for example, read-only) to limit risk.
Missing job-level permissions in
|
| Vulnerability | Missing job-level permissions |
|---|---|
| Description | The 'test' job in the CI workflow lacks an explicit 'permissions' block, which can cause it to inherit broad default repository permissions (e.g., 'contents: write'). Since this job executes potentially untrusted code from pull requests or dependencies via 'yarn install' and 'yarn test', a malicious actor could exploit the GITHUB_TOKEN to make unauthorized changes to the repository. While pull requests from forks are restricted to read-only access by GitHub, pull requests from internal branches or compromised dependencies in the master branch could still gain write access if the repository's default settings are not restricted. |
semantic-release-rubygem/.github/workflows/ci.yml
Lines 10 to 13 in 2e8bb04
All finding details can be found in the DryRun Security Dashboard.
dduugg
left a comment
There was a problem hiding this comment.
Code Review
Bug — Missing fetch-depth: 0 in both workflows
Semantic-release requires the full git history to determine the next version (it walks commits to find the last tag). Both ci.yml (semantic-release-dry-run job) and release.yml (release job) use actions/checkout@v4 without fetch-depth: 0, which produces a shallow clone.
# Both jobs need this:
- uses: actions/checkout@v4
with:
fetch-depth: 0Without this, npx semantic-release may mis-identify the next version or fail entirely in the release job.
Suspicious — eslint-config-gusto downgraded from ^16.0.0 to ^11.0.0
The current package.json on master has "eslint-config-gusto": "^16.0.0". This PR changes it to ^11.0.0, which is a major version downgrade. This doesn't appear intentional and may have been introduced during a rebase or conflict resolution. Worth confirming.
- "eslint-config-gusto": "^16.0.0",
+ "eslint-config-gusto": "^11.0.0",Minor — workflow_run trigger adds latency and complexity
Using workflow_run means the release job won't appear as a required check on the PR itself — it only fires after CI finishes on master. This is intentional and correct for a release pipeline, but worth being aware of: if CI passes but the release fails (e.g., because the release environment or npm trusted publishing isn't configured yet), the failure will show up on the commit, not on the PR.
Minor — No Ruby setup in release.yml
The release.yml job doesn't install Ruby. This is fine because semantic-release (the npm publish step) doesn't need Ruby — Ruby is only required for the gem build / gem push steps at runtime in consumer repos. The CI pipeline here just publishes the npm package itself. Just noting this as expected/intentional.
Suggested blocking items before merge:
- Add
fetch-depth: 0to thesemantic-release-dry-runandreleasejobs. - Confirm (and likely revert) the
eslint-config-gustoversion — should be^16, not^11.
Summary
Replace the dead CircleCI pipeline (Node 12 EOL) with GitHub Actions so that semantic-release can publish new versions again.
.github/workflows/ci.yml: test job (Node 20, Ruby 3.2, lint + test) on push/PR to master.github/workflows/release.yml: test + release pipeline on push to master, using npm trusted publishing (OIDC) instead of an NPM_TOKEN secret.circleci/config.yml: dead pipeline usingcircleci/node:12andcircleci/ruby:2.7-node^26→^29, semantic-release^17→^24engines.node:>=10.18→>=18No runtime dependency changes. All 17 tests pass.
Motivation
PR #51 removed the upper bound on the
semantic-releasepeer dependency, but it was never published because CircleCI's release job runs on Node 12 (EOL) and fails. This PR restores the release pipeline so that change (and future changes) can be published to npm.Post-merge setup
See the GitHub configuration section below for required setup before the release job will work.
GitHub configuration
Create a GitHub environment called
releasein the repo settings (Settings → Environments → New environment)Configure npm trusted publishing on npmjs.com:
Gustosemantic-release-rubygemrelease.ymlreleaseNo
NPM_TOKENsecret is needed — the OIDC token from GitHub Actions authenticates directly with npm.🤖 Generated with Claude Code