You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two small pieces of build hygiene around the TSJS build that every Rust build runs.
1. Most Rust CI jobs build the TSJS bundles with the runner's Node, not the pinned one
trusted-server-core depends on trusted-server-js (crates/trusted-server-core/Cargo.toml:47). The trusted-server-js build script runs npm ci when node_modules is missing, then npm run build unless TSJS_SKIP_BUILD=1, and embeds the resulting bundles (crates/trusted-server-js/build.rs:41-85). A fresh CI checkout has no node_modules, so every job that compiles core runs a Node build.
.tool-versions pins nodejs 24.12.0. Only two of the eleven jobs that compile core run actions/setup-node with that version before building. A third sets it up only after its Rust build. The other eight use whatever Node the runner image has on PATH. For the images used by recent runs, that is Node.js 22.23.2 on ubuntu-24.04 (image 20260907.300) and Node.js 24.20.0 on macos-26-arm64 (image 20260907.0351), per the images' software lists. Nothing in the repository flags the mismatch: crates/trusted-server-js/lib/package.json has no engines field, and there is no .nvmrc or .npmrc.
As a result, the bundles embedded in most of the Rust artifacts that CI builds, tests and lints are produced by a different Node major than the Vitest and format jobs use on Linux. The Node version can also change with a runner image update, with no change in the repository. crates/trusted-server-adapter-cloudflare/build.sh:2-6 already works around a related local problem (sourcing nvm because the build script picked up the wrong system Node), which shows the build script's Node matters.
2. The Cloudflare and Spin adapters declare a trusted-server-js dependency they never use
crates/trusted-server-adapter-cloudflare/Cargo.toml:33 and crates/trusted-server-adapter-spin/Cargo.toml:35 both have:
trusted-server-js = { workspace = true }
Neither crate's sources or tests mention trusted_server_js, and no commit ever has (git log -G trusted_server_js -- crates/trusted-server-adapter-cloudflare crates/trusted-server-adapter-spin is empty). Both crates were created with the line: Cloudflare in #643 and Spin in #735. #614 had already removed the same direct dependency from the Fastly adapter as "accessed transitively via trusted-server-core". Core still depends on the crate, so this is dependency-graph hygiene. Removing the lines does not remove the Node requirement. It does make the graph that the #1194 crate split has to redraw accurate.
The last column counts tsjs: Building per-module bundles lines in the job log of a recent run whose workflow files are identical to a4e01eb. test.yml and format.yml counts come from runs 35968913882 and 35968913845 (head 7e3997a), and integration-tests.yml counts from run 35974697391 (head bf96305).
Workflow / job
Compiles core
Pinned Node set up before the Rust build
TSJS builds in log
test.yml / test-rust
yes (cargo test-fastly)
yes (test.yml:54-57, added for the template-cache harness)
5
test.yml / test-axum
yes
no
13
test.yml / test-cloudflare
yes
no
3
test.yml / test-spin
yes
no
4
test.yml / test-parity
yes (trusted-server-integration-tests depends on core)
yes (composite action builds Axum, then cargo test)
no
2
integration-tests.yml / browser-tests
yes (composite action builds Axum)
only after the Rust build (integration-tests.yml:181-184)
1
deploy-docs.yml / build, deploy
no
docs job yes
n/a
codeql.yml / analyze
no cargo step (build-mode: none)
no
n/a
The composite action .github/actions/setup-integration-test-env/action.yml reads the Node version (:42-45) and exports it, but never calls actions/setup-node. integration-tests-fastly-ec and browser-tests do not pass build-axum: "false", so the action's default (:16-19) builds Axum in both jobs. In the browser job log, the Axum build's TSJS step ran at 08:32:15 and setup-node at 08:32:39.
To see the Node versions:
gh api -H "Accept: application/vnd.github.raw" \
"repos/actions/runner-images/contents/images/ubuntu/Ubuntu2404-Readme.md?ref=ubuntu24/20260907.300"| grep -n "Node.js"
gh api -H "Accept: application/vnd.github.raw" \
"repos/actions/runner-images/contents/images/macos/macos-26-arm64-Readme.md?ref=macos-26-arm64/20260907.0351"| grep -n "Node.js"
Observed. Line 26 of each list is the Node on PATH. The #### Node.js sections list the cached versions that setup-node can select, 22.23.2 and 24.20.0 on both images.
warning: extern crate `trusted_server_js` is unused in crate `trusted_server_adapter_cloudflare`
warning: extern crate `trusted_server_js` is unused in crate `trusted_server_adapter_spin`
On the native host target the lint also flags dependencies that are only used under cfg(target_arch = "wasm32"), so a workspace-wide lint would be noisy. trusted_server_js is the only dependency flagged on the wasm feature builds.
The workspace entry is trusted-server-js = { path = "crates/trusted-server-js" } (Cargo.toml:115), with no features, so removing the direct edges does not change feature resolution.
Expected behavior
Every CI job that compiles trusted-server-core builds the TSJS bundles with the Node version in .tool-versions, the same one the JS jobs use.
Adapter crates declare only the dependencies they use.
Actual behavior
8 of 11 Rust-building jobs never set up the pinned Node, and 1 sets it up only after its Rust build. On Linux those builds use Node 22.
Cloudflare and Spin carry an unused direct trusted-server-js dependency.
Root cause
The Node setup was added job by job for specific needs. In test-rust, for example, the step is named "Use Node.js for the served-seam contract": scripts/template-cache-local-test.sh, which that job runs, needs node to execute the GPT bundle (:69-70, :657). It was not added as a prerequisite of the core build script.
The composite integration action resolves the Node version but does not install it.
Add an actions/setup-node@v4 step that reads .tool-versions, as test-rust does, before the first cargo command in test-axum, test-cloudflare, test-spin, test-parity, test-cli and format-rust.
In .github/actions/setup-integration-test-env/action.yml, add actions/setup-node@v4 with node-version: ${{ steps.node-version.outputs.node-version }} right after the "Retrieve Node.js version" step. That covers prepare-artifacts, integration-tests-fastly-ec and browser-tests. The later setup-node steps in integration-tests and browser-tests then only matter for their npm cache settings.
Optionally, pass cache: npm with cache-dependency-path: crates/trusted-server-js/lib/package-lock.json so the build script's npm ci is cached.
Delete trusted-server-js = { workspace = true } from the Cloudflare and Spin Cargo.toml files and let Cargo update Cargo.lock.
Optional, separate from this task: neither integration-tests-fastly-ec nor browser-tests uses the Axum binary its composite step builds. The Fastly EC job runs only test_ec_lifecycle_fastly, AXUM_BINARY_PATH is read only by tests/environments/axum.rs, and the browser tests never mention Axum. Passing build-axum: "false" would save one full Rust build per job.
Done when
Every job in the table that compiles core runs actions/setup-node with the .tool-versions Node before its first cargo command, and the composite action does the same.
A CI run shows node-version: 24.12.0 (or the current pin) in the setup step of each of those jobs.
The Cloudflare and Spin Cargo.toml files no longer list trusted-server-js, Cargo.lock is updated, and cargo check-cloudflare, cargo check-spin, cargo test-cloudflare and cargo test-spin pass.
Define integrations crate split and ordered configuration #1194 (draft spec): adds a second JS crate (trusted-server-integrations-js) whose build script also runs the Node build, so each Rust build would run two. Setting up Node in every job covers both.
Description
Two small pieces of build hygiene around the TSJS build that every Rust build runs.
1. Most Rust CI jobs build the TSJS bundles with the runner's Node, not the pinned one
trusted-server-coredepends ontrusted-server-js(crates/trusted-server-core/Cargo.toml:47). Thetrusted-server-jsbuild script runsnpm ciwhennode_modulesis missing, thennpm run buildunlessTSJS_SKIP_BUILD=1, and embeds the resulting bundles (crates/trusted-server-js/build.rs:41-85). A fresh CI checkout has nonode_modules, so every job that compiles core runs a Node build..tool-versionspinsnodejs 24.12.0. Only two of the eleven jobs that compile core runactions/setup-nodewith that version before building. A third sets it up only after its Rust build. The other eight use whatever Node the runner image has onPATH. For the images used by recent runs, that is Node.js 22.23.2 onubuntu-24.04(image 20260907.300) and Node.js 24.20.0 onmacos-26-arm64(image 20260907.0351), per the images' software lists. Nothing in the repository flags the mismatch:crates/trusted-server-js/lib/package.jsonhas noenginesfield, and there is no.nvmrcor.npmrc.As a result, the bundles embedded in most of the Rust artifacts that CI builds, tests and lints are produced by a different Node major than the Vitest and format jobs use on Linux. The Node version can also change with a runner image update, with no change in the repository.
crates/trusted-server-adapter-cloudflare/build.sh:2-6already works around a related local problem (sourcing nvm because the build script picked up the wrong system Node), which shows the build script's Node matters.2. The Cloudflare and Spin adapters declare a
trusted-server-jsdependency they never usecrates/trusted-server-adapter-cloudflare/Cargo.toml:33andcrates/trusted-server-adapter-spin/Cargo.toml:35both have:Neither crate's sources or tests mention
trusted_server_js, and no commit ever has (git log -G trusted_server_js -- crates/trusted-server-adapter-cloudflare crates/trusted-server-adapter-spinis empty). Both crates were created with the line: Cloudflare in #643 and Spin in #735. #614 had already removed the same direct dependency from the Fastly adapter as "accessed transitively via trusted-server-core". Core still depends on the crate, so this is dependency-graph hygiene. Removing the lines does not remove the Node requirement. It does make the graph that the #1194 crate split has to redraw accurate.Steps to reproduce
Jobs that compile core, at a4e01eb
The last column counts
tsjs: Building per-module bundleslines in the job log of a recent run whose workflow files are identical to a4e01eb.test.ymlandformat.ymlcounts come from runs 35968913882 and 35968913845 (head 7e3997a), andintegration-tests.ymlcounts from run 35974697391 (head bf96305).test.yml/test-rustcargo test-fastly)test.yml:54-57, added for the template-cache harness)test.yml/test-axumtest.yml/test-cloudflaretest.yml/test-spintest.yml/test-paritytrusted-server-integration-testsdepends on core)test.yml/test-cli(macOS)test.yml/test-typescriptformat.yml/format-rustformat.yml/check-claude-md-symlink,format-typescript,format-docsintegration-tests.yml/prepare-artifactsintegration-tests.yml/integration-testscargo testof the integration-tests crate)integration-tests.yml:93-96)integration-tests.yml/integration-tests-fastly-eccargo test)integration-tests.yml/browser-testsintegration-tests.yml:181-184)deploy-docs.yml/build,deploycodeql.yml/analyzebuild-mode: none)The composite action
.github/actions/setup-integration-test-env/action.ymlreads the Node version (:42-45) and exports it, but never callsactions/setup-node.integration-tests-fastly-ecandbrowser-testsdo not passbuild-axum: "false", so the action's default (:16-19) builds Axum in both jobs. In the browser job log, the Axum build's TSJS step ran at 08:32:15 andsetup-nodeat 08:32:39.To see the Node versions:
Observed. Line 26 of each list is the Node on
PATH. The#### Node.jssections list the cached versions thatsetup-nodecan select, 22.23.2 and 24.20.0 on both images.The unused dependency
rustc's
unused_crate_dependencieslint, applied to each adapter library only:Observed, on the production wasm builds:
On the native host target the lint also flags dependencies that are only used under
cfg(target_arch = "wasm32"), so a workspace-wide lint would be noisy.trusted_server_jsis the only dependency flagged on the wasm feature builds.With the two lines deleted, on a copy of a4e01eb:
The workspace entry is
trusted-server-js = { path = "crates/trusted-server-js" }(Cargo.toml:115), with no features, so removing the direct edges does not change feature resolution.Expected behavior
trusted-server-corebuilds the TSJS bundles with the Node version in.tool-versions, the same one the JS jobs use.Actual behavior
trusted-server-jsdependency.Root cause
test-rust, for example, the step is named "Use Node.js for the served-seam contract":scripts/template-cache-local-test.sh, which that job runs, needsnodeto execute the GPT bundle (:69-70,:657). It was not added as a prerequisite of the core build script.Impact
.tool-versionsmoves. Upgrade to Rust 1.98.1 and align dependencies with EdgeZero #1124 and Upgrade to Rust 1.98.1 and align dependencies with EdgeZero #1123 plan to move it to 24.20.0, and that bump would not reach these jobs.Proposed fix
actions/setup-node@v4step that reads.tool-versions, astest-rustdoes, before the first cargo command intest-axum,test-cloudflare,test-spin,test-parity,test-cliandformat-rust..github/actions/setup-integration-test-env/action.yml, addactions/setup-node@v4withnode-version: ${{ steps.node-version.outputs.node-version }}right after the "Retrieve Node.js version" step. That coversprepare-artifacts,integration-tests-fastly-ecandbrowser-tests. The latersetup-nodesteps inintegration-testsandbrowser-teststhen only matter for their npm cache settings.cache: npmwithcache-dependency-path: crates/trusted-server-js/lib/package-lock.jsonso the build script'snpm ciis cached.trusted-server-js = { workspace = true }from the Cloudflare and SpinCargo.tomlfiles and let Cargo updateCargo.lock.Optional, separate from this task: neither
integration-tests-fastly-ecnorbrowser-testsuses the Axum binary its composite step builds. The Fastly EC job runs onlytest_ec_lifecycle_fastly,AXUM_BINARY_PATHis read only bytests/environments/axum.rs, and the browser tests never mention Axum. Passingbuild-axum: "false"would save one full Rust build per job.Done when
actions/setup-nodewith the.tool-versionsNode before its first cargo command, and the composite action does the same.node-version: 24.12.0(or the current pin) in the setup step of each of those jobs.Cargo.tomlfiles no longer listtrusted-server-js,Cargo.lockis updated, andcargo check-cloudflare,cargo check-spin,cargo test-cloudflareandcargo test-spinpass.Affected area
CI / Tooling
Version
main at a4e01eb
Related
trusted-server-jsdependency from the Fastly adapter..tool-versionsto 24.20.0. With this task done, the bump reaches every Rust job.npm run ciinstead of install to prevent package-lock.json changes in diffs #378 (closed): asked forbuild.rsto usenpm ciinstead ofnpm install, which it does today.trusted-server-integrations-js) whose build script also runs the Node build, so each Rust build would run two. Setting up Node in every job covers both.