Weekly #51
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: Weekly | |
| on: | |
| schedule: | |
| - cron: "0 3 * * 0" | |
| workflow_dispatch: | |
| concurrency: | |
| group: weekly-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| RUST_BACKTRACE: 1 | |
| CARGO_TERM_COLOR: always | |
| RSCRYPTO_TEST_MODE: weekly | |
| CARGO_INCREMENTAL: 0 | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ─── Full CI suite: all platforms, deep cross-compile sweep, full supply chain. ── | |
| suite: | |
| name: CI Suite (weekly) | |
| uses: ./.github/workflows/_ci-suite.yaml | |
| with: | |
| scope: all | |
| cache_key_prefix: weekly | |
| supply_chain_mode: full | |
| cross_depth: deep | |
| # ─── Executable feature-matrix sweep (26 combinations). ── | |
| feature-matrix: | |
| name: Feature Matrix (${{ matrix.target.name }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - name: x86_64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-x64-ci | |
| - name: aarch64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-arm64-ci | |
| uses: ./.github/workflows/_rust-job.yaml | |
| with: | |
| runner: ${{ matrix.target.runner }} | |
| timeout_minutes: 30 | |
| cache_key: weekly-feature-matrix-${{ matrix.target.name }} | |
| tools_mode: minimal | |
| enable_magic_cache: true | |
| enable_rust_cache: true | |
| run_script: just test-feature-matrix | |
| # ─── Miri memory-safety (stacked borrows). ── | |
| miri: | |
| name: Miri (${{ matrix.target.name }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - name: x86_64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-x64-ci | |
| - name: aarch64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-arm64-ci | |
| uses: ./.github/workflows/_rust-job.yaml | |
| with: | |
| runner: ${{ matrix.target.runner }} | |
| timeout_minutes: 120 | |
| cache_key: weekly-miri-${{ matrix.target.name }} | |
| tools_mode: minimal | |
| toolchain_components: "miri, rust-src" | |
| enable_magic_cache: true | |
| enable_rust_cache: true | |
| run_script: just test-miri | |
| # ─── Miri memory-safety (tree borrows). ── | |
| miri-tree-borrows: | |
| name: Miri (Tree Borrows) | |
| uses: ./.github/workflows/_rust-job.yaml | |
| with: | |
| runner: runs-on=${{ github.run_id }}/runner=linux-x64-ci | |
| timeout_minutes: 120 | |
| cache_key: weekly-miri-tree-borrows | |
| tools_mode: minimal | |
| toolchain_components: "miri, rust-src" | |
| enable_magic_cache: true | |
| enable_rust_cache: true | |
| run_script: | | |
| export MIRIFLAGS="-Zmiri-tree-borrows" | |
| just test-miri | |
| # ─── Fuzzing (libFuzzer full + scoped packages). ── | |
| fuzzing: | |
| name: Fuzzing (${{ matrix.target.name }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - name: x86_64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-x64-ci | |
| - name: aarch64 | |
| runner: runs-on=${{ github.run_id }}/runner=linux-arm64-ci | |
| uses: ./.github/workflows/_rust-job.yaml | |
| with: | |
| runner: ${{ matrix.target.runner }} | |
| timeout_minutes: 120 | |
| cache_key: weekly-fuzz-${{ matrix.target.name }} | |
| tools_mode: fuzz | |
| enable_magic_cache: true | |
| enable_rust_cache: true | |
| pre_script: | | |
| echo "RSCRYPTO_FUZZ_DURATION_SECS=60" >> "$GITHUB_ENV" | |
| run_script: | | |
| just test-fuzz --all | |
| rm -rf fuzz-output | |
| mkdir -p fuzz-output | |
| mapfile -t corpus_dirs < <( | |
| { | |
| [ -d fuzz/corpus ] && printf '%s\n' fuzz/corpus | |
| find fuzz-packages -mindepth 2 -maxdepth 2 -type d -name corpus | |
| } | sort | |
| ) | |
| if [ "${#corpus_dirs[@]}" -eq 0 ]; then | |
| tar -czf fuzz-output/corpus.tar.gz --files-from /dev/null | |
| else | |
| tar -czf fuzz-output/corpus.tar.gz "${corpus_dirs[@]}" | |
| fi | |
| artifact_name: fuzz-output-weekly-${{ matrix.target.name }} | |
| artifact_path: | | |
| fuzz-output/corpus.tar.gz | |
| fuzz/artifacts/ | |
| fuzz-packages/*/artifacts/ | |
| artifact_always: false | |
| # ─── Coverage (nextest + fuzz corpus → codecov). ── | |
| coverage: | |
| name: Coverage | |
| needs: [suite, fuzzing] | |
| runs-on: runs-on=${{ github.run_id }}/runner=linux-x64-ci | |
| timeout-minutes: 120 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| with: | |
| cache-key: weekly-coverage | |
| tools-mode: coverage | |
| toolchain-components: "rust-src" | |
| enable-magic-cache: "true" | |
| enable-rust-cache: "true" | |
| - name: Download fuzz corpus artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: fuzz-output-weekly-* | |
| path: fuzz-output-artifacts | |
| - name: Restore fuzz corpora | |
| shell: bash | |
| run: | | |
| shopt -s nullglob | |
| archives=(fuzz-output-artifacts/*/fuzz-output/corpus.tar.gz) | |
| if [ "${#archives[@]}" -eq 0 ]; then | |
| echo "No fuzz corpus archives found" | |
| exit 0 | |
| fi | |
| for archive in "${archives[@]}"; do | |
| echo "Extracting $archive" | |
| tar -xzf "$archive" | |
| done | |
| - name: Total Coverage (nextest + fuzz corpus replay) | |
| run: just test-coverage | |
| - name: Upload to Codecov | |
| uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage/total.lcov | |
| flags: total | |
| name: total | |
| fail_ci_if_error: true | |
| - name: Upload Coverage Artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: coverage-reports | |
| path: | | |
| coverage/total.lcov | |
| coverage/SUMMARY.md | |
| retention-days: 90 | |
| if-no-files-found: warn | |
| # ─── Gate: every required lane must pass. ── | |
| complete: | |
| name: Complete (weekly) | |
| needs: [suite, feature-matrix, miri, miri-tree-borrows, fuzzing, coverage] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Assert all lanes passed | |
| run: | | |
| failed=0 | |
| for lane in \ | |
| "suite=${{ needs.suite.result }}" \ | |
| "feature-matrix=${{ needs.feature-matrix.result }}" \ | |
| "miri=${{ needs.miri.result }}" \ | |
| "miri-tree-borrows=${{ needs.miri-tree-borrows.result }}" \ | |
| "fuzzing=${{ needs.fuzzing.result }}" \ | |
| "coverage=${{ needs.coverage.result }}" | |
| do | |
| name="${lane%%=*}" | |
| result="${lane#*=}" | |
| if [ "$result" != "success" ]; then | |
| echo "FAIL: $name ($result)" | |
| failed=1 | |
| else | |
| echo " OK: $name" | |
| fi | |
| done | |
| if [ "$failed" -eq 1 ]; then | |
| echo "" | |
| echo "One or more required lanes failed." | |
| exit 1 | |
| fi |