Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
b772cd3
Phase the reviewed binary attestation contract
prk-Jr Oct 22, 2026
be81ca8
Map binary attestation phases to review boundaries
prk-Jr Oct 22, 2026
ca06217
Build and attest phased release binaries
prk-Jr Oct 22, 2026
4dd2171
Document binary verification and release deployment
prk-Jr Oct 22, 2026
3c41de5
Align Phase 1 signing and publication with the reviewed contract
prk-Jr Oct 22, 2026
cb82e4b
Allow the exact GitHub Actions build type reference host
prk-Jr Oct 22, 2026
41896cb
Document Phase 1 compatibility and verification boundaries
prk-Jr Oct 22, 2026
ca902b6
Avoid stale API connections during release verification
prk-Jr Oct 22, 2026
f3a8696
Clarify rehearsed release status and CLI verification
prk-Jr Oct 22, 2026
922c221
Retry transient post-publication verification reads
prk-Jr Oct 22, 2026
ff9f9c4
Document offline verification and completed release rehearsal
prk-Jr Oct 22, 2026
7c7f4b0
Add production Axum assets and release startup checks
prk-Jr Oct 22, 2026
b818b59
Disable rustup self-updates in temporary build homes
prk-Jr Oct 22, 2026
16d6690
Expose pinned compiler binaries in the GNU builder
prk-Jr Oct 22, 2026
937214a
Supply runtime trust data to Axum startup checks
prk-Jr Oct 23, 2026
6824226
Record the seven-binary release rehearsal
prk-Jr Oct 23, 2026
e907e26
Derive immutable release build facts
prk-Jr Oct 23, 2026
72b7e1e
Allow runtime Axum bind address overrides
prk-Jr Oct 23, 2026
81a5a72
Harden release eligibility and artifact validation
prk-Jr Oct 23, 2026
39a769c
Align release documentation and reference-host policy
prk-Jr Oct 23, 2026
e22d700
Reduce startup logging and align runtime port aliases
prk-Jr Oct 23, 2026
2cc39ec
Harden release verification and preflight boundaries
prk-Jr Oct 23, 2026
7a05940
Record rehearsal failure and release recovery checks
prk-Jr Oct 23, 2026
f84ab21
Record the successful binary attestation rehearsal
prk-Jr Oct 23, 2026
149754d
Handle attestation availability and verify published bytes
prk-Jr Oct 23, 2026
f66da48
Record the successful ninth attestation rehearsal
prk-Jr Oct 23, 2026
a501d1b
Clarify final release verification notes (docs-only)
prk-Jr Oct 23, 2026
26d69ce
Record approved attestation phase assignment and closure checks
prk-Jr Oct 26, 2026
4ee86da
Require runtime source resources in release CLI builds
prk-Jr Oct 26, 2026
15a7b40
Propose ordinary Fastly release equality integration
prk-Jr Oct 26, 2026
8874e4f
Record approved Fastly gate activation and compatibility conditions
prk-Jr Oct 26, 2026
1534d46
Port strict release documents and process supervision
prk-Jr Oct 26, 2026
d0d5c37
Specify reviewed ordinary Fastly gate implementation
prk-Jr Oct 26, 2026
d1c1d69
Align integration notes with immutable release facts
prk-Jr Oct 26, 2026
021fdfd
Validate ordinary Fastly build observations
prk-Jr Oct 26, 2026
ad78fc5
Compare complete ordinary Fastly final bytes
prk-Jr Oct 26, 2026
bb05d98
Validate bounded ordinary Fastly transfer archives
prk-Jr Oct 26, 2026
afdc928
Merge current main and clarify bind diagnostics
prk-Jr Oct 26, 2026
6de495a
Merge Phase 1 updates into Phase 2
prk-Jr Oct 26, 2026
ce7daa5
Bind ordinary uploads to current producing jobs
prk-Jr Oct 26, 2026
4447b68
Port reviewed tool tree content measurement
prk-Jr Oct 26, 2026
ee5598b
Port reviewed final executable inspection
prk-Jr Oct 26, 2026
cb5f16a
Join ordinary archive bytes to release observations
prk-Jr Oct 26, 2026
13f63f0
Port the closed recipe and composition dependency graph
prk-Jr Oct 26, 2026
f0d00dd
Record the closed Phase 2 port and policy boundaries
prk-Jr Oct 26, 2026
c8ea09d
Measure ordinary recipe and private JavaScript input identities
prk-Jr Oct 26, 2026
c0f53a5
Port checked JavaScript preparation alongside ordinary release builds
prk-Jr Oct 26, 2026
f721ddb
Align remaining source identity documentation and comments
prk-Jr Oct 26, 2026
b2cde8b
Record compatible preparation and remaining release integration
prk-Jr Oct 26, 2026
3776d27
Link excluded compatibility notes through their committed source
prk-Jr Oct 26, 2026
cc4d0f3
Record source-pinned ordinary Fastly build observations
prk-Jr Oct 26, 2026
6e9f713
Seal real ordinary equality results in fresh atomic outputs
prk-Jr Oct 26, 2026
d365f56
Expose checked ordinary measurement and comparison commands
prk-Jr Oct 26, 2026
f9e6cce
Acquire ordinary transfer archives through bounded authenticated reads
prk-Jr Oct 26, 2026
4ede699
Keep diagnostic payload assertions independent of optional backtraces
prk-Jr Oct 26, 2026
1e9a209
Record ordinary adapter progress and remaining release wiring
prk-Jr Oct 26, 2026
cc7df93
Compare fresh ordinary Fastly builds before signing
prk-Jr Oct 26, 2026
604d5d8
Propose Fastly path normalization after the real A/B mismatch
prk-Jr Oct 27, 2026
7885bed
Bind Docker image configuration and disable inherited commands
prk-Jr Oct 27, 2026
18df990
Remove owned comparison outputs after sealing failures
prk-Jr Oct 27, 2026
635086d
Close inherited build controls and check direct JS entrypoints
prk-Jr Oct 27, 2026
7beaa54
Normalize compiler paths before ordinary Fastly byte comparison
prk-Jr Oct 27, 2026
169e2a3
Attest and publish the real Fastly rebuild check
prk-Jr Oct 27, 2026
6f34d62
Prove failed comparison skips downstream CI stages
prk-Jr Oct 27, 2026
886cf33
Pin the browser integration test job to ubuntu-24.04
prk-Jr Oct 27, 2026
a7e2056
Verify the pinned Fastly package route without network access
prk-Jr Oct 27, 2026
a8f8bcb
Record bounded raw Fastly package header diagnostics
prk-Jr Oct 27, 2026
7127077
Accept the confirmed Fastly directory header forms
prk-Jr Oct 27, 2026
3ccfe29
Construct duplicate-key fixtures explicitly
prk-Jr Oct 27, 2026
34e7e9e
Address self-review findings in release attestations
prk-Jr Oct 27, 2026
ab6e549
Strengthen release build-fact and gate tests
prk-Jr Oct 27, 2026
770a425
Merge Phase 1 updates into Phase 2
prk-Jr Oct 27, 2026
2ed1b94
Record verified rehearsals and online SBOM checks
prk-Jr Oct 27, 2026
68eef90
Merge remote-tracking branch 'origin/main' into feature/binary-attest…
prk-Jr Oct 27, 2026
2015231
Record the main-merge Phase 1 rehearsal
prk-Jr Oct 28, 2026
81020c0
Merge branch 'feature/binary-attestations-phase1' into feature/binary…
prk-Jr Oct 28, 2026
3ae0e19
Record the exact Phase 2 integration commit
prk-Jr Oct 28, 2026
7d55177
Merge commit '054c7b777ce67db34744cb1f4100b14e59c4bc5a' into feature/…
prk-Jr Oct 28, 2026
5349b7c
Record the newer-main Phase 2 integration
prk-Jr Oct 28, 2026
c9a6117
Record two independent Phase 1 spec review rounds
prk-Jr Oct 28, 2026
08e1c33
Merge the Phase 1 spec review log into Phase 2
prk-Jr Oct 28, 2026
4940928
Merge branch 'main' into feature/binary-attestations-phase1
prk-Jr Oct 28, 2026
8a797db
Merge the updated Phase 1 branch into Phase 2
prk-Jr Oct 28, 2026
f2b2fa8
Retain structured ordinary comparison failure diagnostics
prk-Jr Oct 28, 2026
5fa3843
Record Phase 2 spec reviews and reconcile readiness evidence
prk-Jr Oct 28, 2026
fb48433
Record the exact-source Phase 2 rehearsal and completed checks
prk-Jr Oct 28, 2026
927109f
Observe process groups without signalling after reaping
prk-Jr Oct 28, 2026
36454c5
Record the runtime verification and current phase tracking
prk-Jr Oct 28, 2026
5163241
Record the remaining rehearsal gate and runner failures
prk-Jr Oct 28, 2026
0f89eae
Record the successful Phase 2 release rehearsal
prk-Jr Oct 29, 2026
79b1188
Address attested release review feedback
prk-Jr Oct 29, 2026
990509b
Merge branch 'main' into feature/binary-attestations-phase1
prk-Jr Oct 29, 2026
c827eb2
Address maintainer review of Phase 1 attested releases
prk-Jr Nov 2, 2026
5f0139b
Merge main into feature/binary-attestations-phase1
prk-Jr Nov 2, 2026
890acd2
Record Phase 1 fork rehearsal .22 at the current head
prk-Jr Nov 2, 2026
029f204
Merge main into feature/binary-attestations-phase1
prk-Jr Nov 2, 2026
69b74e2
Bound release-attestation availability checks by their deadline
prk-Jr Nov 2, 2026
ba54b27
Merge main into feature/binary-attestations-phase1
prk-Jr Nov 2, 2026
54d10bb
Address second maintainer review of Phase 1 attested releases
prk-Jr Nov 3, 2026
121ad4e
Merge the updated Phase 1 branch into Phase 2
prk-Jr Nov 3, 2026
28d3552
Address self-review findings on the Phase 2 release gate
prk-Jr Nov 3, 2026
eb61157
Potential fix for pull request finding 'Unused variable, import, func…
prk-Jr Nov 3, 2026
07c2bdf
Address third maintainer review of Phase 1 attested releases
prk-Jr Nov 5, 2026
739016b
Raise the bundle check output limit and pin its real output size
prk-Jr Nov 5, 2026
3e2dd48
Test the remaining publisher and SPDX guards
prk-Jr Nov 5, 2026
3ddcd19
Merge the narrowed Phase 1 into Phase 2
prk-Jr Nov 5, 2026
9eeccbb
Restore the Cargo metadata file the ordinary capture reads
prk-Jr Nov 5, 2026
c8c1efd
Record rehearsal .27 of the narrowed Phase 2
prk-Jr Nov 5, 2026
861ed76
Refuse release tags on commits that are on no branch
prk-Jr Nov 5, 2026
4455722
Merge the Phase 1 branch check into Phase 2
prk-Jr Nov 5, 2026
1858b6d
Address Phase 2 review: drop inert canaries and unrelated churn
prk-Jr Nov 5, 2026
1860b99
Document Phase 2 review follow-ups
prk-Jr Nov 5, 2026
3e6bb0f
Address fourth maintainer review of Phase 1 attested releases
prk-Jr Nov 10, 2026
61fd178
Merge the Phase 1 fourth review round into Phase 2
prk-Jr Nov 10, 2026
f243408
Address the CHANGES_REQUESTED review of Phase 2 attested releases
prk-Jr Nov 10, 2026
e63ca7e
Give each Fastly role a private remapped Cargo home
prk-Jr Nov 10, 2026
092de44
Pin the remaining comparison and signing checks and drop unused code
prk-Jr Nov 10, 2026
0b1e350
Address the optional Phase 2 review suggestions
prk-Jr Nov 10, 2026
37dfc6d
Authenticate packaged Wasm before parsing and keep children waitable
prk-Jr Nov 10, 2026
ba05cab
Pin the round-3 release checks and correct the Phase 2 docs
prk-Jr Nov 11, 2026
e9e46e5
Merge main into Phase 2
prk-Jr Nov 11, 2026
27361ec
Narrow producer and attest Fastly packages
prk-Jr Nov 12, 2026
17e509b
Point release deployment links at the Fastly package section
prk-Jr Nov 12, 2026
fd33f2c
Merge main into Phase 2
prk-Jr Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ jobs:
- name: Run host-target CLI clippy
run: cargo clippy --package trusted-server-cli --target x86_64-unknown-linux-gnu --all-targets --all-features -- -D warnings

