chore: add script to bump versions and release workflows#764
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughRelease flow replaced with a tag-triggered, multi-job GitHub Actions pipeline that extracts/verifies versions, builds multi-target binaries, publishes Rust crates and npm packages (prerelease-aware), and creates GitHub releases. Adds a TypeScript VersionBumper CLI, bumps workspace/npm versions, removes Changesets config, and updates docs/changelog. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant GH as GitHub (Tag Push)
participant WF as Releases Workflow
participant Prep as Validate & Prepare
participant Build as Build Binaries
participant Rust as Publish Rust Crates
participant NPM as Publish NPM Packages
participant Rel as Create GitHub Release
Dev->>GH: Push tag vX.Y.Z[-prerelease]
GH->>WF: Trigger workflow (tag or PR)
WF->>Prep: Extract version, determine prerelease, verify Cargo.toml/package.json
Prep-->>WF: outputs version, prerelease
WF->>Build: Matrix build, archive, upload artifacts
par Publish
WF->>Rust: Publish crates (token, prerelease-aware)
WF->>NPM: Publish packages (tag=next for prerelease, latest for stable)
end
WF->>Rel: Download artifacts, compose notes (changelog, install, assets)
alt Stable
Rel->>GH: Create release (prerelease=false), update stable tag
else Prerelease
Rel->>GH: Create release (prerelease=true)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
|
❌ License Header Check Failed Some files are missing the required SPDX license header. Please add the following header to the beginning of all You can run Or run |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (8)
.github/workflows/releases.yml (1)
51-63: Drop the unused dprint install step.Since the formatting step now runs
cargo fmt, the preceding “Install dprint” step no longer serves a purpose and just adds time and a network call to the workflow. Please remove that step (and any related references) to keep the job lean.scripts/README.md (1)
21-26: Document actual scope of updates.The script currently bumps a curated set of packages (sdk, contracts, config, react, crates/wasm) plus the root Cargo.toml. Clarify this to avoid confusion about “all packages.”
Proposed wording:
- “Updates the workspace version and workspace dependencies in the root Cargo.toml.”
- “Bumps versions in: packages/enclave-{sdk,contracts,config,react} and crates/wasm/package.json.”
scripts/bump-versions.ts (6)
104-155: Make TOML update more robust (don’t limit to next 10 lines; preserve indentation).Limiting to 10 lines risks missing
versionif the section grows. Also, preserve indentation when rewriting.Apply this diff:
- if (line === '[workspace.package]') { - // Look for version in the next few lines - for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) { - if (lines[j].trim().startsWith('version = ')) { - lines[j] = `version = "${this.newVersion}"` - updated = true - break - } - } - } + if (line === '[workspace.package]') { + for (let j = i + 1; j < lines.length; j++) { + const t = lines[j].trim() + if (t.startsWith('[')) break + if (t.startsWith('version = ')) { + const indent = lines[j].match(/^\s*/)?.[0] ?? '' + lines[j] = `${indent}version = "${this.newVersion}"` + updated = true + break + } + } + }
160-189: Redundant/ineffective workspace deps updater.
updateWorkspaceDependenciesonly updates lines that start withversion =, which won’t match inline entries likefoo = { version = "...", path = ... }. SinceupdateCargoTomlalready updates those inline versions, this method is redundant and can confuse future readers.Apply one of:
- Remove the method and its call in
bumpRustCrates(), or- Generalize it to replace
version = "..."anywhere between[workspace.dependencies]and the next section:- if (inWorkspaceDeps && line.startsWith('version = ')) { - lines[i] = `version = "${this.newVersion}"` - updated = true - } + if (inWorkspaceDeps) { + if (line === '' || line.startsWith('[')) break + if (line.includes('version = ')) { + lines[i] = lines[i].replace(/version = "[^"]*"/, `version = "${this.newVersion}"`) + updated = true + } + }
80-102: Avoid hard‑coded package list; discover workspaces dynamically.Static paths risk missing future packages. Consider globbing or reading
pnpm-workspace.yamlto find publishable packages.Example (using fast-glob):
-import { join, resolve } from 'path' +import { join, resolve } from 'path' +import fg from 'fast-glob' ... - const packagesToBump = [ - 'packages/enclave-sdk', - 'packages/enclave-contracts', - 'packages/enclave-config', - 'packages/enclave-react', - 'crates/wasm' - ] - - for (const packagePath of packagesToBump) { + const packagesToBump = await fg(['packages/**/package.json', 'crates/**/package.json'], { + cwd: this.rootDir, ignore: ['**/node_modules/**', '**/examples/**', '**/template/**'] + }) + for (const packageJsonRel of packagesToBump) { - const fullPath = join(this.rootDir, packagePath) - const packageJsonPath = join(fullPath, 'package.json') + const packageJsonPath = join(this.rootDir, packageJsonRel)You can then filter by
private !== trueor a whitelist if needed.
54-59: Semver validator: allow common “v” prefix (optional).Some teams pass versions like
v1.2.3. You might strip a leadingvbefore validation.Example:
const normalized = version.startsWith('v') ? version.slice(1) : version
195-202: Consider updating inter‑package deps when not usingworkspace:*.If any internal packages depend on others without
workspace:*, you may also want to bump those dependency ranges. Not blocking for now.
215-229: Add a dry‑run flag (optional).A
--dry-runto print pending edits without writing would help reviewers during releases.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
.github/workflows/releases.yml(1 hunks)Cargo.toml(1 hunks)crates/wasm/package.json(1 hunks)package.json(2 hunks)packages/enclave-config/package.json(1 hunks)packages/enclave-contracts/package.json(1 hunks)packages/enclave-react/package.json(1 hunks)packages/enclave-sdk/package.json(1 hunks)scripts/README.md(1 hunks)scripts/bump-versions.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-10-22T02:36:01.448Z
Learnt from: ryardley
PR: gnosisguild/enclave#145
File: packages/ciphernode/data/Cargo.toml:0-0
Timestamp: 2024-10-22T02:36:01.448Z
Learning: In `packages/ciphernode/data/Cargo.toml`, `actix-rt` is only used in tests and should remain in `[dev-dependencies]`.
Applied to files:
Cargo.toml
📚 Learning: 2025-08-25T10:28:56.174Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#657
File: Cargo.toml:32-34
Timestamp: 2025-08-25T10:28:56.174Z
Learning: The examples/CRISP directory has its own Cargo.toml workspace configuration with members like "server", "wasm-crypto", "program/core", "program/client", etc. The root workspace intentionally excludes "examples/CRISP/server", "examples/CRISP/program", and "examples/CRISP/wasm-crypto" to prevent double workspace membership, which is the correct approach for self-contained example workspaces.
Applied to files:
Cargo.toml
🪛 GitHub Actions: License Header Check
scripts/bump-versions.ts
[error] 1-1: License header missing. The file must include the SPDX license header as specified. Expected header format: // SPDX-License-Identifier: LGPL-3.0-only ...
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: integration_prebuild
- GitHub Check: build_enclave_cli
- GitHub Check: build_e3_support_dev
- GitHub Check: build_sdk
- GitHub Check: test_contracts
- GitHub Check: rust_unit
🔇 Additional comments (5)
packages/enclave-contracts/package.json (1)
4-4: Version bump looks fine; confirm publish flow.All good on the manifest. Please double‑check that the release workflow/publish job is prepared to publish 0.0.15-test for this package and that any downstream examples pinning this version are updated.
Cargo.toml (2)
55-55: Workspace version bump LGTM.Setting
[workspace.package].version = "0.0.15-test"aligns withshared-version = true. No concerns.
62-86: Sanity check: all workspace dependency versions updated consistently.The inline
{ version = "...", path = "..." }entries are consistent at 0.0.15-test. If any crates use the table form ([workspace.dependencies.foo]with a separateversion =line), ensure they’re also updated by the bump script.package.json (2)
12-12: Script wiring LGTM.
"bump:versions": "tsx scripts/bump-versions.ts"matches the CLI; no shebang needed in the TS file for this path.
62-65: Dev deps OK; check Node/PNPM alignment.
tsxandtypescript@5.8.3align with your existing overrides. Ensure the CI Node version supports tsx (≥16.8, ideally ≥18).
43ef721 to
bf98bbf
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
scripts/bump-versions.ts (6)
58-63: Use a proven semver parser instead of a homegrown regex.Regex here will accept some invalid semver variants and reject edge cases. Use
semverfor correctness.Apply this diff:
@@ -import { readFileSync, writeFileSync, existsSync } from 'fs' +import { readFileSync, writeFileSync, existsSync } from 'fs' +import semver from 'semver' @@ - private validateVersion(version: string): void { - const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/ - if (!semverRegex.test(version)) { - throw new Error(`Invalid version format: ${version}. Expected format: x.y.z[-prerelease][+build]`) - } - } + private validateVersion(version: string): void { + if (!semver.valid(version)) { + throw new Error(`Invalid version: ${version}. Expected SemVer (e.g., 1.2.3, 1.2.3-beta.1)`) + } + }Remember to add
semverto dependencies (or devDependencies).Also applies to: 7-9
19-22: MakerootDirresolution ESM‑safe (if the repo uses"type": "module").
__dirnameis undefined under ESM. If your repo is ESM, switch toimport.meta.urlfallback.Snippet:
import { fileURLToPath } from 'url' import { dirname, resolve } from 'path' const here = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url)) this.rootDir = resolve(here, '..')If you’re CJS, current code is fine. Please confirm the module type.
96-105: Avoid double I/O: return the name from updatePackageJson and drop getPackageName.You read package.json twice. Read once, write, and return the name for logging.
Apply this diff:
@@ - if (existsSync(packageJsonPath)) { - this.updatePackageJson(packageJsonPath) - const packageName = this.getPackageName(packageJsonPath) - console.log(` ✓ ${packageName}`) - } + if (existsSync(packageJsonPath)) { + const packageName = this.updatePackageJson(packageJsonPath) + console.log(` ✓ ${packageName}`) + } @@ - private updatePackageJson(filePath: string): void { + private updatePackageJson(filePath: string): string { const content = readFileSync(filePath, 'utf-8') const packageJson: PackageJson = JSON.parse(content) packageJson.version = this.newVersion // Write back with proper formatting writeFileSync(filePath, JSON.stringify(packageJson, null, 2) + '\n') + return packageJson.name || 'unknown' } @@ - private getPackageName(filePath: string): string { - const content = readFileSync(filePath, 'utf-8') - const packageJson: PackageJson = JSON.parse(content) - return packageJson.name || 'unknown' - } + // getPackageName removed (no longer needed)Also applies to: 198-206, 211-215
88-95: Consider discovering packages from workspaces instead of hardcoding paths.Read packages from
pnpm-workspace.yaml(or root package.jsonworkspaces) to avoid drift and ensure new packages are bumped automatically. I can wire this withyamlparsing and simple glob expansion.
154-159: Fail fast if no version was updated in Cargo.toml.A warning here can hide failures; prefer throwing to stop the run and surface misconfigurations.
Apply this diff:
- if (updated) { - writeFileSync(filePath, lines.join('\n')) - } else { - console.warn(`⚠️ Could not find version in ${filePath}`) - } + if (!updated) { + throw new Error(`Could not find [workspace.package].version in ${filePath}`) + } + writeFileSync(filePath, lines.join('\n'))
219-238: Optional CLI polish: add-h/--helpand a--dry-runmode.Small UX wins for release engineers; dry‑run prints planned edits without writing files.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockexamples/CRISP/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (1)
scripts/bump-versions.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: build_sdk
- GitHub Check: build_enclave_cli
- GitHub Check: test_net
- GitHub Check: build_e3_support_dev
- GitHub Check: test_contracts
- GitHub Check: integration_prebuild
- GitHub Check: rust_unit
- GitHub Check: Build & Push Image
🔇 Additional comments (1)
scripts/bump-versions.ts (1)
1-7: Fix CI: SPDX header must be the first line; remove the shebang.License check requires the SPDX header at line 1. Also, the shebang isn’t needed when running via pnpm/tsx.
Apply this diff:
-#!/usr/bin/env tsx -// SPDX-License-Identifier: LGPL-3.0-only -// -// This file is provided WITHOUT ANY WARRANTY; -// without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE.
bf98bbf to
820ea9d
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (2)
scripts/bump-versions.ts (2)
1-7: License header must be first line (drop the shebang).The compliance check still fails because the shebang precedes the SPDX block that must start the file. Remove the shebang so the header is the very first line.
-#!/usr/bin/env tsx -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only // // This file is provided WITHOUT ANY WARRANTY;
255-275: Stop mass-overwriting[workspace.dependencies]versions.
updateCargoToml()still replaces everyversion = "..."
in the workspace dependencies block, which will rewrite third-party crates likealloy,opentelemetry, etc. to0.0.15-testand break the build. Only bump entries that point to in-repo crates (e.g. those with apath), or drop the automatic edit entirely.- if (depLine.includes('version = ')) { - const updatedLine = depLine.replace(/version = "[^"]*"/, `version = "${this.newVersion}"`) + if (depLine.includes('path =') && depLine.includes('version = ')) { + const updatedLine = depLine.replace(/version = "[^"]*"/, `version = "${this.newVersion}"`) lines[j] = updatedLine updated = true }(Consider a proper TOML parse if you need to handle multi-line dependency tables.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
Cargo.lockis excluded by!**/*.lockexamples/CRISP/Cargo.lockis excluded by!**/*.lockpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
.changeset/README.md(0 hunks).changeset/config.json(0 hunks).github/workflows/binary-releases.yml(0 hunks).github/workflows/ci.yml(1 hunks).github/workflows/publish-evm.yml(0 hunks).github/workflows/releases.yml(1 hunks)CHANGELOG.md(1 hunks)Cargo.toml(1 hunks)README.md(1 hunks)package.json(2 hunks)scripts/bump-versions.ts(1 hunks)
💤 Files with no reviewable changes (4)
- .github/workflows/binary-releases.yml
- .changeset/README.md
- .changeset/config.json
- .github/workflows/publish-evm.yml
✅ Files skipped from review due to trivial changes (1)
- .github/workflows/ci.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: test_contracts
- GitHub Check: test_net
- GitHub Check: integration_prebuild
- GitHub Check: build_enclave_cli
- GitHub Check: build_sdk
- GitHub Check: build_e3_support_dev
- GitHub Check: build_e3_support_risc0
- GitHub Check: rust_unit
- GitHub Check: Build & Push Image
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
scripts/bump-versions.ts (1)
379-440: Stop overwriting every[workspace.dependencies]version.This still rewrites every dependency under
[workspace.dependencies]to the new release version, so crates likeserde,anyhow, etc. end up set to0.0.14-test, breaking the workspace the next timecargoruns. Please revert to only touching[workspace.package].versionand drop the dependency-mutation logic entirely.- // Update workspace dependencies in root Cargo.toml - this.updateWorkspaceDependencies(rootCargoPath) - - console.log(' ✓ All workspace crates updated via workspace.version') + console.log(' ✓ All workspace crates updated via workspace.version') @@ - // Update workspace dependencies - if (line === '[workspace.dependencies]') { - // Look for dependency lines with inline versions - for (let j = i + 1; j < lines.length; j++) { - const depLine = lines[j].trim() - - // Skip empty lines and new sections - if (depLine === '' || depLine.startsWith('[')) { - break - } - - // Update lines that have version = "..." in them - if (depLine.includes('version = ')) { - // Replace the version part while preserving the rest - const updatedLine = depLine.replace(/version = "[^"]*"/, `version = "${this.newVersion}"`) - lines[j] = updatedLine - updated = true - } - } - } @@ - /** - * Update workspace dependencies in root Cargo.toml - */ - private updateWorkspaceDependencies(filePath: string): void { - const content = readFileSync(filePath, 'utf-8') - const lines = content.split('\n') - - let inWorkspaceDeps = false - let updated = false - - for (let i = 0; i < lines.length; i++) { - const line = lines[i].trim() - - if (line === '[workspace.dependencies]') { - inWorkspaceDeps = true - continue - } - - if (inWorkspaceDeps && line.startsWith('version = ')) { - lines[i] = `version = "${this.newVersion}"` - updated = true - } - - // Reset when we hit a new section - if (line.startsWith('[') && inWorkspaceDeps && line !== '[workspace.dependencies]') { - break - } - } - - if (updated) { - writeFileSync(filePath, lines.join('\n')) - } - }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
CHANGELOG.md(1 hunks)README.md(1 hunks)enclave.sh(1 hunks)run_nodes.sh(1 hunks)scripts/bump-versions.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
run_nodes.sh (1)
crates/config/src/app_config.rs (1)
nodes(283-285)
🪛 Gitleaks (8.28.0)
enclave.sh
[high] 10-10: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md
31-31: Multiple headings with the same content
(MD024, no-duplicate-heading)
61-61: Multiple headings with the same content
(MD024, no-duplicate-heading)
117-117: Multiple headings with the same content
(MD024, no-duplicate-heading)
145-145: Multiple headings with the same content
(MD024, no-duplicate-heading)
🪛 Shellcheck (0.11.0)
enclave.sh
[error] 1-1: Remove spaces between # and ! in the shebang.
(SC1115)
run_nodes.sh
[error] 1-1: Remove spaces between # and ! in the shebang.
(SC1115)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: rust_unit
- GitHub Check: build_sdk
- GitHub Check: integration_prebuild
- GitHub Check: test_net
- GitHub Check: test_contracts
- GitHub Check: build_enclave_cli
- GitHub Check: Build & Push Image
🔇 Additional comments (1)
README.md (1)
163-299: Release process doc looks great.The new release/versioning walkthrough is clear and ties together the scripts and workflows nicely. Thanks for spelling this out.
d96c268 to
49a35f7
Compare
833006d to
e3245e2
Compare
re #744
Summary by CodeRabbit
New Features
Documentation
Chores