diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index f653c1a0f..a61d9f2b1 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -35,7 +35,32 @@ on: - '.github/workflows/conformance.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/conformance.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches conformance: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + validate-json: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: Validate conformance JSON files runs-on: linux steps: @@ -110,6 +135,8 @@ jobs: # language, so a mistake shared by the generator and its own verifier still # fails here. Standard library only: nothing to install beyond python3. crosscheck: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: Second implementation reproduces every vector runs-on: linux steps: @@ -130,9 +157,10 @@ jobs: run: python3 smart-byte/conformance/crosscheck/verify_v1.py smart-byte/conformance/v1 spec-vector-coupling: + needs: relevant + if: needs.relevant.outputs.run == 'true' && (github.event_name == 'pull_request') name: Spec changes require vector-pack updates runs-on: linux - if: github.event_name == 'pull_request' steps: - name: Checkout (with full history for diff) uses: actions/checkout@v4 @@ -176,6 +204,8 @@ jobs: echo "coupling check passed (spec_touched=$spec_touched, conformance_touched=$conformance_touched)" versions-present: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: VERSIONS.md and README.md must exist runs-on: linux steps: diff --git a/.github/workflows/wai-byte-equality.yml b/.github/workflows/wai-byte-equality.yml index 7b6aea5f0..feaad6d1e 100644 --- a/.github/workflows/wai-byte-equality.yml +++ b/.github/workflows/wai-byte-equality.yml @@ -112,7 +112,32 @@ on: - '.github/workflows/wai-byte-equality.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-byte-equality.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-byte-equality: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + byte-equality: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: ${{ matrix.label }} runs-on: ${{ matrix.os }} strategy: diff --git a/.github/workflows/wai-conformance.yml b/.github/workflows/wai-conformance.yml index 3f79cce22..281ab55f5 100644 --- a/.github/workflows/wai-conformance.yml +++ b/.github/workflows/wai-conformance.yml @@ -116,7 +116,32 @@ on: # their pwsh steps stay, inactive, so restoring a leg is a one-line change. jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-conformance.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-conformance: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + cargo-classes: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: cargo-class corpora · ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: @@ -530,6 +555,8 @@ jobs: # One leg: wasm32 is the same machine on every host. Linux, so it does not queue on the # single macOS runner. quantum-wasip2: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: quantum core and corpus under wasm32-wasip2 (wasmtime) runs-on: linux # The fabric's planner test runs fabric-v1 under every planner configuration in a @@ -675,6 +702,8 @@ jobs: # rejected; a media value no revision lists is accepted). One leg: RDF tooling, # not arithmetic. The tool versions are pinned. vocab-shapes: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: v2 vocabulary · manifests validate as stated runs-on: linux steps: @@ -703,6 +732,8 @@ jobs: # Each exits non-zero on any failure or any difference, and the step fails with it. # One platform: what they check is the reading of the text, not the architecture. independent-verifiers: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: independent verifiers · claims, JWP, key discovery and integer payloads (Python) runs-on: linux steps: @@ -861,6 +892,8 @@ jobs: # the expected strings back as dictionary, query and header shards, and validates every # report with no error. One platform: string encoding, not arithmetic. telemetry-differential: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: delivery telemetry · CMCD and CMSD against an independent library runs-on: linux steps: @@ -877,6 +910,8 @@ jobs: node differential.mjs .. byte-exact: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: cross-arch byte-equality · ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: @@ -922,6 +957,8 @@ jobs: # is how the wrappers treat hostile bytes and where their limits fall, which is the # same code on every host. A missing library fails the build step by name. codec-wrappers: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path runs-on: macos steps: @@ -1000,6 +1037,8 @@ jobs: # this job proves is that the manifest is still well-formed, still carries the three # assertions, and still validates — which is architecture-independent. c2pa-emitter: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: C2PA manifest emission · signed, read back, validated runs-on: linux steps: diff --git a/.github/workflows/wai-energy-receipts.yml b/.github/workflows/wai-energy-receipts.yml index f0dc3538e..d7ca3b974 100644 --- a/.github/workflows/wai-energy-receipts.yml +++ b/.github/workflows/wai-energy-receipts.yml @@ -120,7 +120,32 @@ on: - '.github/workflows/wai-energy-receipts.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-energy-receipts.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-energy-receipts: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + energy-receipts: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: energy receipts · ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: diff --git a/.github/workflows/wai-formal-verification.yml b/.github/workflows/wai-formal-verification.yml index 8b4c92936..5a2a6eb39 100644 --- a/.github/workflows/wai-formal-verification.yml +++ b/.github/workflows/wai-formal-verification.yml @@ -88,10 +88,35 @@ on: - '.github/workflows/wai-formal-verification.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-formal-verification.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-formal-verification: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + # Every harness the host compiles runs in exactly one shard of the matrix below: # one no shard runs would be compiled and never checked. No toolchain is needed; # the script reads the included sources and this file. shards: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: every harness in one shard runs-on: linux timeout-minutes: 10 @@ -106,6 +131,8 @@ jobs: run: python3 -I wai/wai-verify/check_shards.py . kani: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: kani (${{ matrix.shard }}) runs-on: ${{ matrix.os }} timeout-minutes: 120 diff --git a/.github/workflows/wai-jpegai-e2e.yml b/.github/workflows/wai-jpegai-e2e.yml index 1890a3c91..aafbe3d8a 100644 --- a/.github/workflows/wai-jpegai-e2e.yml +++ b/.github/workflows/wai-jpegai-e2e.yml @@ -165,7 +165,32 @@ on: - cron: '41 6 * * 1' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-jpegai-e2e.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-jpegai-e2e: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + jpegai-e2e: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: fetch pinned JPEG-AI inputs → whole decode + pixel hash, required runs-on: linux timeout-minutes: 30 diff --git a/.github/workflows/wai-neural-e2e.yml b/.github/workflows/wai-neural-e2e.yml index 756775242..159b53f10 100644 --- a/.github/workflows/wai-neural-e2e.yml +++ b/.github/workflows/wai-neural-e2e.yml @@ -47,7 +47,32 @@ on: - '.github/workflows/wai-neural-e2e.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-neural-e2e.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-neural-e2e: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + neural-e2e: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: synthetic fixtures → Rust decode → reference (±4) runs-on: linux # The Rust decoders link `ort`, whose `download-binaries` feature pulls a diff --git a/.github/workflows/wai-neural-gates.yml b/.github/workflows/wai-neural-gates.yml index fbd817473..10dc19da3 100644 --- a/.github/workflows/wai-neural-gates.yml +++ b/.github/workflows/wai-neural-gates.yml @@ -133,7 +133,32 @@ on: - '.github/workflows/wai-neural-gates.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-neural-gates.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-neural-gates: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + neural-gates: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: model-free refusals of the neural sink runs-on: linux # The ONNX Runtime binary the `ort` crate downloads needs glibc 2.38 and a diff --git a/.github/workflows/wai-ops.yml b/.github/workflows/wai-ops.yml index 9dc7da721..233414008 100644 --- a/.github/workflows/wai-ops.yml +++ b/.github/workflows/wai-ops.yml @@ -75,7 +75,32 @@ on: - '.github/workflows/wai-ops.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-ops.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-ops: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + native: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: ${{ matrix.label }} runs-on: ${{ matrix.os }} timeout-minutes: 40 @@ -163,6 +188,8 @@ jobs: --check $C/c6a362696d61605931ef4da98ae630362dcd73ea6be7864db6e61d6c5abbcd24.json wasip2: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wasm32-wasip2 (wasmtime) runs-on: linux timeout-minutes: 30 @@ -215,6 +242,8 @@ jobs: wasmtime run --dir .::/wai wai-verify/target/wasm32-wasip2/release/wai-verify.wasm vectors verify /wai node: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wasm32 under Node runs-on: linux timeout-minutes: 30 @@ -247,6 +276,8 @@ jobs: run: node verify.mjs target/wasm32-unknown-unknown/release/wai_ops_node.wasm ../../ops-conformance checker: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: independent checker (Python) runs-on: linux timeout-minutes: 20 diff --git a/.github/workflows/wai-quantum-webgpu.yml b/.github/workflows/wai-quantum-webgpu.yml index dc3bf3178..1429f9218 100644 --- a/.github/workflows/wai-quantum-webgpu.yml +++ b/.github/workflows/wai-quantum-webgpu.yml @@ -89,7 +89,32 @@ on: - '.github/workflows/wai-quantum-webgpu.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-quantum-webgpu.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-quantum-webgpu: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + checks: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: shader checks · browser build · wasip2 inertness · MSRV runs-on: linux timeout-minutes: 60 @@ -165,6 +190,8 @@ jobs: || { echo "::error::the member's unit test did not run"; exit 1; } member-software: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: member · software Vulkan (linux) runs-on: linux timeout-minutes: 120 @@ -205,6 +232,8 @@ jobs: || { echo "::error::the meter's device test found no adapter, so it checked nothing"; exit 1; } member-metal: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: member · Metal (macos) runs-on: macos timeout-minutes: 90 @@ -242,6 +271,8 @@ jobs: || { echo "::error::the tool ran no window on the CPU reference"; exit 1; } member-hw: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: member · discrete GPU, Vulkan (jetson-hub) runs-on: linux-hw timeout-minutes: 150 @@ -278,6 +309,8 @@ jobs: run: CARGO_TARGET_DIR="$HOME/hw-target/wai-rs" nice -n 10 cargo run --locked --no-default-features --features quantum_fabric_webgpu --bin wai_quantum_vectors -- verify ../quantum-conformance --webgpu browser: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: member · browser WebGPU (macos) runs-on: macos timeout-minutes: 60 diff --git a/.github/workflows/wai-sota-vectors.yml b/.github/workflows/wai-sota-vectors.yml index eaa3b589a..4ab59c4ec 100644 --- a/.github/workflows/wai-sota-vectors.yml +++ b/.github/workflows/wai-sota-vectors.yml @@ -183,7 +183,32 @@ on: - cron: '17 6 * * 1' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-sota-vectors.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-sota-vectors: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + sota-vectors: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: regenerate mbt2018_mean integer vectors → Rust decode, required # The `linux` runner is a docker executor on catthehacker/ubuntu:act-22.04 # (glibc 2.35, no Rust). The Python half of this setup — setup-python 3.11, diff --git a/.github/workflows/wai-vector.yml b/.github/workflows/wai-vector.yml index e160b6535..1db17d08f 100644 --- a/.github/workflows/wai-vector.yml +++ b/.github/workflows/wai-vector.yml @@ -83,7 +83,32 @@ on: - '.github/workflows/wai-vector.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-vector.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-vector: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + native: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: ${{ matrix.label }} runs-on: ${{ matrix.os }} timeout-minutes: 40 @@ -134,6 +159,8 @@ jobs: run: cargo build --locked --no-default-features --lib wasip2: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wasm32-wasip2 (wasmtime) runs-on: linux timeout-minutes: 30 @@ -186,6 +213,8 @@ jobs: wasmtime run --dir .::/wai wai-vector/target/wasm32-wasip2/release/wai-vector.wasm vectors verify /wai node: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wasm32 under Node runs-on: linux timeout-minutes: 30 @@ -218,6 +247,8 @@ jobs: run: node verify.mjs target/wasm32-unknown-unknown/release/wai_vector_wasm.wasm ../../vector-conformance browser: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wasm32 in three browser engines runs-on: linux timeout-minutes: 45 @@ -299,6 +330,8 @@ jobs: ../../vector-conformance fuzz: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: fuzz, peak allocation, comparison count runs-on: linux timeout-minutes: 30 @@ -335,6 +368,8 @@ jobs: run: bash scripts/check-workflow-concurrency.sh checker: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: independent checker (Python) runs-on: linux timeout-minutes: 30 diff --git a/.github/workflows/wai-web-wasm.yml b/.github/workflows/wai-web-wasm.yml index b7ad7982b..9b6257960 100644 --- a/.github/workflows/wai-web-wasm.yml +++ b/.github/workflows/wai-web-wasm.yml @@ -91,7 +91,32 @@ on: - '.github/workflows/wai-web-wasm.yml' jobs: + # Does this pull request's own diff touch the paths below? This forge matches a + # workflow's `paths:` against the push, so a merge of main into a branch fires the + # workflow whatever the pull request changes; every job here waits on this answer. + # A push to main, a schedule, or anything the script cannot determine answers + # `true` (scripts/pr-touches-paths.py). + relevant: + name: does this change touch it + runs-on: linux-arm64 + outputs: + run: ${{ steps.gate.outputs.run }} + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - id: gate + run: | + set -euo pipefail + r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-web-wasm.yml \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}") + echo "this change touches wai-web-wasm: $r" + echo "run=$r" >> "$GITHUB_OUTPUT" + wasm32: + needs: relevant + if: needs.relevant.outputs.run == 'true' name: wai-web wasm32 build · corpus, menu and writers runs-on: linux timeout-minutes: 45 diff --git a/scripts/pr-touches-paths-selftest.sh b/scripts/pr-touches-paths-selftest.sh index 9df21e099..f0c143849 100755 --- a/scripts/pr-touches-paths-selftest.sh +++ b/scripts/pr-touches-paths-selftest.sh @@ -67,4 +67,19 @@ echo z > "$repo/jcp/top.md" git -C "$repo" add -A >/dev/null; git -C "$repo" commit -qm top >/dev/null check "a single star matches at its own level" true "$(run "$tmp/star.yml" "$SUB" "$(git -C "$repo" rev-parse HEAD)")" +# A comment or a blank line inside a list does not end it, and a trailing comment is not +# part of a glob. (Lists with a comment used to be read only up to it, so a pull request +# touching a path after the comment was answered `false` and its tests skipped.) +cat > "$tmp/commented.yml" <<'Y' +on: + pull_request: + paths: + - 'jcp/nothing-here/**' + # a comment between entries + + - 'wai/wai-pack/**' # and one after an entry +Y +check "a path listed after a comment and a blank line" true "$(run "$tmp/commented.yml" "$BASE" "$WAI")" +check "and the list still says false for a diff outside it" false "$(run "$tmp/commented.yml" "$BASE" "$JCP")" + [ "$fail" = 0 ] && echo "pr-touches-paths self-test: all cases pass" || { echo "pr-touches-paths self-test FAILED"; exit 1; } diff --git a/scripts/pr-touches-paths.py b/scripts/pr-touches-paths.py index 767d03bb5..b27b24d5c 100755 --- a/scripts/pr-touches-paths.py +++ b/scripts/pr-touches-paths.py @@ -39,12 +39,18 @@ def paths_of(workflow: Path) -> list[str]: in_paths = True continue if in_paths: - m = re.match(r"\s*-\s*'([^']+)'\s*$", line) or re.match(r'\s*-\s*"([^"]+)"\s*$', line) + stripped = line.strip() + # A comment or a blank line inside the list does not end it. (It used to: + # every glob after a list's first comment was dropped, and a pull request + # touching only those paths was answered `false`.) + if not stripped or stripped.startswith("#"): + continue + m = re.match(r"\s*-\s*'([^']+)'\s*(#.*)?$", line) or re.match(r'\s*-\s*"([^"]+)"\s*(#.*)?$', line) if m: globs.append(m.group(1)) continue - if line.strip().startswith("- "): - globs.append(line.strip()[2:].strip()) + if stripped.startswith("- "): + globs.append(re.sub(r"\s+#.*$", "", stripped[2:]).strip()) continue in_paths = False return globs