- name: Run host-target release producer clippy
run: cargo clippy --package trusted-server-release --target x86_64-unknown-linux-gnu --all-targets --all-features --locked -- -D warnings

- name: Lint native JS release build fixtures
run: cargo clippy --package trusted-server-js --target x86_64-unknown-linux-gnu --all-targets --all-features --locked -- -D warnings

# The codegen crate is a workspace member but is not a default member and
# is not covered by any adapter-scoped alias, so lint it explicitly.
- name: Run host-target OpenRTB codegen clippy
Expand Down Expand Up @@ -247,7 +253,7 @@ jobs:
node-version: ${{ steps.node-version.outputs.node-version }}

- name: Run shellcheck
run: shellcheck scripts/release/phase1-build.sh
run: shellcheck scripts/release/phase1-build.sh scripts/release/validate-fastly-package.sh scripts/release/bootstrap.sh scripts/release/build.sh scripts/release/build-js.sh

- name: Test release producer scripts
run: node --test scripts/release/phase1.test.mjs
354 changes: 339 additions & 15 deletions .github/workflows/release-build.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
uses: ./.github/workflows/release-build.yml
permissions:
contents: read
actions: read
id-token: write
attestations: write
release:
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ jobs:
- name: Run host-target CLI tests
run: ./scripts/test-cli.sh

