Conversation
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
…rsion on Fastly Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Review summary
Reviewed cd704a7aacb4df866c471cfafe3cf6d130ad5fcb against a4e01eb55fe940bd02b2426dccd46050704c54c5. Requesting changes for the two P2 correctness issues documented inline. Both were reproduced in temporary fixtures without editing repository files.
Validation
The 10 resolver tests, 7 core header tests, and focused Fastly, Axum, Cloudflare, and Spin tests passed. Consecutive override builds emitted the requested versions without cleaning the target cache; removing the override restored the local branch value. All 20 reported CI checks pass.
The second pass exercised the shipped header helper with repository-locked dependencies and the unchanged build script in a packed-ref Cargo fixture. No duplicate review feedback was present. Full Viceroy HTTP smoke testing and live Cloudflare/Spin deployment were not independently repeated.
| /// Sets `x-ts-version` to `version`, or leaves it unset when `version` is | ||
| /// unknown or invalid. | ||
| pub fn apply_git_version_header_from(version: Option<&str>, response: &mut Response) { | ||
| if let Some(value) = header_value_from(version) { |
There was a problem hiding this comment.
P2: Remove an upstream version when the compiled version is unknown
When a build has neither git metadata nor TRUSTED_SERVER_GIT_VERSION, this branch does nothing rather than ensuring the header is absent. Publisher pass-through preserves origin response headers, so an upstream x-ts-version survives and is presented as this deployment's version. This contradicts the documented omission behavior and can mislead external deployment checks.
Reproduced with the shipped helper and repository-locked dependencies: starting with x-ts-version: 42, both None and an invalid version left 42 intact; a valid v2.0.0 correctly replaced it. The existing omission test starts with an empty response and misses this case.
Remove the existing header before conditionally inserting the compiled value. Operator response headers still run afterward and can intentionally override it. Add regression coverage starting with a pre-existing header.
| if let Some(value) = header_value_from(version) { | |
| response.headers_mut().remove(HEADER_X_TS_VERSION); | |
| if let Some(value) = header_value_from(version) { |
| if let Some(common_dir) = git(&["rev-parse", "--path-format=absolute", "--git-common-dir"]) { | ||
| let common_dir = Path::new(&common_dir); | ||
| if let Some(branch_ref) = git(&["symbolic-ref", "-q", "HEAD"]) { | ||
| rerun_if_exists(&common_dir.join(branch_ref)); |
There was a problem hiding this comment.
P2: Detect creation of the current branch's loose ref
If the current branch exists only in packed-refs, rerun_if_exists omits its loose ref from Cargo's watch list. Advancing that branch creates the loose ref without changing HEAD, packed-refs, or refs/tags, so a warm build retains the previous compiled version.
Reproduced in a temporary Cargo fixture using this unchanged build script: tag the current commit v1.2.3, run git pack-refs --all --prune, and build. Then change application code, commit, and rebuild without an override. The new executable printed changed code: Some("v1.2.3"); all watched git mtimes were unchanged and the build script did not rerun. Executing the resolver afresh returned main.
The design explicitly acknowledges this limitation, but it means newer code can identify itself as an earlier release, undermining the purpose of the header. When the loose ref is absent, watch its nearest existing parent directory, or accept watching the missing current-ref path. Add a warm-cache regression covering a tagged, packed branch advancing to a new commit.
Summary
x-ts-versionnow reports the deployed git version: the tag, else the branch, else exactly the first 6 characters of the commit. It is compiled in from the build-timeTRUSTED_SERVER_GIT_VERSION(set by the deploy pipeline), falling back to local git, and is omitted when neither is available.x-ts-fastly-version. Under Viceroy,maintoday answers withx-ts-version: 0, which is the Fastly version, not a Trusted Server one. Breaking for anything that readsx-ts-versionas the Fastly version number.x-ts-version, including the FastlyGET /healthfast path that deploy health checks probe. Operatorresponse_headersstill apply last.Changes
crates/trusted-server-core/build.rsTS_GIT_VERSION;rerun-if-env-changed=TRUSTED_SERVER_GIT_VERSION; watch the worktreeHEAD, the current branch's ref,refs/tagsandpacked-refs(existing paths only; other branches andrefs/remotesskipped)crates/trusted-server-core/build_support/git_version.rs#[path]; visible-ASCII rulecrates/trusted-server-core/tests/git_version_resolve.rscrates/trusted-server-core/src/constants.rsHEADER_X_TS_FASTLY_VERSION,TS_GIT_VERSIONcrates/trusted-server-core/src/version_header.rsgit_version_header_value,apply_git_version_header(+ testable variants)crates/trusted-server-core/src/lib.rsversion_headercrates/trusted-server-adapter-fastly/src/middleware.rsx-ts-version,FASTLY_SERVICE_VERSIONtox-ts-fastly-version; doc commentscrates/trusted-server-adapter-fastly/src/main.rs/healthfast path setsx-ts-versioncrates/trusted-server-adapter-{axum,cloudflare,spin}/src/middleware.rsapply_git_version_headerbefore operator headerscrates/trusted-server-adapter-axum/tests/routes.rs,crates/trusted-server-adapter-spin/src/app.rs/healthroute tests assert the headerdocs/guide/first-party-proxy.mdX-TS-VersionCHANGELOG.mddocs/superpowers/{specs,plans}/2026-09-25-git-version-header*.mdCloses
Closes #1212
Related: #325 (introduced
x-ts-versionas the Fastly version)Test plan
cargo test-fastly && cargo test-axum && cargo test-cloudflare && cargo test-spinclippy-fastly,-axum,-cloudflare,-cloudflare-wasm,-spin-native,-spin-wasm,-cli,-codegen)cargo fmt --all -- --checkcargo test --manifest-path crates/trusted-server-integration-tests/Cargo.toml --test paritycd crates/trusted-server-js/lib && npx vitest run(1130 passed; no JS changes. Run withNODE_OPTIONS=--no-webstoragelocally, because Node 26's built-inlocalStorageshadows jsdom's. The repo pins Node 24.12.0, where this doesn't apply.)cd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serve: offline end-to-end under Viceroy (below)End-to-end under Viceroy. Release Wasm served with
fastly compute serve --file <wasm>and a local config pushed withts config push --adapter fastly --local, set up the same way asscripts/smoke-fastly.sh. Each case curlsGET /healthandGET /and asserts200.x-geo-info-availableon/proves the response went throughapply_finalize_headers. Viceroy reportsFASTLY_SERVICE_VERSION=0./healthx-ts-version/x-ts-version/x-ts-fastly-versionTRUSTED_SERVER_GIT_VERSION=v9.9.9-testv9.9.9-testv9.9.9-test0…=v9.9.9-test2, no clean; Cargo: "the env variable TRUSTED_SERVER_GIT_VERSION changed"v9.9.9-test2v9.9.9-test20feat/git-version-header0HEAD00.git, unset0It also checks the rebuild triggers. A new tag alone triggers a rebuild through
refs/tags. Moving the current branch off a tagged commit triggers one through the branch ref and switches the value from the tag to the branch. A simulated fetch (git update-ref refs/remotes/...) and a ref update on another branch both leave coreFresh. An override ofv1-étéprints acargo:warningand falls back to local git.Checklist
unwrap()in production code — useexpect("should ...")tracingmacros (notprintln!) — this repo useslogper AGENTS.md; the onlyprintln!calls are thecargo:directives inbuild.rs