Bump actions/checkout from 4.2.2 to 6.0.3 (#69) #92
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: Test | |
| # Runs on pushes to the default branch AND on every pull request, so the | |
| # matrix can be used as a required merge gate. (Baseline only ran on push.) | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| workflow_dispatch: | |
| # Cancel superseded runs for the same ref to save runner minutes. | |
| concurrency: | |
| group: test-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Lint. rustfmt is enforced (blocking) now that the source is rustfmt-clean. | |
| # clippy and mypy stay advisory (continue-on-error) until their debt clears, | |
| # and each runs regardless of the others: | |
| # - clippy -> flip to blocking after the str->bytes fix (#19) | |
| # - mypy -> flip to blocking after the .pyi stubs type-check clean (#42) | |
| # --------------------------------------------------------------------------- | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: "3.10" | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master | |
| with: | |
| toolchain: "1.83" | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| - name: cargo fmt --check | |
| run: cargo fmt --all -- --check | |
| # clippy::cast_possible_truncation pinpoints the str->bytes corruption bug. | |
| - name: cargo clippy | |
| if: always() | |
| run: cargo clippy --all-targets -- -D warnings -W clippy::cast_possible_truncation | |
| continue-on-error: true | |
| - name: mypy (type stubs) | |
| if: always() | |
| run: | | |
| python -m pip install --upgrade pip mypy | |
| mypy fast_mail_parser/ | |
| continue-on-error: true | |
| # --------------------------------------------------------------------------- | |
| # Supply-chain audit. Blocking (no continue-on-error): the dependency stack is | |
| # current (PyO3 0.29) and the Cargo.lock audits clean, so a new advisory | |
| # against any dependency should fail the build and gate the PR rather than pass | |
| # silently. (It was previously advisory only because the stack was stale and a | |
| # fresh advisory against a pinned dep would have blocked unrelated PRs.) | |
| # cargo-audit needs a newer rustc than the repo's pinned 1.83, so the job runs | |
| # on stable via RUSTUP_TOOLCHAIN (overrides the rust-toolchain file). | |
| # | |
| # cargo-audit is `cargo install`ed from source (~3 min — previously the | |
| # slowest job by far). The compiled binary is cached and keyed on the pinned | |
| # CARGO_AUDIT_VERSION: a cache hit skips the build (restores in seconds); a | |
| # miss builds it once and caches it. | |
| # | |
| # Cache invalidation: to upgrade cargo-audit, bump CARGO_AUDIT_VERSION below. | |
| # That installs the new version AND invalidates the cache in one change — the | |
| # version IS the cache key, so there is no separate suffix to remember. The | |
| # key is intentionally NOT tied to the rustc/cargo version: the binary runs | |
| # fine across toolchain updates, and keying on it would force a needless | |
| # ~3-min rebuild on every stable bump. The RustSec advisory DB is fetched | |
| # fresh on every run, so findings stay current regardless of the cached | |
| # binary version. | |
| # --------------------------------------------------------------------------- | |
| security-audit: | |
| name: cargo audit | |
| runs-on: ubuntu-latest | |
| env: | |
| RUSTUP_TOOLCHAIN: stable | |
| # Bump to upgrade cargo-audit; this also invalidates the binary cache. | |
| CARGO_AUDIT_VERSION: "0.22.2" | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master | |
| with: | |
| toolchain: stable | |
| - name: Cache cargo-audit binary | |
| id: cache-cargo-audit | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: ~/.cargo/bin/cargo-audit | |
| key: cargo-audit-${{ runner.os }}-${{ env.CARGO_AUDIT_VERSION }} | |
| - name: Install cargo-audit | |
| if: steps.cache-cargo-audit.outputs.cache-hit != 'true' | |
| run: cargo install cargo-audit --version ${{ env.CARGO_AUDIT_VERSION }} --locked | |
| - name: cargo audit | |
| run: cargo audit | |
| # --------------------------------------------------------------------------- | |
| # Test matrix — the real merge gate. Builds & passes on CPython 3.9–3.13 with | |
| # PyO3 0.29 (3.7/3.8 are EOL and unavailable on current ubuntu runners). 3.13 | |
| # is a required cell now that PyO3 0.29 supports it (was allowed-failure under | |
| # the old 0.16 pin). | |
| # --------------------------------------------------------------------------- | |
| test: | |
| name: Test (py${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| - name: Install the package | |
| run: make install | |
| - name: Install test dependencies | |
| run: make install-test | |
| - name: Test | |
| run: make test | |
| # --------------------------------------------------------------------------- | |
| # Benchmark quality gate. The benchmark used to run inside every matrix cell | |
| # (6x redundant, slow). It now runs once here and acts as a performance gate: | |
| # fast_mail_parser must stay at least BENCH_MIN_SPEEDUP times faster than the | |
| # pure-Python mail-parser baseline (README reports ~8x). The ratio is measured | |
| # on the same runner in the same run, so it is hardware-independent and stable. | |
| # Getting faster always passes; only regressions below the floor fail. | |
| # --------------------------------------------------------------------------- | |
| benchmark: | |
| name: Benchmark quality gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: "3.10" | |
| cache: pip | |
| - name: Install the package + test dependencies | |
| run: | | |
| make install | |
| make install-test | |
| - name: Run benchmark | |
| run: pytest -v tests/benchmark --benchmark-min-rounds=25 --benchmark-json=benchmark.json | |
| - name: Enforce performance gate | |
| env: | |
| # Gate on min-time ratio. 8x matches the README headline figure and | |
| # requires the str-input fast path; the optimized parser measures | |
| # ~8.7x on CI. Headroom is tight, so a slow-relative runner can dip | |
| # below 8x. | |
| BENCH_MIN_SPEEDUP: "8.0" | |
| run: python .github/scripts/check_benchmark.py benchmark.json | |
| - name: Upload benchmark report | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: benchmark-json | |
| path: benchmark.json |