From 3e7fce9693efe01d86567158d5b4bf73f7214487 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 25 Oct 2026 15:28:39 -0700 Subject: [PATCH 1/6] ci(star-history): draw the chart through today The repo has held 40 stars since 2026-09-30, so the daily job found no movement and the chart's line stopped at that date, reading as a frozen chart. Carry the last count forward to today when rendering; the stored series still records only days the count moved. --- ci/star_history.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ci/star_history.py b/ci/star_history.py index dfa949fff..efc6c9cf9 100644 --- a/ci/star_history.py +++ b/ci/star_history.py @@ -179,6 +179,13 @@ def append_snapshot(series: list[Point], count: int, today: str) -> list[Point]: return [*trimmed, Point(today, count)] +def extend_to(series: list[Point], today: str) -> list[Point]: + """Carry the last count forward to `today` for drawing; the stored series is untouched.""" + if series and series[-1].day < today: + return [*series, Point(today, series[-1].stars)] + return series + + def resolve_series(repo: str, existing: list[Point], today: str) -> list[Point]: """Prefer an exact rebuild from timestamps; otherwise extend what we already have.""" count = fetch_star_count(repo) @@ -318,10 +325,13 @@ def main(argv: Optional[list[str]] = None) -> int: ) return 1 + # The JSON records only days the count moved; the chart carries the last count + # forward to today, so a quiet stretch reads as flat rather than as a frozen chart. + drawn = extend_to(series, today) artifacts = { json_path: dump_series(json_path, series), - out_dir / "star-history-light.svg": render_svg(series, repo, LIGHT), - out_dir / "star-history-dark.svg": render_svg(series, repo, DARK), + out_dir / "star-history-light.svg": render_svg(drawn, repo, LIGHT), + out_dir / "star-history-dark.svg": render_svg(drawn, repo, DARK), } if args.check: From 396406e079d92f86cf9efc24cdb1b4b19b5bce88 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 25 Oct 2026 15:28:39 -0700 Subject: [PATCH 2/6] ci: pin every action to a full SHA on its Node 24 release; fix two benchmark workflows - Pin actions/*, astral-sh/setup-uv, msys2/setup-msys2 and softprops/action-gh-release to the commit of their latest release, with the tag in a comment (the policy the benchmark workflows already enforced). Clears the Node 20 deprecation on every job. - benchmark-memory: move off benchmark-latency's identical Sunday cron; both share benchmark-stats-production, where GitHub keeps one pending run, so latency cancelled memory before it got a runner. Raise the 60 min job timeout that the 5-allocator suite outgrew to 90 (repo variable BENCHMARK_MEMORY_TIMEOUT_MINUTES overrides). - benchmark-pprof-tax: upload the validation report only when validation ran, so a matrix failure is not buried under a missing-file error. --- .github/workflows/amalgamation-drift.yml | 2 +- .github/workflows/asan.yml | 4 +- .github/workflows/auto-release.yml | 48 ++++++------ .github/workflows/benchmark-arena-reclaim.yml | 20 ++--- .../benchmark-large-span-diagnostic.yml | 4 +- .github/workflows/benchmark-latency.yml | 28 +++---- .github/workflows/benchmark-memory.yml | 38 ++++++---- .github/workflows/benchmark-pprof-tax.yml | 33 ++++---- .github/workflows/benchmark-scaling.yml | 46 +++++------ .github/workflows/benchmark-sentinel.yml | 6 +- .github/workflows/benchmark-stats.yml | 32 ++++---- .github/workflows/c-unit.yml | 76 +++++++++---------- .github/workflows/cross.yml | 18 ++--- .github/workflows/doc-snippets.yml | 2 +- .github/workflows/fuzz.yml | 4 +- .github/workflows/macos-bundles.yml | 44 +++++------ .github/workflows/perf-ab.yml | 8 +- .github/workflows/pr-ci-gate.yml | 2 +- .github/workflows/pr-ci-mode.yml | 2 +- .../workflows/purge-teardown-regression.yml | 10 +-- .github/workflows/python-lint.yml | 6 +- .github/workflows/release.yaml | 4 +- .github/workflows/rust-native.yml | 10 +-- .github/workflows/star-history.yml | 6 +- .github/workflows/test.yaml | 2 +- .github/workflows/windows-bundles.yml | 54 ++++++------- .github/workflows/zero-tracking.yml | 4 +- 27 files changed, 261 insertions(+), 252 deletions(-) diff --git a/.github/workflows/amalgamation-drift.yml b/.github/workflows/amalgamation-drift.yml index 315efa047..972176e8f 100644 --- a/.github/workflows/amalgamation-drift.yml +++ b/.github/workflows/amalgamation-drift.yml @@ -36,7 +36,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: zackees/setup-soldr@v0 with: # Save caches fully under act (local bosn runs are pull_request events); setup-soldr#537 makes this the default. Remove then. diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml index d4c916ee1..925639ada 100644 --- a/.github/workflows/asan.yml +++ b/.github/workflows/asan.yml @@ -90,7 +90,7 @@ jobs: CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # MI_TRACK_ASAN silently turns itself OFF if sanitizer/asan_interface.h is # missing, which would leave this job green while sanitizing nothing. Fail @@ -162,7 +162,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # verify_local SKIPS the tsan config without clang: a skipped sanitizer is a green job that # sanitized nothing, so fail here instead. - name: clang is present diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index c0ecfddfc..b9f458950 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -106,7 +106,7 @@ jobs: contents: read issues: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} fetch-depth: 0 @@ -131,7 +131,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - name: Verify package checkout is the release candidate @@ -183,7 +183,7 @@ jobs: cp "$crate" dist/crate/ - name: Upload exact packaged crate - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: release-crate-${{ inputs.candidate_sha }} path: rust/dist/crate/*.crate @@ -205,7 +205,7 @@ jobs: cp "$RUNNER_TEMP/mimalloc-pprof-c.zip" dist/ - name: Upload release ZIP artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: mimalloc-pprof-c-zip path: rust/dist/mimalloc-pprof-c.zip @@ -240,7 +240,7 @@ jobs: triple: x86_64-pc-windows-msvc archive: zip steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - name: Verify binary checkout is the release candidate @@ -248,7 +248,7 @@ jobs: CANDIDATE_SHA: ${{ inputs.candidate_sha }} run: | [[ "$CANDIDATE_SHA" =~ ^[0-9a-f]{40}$ ]] && test "$(git rev-parse HEAD)" = "$CANDIDATE_SHA" || { echo '::error::binary checkout differs from candidate_sha'; exit 1; } - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - uses: zackees/setup-soldr@v0 with: version: v0.9.11 # pinned: v0.9.12 archive lacks the binary (zackees/soldr#3091) @@ -258,7 +258,7 @@ jobs: lockfile: rust/Cargo.lock target-dir: rust/target - name: Cache the prepared ${{ matrix.triple }} toolchain - uses: actions/cache@v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: # Deliberately the same path and key macos-bundles.yml / windows-bundles.yml use, # so a release run hits the cache those workflows already warmed on this commit. @@ -325,7 +325,7 @@ jobs: *) uv run ci/bundle_tests.py build release-test-bundle ;; esac tar -C release-test-bundle -czf release-test-bundle.tar.gz . - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: release-test-bundle-${{ matrix.asset }} path: release-test-bundle.tar.gz @@ -472,7 +472,7 @@ jobs: (cd stage && zip -r "$GITHUB_WORKSPACE/dist/${name}.zip" .) fi ls -l dist - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: release-binaries-${{ matrix.asset }} path: dist/* @@ -502,17 +502,17 @@ jobs: contents: read actions: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - - uses: actions/setup-python@v5 + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 with: python-version: '3.12' - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: release-binaries-${{ matrix.asset }} path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: release-test-bundle-${{ matrix.asset }} path: test-input @@ -551,14 +551,14 @@ jobs: actions: read issues: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: mimalloc-pprof-c-zip path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: release-binaries-* merge-multiple: true @@ -589,7 +589,7 @@ jobs: ISSUE_NUMBER: ${{ inputs.issue_number }} CANDIDATE_SHA: ${{ inputs.candidate_sha }} run: python3 ci/release.py preflight-artifacts --issue "$ISSUE_NUMBER" --candidate-sha "$CANDIDATE_SHA" --dist dist - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: release-preflight-${{ inputs.candidate_sha }} path: dist/ @@ -608,7 +608,7 @@ jobs: id-token: write issues: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} fetch-depth: 0 # origin/main is needed to prove a real candidate was merged @@ -702,12 +702,12 @@ jobs: build-cache-mode: full - name: Download archives already tested on native hosts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: release-preflight-${{ inputs.candidate_sha }} path: dist - name: Download exact packaged crate - uses: actions/download-artifact@v4 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: release-crate-${{ inputs.candidate_sha }} path: release-crate @@ -785,14 +785,14 @@ jobs: contents: read actions: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - - uses: actions/setup-python@v5 + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 with: python-version: '3.12' - name: Download exact worker preflight archive and info.json - uses: actions/download-artifact@v4 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: release-preflight-${{ inputs.candidate_sha }} path: dist @@ -842,7 +842,7 @@ jobs: contents: read issues: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} - name: Append run URL and outcome to the release control issue diff --git a/.github/workflows/benchmark-arena-reclaim.yml b/.github/workflows/benchmark-arena-reclaim.yml index 05b88fd0e..170809664 100644 --- a/.github/workflows/benchmark-arena-reclaim.yml +++ b/.github/workflows/benchmark-arena-reclaim.yml @@ -18,10 +18,10 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: d5bdb464debf59d0816eeac038d9d4423736c9c4 path: baseline-main @@ -29,7 +29,7 @@ jobs: run: | python3 ci/bench_arena_reclaim.py --measure --toolchain unix --build-root "$RUNNER_TEMP/arena-build-pr" --data "$RUNNER_TEMP/arena-reclaim-linux-pr.json" --runs 3 python3 ci/bench_arena_reclaim.py --measure --toolchain unix --build-root "$RUNNER_TEMP/arena-build-main" --allocator-source baseline-main --allocator-source-sha d5bdb464debf59d0816eeac038d9d4423736c9c4 --data "$RUNNER_TEMP/arena-reclaim-linux-main.json" --runs 3 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: arena-reclaim-linux path: ${{ runner.temp }}/arena-reclaim-linux-*.json @@ -38,10 +38,10 @@ jobs: runs-on: windows-latest timeout-minutes: 45 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: d5bdb464debf59d0816eeac038d9d4423736c9c4 path: baseline-main @@ -50,7 +50,7 @@ jobs: run: | python ci/bench_arena_reclaim.py --measure --toolchain msvc --build-root "$RUNNER_TEMP/arena-build-pr" --data "$RUNNER_TEMP/arena-reclaim-msvc-pr.json" --runs 3 python ci/bench_arena_reclaim.py --measure --toolchain msvc --build-root "$RUNNER_TEMP/arena-build-main" --allocator-source baseline-main --allocator-source-sha d5bdb464debf59d0816eeac038d9d4423736c9c4 --data "$RUNNER_TEMP/arena-reclaim-msvc-main.json" --runs 3 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: arena-reclaim-msvc path: ${{ runner.temp }}/arena-reclaim-msvc-*.json @@ -59,14 +59,14 @@ jobs: runs-on: windows-latest timeout-minutes: 45 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: d5bdb464debf59d0816eeac038d9d4423736c9c4 path: baseline-main - - uses: msys2/setup-msys2@v2 + - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0 with: msystem: MINGW64 install: mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-python @@ -75,7 +75,7 @@ jobs: run: | python ci/bench_arena_reclaim.py --measure --toolchain mingw --build-root "$RUNNER_TEMP/arena-build-pr" --data "$RUNNER_TEMP/arena-reclaim-mingw-pr.json" --runs 3 python ci/bench_arena_reclaim.py --measure --toolchain mingw --build-root "$RUNNER_TEMP/arena-build-main" --allocator-source baseline-main --allocator-source-sha d5bdb464debf59d0816eeac038d9d4423736c9c4 --data "$RUNNER_TEMP/arena-reclaim-mingw-main.json" --runs 3 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: arena-reclaim-mingw path: ${{ runner.temp }}/arena-reclaim-mingw-*.json diff --git a/.github/workflows/benchmark-large-span-diagnostic.yml b/.github/workflows/benchmark-large-span-diagnostic.yml index 7c3cb5260..9f25dd1a8 100644 --- a/.github/workflows/benchmark-large-span-diagnostic.yml +++ b/.github/workflows/benchmark-large-span-diagnostic.yml @@ -36,7 +36,7 @@ jobs: RUN_LOCAL_ID: gha-${{ github.run_id }}-${{ github.run_attempt }} OUTPUT_DIR: ${{ github.workspace }}/.large-span-diagnostic-${{ github.run_id }}-${{ github.run_attempt }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.candidate_sha }} fetch-depth: 0 @@ -149,7 +149,7 @@ jobs: --output "$OUTPUT_DIR/large-span-scaling-refs.json" - name: upload raw diagnostic artifacts if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: large-span-diagnostic-${{ github.run_id }}-${{ github.run_attempt }} overwrite: true diff --git a/.github/workflows/benchmark-latency.yml b/.github/workflows/benchmark-latency.yml index 9be30e2ee..2912b87c8 100644 --- a/.github/workflows/benchmark-latency.yml +++ b/.github/workflows/benchmark-latency.yml @@ -43,7 +43,7 @@ jobs: mode: ${{ inputs.mode || 'full' }} prior_branch_sha: ${{ steps.prior.outputs.prior_sha }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Fail before any build if the lockfile setup-soldr's yank audit reads is @@ -155,7 +155,7 @@ jobs: echo "publish_eligible=$ELIGIBLE" >> "$GITHUB_OUTPUT" - name: upload raw latency artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-latency-raw-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -165,7 +165,7 @@ jobs: if-no-files-found: error - name: upload validation artifact if: (inputs.mode || 'full') == 'full' && always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-latency-validation-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -176,7 +176,7 @@ jobs: if-no-files-found: error - name: upload site artifact if: (inputs.mode || 'full') == 'full' && success() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-latency-site-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -193,14 +193,14 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-latency-site-${{ github.run_id }} path: audit/site/ - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-latency-validation-${{ github.run_id }} path: audit/validation/ @@ -218,10 +218,10 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-latency-site-${{ github.run_id }} path: site-temp/ @@ -256,11 +256,11 @@ jobs: permissions: contents: read steps: - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-latency-site-${{ github.run_id }} path: _site/ - - uses: actions/upload-pages-artifact@v4.0.0 + - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: _site/ include-hidden-files: true @@ -279,7 +279,7 @@ jobs: outputs: page_url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/deploy-pages@v4.0.5 + - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 id: deployment publication-audit: @@ -290,10 +290,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-latency-site-${{ github.run_id }} path: audit/site/ diff --git a/.github/workflows/benchmark-memory.yml b/.github/workflows/benchmark-memory.yml index 2807e6b2e..1d46dfcdd 100644 --- a/.github/workflows/benchmark-memory.yml +++ b/.github/workflows/benchmark-memory.yml @@ -23,7 +23,10 @@ on: default: 17 required: false schedule: - - cron: "41 8 * * 0" + # Saturday: Sunday 08:41 collided with benchmark-latency's identical cron; both + # share benchmark-stats-production, where GitHub keeps one pending run per group, + # so latency cancelled this run before it got a runner (run 40178014027). + - cron: "41 8 * * 6" concurrency: group: benchmark-stats-production @@ -38,7 +41,10 @@ env: jobs: build-and-measure: runs-on: ubuntu-24.04 - timeout-minutes: 60 + # Measured: the suite step grew 43m (08-30) -> 49m (09-04) -> >53m with the Bun + # row (09-20), plus ~7m of builds; 60 cut every run off. Override with the repo + # variable BENCHMARK_MEMORY_TIMEOUT_MINUTES. + timeout-minutes: ${{ fromJSON(vars.BENCHMARK_MEMORY_TIMEOUT_MINUTES || '90') }} permissions: contents: read outputs: @@ -46,7 +52,7 @@ jobs: mode: ${{ inputs.mode || 'full' }} prior_branch_sha: ${{ steps.prior.outputs.prior_sha }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Fail before any build if the lockfile setup-soldr's yank audit reads is @@ -158,7 +164,7 @@ jobs: echo "publish_eligible=$ELIGIBLE" >> "$GITHUB_OUTPUT" - name: upload raw proc artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-memory-raw-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -168,7 +174,7 @@ jobs: if-no-files-found: error - name: upload validation artifact if: (inputs.mode || 'full') == 'full' && always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-memory-validation-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -179,7 +185,7 @@ jobs: if-no-files-found: error - name: upload site artifact if: (inputs.mode || 'full') == 'full' && success() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-memory-site-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -196,14 +202,14 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-memory-site-${{ github.run_id }} path: audit/site/ - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-memory-validation-${{ github.run_id }} path: audit/validation/ @@ -221,10 +227,10 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-memory-site-${{ github.run_id }} path: site-temp/ @@ -259,11 +265,11 @@ jobs: permissions: contents: read steps: - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-memory-site-${{ github.run_id }} path: _site/ - - uses: actions/upload-pages-artifact@v4.0.0 + - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: _site/ include-hidden-files: true @@ -282,7 +288,7 @@ jobs: outputs: page_url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/deploy-pages@v4.0.5 + - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 id: deployment publication-audit: @@ -293,10 +299,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-memory-site-${{ github.run_id }} path: audit/site/ diff --git a/.github/workflows/benchmark-pprof-tax.yml b/.github/workflows/benchmark-pprof-tax.yml index 0a24d8bc6..c4a6fd695 100644 --- a/.github/workflows/benchmark-pprof-tax.yml +++ b/.github/workflows/benchmark-pprof-tax.yml @@ -60,7 +60,7 @@ jobs: mode: ${{ inputs.mode || 'full' }} prior_branch_sha: ${{ steps.prior.outputs.prior_sha }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Fail before any build if the lockfile setup-soldr's yank audit reads is @@ -139,6 +139,7 @@ jobs: DIGEST=$(sha256sum "$RUNNER_TEMP/pprof-tax-output-${{ github.run_id }}/pprof-tax-raw-run.json" | awk '{print $1}') echo "sha256=$DIGEST" >> "$GITHUB_OUTPUT" - name: validate and overlay complete pprof-tax report + id: validate if: (inputs.mode || 'full') == 'full' run: | set -euxo pipefail @@ -184,7 +185,7 @@ jobs: echo "publish_eligible=$ELIGIBLE" >> "$GITHUB_OUTPUT" - name: upload raw pprof-tax artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-pprof-tax-raw-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -193,8 +194,10 @@ jobs: retention-days: 30 if-no-files-found: error - name: upload validation artifact - if: (inputs.mode || 'full') == 'full' && always() - uses: actions/upload-artifact@v4.6.2 + # Only when validation ran: a matrix failure skips it, and uploading the + # report it never wrote buried the real error under a second one. + if: (inputs.mode || 'full') == 'full' && always() && steps.validate.outcome != 'skipped' + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-pprof-tax-validation-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -205,7 +208,7 @@ jobs: if-no-files-found: error - name: upload site artifact if: (inputs.mode || 'full') == 'full' && success() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-pprof-tax-site-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -222,14 +225,14 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-pprof-tax-site-${{ github.run_id }} path: audit/site/ - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-pprof-tax-validation-${{ github.run_id }} path: audit/validation/ @@ -247,10 +250,10 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-pprof-tax-site-${{ github.run_id }} path: site-temp/ @@ -285,11 +288,11 @@ jobs: permissions: contents: read steps: - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-pprof-tax-site-${{ github.run_id }} path: _site/ - - uses: actions/upload-pages-artifact@v4.0.0 + - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: _site/ include-hidden-files: true @@ -308,7 +311,7 @@ jobs: outputs: page_url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/deploy-pages@v4.0.5 + - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 id: deployment publication-audit: @@ -319,10 +322,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-pprof-tax-site-${{ github.run_id }} path: audit/site/ diff --git a/.github/workflows/benchmark-scaling.yml b/.github/workflows/benchmark-scaling.yml index 75b52c3d4..3a5f61b86 100644 --- a/.github/workflows/benchmark-scaling.yml +++ b/.github/workflows/benchmark-scaling.yml @@ -95,7 +95,7 @@ jobs: outputs: run_seed: ${{ steps.seed.outputs.seed }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: validate dispatch inputs @@ -127,7 +127,7 @@ jobs: # reference allocators (TCMalloc alone is a Bazel build of many minutes). The references # depend only on their pins, patches and the builder; the fork tree on its own sources too. - name: cache reference allocator trees - uses: actions/cache@v4.2.4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | rust/target/release/archives @@ -141,7 +141,7 @@ jobs: rust/target/release/sources/bun-mimalloc key: benchmark-references-${{ runner.os }}-${{ hashFiles('rust/benchmark-suite/allocators/allocator-lock.json', 'rust/benchmark-suite/allocators/patches/**', 'ci/build_benchmark_allocators.py') }} - name: cache fork allocator tree - uses: actions/cache@v4.2.4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: rust/target/release/build/mimalloc-pprof # #528: a diagnostic build with extra defines never shares a tree with a default @@ -176,7 +176,7 @@ jobs: echo "seed=$SEED" >> "$GITHUB_OUTPUT" printf '%s\n' "$SEED" > rust/target/release/scaling-run-seed.txt - name: upload scaling build - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-scaling-build-${{ github.run_id }} overwrite: true @@ -200,7 +200,7 @@ jobs: permissions: contents: read steps: - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-build-${{ github.run_id }} path: rust/target/release/ @@ -240,7 +240,7 @@ jobs: done - name: upload raw scaling shard if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-scaling-shards-${{ github.run_id }} overwrite: true @@ -260,16 +260,16 @@ jobs: mode: ${{ inputs.mode || 'full' }} prior_branch_sha: ${{ steps.prior.outputs.prior_sha }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-build-${{ github.run_id }} path: rust/target/release/ - name: restore executable modes run: chmod +x rust/target/release/benchmark-scaling-merge rust/target/release/benchmark-scaling-validate - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-shards-${{ github.run_id }} path: scaling-shards/ @@ -346,7 +346,7 @@ jobs: echo "publish_eligible=$ELIGIBLE" >> "$GITHUB_OUTPUT" - name: upload merged raw scaling artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-scaling-raw-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -356,7 +356,7 @@ jobs: if-no-files-found: error - name: upload validation artifact if: (inputs.mode || 'full') == 'full' && always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-scaling-validation-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -367,7 +367,7 @@ jobs: if-no-files-found: error - name: upload site artifact if: (inputs.mode || 'full') == 'full' && success() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-scaling-site-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -384,14 +384,14 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-site-${{ github.run_id }} path: audit/site/ - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-validation-${{ github.run_id }} path: audit/validation/ @@ -409,10 +409,10 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-site-${{ github.run_id }} path: site-temp/ @@ -447,11 +447,11 @@ jobs: permissions: contents: read steps: - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-site-${{ github.run_id }} path: _site/ - - uses: actions/upload-pages-artifact@v4.0.0 + - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: _site/ include-hidden-files: true @@ -470,7 +470,7 @@ jobs: outputs: page_url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/deploy-pages@v4.0.5 + - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 id: deployment publication-audit: @@ -481,10 +481,10 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: actions/download-artifact@v4.3.0 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-scaling-site-${{ github.run_id }} path: audit/site/ @@ -532,7 +532,7 @@ jobs: issues: write actions: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: open or update the failure issue diff --git a/.github/workflows/benchmark-sentinel.yml b/.github/workflows/benchmark-sentinel.yml index 8bd19e068..24b06daaf 100644 --- a/.github/workflows/benchmark-sentinel.yml +++ b/.github/workflows/benchmark-sentinel.yml @@ -72,7 +72,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: zackees/setup-soldr@v0 with: # Save caches fully under act (local bosn runs are pull_request events); setup-soldr#537 makes this the default. Remove then. @@ -84,13 +84,13 @@ jobs: - name: Run PR sentinel benchmarks run: soldr cargo run -p dashboard --release - name: Upload benchmark report - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-report-${{ matrix.os }} path: rust/benchmark-report.html if-no-files-found: error - name: Upload benchmark JSON - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-json-${{ matrix.os }} path: rust/target/release/*.json diff --git a/.github/workflows/benchmark-stats.yml b/.github/workflows/benchmark-stats.yml index 36c5250e8..edc7ff744 100644 --- a/.github/workflows/benchmark-stats.yml +++ b/.github/workflows/benchmark-stats.yml @@ -54,7 +54,7 @@ jobs: mode: ${{ inputs.mode || 'full' }} prior_branch_sha: ${{ steps.history.outputs.prior_sha }} steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Fail before any build if the lockfile setup-soldr's yank audit reads is @@ -192,7 +192,7 @@ jobs: echo "publish_eligible=$ELIGIBLE" >> "$GITHUB_OUTPUT" - name: upload raw artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-raw-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -201,7 +201,7 @@ jobs: if-no-files-found: ignore - name: upload provenance artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-provenance-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -212,7 +212,7 @@ jobs: if-no-files-found: ignore - name: upload validation artifact if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-validation-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -223,7 +223,7 @@ jobs: if-no-files-found: ignore - name: upload site artifact if: success() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-site-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -233,7 +233,7 @@ jobs: if-no-files-found: error - name: upload diagnostics artifact if: failure() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-diagnostics-${{ github.run_id }} overwrite: true # a re-run of this job replaces attempt 1's upload (#341) @@ -250,16 +250,16 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: download site artifact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-site-${{ github.run_id }} path: audit/site/ - name: download validation artifact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-validation-${{ github.run_id }} path: audit/validation/ @@ -281,11 +281,11 @@ jobs: env: PUBLISH_REF: refs/heads/benchmark-stats steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: download site artifact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-site-${{ github.run_id }} path: site-temp/ @@ -337,12 +337,12 @@ jobs: contents: read steps: - name: download site artifact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-site-${{ github.run_id }} path: _site/ - name: upload pages artifact - uses: actions/upload-pages-artifact@v4.0.0 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: _site/ include-hidden-files: true @@ -361,7 +361,7 @@ jobs: outputs: page_url: ${{ steps.deployment.outputs.page_url }} steps: - - uses: actions/deploy-pages@v4.0.5 + - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 id: deployment publication-audit: @@ -372,11 +372,11 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: download sealed site artifact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: benchmark-site-${{ github.run_id }} path: audit/site/ diff --git a/.github/workflows/c-unit.yml b/.github/workflows/c-unit.yml index d8923abe3..956562d78 100644 --- a/.github/workflows/c-unit.yml +++ b/.github/workflows/c-unit.yml @@ -70,7 +70,7 @@ jobs: outputs: sha: ${{ steps.identity.outputs.sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.candidate_sha || github.sha }} fetch-depth: 0 @@ -127,7 +127,7 @@ jobs: outputs: run: ${{ steps.decide.outputs.run }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} fetch-depth: 0 @@ -150,10 +150,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - name: Configure -- the `release` build row's flags, which the baseline was recorded from run: | set -euo pipefail @@ -180,7 +180,7 @@ jobs: fi exit $rc - if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: memory-gate-minimal-lane path: result-*.json @@ -391,10 +391,10 @@ jobs: - name: Install build dependencies (alpine only) if: matrix.container != '' run: apk add --no-cache build-base cmake ninja python3 git tar - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 if: matrix.container == '' - name: Configure shell: sh @@ -457,7 +457,7 @@ jobs: run: tar -C bundle -czf ${{ matrix.config }}.tar.gz . - name: Upload the bundle if: matrix.kind == 'bundle' || matrix.kind == 'control' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-bundle-${{ matrix.config }} path: | @@ -467,7 +467,7 @@ jobs: retention-days: 1 - name: Upload the library if: matrix.kind == 'lib' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-lib-${{ matrix.config }} path: | @@ -503,15 +503,15 @@ jobs: - name: Install build dependencies (alpine only) if: matrix.container != '' run: apk add --no-cache build-base git python3 - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 if: matrix.container == '' - name: Compile the probe's objects with Bun's exact define set shell: sh run: ${{ matrix.python }} ci/check_bun_surface.py --emit-objects bun-objects ${{ matrix.args }} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-bun-objects-${{ matrix.name }} path: bun-objects @@ -539,10 +539,10 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 # -DMI_DHAT=ON: DHAT is opt-in (default OFF since 2026-09-18), so the main `cl` tree # builds it in to keep test-dhat running under Microsoft's compiler; the owner-gate # tree below stays at the default, so `cl` compiles both the ON and OFF shapes. @@ -608,7 +608,7 @@ jobs: set -euo pipefail tar -C bundle -czf windows-native.tar.gz . tar -C bundle-gated -czf windows-native-gated.tar.gz . - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-bundle-windows-native path: | @@ -627,19 +627,19 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 - - uses: actions/download-artifact@v4 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: c-unit-bundle-* path: artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: c-unit-lib-* path: libs - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: c-unit-bun-objects-* path: bun-objects @@ -795,7 +795,7 @@ jobs: # The coverage job needs this half's JUnit; `if: always()` so a red wave still # uploads what it managed to run. - if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-results-parallel path: | @@ -815,11 +815,11 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 45 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 - - uses: actions/download-artifact@v4 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: c-unit-bundle-* path: artifacts @@ -859,7 +859,7 @@ jobs: --jobs 1 --select serial --junit-dir results ' - if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-results-serial path: results @@ -883,19 +883,19 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 - - uses: actions/download-artifact@v4 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: c-unit-bundle-* path: artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: c-unit-results-parallel path: parallel - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: c-unit-results-serial path: serial @@ -954,11 +954,11 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 - - uses: actions/download-artifact@v4 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: c-unit-bundle-windows-native path: artifacts @@ -986,7 +986,7 @@ jobs: --names "ctest --show-only" executed \ --summary "$GITHUB_STEP_SUMMARY" - if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: c-unit-windows-native-results path: results @@ -1006,12 +1006,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} # the base revision must be reachable for the worktree the script builds fetch-depth: 0 - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - name: Normaliser and slicer self-test run: uv run ci/check_fastpath_identity.py --selftest - name: Default build byte-identical to the base; gated build differs @@ -1033,10 +1033,10 @@ jobs: runs-on: ubuntu-24.04-arm timeout-minutes: 20 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - name: Disassembly parser selftest run: uv run ci/check_isa_baseline.py --selftest - name: Portable build must contain no above-baseline instructions diff --git a/.github/workflows/cross.yml b/.github/workflows/cross.yml index 9fa13e4d7..d535b9284 100644 --- a/.github/workflows/cross.yml +++ b/.github/workflows/cross.yml @@ -36,7 +36,7 @@ jobs: outputs: sha: ${{ steps.identity.outputs.sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.candidate_sha || github.sha }} fetch-depth: 0 @@ -103,7 +103,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -162,7 +162,7 @@ jobs: ls -1 "dist/$TARGET" || echo " (none)" exit 1 fi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: test-bins-${{ matrix.target }} path: rust/dist/${{ matrix.target }} @@ -186,7 +186,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -308,7 +308,7 @@ jobs: ls -1 "dist/$TARGET" || echo " (none)" exit 1 fi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: test-bins-${{ matrix.target }} path: rust/dist/${{ matrix.target }} @@ -330,7 +330,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -362,7 +362,7 @@ jobs: $dist = Join-Path $PWD 'dist/x86_64-pc-windows-gnu' New-Item -ItemType Directory -Force -Path $dist | Out-Null $bins | ForEach-Object { Copy-Item $_ -Destination $dist } - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: test-bins-x86_64-pc-windows-gnu path: rust/dist/x86_64-pc-windows-gnu @@ -416,7 +416,7 @@ jobs: runner: windows-latest pprof: true steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: test-bins-${{ matrix.target }} path: dist/${{ matrix.target }} @@ -436,7 +436,7 @@ jobs: & $_.FullName --test-threads=4 if ($LASTEXITCODE -ne 0) { throw "test failed: $($_.Name)" } } - - uses: actions/setup-go@v5 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 if: matrix.pprof with: go-version: stable diff --git a/.github/workflows/doc-snippets.yml b/.github/workflows/doc-snippets.yml index 8bfba1da4..474911d1b 100644 --- a/.github/workflows/doc-snippets.yml +++ b/.github/workflows/doc-snippets.yml @@ -32,7 +32,7 @@ jobs: check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # ubuntu-latest ships both gcc and clang already; nothing to install. - name: Positive control (must catch a deliberately broken snippet) run: python3 ci/check_doc_snippets.py --self-test diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index fb22f1c68..6e13a1fad 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -45,7 +45,7 @@ jobs: CC: clang CXX: clang++ steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Build harnesses (libFuzzer + ASan) run: | @@ -113,7 +113,7 @@ jobs: fi echo "positive control fired: ASan reported the planted use-after-free (rc=$rc)" - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 if: failure() with: name: fuzz-crashes diff --git a/.github/workflows/macos-bundles.yml b/.github/workflows/macos-bundles.yml index fe73ba1b8..fb79f78f7 100644 --- a/.github/workflows/macos-bundles.yml +++ b/.github/workflows/macos-bundles.yml @@ -98,7 +98,7 @@ jobs: fi [[ "$sha" =~ ^[0-9a-f]{40}$ ]] || { echo '::error::candidate_sha must be a complete lowercase 40-hex SHA'; exit 1; } echo "sha=$sha" >> "$GITHUB_OUTPUT" - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ steps.candidate.outputs.sha }} - name: Verify checked-out candidate identity @@ -199,7 +199,7 @@ jobs: - name: Report minimal-mode skip if: env.RUN_MACOS_BUILD != 'true' run: echo '${{ matrix.bundle }} is reserved for selective macOS or ci-full validation.' >> "$GITHUB_STEP_SUMMARY" - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: env.RUN_MACOS_BUILD == 'true' with: ref: ${{ needs.resolve-candidate.outputs.sha }} @@ -216,7 +216,7 @@ jobs: target-dir: rust/target - name: Cache the prepared Darwin toolchain if: env.RUN_MACOS_BUILD == 'true' - uses: actions/cache@v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: ~/soldr-${{ matrix.triple }}.tar.zst key: soldr-prepare-${{ matrix.triple }}-${{ hashFiles('rust/rust-toolchain.toml') }} @@ -373,7 +373,7 @@ jobs: # and does not preserve symlinks, and this bundle needs both (every test exe, and # the libmimalloc.dylib -> libmimalloc.3.dylib SONAME chain). run: tar -C bundle -czf "${{ matrix.bundle }}.tar.gz" . - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 if: env.RUN_MACOS_BUILD == 'true' with: name: bundle-${{ matrix.bundle }} @@ -399,7 +399,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -493,7 +493,7 @@ jobs: ls -1 "dist/$TARGET" || echo " (none)" exit 1 fi - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: rust-test-bins-${{ matrix.target }} path: rust/dist/${{ matrix.target }} @@ -545,7 +545,7 @@ jobs: run: ${{ steps.decide.outputs.run || steps.no-pr.outputs.run }} reason: ${{ steps.decide.outputs.reason }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: github.event_name == 'pull_request' with: ref: ${{ needs.resolve-candidate.outputs.sha }} @@ -572,10 +572,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: bundle-macos-x64-* path: artifacts @@ -638,14 +638,14 @@ jobs: test -f "$C/sel-debug-full.xml" || { echo "::error::debug-full JUnit missing"; exit 1; } python3 ci/recovery_expected_failures.py "$C/sel-release.xml" "$C/sel-debug-full.xml" - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-selective-results path: ${{ steps.macos.outputs.workdir }}/collected/ if-no-files-found: warn retention-days: 7 - if: ${{ failure() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-selective-guest-screens path: ${{ steps.macos.outputs.workdir }}/results/*.ppm @@ -673,17 +673,17 @@ jobs: runner: macos-15-intel triple: x86_64-apple-darwin steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: actions/setup-python@v5 + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 with: python-version: '3.12' - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: bundle-macos-${{ matrix.arch }}-* path: artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: rust-test-bins-${{ matrix.triple }} path: rust-bins @@ -742,7 +742,7 @@ jobs: "$bin" --test-threads=4 done - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-native-${{ matrix.arch }}-results path: results/ @@ -760,19 +760,19 @@ jobs: timeout-minutes: 90 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: bundle-macos-x64-* path: artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: bundle-macos-arm64-* path: arm64-artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: rust-test-bins-x86_64-apple-darwin path: rust-bins @@ -921,14 +921,14 @@ jobs: esac - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-bundle-results path: ${{ steps.macos.outputs.workdir }}/collected/ if-no-files-found: warn retention-days: 7 - if: ${{ failure() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: macos-guest-screens path: ${{ steps.macos.outputs.workdir }}/results/*.ppm diff --git a/.github/workflows/perf-ab.yml b/.github/workflows/perf-ab.yml index c68b40f6a..d8a5e2328 100644 --- a/.github/workflows/perf-ab.yml +++ b/.github/workflows/perf-ab.yml @@ -89,7 +89,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 90 steps: - - uses: actions/checkout@v4.4.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Use this workflow revision's harness even when measuring an older # allocator. Historical perf_ab.py versions may not accept today's flags. @@ -128,7 +128,7 @@ jobs: fi - name: upload the build-only diagnostic if: always() && inputs.build_report_only - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: perf-ab-build-report path: perf-ab-build-report @@ -136,7 +136,7 @@ jobs: retention-days: 30 - name: upload the measured executables if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: perf-ab-builds path: perf-ab-builds @@ -146,7 +146,7 @@ jobs: # re-judge them, and runs on the same CPU model can be pooled - name: upload the samples if: always() - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: perf-ab-samples path: perf-ab-samples.json diff --git a/.github/workflows/pr-ci-gate.yml b/.github/workflows/pr-ci-gate.yml index 0de0a0f85..3fe84fb0c 100644 --- a/.github/workflows/pr-ci-gate.yml +++ b/.github/workflows/pr-ci-gate.yml @@ -23,7 +23,7 @@ jobs: verify: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - env: NEEDS_JSON: ${{ inputs.needs-json }} CI_TEST: ${{ inputs.ci-test }} diff --git a/.github/workflows/pr-ci-mode.yml b/.github/workflows/pr-ci-mode.yml index 97dac104b..17543e6bc 100644 --- a/.github/workflows/pr-ci-mode.yml +++ b/.github/workflows/pr-ci-mode.yml @@ -16,7 +16,7 @@ jobs: outputs: external: ${{ steps.mode.outputs.external }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - id: mode env: GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/purge-teardown-regression.yml b/.github/workflows/purge-teardown-regression.yml index 9f8fc2522..2478f4ad9 100644 --- a/.github/workflows/purge-teardown-regression.yml +++ b/.github/workflows/purge-teardown-regression.yml @@ -48,8 +48,8 @@ jobs: env: SOLDR_GITHUB_TOKEN: ${{ github.token }} steps: - - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - uses: zackees/setup-soldr@v0 with: # Save caches fully under act (local bosn runs are pull_request events); setup-soldr#537 makes this the default. Remove then. @@ -82,7 +82,7 @@ jobs: find "$MINGW_W64_CROSS_ROOT" -name libgcc_s_seh-1.dll -exec cp '{}' regression/ \; "$CC_x86_64_pc_windows_gnu" --version sha256sum regression/mimalloc-test-purge-all.exe regression/libgcc_s_seh-1.dll - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: purge-teardown-binary-${{ matrix.gate }}-${{ matrix.control }} path: | @@ -101,7 +101,7 @@ jobs: - gate: 'ON' control: true steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: purge-teardown-binary-${{ matrix.gate }}-${{ matrix.control }} path: regression @@ -155,7 +155,7 @@ jobs: } finally { Remove-Item $key } - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 if: always() with: name: purge-teardown-evidence-${{ matrix.gate }}-${{ matrix.control }} diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index 8de521bcb..25012686e 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -32,7 +32,7 @@ jobs: trusted: ${{ steps.gate.outputs.trusted }} skip_lint: ${{ steps.gate.outputs.skip_lint }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} persist-credentials: false @@ -57,8 +57,8 @@ jobs: if: needs.ci-mode.outputs.skip_lint != 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 # check_usdt_probes.py --require compiles src/static.c against . - name: Install USDT probe headers run: sudo apt-get install -y --no-install-recommends systemtap-sdt-dev binutils diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 60039e002..468611c46 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -29,7 +29,7 @@ jobs: steps: # Checkout: https://github.com/actions/checkout - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ matrix.branch }} fetch-tags: true @@ -48,7 +48,7 @@ jobs: # Create a release: https://github.com/softprops/action-gh-release (MIT license) - name: Release - uses: softprops/action-gh-release@v3 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 if: ${{ env.RELEASE != '' && env.RELEASE != 'no' }} with: name: ${{ env.RELEASE }} diff --git a/.github/workflows/rust-native.yml b/.github/workflows/rust-native.yml index a35ad76e6..7861ff7c1 100644 --- a/.github/workflows/rust-native.yml +++ b/.github/workflows/rust-native.yml @@ -28,7 +28,7 @@ jobs: outputs: sha: ${{ steps.identity.outputs.sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.candidate_sha || github.sha }} fetch-depth: 0 @@ -83,7 +83,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -170,10 +170,10 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: msys2/setup-msys2@v2 + - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0 with: release: true install: mingw-w64-x86_64-gcc @@ -202,7 +202,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 diff --git a/.github/workflows/star-history.yml b/.github/workflows/star-history.yml index a0815d2b1..9cfbefbf5 100644 --- a/.github/workflows/star-history.yml +++ b/.github/workflows/star-history.yml @@ -38,15 +38,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the generator - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Check out the data branch - uses: actions/checkout@v4 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ env.DATA_BRANCH }} path: star-history-data - - uses: actions/setup-python@v5 + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 with: python-version: "3.12" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 26613a665..c2d32448a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,7 +23,7 @@ jobs: steps: # Checkout: https://github.com/actions/checkout - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Basic - name: Debug diff --git a/.github/workflows/windows-bundles.yml b/.github/workflows/windows-bundles.yml index c07de83d0..f84cd3fca 100644 --- a/.github/workflows/windows-bundles.yml +++ b/.github/workflows/windows-bundles.yml @@ -93,7 +93,7 @@ jobs: outputs: sha: ${{ steps.identity.outputs.sha }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.candidate_sha || github.sha }} fetch-depth: 0 @@ -176,10 +176,10 @@ jobs: # the memory gate today -- see the coverage table in docs/ci-gates.md. cmake: -DCMAKE_BUILD_TYPE=Release -DMI_PPROF=ON -DMI_BENCH_INJECT_LEAK=200000 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - uses: zackees/setup-soldr@v0 with: # Save caches fully under act (local bosn runs are pull_request events); setup-soldr#537 makes this the default. Remove then. @@ -191,7 +191,7 @@ jobs: lockfile: rust/Cargo.lock target-dir: rust/target - name: Cache the prepared MinGW toolchain - uses: actions/cache@v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: ~/soldr-x86_64-pc-windows-gnu.tar.zst key: soldr-prepare-x86_64-pc-windows-gnu-${{ hashFiles('rust/rust-toolchain.toml') }} @@ -326,7 +326,7 @@ jobs: # (Nothing in a Windows bundle is a symlink, but keeping the two lanes identical # means one unpack step on the runner rather than two.) run: tar -C bundle -czf "${{ matrix.bundle }}.tar.gz" . - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: bundle-${{ matrix.bundle }} path: ${{ matrix.bundle }}.tar.gz @@ -346,7 +346,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -398,7 +398,7 @@ jobs: exit 1 fi done - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: rust-test-bins-x86_64-pc-windows-gnu path: rust/dist/x86_64-pc-windows-gnu @@ -474,10 +474,10 @@ jobs: # it cannot be an entry in another bundle's manifest. cmake: -DCMAKE_BUILD_TYPE=Release -DMI_PPROF=ON -DMI_BENCH_INJECT_LEAK=200000 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - - uses: astral-sh/setup-uv@v3 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 - uses: zackees/setup-soldr@v0 with: save-cache: ${{ env.ACT && 'true' || 'auto' }} @@ -487,7 +487,7 @@ jobs: lockfile: rust/Cargo.lock target-dir: rust/target - name: Cache the prepared MSVC toolchain - uses: actions/cache@v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: # The xwin CRT/SDK splat is the expensive part of this lane: `soldr prepare` # downloads and materialises it from Microsoft on a cold runner. @@ -673,7 +673,7 @@ jobs: - name: Pack the bundle # tar, not a plain artifact upload: upload-artifact@v4 drops the executable bit. run: tar -C bundle -czf "${{ matrix.bundle }}.tar.gz" . - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: bundle-${{ matrix.bundle }} path: ${{ matrix.bundle }}.tar.gz @@ -719,7 +719,7 @@ jobs: run: working-directory: rust steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} - uses: zackees/setup-soldr@v0 @@ -925,13 +925,13 @@ jobs: cargo build -p dashboard --release --target x86_64-pc-windows-msvc mkdir -p dist/sentinel-x86_64-pc-windows-msvc cp target/x86_64-pc-windows-msvc/release/dashboard.exe dist/sentinel-x86_64-pc-windows-msvc/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: rust-test-bins-x86_64-pc-windows-msvc path: rust/dist/msvc-tests if-no-files-found: error retention-days: 7 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: rust-sentinel-x86_64-pc-windows-msvc path: rust/dist/sentinel-x86_64-pc-windows-msvc @@ -953,25 +953,25 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.resolve-candidate.outputs.sha }} # `windows-latest` ships a Python, but every ci/ script in this repo is run through # uv everywhere else and the two must not drift. - - uses: astral-sh/setup-uv@v3 - - uses: actions/download-artifact@v4 + - uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: bundle-windows-* path: artifacts - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: rust-test-bins-x86_64-pc-windows-gnu path: rust-bins - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: rust-test-bins-x86_64-pc-windows-msvc path: rust-bins-msvc - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: rust-sentinel-x86_64-pc-windows-msvc path: rust-sentinel-msvc @@ -1117,7 +1117,7 @@ jobs: "$test_binary" --test-threads=4 echo "::endgroup::" done - - uses: actions/setup-go@v5 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version: stable - name: Install pprof @@ -1233,7 +1233,7 @@ jobs: ;; esac - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: memory-gate-windows-gnu-x64-soldr # The leak runs too: they are what a reader needs to see why the control did or @@ -1525,7 +1525,7 @@ jobs: ;; esac - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: memory-gate-windows-msvc-x64-soldr # The leak runs too: they are what a reader needs to see why the control did or @@ -1567,7 +1567,7 @@ jobs: ls -l benchmark-report.html benchmark-report.json - if: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'benchmark') && !cancelled() }} continue-on-error: true - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: benchmark-report-windows-msvc-soldr path: | @@ -1636,13 +1636,13 @@ jobs: MIMALLOC_PURGE_ZEROES=1 "$exe" done | tee ab.jsonl uv run ci/zero_tracking_report.py ab.jsonl | tee -a "$GITHUB_STEP_SUMMARY" - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 if: ${{ !cancelled() && steps.zt_scope.outputs.run == 'true' }} with: name: zero-tracking-windows-msvc-x64 path: ab.jsonl - - uses: msys2/setup-msys2@v2 + - uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0 if: ${{ !cancelled() }} with: msystem: MINGW64 @@ -1874,7 +1874,7 @@ jobs: exit 1 fi - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: windows-bundle-results path: | diff --git a/.github/workflows/zero-tracking.yml b/.github/workflows/zero-tracking.yml index c81197a7f..e4c1d625c 100644 --- a/.github/workflows/zero-tracking.yml +++ b/.github/workflows/zero-tracking.yml @@ -45,7 +45,7 @@ jobs: ab: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - run: cmake -B build -DMI_PPROF=ON -DCMAKE_BUILD_TYPE=Release - run: cmake --build build --config Release # Correctness first: every byte of every mi_zalloc must read zero, with the @@ -67,7 +67,7 @@ jobs: MIMALLOC_PURGE_ZEROES=1 "$exe" done | tee ab.jsonl python3 ci/zero_tracking_report.py ab.jsonl - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: zero-tracking-ubuntu-latest path: ab.jsonl From 6d2fd862c785bd2355aa0b70cd78e05be18be171 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 25 Oct 2026 15:28:39 -0700 Subject: [PATCH 3/6] fix(bench): pprof-tax validator knows MI_DIAGNOSTICS and MI_MEMEVT #414 added both to ci/build_pprof_tax_configurations.py's equivalence and fork-only key lists but not to the Rust copy, so benchmark-pprof-tax-run rejected every real run before measuring (every weekly run since 09-27). --- rust/benchmark-suite/src/pprof_tax.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/rust/benchmark-suite/src/pprof_tax.rs b/rust/benchmark-suite/src/pprof_tax.rs index 7da014dce..516de821a 100644 --- a/rust/benchmark-suite/src/pprof_tax.rs +++ b/rust/benchmark-suite/src/pprof_tax.rs @@ -87,7 +87,8 @@ pub const PPROF_TAX_COMPILED_CONFIGURATION_IDS: [&str; 4] = [ /// CMake cache keys that must be identical (or allowlisted-different) across /// every compiled configuration for the comparison to mean anything. Sorted. -pub const PPROF_TAX_EQUIVALENCE_CACHE_KEYS: [&str; 20] = [ +/// Must equal EQUIVALENCE_CACHE_KEYS in ci/build_pprof_tax_configurations.py. +pub const PPROF_TAX_EQUIVALENCE_CACHE_KEYS: [&str; 22] = [ "CMAKE_AR", "CMAKE_BUILD_TYPE", "CMAKE_C_COMPILER", @@ -101,6 +102,8 @@ pub const PPROF_TAX_EQUIVALENCE_CACHE_KEYS: [&str; 20] = [ "MI_BUILD_TESTS", "MI_DEBUG_FULL", "MI_DHAT", + "MI_DIAGNOSTICS", + "MI_MEMEVT", "MI_OPT_ARCH", "MI_OPT_SIMD", "MI_OVERRIDE", @@ -113,7 +116,8 @@ pub const PPROF_TAX_EQUIVALENCE_CACHE_KEYS: [&str; 20] = [ /// Cache keys that exist only on the fork's CMakeLists.txt. Upstream must /// report these as `null`, never as an explicit "off" value: upstream simply /// has no such option. -pub const PPROF_TAX_FORK_ONLY_CACHE_KEYS: [&str; 2] = ["MI_DHAT", "MI_PPROF"]; +pub const PPROF_TAX_FORK_ONLY_CACHE_KEYS: [&str; 4] = + ["MI_DHAT", "MI_DIAGNOSTICS", "MI_MEMEVT", "MI_PPROF"]; /// One cell of the pprof-tax workload matrix, resolved against runner /// topology. @@ -2019,6 +2023,8 @@ fn fixture_cache( cache.insert("MI_BUILD_TESTS".into(), Some("OFF".into())); cache.insert("MI_DEBUG_FULL".into(), Some("OFF".into())); cache.insert("MI_DHAT".into(), mi_dhat.map(String::from)); + cache.insert("MI_DIAGNOSTICS".into(), Some("OFF".into())); + cache.insert("MI_MEMEVT".into(), Some("OFF".into())); cache.insert("MI_OPT_ARCH".into(), Some("OFF".into())); cache.insert("MI_OPT_SIMD".into(), Some("ON".into())); cache.insert("MI_OVERRIDE".into(), Some("ON".into())); @@ -2038,8 +2044,9 @@ pub fn synthetic_pprof_tax_fixture(run_seed: u64) -> Result Date: Sun, 25 Oct 2026 15:28:40 -0700 Subject: [PATCH 4/6] fix(bench): gate latency timer resolution on the fork only The overhead check (control p50 <= 5% of measured p50, measured p99 > 2x control p99) was fatal for every allocator, and tcmalloc's tiny-fixed-64/1 cell sits at timer resolution on hosted runners, so benchmark-latency has failed every week. Keep it a hard gate for mimalloc-pprof; record overhead_valid for references (still checked for consistency). Name the thresholds in Rust and in the Python site validator, and write the raw run before validating so a failed run uploads its evidence. --- ci/benchmark_report.py | 21 +++++++++++++--- rust/benchmark-suite/src/latency.rs | 28 ++++++++++++++++------ rust/benchmark-suite/src/latency_runner.rs | 4 +++- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/ci/benchmark_report.py b/ci/benchmark_report.py index 357054650..f913a3d96 100644 --- a/ci/benchmark_report.py +++ b/ci/benchmark_report.py @@ -1788,6 +1788,15 @@ def validate_latency_paired(value: object, label: str) -> dict[str, object]: return item +# Mirrors rust/benchmark-suite/src/latency.rs: a cell resolves above timer overhead when +# control p50 is at most this share of measured p50 and measured p99 exceeds control p99 +# by this factor. Only the fork is gated; a reference allocator at timer resolution +# (tcmalloc tiny-fixed-64/1) records overhead_valid=false instead of failing the run. +LATENCY_OVERHEAD_MAX_CONTROL_P50_RATIO = 0.05 +LATENCY_OVERHEAD_MIN_P99_FACTOR = 2.0 +LATENCY_OVERHEAD_GATED_ALLOCATORS = frozenset({"mimalloc-pprof"}) + + def validate_latency_report( value: object, label: str, *, compact: bool = False ) -> dict[str, object]: @@ -1916,12 +1925,18 @@ def validate_latency_report( control = validate_latency_distribution( item.get("control"), f"{label}.absolute_summaries[{index}].control" ) + resolved = ( + cast(float, control["p50_ns"]) + <= cast(float, measured["p50_ns"]) * LATENCY_OVERHEAD_MAX_CONTROL_P50_RATIO + and cast(float, measured["p99_ns"]) + > cast(float, control["p99_ns"]) * LATENCY_OVERHEAD_MIN_P99_FACTOR + ) + gated = item.get("allocator_id") in LATENCY_OVERHEAD_GATED_ALLOCATORS if ( int_value(measured["count"], "latency measured count") < 10_000 or int_value(control["count"], "latency control count") < 10_000 - or item.get("overhead_valid") is not True - or cast(float, control["p50_ns"]) > cast(float, measured["p50_ns"]) * 0.05 - or cast(float, measured["p99_ns"]) <= cast(float, control["p99_ns"]) * 2.0 + or item.get("overhead_valid") is not resolved + or (gated and not resolved) ): fail(f"{label}.absolute_summaries[{index}]: control/sample threshold failed") diff --git a/rust/benchmark-suite/src/latency.rs b/rust/benchmark-suite/src/latency.rs index fc4c5413c..46ec2c2d9 100644 --- a/rust/benchmark-suite/src/latency.rs +++ b/rust/benchmark-suite/src/latency.rs @@ -1207,8 +1207,18 @@ pub fn summarize_latency(values: &[u64]) -> Result }) } +/// Control p50 may be at most this share of measured p50 (timer cost negligible). +pub const LATENCY_OVERHEAD_MAX_CONTROL_P50_RATIO: f64 = 0.05; +/// Measured p99 must exceed control p99 by this factor. +pub const LATENCY_OVERHEAD_MIN_P99_FACTOR: f64 = 2.0; +/// Allocators whose cells must resolve above timer overhead. A reference allocator +/// fast enough to sit at timer resolution (tcmalloc tiny-fixed-64/1) is not a defect: +/// its `overhead_valid` is recorded, not fatal. +pub const LATENCY_OVERHEAD_GATED_ALLOCATORS: [&str; 1] = ["mimalloc-pprof"]; + pub fn overhead_is_valid(measured: &LatencyDistribution, control: &LatencyDistribution) -> bool { - control.p50_ns <= measured.p50_ns * 0.05 && measured.p99_ns > control.p99_ns * 2.0 + control.p50_ns <= measured.p50_ns * LATENCY_OVERHEAD_MAX_CONTROL_P50_RATIO + && measured.p99_ns > control.p99_ns * LATENCY_OVERHEAD_MIN_P99_FACTOR } pub fn validate_latency_raw_run(raw: &LatencyRawRun) -> Result<(), String> { @@ -1544,10 +1554,12 @@ pub fn validate_latency_raw_run(raw: &LatencyRawRun) -> Result<(), String> { .map(|observation| observation.duration_ns) }) .collect::>(); - if !overhead_is_valid( - &summarize_latency(&measured)?, - &summarize_latency(&control)?, - ) { + if LATENCY_OVERHEAD_GATED_ALLOCATORS.contains(&allocator) + && !overhead_is_valid( + &summarize_latency(&measured)?, + &summarize_latency(&control)?, + ) + { return Err(format!( "latency overhead threshold failed for {allocator} {}/{}", card.as_str(), @@ -1963,12 +1975,14 @@ pub fn validate_latency_report(report: &LatencyMetricReport) -> Result<(), Strin && value.allocator_id == allocator }) .collect::>(); + let gated = LATENCY_OVERHEAD_GATED_ALLOCATORS.contains(&allocator); if absolute.len() != 1 || absolute[0].transaction_definition != definition - || !absolute[0].overhead_valid + || absolute[0].overhead_valid + != overhead_is_valid(&expected_measured, &expected_control) + || (gated && !absolute[0].overhead_valid) || absolute[0].measured != expected_measured || absolute[0].control != expected_control - || !overhead_is_valid(&expected_measured, &expected_control) || absolute[0].measured.count < LATENCY_MIN_SAMPLES as u64 || absolute[0].control.count < LATENCY_MIN_SAMPLES as u64 || absolute[0].measured.zero_count != 0 diff --git a/rust/benchmark-suite/src/latency_runner.rs b/rust/benchmark-suite/src/latency_runner.rs index dc118f87e..7582363e1 100644 --- a/rust/benchmark-suite/src/latency_runner.rs +++ b/rust/benchmark-suite/src/latency_runner.rs @@ -433,10 +433,12 @@ fn run(options: Options) -> Result<(), String> { sampling_denominators: denominators, samples, }; + // Write before validating, so a failed run still uploads its evidence (nothing + // downstream publishes a raw run the validator rejected). + write_new_json(options.output_dir.join("latency-raw-run.json"), &raw)?; if !options.reduced_smoke { validate_latency_raw_run(&raw)?; } - write_new_json(options.output_dir.join("latency-raw-run.json"), &raw)?; println!( "PASS latency run: {} paired raw records; projected complete runtime {:.1}s", raw.samples.len(), From 32b48501de26e6b9dd4ac40006ea464f50e1a593 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 25 Oct 2026 15:30:20 -0700 Subject: [PATCH 5/6] ci: keep benchmark-memory at its 60 min budget; match pinned checkout in tests The memory checker enforces 60 minutes as a hard budget, so raising it is an owner decision (escalated on the issue), not part of this fix. Two workflow tests matched checkout by its old tag; match the action, not the ref. --- .github/workflows/benchmark-memory.yml | 5 +---- ci/tests/test_candidate_dispatch_workflows.py | 4 ++-- ci/tests/test_lint_no_macos_runners.py | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark-memory.yml b/.github/workflows/benchmark-memory.yml index 1d46dfcdd..37451aea8 100644 --- a/.github/workflows/benchmark-memory.yml +++ b/.github/workflows/benchmark-memory.yml @@ -41,10 +41,7 @@ env: jobs: build-and-measure: runs-on: ubuntu-24.04 - # Measured: the suite step grew 43m (08-30) -> 49m (09-04) -> >53m with the Bun - # row (09-20), plus ~7m of builds; 60 cut every run off. Override with the repo - # variable BENCHMARK_MEMORY_TIMEOUT_MINUTES. - timeout-minutes: ${{ fromJSON(vars.BENCHMARK_MEMORY_TIMEOUT_MINUTES || '90') }} + timeout-minutes: 60 permissions: contents: read outputs: diff --git a/ci/tests/test_candidate_dispatch_workflows.py b/ci/tests/test_candidate_dispatch_workflows.py index 79e016091..8dbfb2cd2 100644 --- a/ci/tests/test_candidate_dispatch_workflows.py +++ b/ci/tests/test_candidate_dispatch_workflows.py @@ -39,7 +39,7 @@ def test_full_dispatch_checks_out_one_merged_sha_and_preserves_pr_merge_checkout needs = [needs] assert "resolve-candidate" in needs, (workflow_name, job_name) for step in job.get("steps", []): - if step.get("uses") == "actions/checkout@v4": + if step.get("uses", "").startswith("actions/checkout@"): assert step["with"]["ref"] == VERIFIED_SHA, (workflow_name, job_name) @@ -55,7 +55,7 @@ def test_macos_pr_uses_merge_sha_for_workflow_tools_and_bundles() -> None: # Native full execution calls --exclude, added after older fork heads were cut. # Checking out the fork head would pair the new workflow with an old runner CLI. native = workflow["jobs"]["run-macos-native-full"] - checkouts = [step for step in native["steps"] if step.get("uses") == "actions/checkout@v4"] + checkouts = [step for step in native["steps"] if step.get("uses", "").startswith("actions/checkout@")] assert len(checkouts) == 1 assert checkouts[0]["with"]["ref"] == VERIFIED_SHA assert "--exclude test-osx-zone-introspect-remote" in next( diff --git a/ci/tests/test_lint_no_macos_runners.py b/ci/tests/test_lint_no_macos_runners.py index 1a9745487..e88d2e0fd 100644 --- a/ci/tests/test_lint_no_macos_runners.py +++ b/ci/tests/test_lint_no_macos_runners.py @@ -78,7 +78,7 @@ def test_every_job_checks_out_the_resolved_candidate(self) -> None: if name in {"resolve-candidate", "pr-ci-mode", "pr-test-gate"}: continue self.assertIn("resolve-candidate", job["needs"], name) - checkouts = [s for s in job["steps"] if s.get("uses") == "actions/checkout@v4"] + checkouts = [s for s in job["steps"] if s.get("uses", "").startswith("actions/checkout@")] self.assertEqual(len(checkouts), 1, name) self.assertEqual( checkouts[0]["with"]["ref"], "${{ needs.resolve-candidate.outputs.sha }}" From 5adaab6070ce7c90e214c9d64a3b033c51c108bd Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sun, 25 Oct 2026 15:31:42 -0700 Subject: [PATCH 6/6] style: ruff format Local-Gate: v1 tree=3572d92417ec8f94e84bd8a9b58b9b561ea78b3a secs=67 lanes=lint:run Ci-Attestation: {"at":1792967571,"gate":"python/all/lint","host":"linux-x86_64","key":"44d2f62f96209c34eace739e0010857fa8449ed308c3a56e5069da2f57267d14","lane":"lint","parents":["32b48501de26e6b9dd4ac40006ea464f50e1a593"],"secs":67,"stamp":"5c7273c53be9fa9e7dceb7aca69c286c","tree":"3572d92417ec8f94e84bd8a9b58b9b561ea78b3a","v":1,"via":"run"} --- ci/tests/test_candidate_dispatch_workflows.py | 4 +++- ci/tests/test_lint_no_macos_runners.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ci/tests/test_candidate_dispatch_workflows.py b/ci/tests/test_candidate_dispatch_workflows.py index 8dbfb2cd2..15d55a707 100644 --- a/ci/tests/test_candidate_dispatch_workflows.py +++ b/ci/tests/test_candidate_dispatch_workflows.py @@ -55,7 +55,9 @@ def test_macos_pr_uses_merge_sha_for_workflow_tools_and_bundles() -> None: # Native full execution calls --exclude, added after older fork heads were cut. # Checking out the fork head would pair the new workflow with an old runner CLI. native = workflow["jobs"]["run-macos-native-full"] - checkouts = [step for step in native["steps"] if step.get("uses", "").startswith("actions/checkout@")] + checkouts = [ + step for step in native["steps"] if step.get("uses", "").startswith("actions/checkout@") + ] assert len(checkouts) == 1 assert checkouts[0]["with"]["ref"] == VERIFIED_SHA assert "--exclude test-osx-zone-introspect-remote" in next( diff --git a/ci/tests/test_lint_no_macos_runners.py b/ci/tests/test_lint_no_macos_runners.py index e88d2e0fd..366c7efe6 100644 --- a/ci/tests/test_lint_no_macos_runners.py +++ b/ci/tests/test_lint_no_macos_runners.py @@ -78,7 +78,9 @@ def test_every_job_checks_out_the_resolved_candidate(self) -> None: if name in {"resolve-candidate", "pr-ci-mode", "pr-test-gate"}: continue self.assertIn("resolve-candidate", job["needs"], name) - checkouts = [s for s in job["steps"] if s.get("uses", "").startswith("actions/checkout@")] + checkouts = [ + s for s in job["steps"] if s.get("uses", "").startswith("actions/checkout@") + ] self.assertEqual(len(checkouts), 1, name) self.assertEqual( checkouts[0]["with"]["ref"], "${{ needs.resolve-candidate.outputs.sha }}"