This repository uses a single release orchestrator workflow:
.github/workflows/release.yml(Release)
The workflow handles release branch creation, version bump, artifact build, tag/release finalization, and crates.io publish in one run.
- You have write access to run workflows.
- crates.io trusted publisher is configured for this repository/package.
- The workflow file exists on the default branch (
master).
.github/workflows/release.yml(Release) is the canonical release workflow:
- validates release inputs
- bumps
Cargo.tomlandCargo.lock - validates crate publishability with
cargo publish --dry-run(normal mode) - creates/reuses tag and GitHub release assets (real mode)
- publishes to crates.io as the final irreversible step (normal mode)
.github/workflows/build.yml(Build Release Artifacts) is a manual utility:
- builds Linux/macOS binaries for any input ref
- uploads build artifacts
- does not bump version
- does not publish to crates.io
- does not create tag or GitHub release
- Open Actions in GitHub.
- Select Release workflow.
- Click Run workflow on
master. - Enter version as
X.Y.Z(example:0.4.14). - Choose
dry_run:
truefor safe validation (recommended first run)falsefor real publish/tag/release
- Choose
skip_publish_check:
falsefor normal releases (default)trueonly for recovery when the crate version is already published and you need to finish tag/release
- Start run.
- Validates:
- trigger branch is default branch
- version format is semver (
X.Y.Z) skip_publish_checkis a valid boolean and only used withdry_run=false- records whether the target tag already exists (for safe reruns)
- when
skip_publish_check=false: crate version is not already published - when
skip_publish_check=true: crate version is already published
- Prepares release commit:
- when
skip_publish_check=false: bumpsCargo.toml+Cargo.lockand runscargo check --locked - when
dry_run=falseandskip_publish_check=falseand tag does not exist: pushesrelease/vX.Y.Zbranch and opens/reuses release PR - when
skip_publish_check=falseand tag already exists: reuses the tagged release commit for reruns - when
skip_publish_check=true: reuses existingrelease/vX.Y.Zbranch commit without rewriting it
-
Builds artifacts (Linux + macOS) with
fail-fast: false. -
Publishes crate:
- when
skip_publish_check=false: runscargo publish --dry-run --lockedas a preflight validation - when
skip_publish_check=true: skips dry-run publish validation
- Finalizes release:
- when
dry_run=false: creates/reuses tag (vX.Y.Z), creates GitHub release with binaries + checksums, then publishes to crates.io - crates.io publish is the final step in normal mode
- when
skip_publish_check=true: skips crates.io publish because version is already published - when
dry_run=true:finalize_releasejob is skipped
- Merge the release PR (
release/vX.Y.Z) intomaster. - (Not applicable for
dry_run=true, because no PR is created.)
After a published GitHub Release, workflow Open API Dockerfile bump PR (.github/workflows/open-verified-programs-api-pr.yml) opens a pull request on otter-sec/solana-verified-programs-api so api/Dockerfile pins the same solana-verify tag (vX.Y.Z) as this release.
- Keep Docker image publish and whitelist updates in sync:
- merge Dockerfile changes
- publish images
- merge whitelist update PR
- Keep auto-generated PR commits signed (
sign-commits: truein create-pull-request workflows). - Post-install verification of installed toolchain/platform-tools is tracked as follow-up hardening.
- Fails in
dry_run=truemode:
- fix workflow/build issues and rerun
dry_run=trueuntil green
- Fails before finalization in real mode:
- fix issue
- re-run workflow with same version
- Fails during finalization before crates publish:
- rerun workflow with the same version
- existing tag/commit state is reused where possible, and tag push is idempotent when it already points to the expected commit
- Crates publish step fails in real mode:
- fix the publish error and rerun workflow with the same version
- if tag/release already exists from the previous attempt, rerun will reuse it and continue to the publish step
- Crate already published but tag/release missing:
- rerun
Releasewith the same version anddry_run=false,skip_publish_check=true - this reuses the existing published crate version and continues with tag/release creation
- recovery mode requires
release/vX.Y.Zto already exist on origin - if the tag already exists but GitHub release is missing, create the GitHub release manually for that existing tag
- merge the existing release PR after tag/release is in place
- do not publish a new crate version unless you intentionally want a new release