- name: Run release producer primitive and process tests
run: |
set -euo pipefail
cargo test --package trusted-server-release --target x86_64-unknown-linux-gnu --locked --test commands -- --list > "$RUNNER_TEMP/ordinary-command-tests.txt"
grep -Fx 'ordinary_compare_mismatch_writes_no_companion: test' "$RUNNER_TEMP/ordinary-command-tests.txt"
cargo test --package trusted-server-release --target x86_64-unknown-linux-gnu --locked
cargo test --package trusted-server-release --target x86_64-unknown-linux-gnu --locked --test commands ordinary_compare_mismatch_writes_no_companion -- --exact > "$RUNNER_TEMP/ordinary-negative-result.txt"
cat "$RUNNER_TEMP/ordinary-negative-result.txt"
grep -E '^test result: ok\. 1 passed; 0 failed; 0 ignored;' "$RUNNER_TEMP/ordinary-negative-result.txt"

- name: Run checked and ordinary JS release build fixtures
shell: bash
run: |
cargo test --package trusted-server-js --target x86_64-unknown-linux-gnu --locked --test release_prebuilt -- --list > "$RUNNER_TEMP/js-release-tests.txt"
grep -Fx 'ordinary_release_without_prebuilt_builds_private_bundles: test' "$RUNNER_TEMP/js-release-tests.txt"
cargo test --package trusted-server-js --target x86_64-unknown-linux-gnu --locked --test release_prebuilt

