Nightly Toolchain Check #57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Nightly Toolchain Check | |
| on: | |
| schedule: | |
| # Every day at 03:00 UTC. | |
| - cron: '0 3 * * *' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write # Used by the failure alert step below | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_RETRY: 10 | |
| RUST_BACKTRACE: short | |
| jobs: | |
| check: | |
| name: ${{ matrix.toolchain }} / ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| # Nightly may break — allow failure. Beta must pass. | |
| continue-on-error: ${{ matrix.toolchain == 'nightly' }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| # NOTE: cross-OS matrix catches platform-specific regressions early. | |
| # Audit 2026-04-18 Tier 2 flagged mono-OS coverage as a blind spot. | |
| matrix: | |
| toolchain: [beta, nightly] | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: step-security/harden-runner@v2 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: main | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ matrix.toolchain }} | |
| components: clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: nightly-${{ matrix.toolchain }}-${{ matrix.os }} | |
| save-if: true | |
| # NOTE: Windows cannot build `tikv-jemalloc-sys` (MSVC toolchain + | |
| # autoconf mismatch). Mirror ci.yml and skip `jemalloc` + `unix-signals` | |
| # features on Windows. Other OSes keep the full feature matrix so we | |
| # still catch real nightly/beta regressions. | |
| - name: Clippy | |
| shell: bash | |
| run: | | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| cargo clippy --all-targets --no-default-features \ | |
| --features dlp,oauth,tap,compliance,mcp,watch,policies,socket-opts,dirs \ | |
| -- -D warnings | |
| else | |
| cargo clippy --all-targets --all-features -- -D warnings | |
| fi | |
| - name: Tests | |
| shell: bash | |
| run: | | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| cargo test --lib --bins --no-default-features \ | |
| --features dlp,oauth,tap,compliance,mcp,watch,policies,socket-opts,dirs | |
| else | |
| cargo test --lib --bins | |
| fi | |
| - name: Doc tests | |
| shell: bash | |
| run: | | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| cargo test --doc --no-default-features \ | |
| --features dlp,oauth,tap,compliance,mcp,watch,policies,socket-opts,dirs | |
| else | |
| cargo test --doc | |
| fi | |
| # Open (or reuse) a tracking issue when the BETA matrix fails. Nightly | |
| # failures stay silent (they are allowed to break). Avoids spamming: the | |
| # step searches for an open "nightly-toolchain" labeled issue and | |
| # comments on it instead of creating duplicates. | |
| alert: | |
| name: Alert on beta regression | |
| needs: [check] | |
| if: always() && contains(needs.check.result, 'failure') && github.event_name == 'schedule' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: step-security/harden-runner@v2 | |
| with: | |
| egress-policy: audit | |
| - name: Open or update tracking issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const label = 'nightly-toolchain'; | |
| const title = `Beta/nightly toolchain regression (${new Date().toISOString().slice(0,10)})`; | |
| const body = [ | |
| `Nightly run ${context.runId} observed a failure on the \`beta\` or \`nightly\` toolchain.`, | |
| ``, | |
| `Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, | |
| ``, | |
| `If this is a nightly-only soft failure, close the issue. If beta is broken, this is a release blocker.`, | |
| ].join('\n'); | |
| const { data: issues } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: label, | |
| per_page: 1, | |
| }); | |
| if (issues.length > 0) { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: issues[0].number, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title, | |
| body, | |
| labels: [label], | |
| }); | |
| } |