Skip to content

v2.9.9 "Ballast": the release candidate -- audits re-run, MMC3 and MMC5 by their documentation, exact audio across states #1836

v2.9.9 "Ballast": the release candidate -- audits re-run, MMC3 and MMC5 by their documentation, exact audio across states

v2.9.9 "Ballast": the release candidate -- audits re-run, MMC3 and MMC5 by their documentation, exact audio across states #1836

Workflow file for this run

name: Security
# Dependency-vulnerability scan (cargo-audit) + licence / advisory / source
# policy (cargo-deny).
#
# Both tools read the dependency graph and nothing else -- the manifests, the
# lockfile, `deny.toml`, and `.cargo/` (registry and source configuration) -- so
# a push or PR runs this workflow only when one of those changes. The weekly
# `schedule` cron runs it regardless, which is what catches an advisory
# published against an UNCHANGED lockfile. Not a required check, so a skipped
# run blocks nothing.
#
# History (2026-09-23): this used to trigger on every non-documentation change
# and carried a third job, `Clippy Security Lints`, that re-ran clippy with the
# `retroachievements` and `gpu-timing` frontend features. Both are already
# linted by ci.yml -- `retroachievements` twice, and `gpu-timing` is a DEFAULT
# feature of rustynes-frontend, so the lint job's workspace clippy compiles it
# (caught in review on #547) -- so the job was a second full workspace compile
# adding no coverage, and it is gone.
on:
push:
branches: [main]
paths: &dependency-graph
- "**/Cargo.toml"
- "Cargo.lock"
- "deny.toml"
- ".cargo/**"
- ".github/workflows/security.yml"
pull_request:
branches: [main]
paths: *dependency-graph
schedule:
- cron: "0 0 * * 1"
workflow_dispatch:
# Cancel superseded PR runs; let every `main` commit finish.
concurrency:
group: security-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
# Least-privilege default: the audit and deny jobs only read the checked-out
# tree (cargo-audit, cargo-deny) — neither uploads SARIF or
# writes to the repo — so the default GITHUB_TOKEN is narrowed to read-only.
# Resolves the CodeQL `actions/missing-workflow-permissions` alerts (one per job).
permissions:
contents: read
# Every job carries an explicit `timeout-minutes`, for the reason PR #400
# established for `ci.yml` and this file was missed by: without one a job
# inherits GitHub's SIX-HOUR default, and a hung job then blocks a release while
# reporting nothing at all. That is not hypothetical here — `Clippy Security
# Lints` hung for over two hours during the v2.3.7 cut, in a setup step, on a
# job whose observed runtime is 2-3 minutes, and the release waited on it.
#
# Budgets are generous multiples of observed runtime (audit and deny complete in
# under a minute), because the purpose is to bound a hang, not to
# police normal variance on a cold cache.
jobs:
audit:
name: Dependency Audit
runs-on: ubuntu-26.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
# Install the PREBUILT binary, never `cargo install` (build-from-source):
# 1. compiling the tool on every run dwarfs downloading it, and
# 2. `rust-toolchain.toml` is a directory override, so a build-from-source
# install is subject to this repo's rustc pin -- if a tool's own MSRV
# ever rises above that pin, the SECURITY gate is what breaks. The
# prebuilt binary only parses `Cargo.lock` and runs under any toolchain.
# Reason 2 was an ACTIVE constraint until the v1.3.0 pin bump (1.86 vs
# cargo-audit's 1.88); it is slack today and can bind again after an MSRV
# change in either direction, so it is kept rather than deleted as history.
- uses: taiki-e/install-action@v2.87.21
with:
tool: cargo-audit
- run: cargo audit
deny:
name: Cargo Deny Check
runs-on: ubuntu-26.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
# Prebuilt binary for the same two reasons as the audit job above: it is
# much faster than compiling cargo-deny, and it keeps the security gate
# independent of this repo's rustc pin. Policy lives in `deny.toml`.
- uses: taiki-e/install-action@v2.87.21
with:
tool: cargo-deny
- run: cargo deny check