# The codegen crate is not a default member and no adapter alias builds it,
# so its tests only run if invoked explicitly on the host target.
- name: Run host-target OpenRTB codegen tests
Expand Down Expand Up @@ -351,6 +368,11 @@ jobs:
run: |
cargo clippy --manifest-path crates/trusted-server-cli/Cargo.toml --target "$(rustc -vV | sed -n 's/host: //p')" --all-targets -- -D warnings

- name: Run producer process supervision on macOS
if: runner.os == 'macOS'
run: |
cargo test --package trusted-server-release --target "$(rustc -vV | sed -n 's/host: //p')" --locked --bin trusted-server-release process::

- name: Set up Chrome for browser fixture tests
if: runner.os == 'macOS'
id: setup-chrome
Expand All @@ -371,6 +393,11 @@ jobs:
TRUSTED_SERVER__GIT_VERSION: abcdef0123456789abcdef0123456789abcdef01
run: |
cargo test --manifest-path crates/trusted-server-cli/Cargo.toml --target "$(rustc -vV | sed -n 's/host: //p')" --test release_build_facts
# The release cfg also selects resource discovery without the
# builder's checkout path; only a release-mode lib build reaches it.
cargo test --manifest-path crates/trusted-server-cli/Cargo.toml --target "$(rustc -vV | sed -n 's/host: //p')" --lib prebid_bundle::tests::actual_resource_discovery_uses_owning_release_cfg -- --exact > "$RUNNER_TEMP/release-cfg-result.txt"
cat "$RUNNER_TEMP/release-cfg-result.txt"
grep -E '^test result: ok\. 1 passed; 0 failed;' "$RUNNER_TEMP/release-cfg-result.txt"

