Skip to content

Add versioned release workflow - #50

Merged
tomusdrw merged 2 commits into
mainfrom
c/release-process
Jun 7, 2026
Merged

Add versioned release workflow#50
tomusdrw merged 2 commits into
mainfrom
c/release-process

Conversation

@tomusdrw

@tomusdrw tomusdrw commented Jun 6, 2026

Copy link
Copy Markdown
Member

Summary

  • add a manual patch/minor/major version bump workflow
  • create the version bump PR with a GitHub App token and prepare a draft GitHub release
  • publish npm artifacts from the published release tag using X.Y.Z-<short-sha> versions

Repository configuration

  • variable: PR_APP_ID
  • secret: PR_APP_PRIVATE_KEY

Validation

  • actionlint .github/workflows/*.yml
  • node --check .github/scripts/bump-version.mjs
  • tested patch, minor, and major bump calculations
  • validated the bumped Cargo workspace with locked metadata

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 76504669-ad34-40cb-b097-f61556950c53

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces a complete release automation pipeline for the monorepo. A version-bump CLI script updates version references across JavaScript, Rust, and lock files. A new release workflow orchestrates version bumping, creates a version-bump PR, and drafts a GitHub release. The publish workflow is updated to trigger on published releases and verify the release tag matches the package version before proceeding with builds and publishing.

Changes

Release Automation Pipeline

Layer / File(s) Summary
Version bump script
.github/scripts/bump-version.mjs
CLI tool that reads the root package.json version, validates and increments it based on a patch/minor/major argument, then updates that version across all JavaScript package manifests and their optionalDependencies, package-lock.json entries, and Rust Cargo manifests with validation errors on missing or mismatched fields.
Release workflow orchestration
.github/workflows/release.yml
Manual workflow that computes a new version via the bump script, validates Cargo and package-lock.json consistency, authenticates via GitHub App, creates a version-bump PR on a release branch, and opens a draft GitHub release with generated notes and a checklist.
Publish workflow release gating
.github/workflows/publish.yml
Changes trigger from manual/branch-based to release-published events, introduces a verify-release job that validates the release tag against package.json version, and gates build-wasm, build-native, and publish jobs on verification while pinning checkouts to the release tag.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add versioned release workflow' directly reflects the main change: a new release workflow system for version management, matching the addition of release.yml, publish.yml updates, and the bump-version.mjs script.
Description check ✅ Passed The description is clearly related to the changeset, detailing the summary of changes, repository configuration requirements, and validation performed. It accurately describes the version bump workflow, PR creation with GitHub App token, and draft release preparation.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch c/release-process

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

@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 (4)
.github/workflows/publish.yml (2)

24-32: ⚡ Quick win

Use environment variables to avoid potential template injection.

While the risk is low (only maintainers can publish releases), it's safer to pass github.event.release.tag_name through an environment variable rather than expanding it directly in the shell script.

Safer pattern using environment variables
       - name: Verify release version
+        env:
+          RELEASE_TAG: ${{ github.event.release.tag_name }}
         run: |
-          tag="${{ github.event.release.tag_name }}"
+          tag="$RELEASE_TAG"
           package_version=$(node -p "require('./package.json').version")
 
           if [ "$tag" != "v$package_version" ]; then
🤖 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/publish.yml around lines 24 - 32, The "Verify release
version" step expands github.event.release.tag_name directly into the shell
which risks template injection; change the step to pass the tag through an
environment variable (e.g. GH_TAG) using the step's env block and then reference
$GH_TAG in the script (keep package_version as-is), updating the variable name
references (tag -> GH_TAG) in the shell commands so the check uses the env var
rather than direct template expansion.

172-172: ⚡ Quick win

Inconsistent version handling in platform package updates.

Line 172 recomputes the base version from each platform package instead of reusing baseVersion from distPkg. The comment on line 171 says "reuse baseVersion from distPkg assuming they are synced" but then doesn't actually reuse it.

This creates a risk: if platform packages somehow have different versions, the script will silently use those different versions instead of enforcing consistency.

Recommended fix to enforce version consistency
           for (const pkgPath of packages) {
             if (fs.existsSync(pkgPath)) {
               const pkg = JSON.parse(fs.readFileSync(pkgPath));
-              // reuse baseVersion from distPkg assuming they are synced
-              const pkgNewVersion = `${pkg.version.split('-')[0]}-${shortSha}`;
+              // Ensure platform packages match the base version
+              if (pkg.version !== baseVersion) {
+                throw new Error(`Platform package ${pkgPath} version ${pkg.version} does not match expected ${baseVersion}`);
+              }
+              const pkgNewVersion = `${baseVersion}-${shortSha}`;
               pkg.version = pkgNewVersion;

This enforces that all packages have the same base version before publishing.

🤖 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/publish.yml at line 172, The code recomputes each platform
package's base version with `pkg.version.split('-')[0]` instead of reusing the
canonical `baseVersion` from `distPkg`; update the logic that assigns
`pkgNewVersion` to use the `baseVersion` derived from `distPkg` (e.g.,
`baseVersion`) and add a consistency check that compares
`pkg.version.split('-')[0]` to `baseVersion` for every platform package (throw
or fail the job if they differ) so publishing enforces a single source-of-truth
version rather than silently accepting divergent package versions.
.github/workflows/release.yml (1)

29-29: ⚡ Quick win

Consider pinning GitHub Actions to commit SHAs.

The workflow uses tag-based action references (e.g., @v6, @v2). For enhanced security and reproducibility, consider pinning to specific commit SHAs instead.

Example pinning pattern
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v6.1.0

You can find commit SHAs for action versions at their respective GitHub repositories.

Also applies to: 34-34, 55-55, 61-61, 75-75

🤖 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 at line 29, Replace tag-based GitHub Action
references with pinned commit SHAs to improve security and reproducibility: for
each "uses:" entry such as "actions/checkout@v6", "actions/setup-node@v19",
"actions/upload-release-asset@v1", and any other tag references mentioned, look
up the exact commit SHA for the target version in the action's GitHub repo and
update the "uses:" value to "actions/<repo>@<sha>" (keep the same version
semantics but use the SHA). Ensure you update all occurrences referenced in the
review (the uses entries at the noted locations) and verify the workflow still
runs successfully after pinning.
.github/scripts/bump-version.mjs (1)

110-120: Scope the Cargo.toml version replacement (or use a TOML parser) to avoid brittle matches.

bump-version.mjs replaces the first exact occurrence of version = "${currentVersion}" in each manifest (e.g., versionLine at line 112, then manifest.replace(...)). In the current bandersnatch/{core,native-binding,wasm-binding}/Cargo.toml, that exact version = "0.4.0" line appears only once, so dependency versions won’t be affected today—but the approach still relies on exact formatting/uniqueness. Consider updating via a TOML parser or restricting the replacement to the [package] section.

🤖 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/scripts/bump-version.mjs around lines 110 - 120, The current loop in
bump-version.mjs that iterates cargoManifestPaths and does a blind string
replace of versionLine is brittle; update it to parse and modify the Cargo.toml
safely by either (A) using a TOML parser to load the manifest, set
manifest.package.version = nextVersion, then stringify and write back, or (B) if
you want minimal deps, restrict the replacement to the [package] section by
locating the start of the "[package]" block and its end (next section header or
EOF), perform the version key replacement only inside that substring (using the
existing versionLine as the expected pattern), and then recombine and write;
update variables/logic around manifest, versionLine, and the writeFile step
accordingly so dependency version strings outside [package] are never touched.
🤖 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 74-82: The draft release step ("Create draft GitHub release" using
softprops/action-gh-release@v2 with tag_name v${{ steps.version.outputs.version
}} and target_commitish: main) is creating a tag that points to main before the
version-bump PR is merged; fix by removing this step from the current workflow
and instead create the release in a separate workflow triggered on merge/push to
main (or change target_commitish to the actual release branch/PR head reference
like github.head_ref or a steps.version.outputs.branch value so the tag points
at the merged commit), or alternatively delay tag creation until publish
time—apply the change to the action block named "Create draft GitHub release"
and update target_commitish or move the entire block into a post-merge workflow.

---

Nitpick comments:
In @.github/scripts/bump-version.mjs:
- Around line 110-120: The current loop in bump-version.mjs that iterates
cargoManifestPaths and does a blind string replace of versionLine is brittle;
update it to parse and modify the Cargo.toml safely by either (A) using a TOML
parser to load the manifest, set manifest.package.version = nextVersion, then
stringify and write back, or (B) if you want minimal deps, restrict the
replacement to the [package] section by locating the start of the "[package]"
block and its end (next section header or EOF), perform the version key
replacement only inside that substring (using the existing versionLine as the
expected pattern), and then recombine and write; update variables/logic around
manifest, versionLine, and the writeFile step accordingly so dependency version
strings outside [package] are never touched.

In @.github/workflows/publish.yml:
- Around line 24-32: The "Verify release version" step expands
github.event.release.tag_name directly into the shell which risks template
injection; change the step to pass the tag through an environment variable (e.g.
GH_TAG) using the step's env block and then reference $GH_TAG in the script
(keep package_version as-is), updating the variable name references (tag ->
GH_TAG) in the shell commands so the check uses the env var rather than direct
template expansion.
- Line 172: The code recomputes each platform package's base version with
`pkg.version.split('-')[0]` instead of reusing the canonical `baseVersion` from
`distPkg`; update the logic that assigns `pkgNewVersion` to use the
`baseVersion` derived from `distPkg` (e.g., `baseVersion`) and add a consistency
check that compares `pkg.version.split('-')[0]` to `baseVersion` for every
platform package (throw or fail the job if they differ) so publishing enforces a
single source-of-truth version rather than silently accepting divergent package
versions.

In @.github/workflows/release.yml:
- Line 29: Replace tag-based GitHub Action references with pinned commit SHAs to
improve security and reproducibility: for each "uses:" entry such as
"actions/checkout@v6", "actions/setup-node@v19",
"actions/upload-release-asset@v1", and any other tag references mentioned, look
up the exact commit SHA for the target version in the action's GitHub repo and
update the "uses:" value to "actions/<repo>@<sha>" (keep the same version
semantics but use the SHA). Ensure you update all occurrences referenced in the
review (the uses entries at the noted locations) and verify the workflow still
runs successfully after pinning.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 326b9a83-6d58-4d96-b568-21fa6bc72710

📥 Commits

Reviewing files that changed from the base of the PR and between e6c4c58 and 9f6950a.

📒 Files selected for processing (3)
  • .github/scripts/bump-version.mjs
  • .github/workflows/publish.yml
  • .github/workflows/release.yml

Comment thread .github/workflows/release.yml Outdated
@tomusdrw
tomusdrw merged commit f8625b6 into main Jun 7, 2026
4 checks passed
@tomusdrw
tomusdrw deleted the c/release-process branch June 7, 2026 05:45
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.

1 participant