From db68a8f1992764987ca0ce7872dbf3b7ca1067e3 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Fri, 8 May 2026 08:57:21 -0700 Subject: [PATCH 1/4] ci(nightly): trigger from a `nightly` PR label so fixes can iterate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nightly workflow only ran on cron, on workflow_dispatch, and on PRs/pushes that touched `Cargo.toml`/`Cargo.lock`/`rust-toolchain.toml`/ `nightly.yaml`. Iterating on fixes for nightly-only failures (e.g. the nix-flake sandbox tests on #2642) meant either waiting for the cron run or invoking `gh workflow run --ref ` by hand and watching the run page. Add a `nightly` label as the iteration knob. Drop the `paths` filter on the `pull_request` trigger and gate every job on a single `gate` job whose `if:` runs only when the event isn't a PR or the PR carries the `nightly` label. `synchronize` re-runs while the label remains attached, so subsequent pushes get checked without re-labelling. The cron run still catches drift that isn't commit-correlated, and the push-to-main path filter still catches Cargo-affecting changes after merge — so the only behaviour change is "PRs touching Cargo.toml no longer auto-trigger nightly". The label can be added in those cases when desired. Label created on the repo (`nightly`, light blue). Co-Authored-By: Claude --- .github/workflows/nightly.yaml | 36 ++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index ac92cb0f52..0e0018e0ef 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -8,9 +8,11 @@ name: nightly # - minimal-versions: cargo check against minimum-version dep resolution # - nix-flake: nix flake check (packaging-environment bugs, motivated by #2624) # -# Runs daily on cron, on demand via workflow_dispatch, and on pushes/PRs that -# touch dependency or toolchain files — catching cargo-affecting changes at -# PR time avoids a 24-hour bisect window. The cron run still catches drift +# Runs daily on cron, on demand via workflow_dispatch, on pushes to main that +# touch dependency or toolchain files, and on PRs labelled `nightly`. The +# label is the iteration knob for fixes targeting nightly-only failures +# (e.g. nix-flake's sandbox suite); without it, contributors had to wait for +# the cron run or `gh workflow run` manually. The cron still catches drift # that's not commit-correlated (registry updates, transitive resolution). # # Runner versions pinned; see ci.yaml header comment for rationale. @@ -30,11 +32,11 @@ on: - '.github/workflows/nightly.yaml' pull_request: branches: [main] - paths: - - 'Cargo.toml' - - 'Cargo.lock' - - 'rust-toolchain.toml' - - '.github/workflows/nightly.yaml' + # `labeled` fires when the `nightly` label is added; `synchronize` + # re-runs on subsequent pushes while the label is still attached. Each + # job below gates on the label so unlabelled PRs (and unrelated label + # additions) are no-ops. + types: [opened, synchronize, reopened, labeled] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -46,6 +48,18 @@ env: RUSTFLAGS: -C debuginfo=0 jobs: + gate: + # Single point that filters PR events. Skipped → all downstream jobs + # skip via `needs: gate`, which is cheaper than repeating the + # conditional on every job. Schedule / workflow_dispatch / push events + # always pass through. + if: | + github.event_name != 'pull_request' || + contains(github.event.pull_request.labels.*.name, 'nightly') + runs-on: ubuntu-24.04 + steps: + - run: 'true' + feature-powerset: # Every combination of cli/syntax-highlighting/shell-integration-tests/ # git-wt should compile. Catches regressions in feature gating — including @@ -55,6 +69,7 @@ jobs: # Workspace members must use `default-features = false` when depending on # worktrunk, or feature unification will mask gating bugs by silently # enabling `cli` in the lib build (see tests/helpers/wt-perf/Cargo.toml). + needs: gate runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -85,6 +100,7 @@ jobs: # PTY tests are intentionally off because they read $SHELL from the # runner env, which resolves differently on `ubuntu-24.04-arm` and # masks musl/arm signal with environment noise. + needs: gate strategy: fail-fast: false matrix: @@ -122,6 +138,7 @@ jobs: # already advisory non-required (CLAUDE.md: "Don't wait for CI # benchmarks before merging"). The cron run also appends results to the # time-series gist so we have daily perf history on main. + needs: gate runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -181,6 +198,7 @@ jobs: # Moved from ci.yaml — `cargo udeps` requires nightly toolchain anyway, # so it's already in the "nightly concern" bucket; rarely flips between # PRs touching deps. + needs: gate runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -208,6 +226,7 @@ jobs: # exists for the same downstream-protection reason) can resolve to a # lower compatible version that doesn't actually compile if our manifest # under-specifies. + needs: gate runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -238,6 +257,7 @@ jobs: # with default features (lib + bins + integration + doctests; the # `shell-integration-tests` feature is intentionally off). Cold builds # take ~10-15 min without a binary cache; nightly cadence absorbs it. + needs: gate runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code From 649968d2a136362db0c189b8923f4c6c1ddca694 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Fri, 8 May 2026 09:01:26 -0700 Subject: [PATCH 2/4] ci(nightly): also auto-trigger when PR touches Cargo paths Restore the auto-trigger on dependency/toolchain-affecting PR diffs that the previous commit dropped. The `gate` job now ORs the `nightly` label against a path check (`gh pr view --json files`), and downstream jobs gate on `needs.gate.outputs.run == 'true'`. Drops the requirement to label every Cargo bump manually while keeping the label as the iteration knob for fixes that don't touch those paths (nix-flake sandbox tests, etc.). Co-Authored-By: Claude --- .github/workflows/nightly.yaml | 57 ++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 0e0018e0ef..0ef9b31400 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -9,7 +9,8 @@ name: nightly # - nix-flake: nix flake check (packaging-environment bugs, motivated by #2624) # # Runs daily on cron, on demand via workflow_dispatch, on pushes to main that -# touch dependency or toolchain files, and on PRs labelled `nightly`. The +# touch dependency or toolchain files, and on PRs that either (a) touch the +# same dependency/toolchain files or (b) carry the `nightly` label. The # label is the iteration knob for fixes targeting nightly-only failures # (e.g. nix-flake's sandbox suite); without it, contributors had to wait for # the cron run or `gh workflow run` manually. The cron still catches drift @@ -32,10 +33,10 @@ on: - '.github/workflows/nightly.yaml' pull_request: branches: [main] - # `labeled` fires when the `nightly` label is added; `synchronize` - # re-runs on subsequent pushes while the label is still attached. Each - # job below gates on the label so unlabelled PRs (and unrelated label - # additions) are no-ops. + # `labeled` fires when a label is added (so the `nightly` label can + # trigger a run mid-PR); `synchronize` re-runs on subsequent pushes. + # The `gate` job below decides whether to actually run, ORing the + # label against a Cargo-paths diff check. types: [opened, synchronize, reopened, labeled] concurrency: @@ -49,16 +50,40 @@ env: jobs: gate: - # Single point that filters PR events. Skipped → all downstream jobs - # skip via `needs: gate`, which is cheaper than repeating the - # conditional on every job. Schedule / workflow_dispatch / push events - # always pass through. - if: | - github.event_name != 'pull_request' || - contains(github.event.pull_request.labels.*.name, 'nightly') + # Single point that decides whether to run on PR events. Non-PR events + # (cron, workflow_dispatch, push) pass through unconditionally. PR + # events run if either the `nightly` label is attached OR the diff + # touches one of the listed dependency/toolchain files. The decision + # is exposed via `outputs.run`; downstream jobs gate on it. runs-on: ubuntu-24.04 + outputs: + run: ${{ steps.decide.outputs.run }} steps: - - run: 'true' + - id: decide + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + HAS_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'nightly') }} + run: | + set -euo pipefail + if [[ "${{ github.event_name }}" != "pull_request" ]]; then + echo "run=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [[ "$HAS_LABEL" == "true" ]]; then + echo "run=true (label)" + echo "run=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + files=$(gh pr view "$PR" --repo "$REPO" --json files --jq '.files[].path') + if echo "$files" | grep -qE '^(Cargo\.toml|Cargo\.lock|rust-toolchain\.toml|\.github/workflows/nightly\.yaml)$'; then + echo "run=true (cargo-affecting paths changed)" + echo "run=true" >> "$GITHUB_OUTPUT" + else + echo "run=false (no `nightly` label, no cargo-affecting paths)" + echo "run=false" >> "$GITHUB_OUTPUT" + fi feature-powerset: # Every combination of cli/syntax-highlighting/shell-integration-tests/ @@ -70,6 +95,7 @@ jobs: # worktrunk, or feature unification will mask gating bugs by silently # enabling `cli` in the lib build (see tests/helpers/wt-perf/Cargo.toml). needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -101,6 +127,7 @@ jobs: # runner env, which resolves differently on `ubuntu-24.04-arm` and # masks musl/arm signal with environment noise. needs: gate + if: needs.gate.outputs.run == 'true' strategy: fail-fast: false matrix: @@ -139,6 +166,7 @@ jobs: # benchmarks before merging"). The cron run also appends results to the # time-series gist so we have daily perf history on main. needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -199,6 +227,7 @@ jobs: # so it's already in the "nightly concern" bucket; rarely flips between # PRs touching deps. needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -227,6 +256,7 @@ jobs: # lower compatible version that doesn't actually compile if our manifest # under-specifies. needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code @@ -258,6 +288,7 @@ jobs: # `shell-integration-tests` feature is intentionally off). Cold builds # take ~10-15 min without a binary cache; nightly cadence absorbs it. needs: gate + if: needs.gate.outputs.run == 'true' runs-on: ubuntu-24.04 steps: - name: 📂 Checkout code From 1c3f5329c8aa47a3a3378e8fe58dd7e810e789fc Mon Sep 17 00:00:00 2001 From: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com> Date: Fri, 8 May 2026 16:09:56 +0000 Subject: [PATCH 3/4] ci(nightly): single-quote the gate-skip diagnostic to keep backticks literal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backticks inside `"..."` open a command substitution, so the else-branch diagnostic ran `nightly` and dropped the word from the printed message (plus a `nightly: command not found` to stderr). Single-quote the message so it renders verbatim. The `GITHUB_OUTPUT` write was unaffected — gating still worked, this was a logged-output-only bug. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/nightly.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 0ef9b31400..1c802908c9 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -81,7 +81,7 @@ jobs: echo "run=true (cargo-affecting paths changed)" echo "run=true" >> "$GITHUB_OUTPUT" else - echo "run=false (no `nightly` label, no cargo-affecting paths)" + echo 'run=false (no `nightly` label, no cargo-affecting paths)' echo "run=false" >> "$GITHUB_OUTPUT" fi From d73774e110bbae6bebd70c612112a716fffef29c Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Fri, 8 May 2026 09:14:22 -0700 Subject: [PATCH 4/4] ci(nightly): switch gate to dorny/paths-filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the bespoke `gh pr view --json files | grep` shell with the standard `dorny/paths-filter@v3` action — declarative pattern list, glob-aware (`**/Cargo.toml` now covers workspace member manifests), no shell parsing, no auth wiring. Mirror the `**/Cargo.toml` glob into the `push` paths trigger so both sites stay aligned. Mirrors the pattern in the prql repo's tests.yaml. Co-Authored-By: Claude --- .github/workflows/nightly.yaml | 53 +++++++++++++++------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 1c802908c9..c2f33bb4e1 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -27,7 +27,7 @@ on: push: branches: [main] paths: - - 'Cargo.toml' + - '**/Cargo.toml' - 'Cargo.lock' - 'rust-toolchain.toml' - '.github/workflows/nightly.yaml' @@ -50,40 +50,35 @@ env: jobs: gate: - # Single point that decides whether to run on PR events. Non-PR events - # (cron, workflow_dispatch, push) pass through unconditionally. PR - # events run if either the `nightly` label is attached OR the diff - # touches one of the listed dependency/toolchain files. The decision - # is exposed via `outputs.run`; downstream jobs gate on it. + # Decides whether to run on PR events. Non-PR events (cron, + # workflow_dispatch, push) pass through unconditionally. PR events + # run when either the `nightly` label is attached OR the diff touches + # one of the dependency/toolchain files. The decision is exposed via + # `outputs.run`; downstream jobs gate on it. + # + # `dorny/paths-filter` works against the GitHub API for PR events, so + # no checkout step is needed. runs-on: ubuntu-24.04 + permissions: + pull-requests: read outputs: run: ${{ steps.decide.outputs.run }} steps: + - uses: dorny/paths-filter@v3 + if: github.event_name == 'pull_request' + id: changes + with: + filters: | + nightly: + - '**/Cargo.toml' + - 'Cargo.lock' + - 'rust-toolchain.toml' + - '.github/workflows/nightly.yaml' - id: decide - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR: ${{ github.event.pull_request.number }} - REPO: ${{ github.repository }} - HAS_LABEL: ${{ contains(github.event.pull_request.labels.*.name, 'nightly') }} run: | - set -euo pipefail - if [[ "${{ github.event_name }}" != "pull_request" ]]; then - echo "run=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - if [[ "$HAS_LABEL" == "true" ]]; then - echo "run=true (label)" - echo "run=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - files=$(gh pr view "$PR" --repo "$REPO" --json files --jq '.files[].path') - if echo "$files" | grep -qE '^(Cargo\.toml|Cargo\.lock|rust-toolchain\.toml|\.github/workflows/nightly\.yaml)$'; then - echo "run=true (cargo-affecting paths changed)" - echo "run=true" >> "$GITHUB_OUTPUT" - else - echo 'run=false (no `nightly` label, no cargo-affecting paths)' - echo "run=false" >> "$GITHUB_OUTPUT" - fi + echo "run=${{ github.event_name != 'pull_request' || + contains(github.event.pull_request.labels.*.name, 'nightly') || + steps.changes.outputs.nightly == 'true' }}" >> "$GITHUB_OUTPUT" feature-powerset: # Every combination of cli/syntax-highlighting/shell-integration-tests/