# A valid commit also passes when the release gate is bypassed, so check
# that core's build script refuses a branch name in release mode.
Expand Down
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,9 @@ Every PR must pass:
13. CI Node pin guard: `node --test scripts/check-ci-node-pin.test.mjs && node scripts/check-ci-node-pin.mjs` with the `.tool-versions` Node (every CI job that compiles Rust sets up the `.tool-versions` Node before its first cargo step)
14. Fastly absolute-deadline network fixtures under Viceroy (the harness builds the adapter test binary itself): `node crates/trusted-server-adapter-fastly/tests/deadline-origin.mjs "$(command -v viceroy)"`
15. Worker auction-deadline runtime fixtures (`worker-auction-deadlines.yml`): build and lint the runtime fixture, then run it under the local runtime. For Cloudflare, `cargo build --locked -p trusted-server-adapter-cloudflare --example deadline-runtime --target wasm32-unknown-unknown --features cloudflare` and `node scripts/test-worker-auction-deadlines.mjs cloudflare --runtime "$(command -v wrangler)"` (requires wrangler and the `Cargo.lock` wasm-bindgen CLI). For Spin, `cargo build --locked -p trusted-server-adapter-spin --example deadline-runtime --target wasm32-wasip1 --features spin` and `node scripts/test-worker-auction-deadlines.mjs spin --runtime "$(command -v spin)"`. CI lints each fixture with the same `cargo clippy` arguments plus `-- -D warnings`
16. Release producer checks: `node --test scripts/release/phase1.test.mjs && shellcheck scripts/release/phase1-build.sh`
16. Release producer helpers: `node --test scripts/release/phase1.test.mjs && shellcheck scripts/release/phase1-build.sh scripts/release/validate-fastly-package.sh scripts/release/bootstrap.sh scripts/release/build.sh scripts/release/build-js.sh`
17. Native release producer tests and lint: `cargo test --package trusted-server-release --target <host-triple> --locked` and `cargo clippy --package trusted-server-release --target <host-triple> --all-targets --all-features --locked -- -D warnings` (CI uses `x86_64-unknown-linux-gnu`).
18. Native checked/ordinary JS release fixtures: `cargo test --package trusted-server-js --target <host-triple> --locked --test release_prebuilt` and `cargo clippy --package trusted-server-js --target <host-triple> --all-targets --all-features --locked -- -D warnings` (CI uses `x86_64-unknown-linux-gnu`).

CI also runs these HTML EOF checks. Run them locally only when changing EOF
finalization, publisher or HTML-processor code:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Publish a reproducible, provenance- and SBOM-attested `trusted-server-fastly.tar.gz` alongside the Fastly wasm. Both ordinary builds use the same fixed service-neutral manifest and normalized archive metadata; the gate compares both complete files before signing. Operators can verify and deploy the downloaded package unchanged.

- Add an ordinary Fastly release byte-equality gate and a real provenance-attested `trusted-server-fastly.wasm.rebuild-check.json`. Release CI now builds the Fastly wasm a second time on every push to `main` and every `v*` tag and requires both complete files to match byte for byte; a mismatch prevents signing and publication. The ordinary profile remains unqualified, native reproduction is not a release gate, and the four binary names and signer identity stay unchanged.
- Add Phase 1 attested release binaries: the Fastly wasm and the `ts` CLI for Linux x86-64 and macOS (ARM64 and x86-64), with SPDX 2.3 inventories, provenance/SBOM bundles, immutable verification and a GNU glibc 2.34 startup check. Reproducibility, other adapters and the custom verifier remain later work; production publication requires maintainer settings.

### Changed

