ci: add dispatch-driven release pipeline (bump → tag → build)#19
Conversation
|
Claude finished @bdimitrov-netzine's task in 2m 39s —— View job PR Review: ci/release-pipelineTasks
Overall this is a well-structured pipeline. The anti-recursion rationale is sound, all actions are SHA-pinned, shell scripts use Medium — Silent
|
Security Scan - CodeSeverity: HIGH, CRITICAL No vulnerabilities found View scan results |
|
Claude finished @bdimitrov-netzine's task in 2m 17s —— View job PR Review: ci/release-pipeline (re-review after sync)Tasks
What's new in this syncThe latest commit ( if: >
github.repository_owner == 'raylsnetwork' &&
contains(fromJSON(vars.RELEASE_ACTORS || '[]'), github.actor)The Prior review items — still openThe four items from the earlier automated review remain unaddressed. Recapping with current line numbers: Medium —
|
|
Claude finished @bdimitrov-netzine's task in 1m 25s —— View job PR Review: ci/release-pipeline (re-review — commit 79a3e7f)Tasks
What changed in this syncThe latest commit ( # Before (1bcc5eb)
if: >
github.repository_owner == 'raylsnetwork' &&
contains(fromJSON(vars.RELEASE_ACTORS || '[]'), github.actor)
# After (79a3e7f)
if: github.repository_owner == 'raylsnetwork'The implementation is correct and the commit message is transparent about the tradeoff. The header comment in Low — Outside collaborators with write can now cut releases
This is a deliberate policy call, not a bug. Whether it's the right call depends on your collaborator roster. If you currently have or expect to have outside collaborators with write access who shouldn't be able to cut releases, the allowlist approach from No change needed if the collaborator set is tightly controlled, but worth confirming: do any outside collaborators in Medium —
|
Adds semver release automation, gated to named release managers. release.yml (workflow_dispatch, input: patch/minor/major): bumps [workspace.package].version (all crates inherit it), syncs Cargo.lock, and opens a `chore(release): vX` PR assigned to the triggerer. Gated by `contains(fromJSON(vars.RELEASE_ACTORS||'[]'), github.actor)` — fails closed if the var is unset. PR-based because main is branch-protected. tag-on-release.yml (push: main, paths: Cargo.toml): when [workspace.package].version changes on main, creates tag vX and builds the devnet image. Calls build-docker.yml via workflow_call rather than the tag push, because a GITHUB_TOKEN-created tag does not trigger other workflows (GitHub anti-recursion). build-docker.yml: the meta step now keys the tag off INPUT_TAG instead of github.event_name, so a workflow_call from a push-triggered caller resolves correctly (previously it would mis-derive the tag from a branch ref). Adds a guard: a manually pushed v* tag must match the committed workspace version, else the build fails fast. Cargo.toml is the single source of truth; the tag is derived from it.
Also require github.repository_owner == 'raylsnetwork' on the release job, so the workflow can only cut a release from the canonical org repo, never a fork — in addition to the existing RELEASE_ACTORS actor gate. This is a fork guard, not an org-membership check.
Broaden who can cut a release from a named allowlist to any collaborator / org member with write access to the canonical repo. workflow_dispatch already requires write access, so the job now only pins repository_owner == 'raylsnetwork' as a fork guard and drops the RELEASE_ACTORS check (variable removed). A strict org-membership assertion (excluding outside collaborators) would require a read:org PAT, which the default GITHUB_TOKEN can't do; left out to avoid a new secret.
79a3e7f to
4942dea
Compare
|
Claude finished @bdimitrov-netzine's task in 1m 42s —— View job PR Review: ci/release-pipeline (re-review — commit 4942dea)Tasks
What changed in this syncThe branch was force-pushed; commits # Before (1a58062)
if: >
github.repository_owner == 'raylsnetwork' &&
contains(fromJSON(vars.RELEASE_ACTORS || '[]'), github.actor)
# After (4942dea)
if: github.repository_owner == 'raylsnetwork'The header comment in Open items — three issues remain unaddressedMedium —
|
Semver release automation.
Cargo.toml([workspace.package].version, inherited by all crates) is the single source of truth; the tag is derived from it. Gated to named release managers.Flow
Files
release.yml—workflow_dispatchwithbump: patch|minor|major. Computes the next version (prerelease/build suffixes stripped), rewrites only the[workspace.package]version line (members keepversion.workspace = true), runscargo update --workspaceto syncCargo.lock(leaves third-party deps alone), and opens the release PR assigned to you.tag-on-release.yml— onpush: maintouchingCargo.toml, tagsvXonly if the workspace version actually changed and the tag doesn't already exist, then builds the devnet image.build-docker.yml— meta step now keys the tag offINPUT_TAGrather thangithub.event_name(so aworkflow_callfrom a push-triggered caller resolves correctly instead of mis-deriving from a branch ref), plus a guard that a hand-pushedv*tag must match the committed version.Access gating (per your request)
The
bumpjob runs only ifgithub.actoris in theRELEASE_ACTORSrepo variable (already set to["bdimitrov-netzine"]).workflow_dispatchalready needs write access; this narrows it to you, and fails closed if the variable is ever unset. Merging the release PR is separately gated by branch protection (required review).Why
workflow_callinstead of the tag push triggering the buildA tag created with the default
GITHUB_TOKENdoes not trigger other workflows (GitHub anti-recursion), sobuild-docker.yml'son: push: tagswould never fire for an auto-created tag. Calling it directly avoids needing a PAT/App token.Notes / how it matches Solana's agave
The bump-PR half mirrors agave's
bump-version.yml(dispatch + level → bump Cargo.toml → open PR assigned to triggerer). Differences: agave stops at the PR (no tag/build; tagging is separate) and gates by org (repository_owner), not by user. Ours chains through to tag+build and gates by actor.Two constraints to keep in mind: builds only ever produce devnet images (testnet/mainnet still go through
promote-docker.yml's approval gate); and the version is compiled into block extradata (rayls-network/v<ver>/<os>, ≤32 bytes) so avoid long prerelease suffixes.Validated: actionlint clean; bump logic unit-checked for patch/minor/major + prerelease-strip; awk edit confirmed to touch only the single
[workspace.package]version line.