From 1bac383a12fea30f03ca448aa505e8fff00659ca Mon Sep 17 00:00:00 2001 From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com> Date: Tue, 27 Oct 2026 22:11:36 +0000 Subject: [PATCH 1/3] Cache native CI dependencies and rebuild current Server outputs --- .github/workflows/server-parity.yml | 82 +++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/.github/workflows/server-parity.yml b/.github/workflows/server-parity.yml index 35906b9e6..5cec79242 100644 --- a/.github/workflows/server-parity.yml +++ b/.github/workflows/server-parity.yml @@ -471,6 +471,19 @@ jobs: -v "$PWD/mysql-tls:/tls" --entrypoint openssl "$image" req -x509 -newkey rsa:2048 \ -nodes -sha256 -days 1 -keyout /tls/untrusted.key -out /tls/untrusted.crt -subj /CN=untrusted-development-ca \ >> parity-evidence/tls-certificate-generation.txt 2>&1 + # The workflow hash includes the pinned compiler and its build flags; + # the commit identifies every tracked source and fixture input. + - name: Restore native Cargo dependencies from trusted main + id: native_cargo + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + cargo-home/registry + cargo-home/git + rust-target + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} + restore-keys: | + native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -482,6 +495,14 @@ jobs: -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -w /source/rust \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 \ cargo fetch --locked + - name: Discard restored native workspace outputs before rebuilding + run: | + set -euo pipefail + mkdir -p cargo-home rust-target + docker run --rm --init --user="$(id -u):$(id -g)" --network=none --cpus=2 --memory=2g --memory-swap=2g \ + -e CARGO_HOME=/cargo -e CARGO_TARGET_DIR=/target \ + -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -v "$PWD/rust-target:/target" -w /source/rust \ + mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 cargo clean --locked --offline --package durable-workflow-server - name: Bootstrap independent published PHP and native MySQL databases run: | set -euo pipefail @@ -1133,6 +1154,19 @@ jobs: name: corrected-marker-adapters path: corrected-marker-adapters digest-mismatch: error + # The workflow hash includes the pinned compiler and its build flags; + # the commit identifies every tracked source and fixture input. + - name: Restore native Cargo dependencies from trusted main + id: native_cargo + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + cargo-home/registry + cargo-home/git + rust-target + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} + restore-keys: | + native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -1144,6 +1178,14 @@ jobs: -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -w /source/rust \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 \ cargo fetch --locked + - name: Discard restored native workspace outputs before rebuilding + run: | + set -euo pipefail + mkdir -p cargo-home rust-target + docker run --rm --init --user="$(id -u):$(id -g)" --network=none --cpus=2 --memory=2g --memory-swap=2g \ + -e CARGO_HOME=/cargo -e CARGO_TARGET_DIR=/target \ + -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -v "$PWD/rust-target:/target" -w /source/rust \ + mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 cargo clean --locked --offline --package durable-workflow-server - name: Bootstrap independent published PHP and native PostgreSQL databases env: POSTGRES_IMAGE: ${{ matrix.image }} @@ -1833,6 +1875,19 @@ jobs: name: corrected-marker-adapters path: corrected-marker-adapters digest-mismatch: error + # The workflow hash includes the pinned compiler and its build flags; + # the commit identifies every tracked source and fixture input. + - name: Restore native Cargo dependencies from trusted main + id: native_cargo + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + cargo-home/registry + cargo-home/git + rust-target + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} + restore-keys: | + native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -1844,6 +1899,14 @@ jobs: -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -w /source/rust \ mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 \ cargo fetch --locked + - name: Discard restored native workspace outputs before rebuilding + run: | + set -euo pipefail + mkdir -p cargo-home rust-target + docker run --rm --init --user="$(id -u):$(id -g)" --network=none --cpus=2 --memory=2g --memory-swap=2g \ + -e CARGO_HOME=/cargo -e CARGO_TARGET_DIR=/target \ + -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -v "$PWD/rust-target:/target" -w /source/rust \ + mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 cargo clean --locked --offline --package durable-workflow-server - name: Build the native server if: ${{ matrix.part != 'native-tests' }} run: | @@ -2393,6 +2456,25 @@ jobs: path: parity-summary retention-days: 1 if-no-files-found: error + - name: Remove current workspace outputs before caching dependencies + if: ${{ success() && github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.part == 'native-tests' && steps.native_cargo.outputs.cache-hit != 'true' }} + run: | + set -euo pipefail + mkdir -p cargo-home rust-target + docker run --rm --init --user="$(id -u):$(id -g)" --network=none --cpus=2 --memory=2g --memory-swap=2g \ + -e CARGO_HOME=/cargo -e CARGO_TARGET_DIR=/target \ + -v "$PWD:/source:ro" -v "$PWD/cargo-home:/cargo" -v "$PWD/rust-target:/target" -w /source/rust \ + mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0 cargo clean --locked --offline --package durable-workflow-server + - name: Save native Cargo dependencies from successful main native tests + if: ${{ success() && github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.part == 'native-tests' && steps.native_cargo.outputs.cache-hit != 'true' }} + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + cargo-home/registry + cargo-home/git + rust-target + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} + # The one Shared Server fixtures result. It always runs, including after a # failure or cancellation, and passes only when every fixture job passed, or From c74b74a1f871a972987bcd551e5a14824dc6bb5b Mon Sep 17 00:00:00 2001 From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com> Date: Tue, 27 Oct 2026 22:16:47 +0000 Subject: [PATCH 2/3] Use exact trusted dependency cache keys and classify shared preparation --- .github/workflows/server-parity.yml | 26 ++++++++++---------------- tests/Unit/ServerParityPartsTest.mjs | 1 + 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.github/workflows/server-parity.yml b/.github/workflows/server-parity.yml index 5cec79242..3ee559dd2 100644 --- a/.github/workflows/server-parity.yml +++ b/.github/workflows/server-parity.yml @@ -471,8 +471,8 @@ jobs: -v "$PWD/mysql-tls:/tls" --entrypoint openssl "$image" req -x509 -newkey rsa:2048 \ -nodes -sha256 -days 1 -keyout /tls/untrusted.key -out /tls/untrusted.crt -subj /CN=untrusted-development-ca \ >> parity-evidence/tls-certificate-generation.txt 2>&1 - # The workflow hash includes the pinned compiler and its build flags; - # the commit identifies every tracked source and fixture input. + # Exact dependency keys include the pinned compiler, build flags and + # vendored crates. Server outputs are discarded before rebuilding. - name: Restore native Cargo dependencies from trusted main id: native_cargo uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -481,9 +481,7 @@ jobs: cargo-home/registry cargo-home/git rust-target - key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} - restore-keys: | - native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml', 'rust/vendor/**', 'rust/.cargo/**', '.github/workflows/server-parity.yml') }} - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -1154,8 +1152,8 @@ jobs: name: corrected-marker-adapters path: corrected-marker-adapters digest-mismatch: error - # The workflow hash includes the pinned compiler and its build flags; - # the commit identifies every tracked source and fixture input. + # Exact dependency keys include the pinned compiler, build flags and + # vendored crates. Server outputs are discarded before rebuilding. - name: Restore native Cargo dependencies from trusted main id: native_cargo uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -1164,9 +1162,7 @@ jobs: cargo-home/registry cargo-home/git rust-target - key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} - restore-keys: | - native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml', 'rust/vendor/**', 'rust/.cargo/**', '.github/workflows/server-parity.yml') }} - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -1875,8 +1871,8 @@ jobs: name: corrected-marker-adapters path: corrected-marker-adapters digest-mismatch: error - # The workflow hash includes the pinned compiler and its build flags; - # the commit identifies every tracked source and fixture input. + # Exact dependency keys include the pinned compiler, build flags and + # vendored crates. Server outputs are discarded before rebuilding. - name: Restore native Cargo dependencies from trusted main id: native_cargo uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -1885,9 +1881,7 @@ jobs: cargo-home/registry cargo-home/git rust-target - key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} - restore-keys: | - native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}- + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml', 'rust/vendor/**', 'rust/.cargo/**', '.github/workflows/server-parity.yml') }} - name: Fetch locked Rust dependencies # A registry or network failure belongs to this step, not to the # offline native builds and tests that follow. @@ -2473,7 +2467,7 @@ jobs: cargo-home/registry cargo-home/git rust-target - key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', '.github/workflows/server-parity.yml') }}-${{ github.sha }} + key: native-cargo-deps-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml', 'rust/vendor/**', 'rust/.cargo/**', '.github/workflows/server-parity.yml') }} # The one Shared Server fixtures result. It always runs, including after a diff --git a/tests/Unit/ServerParityPartsTest.mjs b/tests/Unit/ServerParityPartsTest.mjs index 309a3bc10..b6a5ff46b 100644 --- a/tests/Unit/ServerParityPartsTest.mjs +++ b/tests/Unit/ServerParityPartsTest.mjs @@ -12,6 +12,7 @@ const workflow = readFileSync('.github/workflows/server-parity.yml', 'utf8'); const PARTS = ['native-tests', 'corpus', 'restarts', 'cohorts', 'sdk-directions', 'corrected-markers']; const SHARED_NODES = 'Start the published PHP and native nodes the corpus parts share'; const EVERY_PART = [/^actions\/checkout@/, /^Pull the pinned images, retrying registry errors$/, /^Fetch /, + /^Restore native Cargo dependencies from trusted main$/, /^Discard restored native workspace outputs before rebuilding$/, /^Create TLS fixture certificates$/, /^Bootstrap independent /, /^Collect /, /^Summarize /, /^Retain /]; function job(name) { From 9a3773839d2e11b9a53b43bfa4b4e2cd02bfcb6a Mon Sep 17 00:00:00 2001 From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com> Date: Tue, 27 Oct 2026 23:09:20 +0000 Subject: [PATCH 3/3] Keep adapter cache assertions scoped to the adapter job --- tests/Unit/ServerParityAdapterCacheTest.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/ServerParityAdapterCacheTest.mjs b/tests/Unit/ServerParityAdapterCacheTest.mjs index 59d152fe6..198b5f652 100644 --- a/tests/Unit/ServerParityAdapterCacheTest.mjs +++ b/tests/Unit/ServerParityAdapterCacheTest.mjs @@ -19,8 +19,8 @@ function job(name) { const steps = block => block.split(/\n {6}(?=- (?:name|uses):)/).slice(1); -test('only the adapter job caches, and only public registry data and the build tree', () => { - const uses = workflow.match(/uses: actions\/cache[^\s]*/g) ?? []; +test('the adapter job caches only public registry data and the build tree', () => { + const uses = job('published-sdk-adapters').match(/uses: actions\/cache[^\s]*/g) ?? []; assert.deepEqual(uses, [ 'uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9', 'uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9',