- **Breaking:** Known `[integrations.*]` tables, `[tester_cookie]`, and `[tinybird]` now reject unknown fields, including in disabled integration blocks. Integration parse errors name the offending key. `ts config validate` and `ts config push` also reject unknown integration IDs and list the supported IDs; runtime startup warns and ignores unknown IDs for compatibility with stored configs. Before deploying the new binary, use the new CLI to run `ts config validate` on the current config, correct the reported fields and IDs, then push the cleaned config while the old binary is still running. On Fastly, wait for the config-store propagation window to elapse before activating the new binary; a successful push does not mean every point of presence (POP) has the new config. Stored unknown fields can otherwise prevent startup. Intentionally open payload maps remain supported. Lockr uses `app_id`; remove unsupported `organization_id` and `project_id` fields.
- **Breaking:** The tsjs bundle build (`crates/trusted-server-js/lib/build-all.mjs`, run by Cargo builds of `trusted-server-js` and by `npm run build`) now requires a Node.js with `import.meta.main` (22.18 or later, or 24.2 or later) and fails on older versions; use the `.tool-versions` Node.
- **Breaking:** Cargo builds of `trusted-server-js` now fail whenever `TSJS_SKIP_BUILD` is set to any value, including empty or `0`; previously only `TSJS_SKIP_BUILD=1` was rejected. Remove it from shell profiles and `.env` files, and use `TSJS_PREBUILT_DIR` to embed prebuilt bundles instead.
- The attested Fastly wasm reports `x-ts-version` as the full 40-character source commit; deploy-pipeline builds keep the tag, branch or short-commit value described below.
- **Breaking:** `ts --version` now prints `ts package=<version> source=<source> target=<triple> variant=default` instead of `ts <version>`. `source` is the full commit in attested release binaries, and otherwise the development ref, short commit or `unknown`. Update scripts that parse the old output.
- **Breaking:** Creative rewrite proxy, click, CSS, `srcset`, sign-response, rebuild-response, and injected creative TSJS URLs are now absolute on `publisher.public_origin`. Review the [default authority, cookie scope, and coordinated upgrade/rollback warning for `public_origin`](docs/guide/configuration.md#publisher-configuration) before deployment. Existing root-relative signed proxy and click inputs remain accepted. TSJS bundle selection and hash calculation are unchanged.
Expand Down
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
# Manual protobuf codegen tool — a member so it shares workspace settings,
# but no default member or alias builds it. Run it explicitly with `-p`.
"crates/trusted-server-openrtb-codegen",
"crates/trusted-server-release",
]

