Skip to content

ci: manual OIDC release, drop semantic-release#7

Merged
gxkl merged 1 commit into
masterfrom
ci/oidc-release
Jul 15, 2026
Merged

ci: manual OIDC release, drop semantic-release#7
gxkl merged 1 commit into
masterfrom
ci/oidc-release

Conversation

@gxkl

@gxkl gxkl commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What

Replace the token-based release with a manually-triggered workflow that publishes via npm OIDC trusted publishing — no NPM_TOKEN, and no semantic-release.

The old release.yml used the shared artusjs/github-actions reusable workflow, which publishes with NPM_TOKEN. That token expired and the last release failed with EINVALIDNPMTOKEN. Trusted publishing removes the token: the workflow exchanges a short-lived GitHub OIDC identity for npm publish rights, with provenance generated automatically.

How it works now

  • Trigger: workflow_dispatch only (run from the Actions tab), with inputs:
    • version_type: patch / minor / major
    • dry_run: build + npm publish --dry-run, no publish/push
  • Steps: install → test → npm version <type> (bump + tag) → npm publish --provenance (OIDC) → push commit + tag → create GitHub release (--generate-notes)
  • Permissions: id-token: write (OIDC) + contents: write
  • Publish happens before the git push, so a failed publish can be retried cleanly without a double version bump.

Behavior change

Releases are no longer automatic on merge to master — a maintainer triggers a release manually and picks the bump type. Auto-changelog-from-commits (a semantic-release feature) is dropped; GitHub release notes are auto-generated via --generate-notes.

⚠️ Required before first release (npm side, pkg owner action)

Configure a trusted publisher for diskstore on npmjs.com:

  • Package → Settings → Trusted PublishersGitHub Actions
  • Owner node-modules, Repository diskstore, Workflow release.yml

Secrets

No long-lived secrets are needed anymore:

  • NPM_TOKEN — no longer used (publishing is via OIDC); can be removed.
  • GIT_TOKEN — no longer used. The bump commit/tag push and the GitHub release use the built-in GITHUB_TOKEN with contents: write. master protection currently allows this (no required reviews / push restrictions); if it is later tightened to require PRs or restrict pushers, a PAT or GitHub App token would be needed again.

Releasing 3.2.0

master already has the unreleased EXDEV-fallback feat. After the trusted publisher is set up, run the workflow with version_type: minor to cut 3.2.0.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release workflow now runs inline, supports manually selected patch, minor, or major releases, validates the package, publishes to npm with provenance, pushes version changes, and creates a GitHub Release. Dry-run execution is supported.

Changes

Manual npm release workflow

Layer / File(s) Summary
Release inputs and permissions
.github/workflows/release.yml
Adds manual version_type and dry_run inputs and grants contents-write and OIDC permissions.
Release preparation and validation
.github/workflows/release.yml
Replaces the reusable workflow with an inline Node.js 20 job that checks out full history, installs dependencies, and runs tests.
Versioning and publication
.github/workflows/release.yml
Bumps the npm version, supports dry-run or provenance publishing, pushes commits and tags for real releases, and creates a GitHub Release.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main workflow change: switching to a manual OIDC-based release process and removing semantic-release.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/oidc-release

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a release.config.js file to configure automated releases using semantic-release, utilizing OIDC trusted publishing for npm. The review feedback recommends enabling provenance generation in package.json to enhance supply chain security and shortening the git release commit message to prevent bloating the git history with full release notes.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread release.config.js Outdated
[ '@semantic-release/changelog', { changelogTitle: '# Changelog' } ],
// publishes to npm via OIDC trusted publishing (no NPM_TOKEN); requires
// `id-token: write` in the workflow and a trusted publisher configured on npmjs.com
[ '@semantic-release/npm', {} ],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

To fully leverage npm OIDC trusted publishing and meet modern security standards, it is highly recommended to enable provenance generation. This allows consumers to verify that the package was built directly from your GitHub repository via a trusted workflow.

Since npm does not generate provenance automatically unless configured, you should add the following to your package.json:

"publishConfig": {
  "provenance": true
}

Comment thread release.config.js Outdated
Comment on lines +10 to +12
[ '@semantic-release/git', {
message: 'Release <%= nextRelease.version %>\n\n[skip ci]\n\n<%= nextRelease.notes %>',
} ],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Including the full release notes (<%= nextRelease.notes %>) in the git commit message can make the git history extremely bloated and hard to read, especially for releases with many changes. Since the release notes are already documented in CHANGELOG.md (which is committed in the same commit) and published on the GitHub Release page, it is recommended to keep the commit message concise.

Suggested change
[ '@semantic-release/git', {
message: 'Release <%= nextRelease.version %>\n\n[skip ci]\n\n<%= nextRelease.notes %>',
} ],
[ '@semantic-release/git', {
message: 'chore(release): <%= nextRelease.version %> [skip ci]',
} ],

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 22-23: Update the actions/checkout step in the release workflow to
set fetch-depth to 0, ensuring Semantic Release has the complete Git history and
prior release tags while preserving the existing checkout action configuration.
- Around line 25-29: Remove the registry-url setting from the Setup Node.js step
in the release workflow, leaving the Node.js version configuration unchanged so
npm uses OIDC trusted publishing without setup-node generating an
NODE_AUTH_TOKEN-based .npmrc.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 91e6323d-8eec-4c99-98d4-35a8b9a647b8

📥 Commits

Reviewing files that changed from the base of the PR and between f517258 and fa9259e.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • release.config.js

Comment thread .github/workflows/release.yml
Comment on lines +25 to +29
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove registry-url when using OIDC trusted publishing.

Setting registry-url causes setup-node to generate an .npmrc file configured to use NODE_AUTH_TOKEN. Since NODE_AUTH_TOKEN is not provided to the workflow steps, this results in an unresolved variable in the config, which can cause npm warnings or authentication conflicts.

