feat: add git-based versioning and auto-release workflow#274
Conversation
There was a problem hiding this comment.
Pull request overview
Adds git-derived versioning to parser binaries and introduces automated tagging/release automation so built artifacts (notably Docker images) can embed meaningful versions instead of a hardcoded string.
Changes:
- Add
scripts/auto-version.shto compute a git-based version string used at build time. - Add
build.rsscripts for parser crates to set a compile-timeVERSIONenv (with fallback behavior). - Introduce a
release.ymlworkflow that auto-tags pushes tomainand dispatchesstagex.ymlto build tagged images with the semver embedded; updatestagex.ymland Containerfiles to passVERSIONthrough Docker builds.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
src/parser/grpc-server/build.rs |
New build script to set compile-time VERSION for grpc-server builds. |
src/parser/cli/src/cli.rs |
Switch clap CLI version string from hardcoded "1.0" to env!("VERSION"). |
src/parser/cli/build.rs |
New build script to compute/set VERSION (env → script → dev). |
src/parser/app/src/cli.rs |
Switch displayed version from CARGO_PKG_VERSION to env!("VERSION"). |
src/parser/app/build.rs |
New build script to compute/set VERSION (env → script → dev). |
scripts/auto-version.sh |
New git-based version computation script (branch + hash + commit-height style). |
images/parser_cli/Containerfile |
Thread VERSION into the container build via ARG/ENV. |
images/parser_app/Containerfile |
Thread VERSION into the container build via ARG/ENV. |
.github/workflows/stagex.yml |
Pass VERSION into make when building from a semver-like tag. |
.github/workflows/release.yml |
New workflow to compute version, create tags/releases, and dispatch stagex on the tag. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- release.yml: gate release job on `github.ref == 'refs/heads/main'` so
workflow_dispatch from a feature branch can't mint a tag/release for a
non-main commit.
- release.yml: fail fast in `check_tag` if the tag already exists at a
different commit than HEAD, instead of proceeding to publish a release
pointing at the wrong commit.
- build.rs (cli/app/grpc-server): add `cargo:rerun-if-changed` for
`.git/packed-refs` and `.git/refs/remotes/origin/{main,master}` so
Cargo invalidates the embedded version when the remote-tracking branch
advances after a `git fetch`.
- dflow_aggregator: recurse into JSON arrays with indexed labels
(`{key}[i]`) instead of collapsing to `[N items]`, so signers see the
actual contents of swap actions, minimum_outputs, etc.
One bot suggestion was skipped: comparing `inputs.dry_run != 'true'` is
correct because GitHub Actions stringifies workflow_dispatch boolean
inputs in expressions.
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- dflow_aggregator: empty objects/arrays were silently dropped after the
recursive flattening change; emit a single text field with value `{}`
or `[]` so the signer still sees the argument exists.
- dflow_aggregator: rename "remaining_account_<i>" labels to
"Remaining Account <i+1>" for consistency with the surrounding
human-readable labels (Program ID, Instruction, Discriminator).
- parser_gateway: stagex.yml already passes VERSION to all three image
targets via --build-arg, but the gateway Containerfile had no
ARG VERSION/ENV VERSION line and the crate had no build.rs, so VERSION
was silently dropped. Add the Containerfile arg, a build.rs mirroring
parser_{app,cli,grpc-server}, and a startup log line that prints the
resolved version, so the wiring stagex.yml put in place is actually
consumed.
- dflow_aggregator: add tests for push_arg_fields (scalars, recursive
objects/arrays, indexed array labels, empty collections) and for
build_named_accounts surfacing trailing accounts as extra_accounts,
plus a test that the remaining-account labels are human-readable.
Skipped: 3 build.rs threads asking us to also watch
refs/remotes/upstream/{main,master}. The fork-with-upstream-remote
scenario is a narrow local-dev edge case and origin/{main,master} +
packed-refs already cover the common case; CI always uses origin.
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adds scripts/auto-version.sh to compute a semver-like version from git
history. Each parser binary crate now has a build.rs that reads the
VERSION env var (set by CI/Containerfiles) or falls back to
auto-version.sh at compile time. Binaries expose version via
env!("VERSION") instead of CARGO_PKG_VERSION.
release.yml runs on every push to main: computes the version, creates a
git tag, publishes a GitHub release, then dispatches the stagex image
build. stagex.yml gains the scripts/** trigger path, fetch-depth: 0 for
full history, and passes VERSION into the Docker build args.
Co-Authored-By: Claude <noreply@anthropic.com>
18473bb to
6d6264b
Compare
prasanna-anchorage
left a comment
There was a problem hiding this comment.
nits around relative paths
| return Ok(()); | ||
| } | ||
|
|
||
| if let Some(version) = Command::new("../../../scripts/auto-version.sh") |
There was a problem hiding this comment.
instead of relative paths, we should be able to use the env!("CARGO_MANIFEST_DIR"); instead so that it's safe in other OSes
There was a problem hiding this comment.
Fixed — now using env!("CARGO_MANIFEST_DIR") + PathBuf to build absolute paths for both the cargo:rerun-if-changed directives and the Command::new call.
Addressed by Claude, code change applied.
| use std::process::Command; | ||
|
|
||
| fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
| println!("cargo:rerun-if-env-changed=VERSION"); |
There was a problem hiding this comment.
same comment, can we try using env!("CARGO_MANIFEST_DIR"); and relative paths using PathBuf? I might have to add a windows builder to make sure these don't break regardless
There was a problem hiding this comment.
Same fix applied here — env!("CARGO_MANIFEST_DIR") + PathBuf for all path construction.
Addressed by Claude, code change applied.
Relative ../../../ paths in cargo:rerun-if-changed directives and
Command::new() work on Linux but aren't safe cross-platform. Use
env!("CARGO_MANIFEST_DIR") + PathBuf to construct absolute paths,
matching Cargo's documented approach.
Co-Authored-By: Claude <noreply@anthropic.com>
| @@ -100,7 +100,7 @@ impl Cli { | |||
| let opts = ParserOpts::new(&mut args); | |||
|
|
|||
| if opts.parsed.version() { | |||
| println!("version: {}", env!("CARGO_PKG_VERSION")); | |||
| println!("version: {}", env!("VERSION")); | |||
There was a problem hiding this comment.
I wonder if templating CARGO_PKG_VERSION is safer here?
There was a problem hiding this comment.
I'm a beginner on rust, but it seems like CARGO_PKG_VERSION will have a static version because we are not changing Cargo.toml.
r-n-o
left a comment
There was a problem hiding this comment.
Reviewing just from a stagex build point of view, I think this will work. But it seems like a lot of new code that's hard to test. So the only real way to gain confidence is to either merge and try (and fix as needed), or maybe make a clone of this repo to try this in earnest.
I agree that there are a lot of changes, but it is not easy to break into smaller PRs. I think we can merge it and quickly fix it in case something breaks. |
env!("VERSION") is baked in by build.rs (added in #274) but was only
surfaced via the dedicated --version flag. Container operators reading
parser_app's stdout (e.g. via TVC deploy logs) couldn't tell which
build they were running. Print it alongside the existing startup
banner so the version is visible without command-line introspection.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Why am I making this PR?
Binaries had a hardcoded version string (
1.0) with no connection to the actual release state. There was no automated way to tag releases or produce versioned Docker images.What am I changing?
Adding
scripts/auto-version.sh(adapted fromvisualsign-turnkeyclient) that computes0.COMMIT_HEIGHT.0+branch-hashfrom git history.build.rsin the three binary crates bakes this intoenv!("VERSION")at compile time, falling through fromVERSIONenv var → script →"dev". A newrelease.ymlworkflow auto-tags every push to main asv0.N.0and explicitly dispatchesstagex.ymlon that tag so released Docker images get the semver embedded.What is the Linear ticket?
N/A
What are the rollback steps?
Revert the
release.ymlworkflow to stop auto-tagging. The build.rs changes are additive and safe to leave in place — binaries will fall back to"dev"ifauto-version.shis unavailable.Is this change backwards compatible?
Yes. The
VERSIONenv var path is additive; nothing relied on the previous hardcoded"1.0"string.Does this require cross-team/service coordination?
No.
How do I know it works as designed? Which tests exercise this code?
Verified locally:
parser_cli --versionoutputs0.609.0+worktree-65634345-e10d806da050(git-derived).cargo clippy --all-targets -- -D warningspasses clean.Co-authored with Claude.