# Viceroy (cargo test-fastly runner) calls `cargo run --bin trusted-server-adapter-fastly`
Expand Down
4 changes: 2 additions & 2 deletions crates/trusted-server-adapter-spin/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,8 @@ impl TrustedServerApp {
/// Build the full application router from explicit settings.
///
/// Testing seam: cross-adapter parity tests use this to drive the router
/// with known-good settings instead of the baked `get_settings()` result,
/// whose embedded placeholder secrets fail validation by design.
/// with known-good settings without external runtime configuration or
/// secret-store bindings.
///
/// # Errors
///
Expand Down
5 changes: 2 additions & 3 deletions crates/trusted-server-adapter-spin/src/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,8 @@ mod tests {
}

fn settings_with_response_headers(headers: Vec<(&str, &str)>) -> Settings {
// Build from explicit test settings: the settings baked into the
// binary contain placeholder secrets that `get_settings()` rejects
// by design.
// Build explicit, deterministic test settings without external runtime
// configuration or secret-store bindings.
let mut s = Settings::from_toml(
r#"
[[handlers]]
Expand Down
6 changes: 3 additions & 3 deletions crates/trusted-server-adapter-spin/tests/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use trusted_server_core::settings::Settings;

/// Build the full application router from explicit test settings.
///
/// The settings baked into the binary contain placeholder secrets that
/// `get_settings()` rejects by design, which would turn every route into a
/// startup error page (and its route table into the fallback-only set).
/// Explicit settings exercise the full route table without external runtime
/// configuration or secret-store bindings. Missing runtime settings would
/// otherwise select the startup error router.
/// The handler regex is the production-shaped `^/_ts/admin`, matching
/// `Settings::ADMIN_ENDPOINTS` and the default config, so the canonical
/// `/_ts/admin/keys/*` routes are auth-gated exactly as in production.
Expand Down
7 changes: 7 additions & 0 deletions crates/trusted-server-cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=TRUSTED_SERVER__RELEASE_BUILD");
println!("cargo:rustc-check-cfg=cfg(trusted_server_release_build)");
// Core's build script rejects an invalid release control for every product
// build; this only selects release-only resource discovery.
if std::env::var_os("TRUSTED_SERVER__RELEASE_BUILD").is_some() {
println!("cargo:rustc-cfg=trusted_server_release_build");
}
let target = std::env::var("TARGET").expect("should set the owning Cargo target");
println!("cargo:rustc-env=TRUSTED_SERVER__BUILD_TARGET={target}");
}
85 changes: 80 additions & 5 deletions crates/trusted-server-cli/src/prebid_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,18 +627,28 @@ fn ensure_file_exists(path: &Path, description: &str) -> CliResult<()> {
}

fn find_js_lib_dir(start: &Path) -> CliResult<PathBuf> {
#[cfg(not(trusted_server_release_build))]
let fallback = Some(
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("crates/trusted-server-js/lib"),
);
#[cfg(trusted_server_release_build)]
let fallback: Option<PathBuf> = None;
find_js_lib_dir_with_fallback(start, fallback.as_deref())
}

fn find_js_lib_dir_with_fallback(start: &Path, fallback: Option<&Path>) -> CliResult<PathBuf> {
for ancestor in start.ancestors() {
let candidate = ancestor.join("crates/trusted-server-js/lib");
if is_js_lib_dir(&candidate) {
return Ok(candidate);
}
}

let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let candidate = manifest_dir
.join("../..")
.join("crates/trusted-server-js/lib");
if is_js_lib_dir(&candidate) {
if let Some(candidate) = fallback
&& is_js_lib_dir(candidate)
{
return candidate.canonicalize().map_err(|error| {
report_error(format!(
"failed to resolve JS library directory {}: {error}",
Expand Down Expand Up @@ -815,6 +825,71 @@ mod tests {
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt as _;

#[test]
fn resource_discovery_without_fallback_requires_runtime_checkout() {
let directory = tempfile::tempdir().expect("should create outside checkout fixture");
let error = find_js_lib_dir_with_fallback(directory.path(), None)
.expect_err("should require runtime checkout when fallback is absent");
assert!(
error
.to_string()
.contains("run `ts prebid client` from the Trusted Server repository"),
"should explain the missing source prerequisites"
);
let resources = directory.path().join("crates/trusted-server-js/lib");
fs::create_dir_all(&resources).expect("should create runtime resources");
fs::write(resources.join("package.json"), "{}").expect("should create package fixture");
fs::write(resources.join("build-prebid-external.mjs"), "")
.expect("should create builder fixture");
let nested = directory.path().join("nested");
fs::create_dir(&nested).expect("should create nested current directory");
assert_eq!(
find_js_lib_dir_with_fallback(&nested, None)
.expect("should discover actual runtime checkout"),
resources,
"should discover runtime ancestor resources"
);
}

#[test]
fn resource_discovery_uses_explicit_development_fallback() {
let directory = tempfile::tempdir().expect("should create fixture");
let resources = directory.path().join("development-lib");
fs::create_dir(&resources).expect("should create development fallback");
fs::write(resources.join("package.json"), "{}").expect("should create package fixture");
fs::write(resources.join("build-prebid-external.mjs"), "")
.expect("should create builder fixture");
assert_eq!(
find_js_lib_dir_with_fallback(directory.path(), Some(&resources))
.expect("should use explicit development fallback"),
resources
.canonicalize()
.expect("should canonicalize fallback"),
"should preserve development fallback behavior"
);
}

#[test]
fn actual_resource_discovery_uses_owning_release_cfg() {
Comment thread
prk-Jr marked this conversation as resolved.
Resolved
let directory = tempfile::tempdir().expect("should create outside checkout fixture");
let result = find_js_lib_dir(directory.path());
if cfg!(trusted_server_release_build) {
let error =
result.expect_err("should exclude the compiled developer checkout in release mode");
assert!(
error
.to_string()
.contains("run `ts prebid client` from the Trusted Server repository"),
"should identify release source prerequisites"
);
} else {
assert!(
result.is_ok(),
"should retain the compiled checkout fallback in development"
);
}
}

fn managed_config(managed: &str, user_id: &str) -> String {
format!(
r#"
Expand Down
17 changes: 14 additions & 3 deletions crates/trusted-server-cli/tests/release_build_facts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,22 @@ fn cli_build_script_emits_only_its_target() {
)
.expect("should emit UTF-8 directives"),
);
for directives in &outputs {
for (index, directives) in outputs.iter().enumerate() {
// Release-only resource discovery is selected for the two release runs.
let release_cfg = if index < 2 {
"cargo:rustc-cfg=trusted_server_release_build\n"
} else {
""
};
assert_eq!(
directives,
"cargo:rerun-if-changed=build.rs\n\
cargo:rustc-env=TRUSTED_SERVER__BUILD_TARGET=example-target\n",
&format!(
"cargo:rerun-if-changed=build.rs\n\
cargo:rerun-if-env-changed=TRUSTED_SERVER__RELEASE_BUILD\n\
cargo:rustc-check-cfg=cfg(trusted_server_release_build)\n\
{release_cfg}\
cargo:rustc-env=TRUSTED_SERVER__BUILD_TARGET=example-target\n"
),
"should emit only the target owned by Cargo TARGET"
);
}
Expand Down
Loading
Loading