Since you are relying on npm's native OIDC trusted publishing (which generates its own token via the OIDC id-token), you can safely remove registry-url.

♻️ Proposed fix
       - name: Setup Node.js
         uses: actions/setup-node@v4
         with:
           node-version: 20
-          registry-url: 'https://registry.npmjs.org'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 25 - 29, Remove the registry-url
setting from the Setup Node.js step in the release workflow, leaving the Node.js
version configuration unchanged so npm uses OIDC trusted publishing without
setup-node generating an NODE_AUTH_TOKEN-based .npmrc.

@gxkl gxkl force-pushed the ci/oidc-release branch from fa9259e to 239d097 Compare July 15, 2026 02:40
@gxkl gxkl changed the title ci: publish to npm via OIDC trusted publishing ci: manual OIDC release, drop semantic-release Jul 15, 2026
@gxkl gxkl force-pushed the ci/oidc-release branch from 239d097 to 3ef355f Compare July 15, 2026 06:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/release.yml (1)

64-80: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Simplify boolean conditions and use the modern inputs context.

The github.event.inputs context is deprecated in favor of inputs. Furthermore, because dry_run is defined as a boolean type, inputs.dry_run natively evaluates to a boolean, removing the need for string comparisons and ${{ }} wrappers in if conditionals.

♻️ Proposed refactor
       - name: Publish (dry run)
-        if: ${{ github.event.inputs.dry_run == 'true' }}
+        if: inputs.dry_run
         run: npm publish --provenance --dry-run
 
       # Publish before pushing: if publish fails, nothing is pushed and the
       # run can be retried cleanly without a double version bump.
       - name: Publish
-        if: ${{ github.event.inputs.dry_run != 'true' }}
+        if: '!inputs.dry_run'
         run: npm publish --provenance
 
       - name: Push commit and tag
-        if: ${{ github.event.inputs.dry_run != 'true' }}
+        if: '!inputs.dry_run'
         run: git push origin HEAD --follow-tags
 
       - name: Create GitHub Release
-        if: ${{ github.event.inputs.dry_run != 'true' }}
+        if: '!inputs.dry_run'
         run: gh release create "${{ steps.bump.outputs.tag }}" --verify-tag --generate-notes
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 64 - 80, Update the dry-run
checks on the “Publish (dry run)”, “Publish”, “Push commit and tag”, and “Create
GitHub Release” steps to use the modern inputs.dry_run context directly as a
boolean, replacing github.event.inputs and string comparisons while preserving
the existing true/false execution behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 60-62: Update the release step’s npm version command to consume
the version type through a step environment variable populated from the modern
inputs context, rather than directly interpolating
github.event.inputs.version_type in the shell script. Preserve the existing
release message and tag output behavior.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 64-80: Update the dry-run checks on the “Publish (dry run)”,
“Publish”, “Push commit and tag”, and “Create GitHub Release” steps to use the
modern inputs.dry_run context directly as a boolean, replacing
github.event.inputs and string comparisons while preserving the existing
true/false execution behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 834e0727-0daf-4d96-be68-2b694644b9f6

📥 Commits

Reviewing files that changed from the base of the PR and between fa9259e and 3ef355f.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Comment on lines +60 to +62
run: |
npm version ${{ github.event.inputs.version_type }} -m "Release v%s"
echo "tag=v$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Prevent template injection by using environment variables.

Directly interpolating GitHub contexts into run scripts can lead to code injection. Although version_type is currently constrained by a choice input, passing it via an environment variable is a safer practice and prevents future vulnerabilities if the input type changes. Additionally, prefer the modern inputs context over the deprecated github.event.inputs.

🛡️ Proposed fix
       - name: Version bump
         id: bump
+        env:
+          VERSION_TYPE: ${{ inputs.version_type }}
         run: |
-          npm version ${{ github.event.inputs.version_type }} -m "Release v%s"
+          npm version "$VERSION_TYPE" -m "Release v%s"
           echo "tag=v$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: |
npm version ${{ github.event.inputs.version_type }} -m "Release v%s"
echo "tag=v$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
env:
VERSION_TYPE: ${{ inputs.version_type }}
run: |
npm version "$VERSION_TYPE" -m "Release v%s"
echo "tag=v$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
🧰 Tools
🪛 zizmor (1.26.1)

[error] 61-61: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 60 - 62, Update the release
step’s npm version command to consume the version type through a step
environment variable populated from the modern inputs context, rather than
directly interpolating github.event.inputs.version_type in the shell script.
Preserve the existing release message and tag output behavior.

Source: Linters/SAST tools

Replace the token-based release with a manually-triggered workflow that
publishes through npm OIDC trusted publishing (no NPM_TOKEN, no
semantic-release, no long-lived PAT).

- workflow_dispatch with a version_type (patch/minor/major) + dry_run input
- `npm version` bumps + tags, `npm publish --provenance` publishes via OIDC
- `id-token: write` for trusted publishing; the built-in GITHUB_TOKEN
  (contents: write) pushes the bump commit/tag and creates the GitHub release
- publish before push so a failed publish retries cleanly

Requires a trusted publisher configured for `diskstore` on npmjs.com
(GitHub Actions -> node-modules/diskstore, workflow release.yml).
Releases are now triggered manually from the Actions tab, not on merge.
@gxkl gxkl force-pushed the ci/oidc-release branch from 3ef355f to ee185ce Compare July 15, 2026 06:50
@gxkl gxkl requested a review from killagu July 15, 2026 06:54

@killagu killagu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gxkl gxkl merged commit 2d167ba into master Jul 15, 2026
13 checks passed
@gxkl gxkl deleted the ci/oidc-release branch July 15, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants