Repository navigation
build(deps): bump the cargo-minor-and-patch group across 1 directory with 3 updates #126
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: fleet-lint | |
| # Distributed by Ordnung's `paranoid` tier: the static-analysis floor every | |
| # member runs — prose, workflow, shell, and public-API hygiene. Edit it in the | |
| # tier and let ordnung distribute it; a local edit here is drift the next fleet | |
| # sync will report. | |
| # | |
| # It replaces, by entry name, the codespell-only workflow the `recommended` tier | |
| # ships: the extra jobs are the checks this tier raises. | |
| on: | |
| push: | |
| branches: [main] | |
| # `edited` joins the three default types because pr-title reads the title out | |
| # of the event payload: without it, a title corrected in response to the | |
| # check raises no event, and a re-run replays the payload that failed. The | |
| # only way left to clear the gate would be another push, which a title fix | |
| # does not have. | |
| pull_request: | |
| types: [opened, synchronize, reopened, edited] | |
| # Periodic coverage: these tools grow rules between releases, so a repository | |
| # nobody has touched can start failing for a reason worth knowing about. | |
| schedule: | |
| - cron: "23 5 * * 1" | |
| permissions: | |
| contents: read | |
| jobs: | |
| # What changed decides what the heavy job runs on. On a push or a schedule | |
| # there is no base to compare against, so everything counts as changed. | |
| changes: | |
| name: changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| rust: ${{ steps.filter.outputs.rust }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - id: filter | |
| env: | |
| BASE: ${{ github.event.pull_request.base.sha }} | |
| run: | | |
| # Answered here rather than inside the heavy job, so a repository | |
| # with no Rust never starts a runner for it and does not carry a | |
| # check that can say nothing. | |
| if [ ! -f Cargo.toml ]; then | |
| echo "rust=false" >> "$GITHUB_OUTPUT" | |
| echo "no Cargo.toml; hawk does not apply here" | |
| exit 0 | |
| fi | |
| if [ -z "$BASE" ]; then | |
| echo "rust=true" >> "$GITHUB_OUTPUT" | |
| echo "not a pull request; the heavy job runs" | |
| exit 0 | |
| fi | |
| if git diff --name-only "$BASE"...HEAD \ | |
| | grep -qE '\.rs$|(^|/)Cargo\.(toml|lock)$'; then | |
| echo "rust=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "rust=false" >> "$GITHUB_OUTPUT" | |
| echo "no Rust changed; hawk skipped" | |
| fi | |
| prose: | |
| name: codespell | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # ignore_words_list carries the identifiers codespell reads as prose and | |
| # would have us break: afterAll is the bun and jest hook, ser the serde | |
| # module, statics the Rust items, implementors rustdoc's own heading, and | |
| # infact a sibling project. A | |
| # repository's own .codespellrc adds to this list rather than replacing | |
| # it, so local vocabulary stays where it is declared. | |
| - uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 # v2.2 | |
| with: | |
| skip: "*.lock,package-lock.json,*.svg,*.woff2,*.min.js,target,node_modules,.git,dist,out,vendor" | |
| ignore_words_list: "afterall,ser,statics,infact,implementors" | |
| workflows: | |
| name: zizmor | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # High severity gates; everything else is visible in the job log. Tighten | |
| # per repository once the backlog is clear. | |
| - uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 | |
| with: | |
| min-severity: high | |
| advanced-security: false | |
| # Pull-request titles, held to the rule the commit-msg hook holds subjects to. | |
| # A squash merge writes the title into the history, so on the default branch it | |
| # is the message that lasts, and nothing was checking it. | |
| title: | |
| name: pr-title | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| # The title arrives through the environment rather than interpolated into | |
| # the script. It is text somebody else wrote, and `${{ }}` would paste it | |
| # in as shell before the shell ever sees it as data. | |
| - name: Conventional Commits | |
| env: | |
| TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| # Git's own generated subjects pass untouched, as they do in the hook. | |
| case "$TITLE" in | |
| "Merge "*|"Revert "*) exit 0 ;; | |
| esac | |
| if printf '%s' "$TITLE" | | |
| grep -qE '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9./_-]+\))?!?: .+'; then | |
| exit 0 | |
| fi | |
| echo "::error::pull-request title must follow Conventional Commits: type(scope): summary" | |
| echo " types: feat fix docs style refactor perf test build ci chore revert" | |
| echo " got: $TITLE" | |
| exit 1 | |
| # Prose style, over the Markdown a member writes. Vale fetches the packages | |
| # named in .vale.ini at run time, so the styles are versioned by that file | |
| # rather than committed here. | |
| prose-style: | |
| name: vale | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # Asked after checkout, never as a job-level `if: hashFiles(...)`: that | |
| # reads a workspace which does not exist yet, and a workflow whose | |
| # expression cannot be evaluated does not start at all. | |
| - name: A configured member is a graded one | |
| id: configured | |
| run: | | |
| if [ -f .vale.ini ]; then | |
| echo "vale=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "vale=false" >> "$GITHUB_OUTPUT" | |
| echo "no .vale.ini; prose style is not graded here" | |
| fi | |
| - uses: errata-ai/vale-action@518a9136acc6e6668ce7c00d367051e0941e87ff # v3.0.0 | |
| if: steps.configured.outputs.vale == 'true' | |
| with: | |
| fail_on_error: true | |
| # Stylesheets, for the members that configure them. Run through bunx rather | |
| # than a dependency, so a repository that writes CSS is not made to declare a | |
| # linter it never imports. | |
| styles: | |
| name: stylelint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: "1.4.0" | |
| - name: A configured member is a graded one | |
| id: configured | |
| run: | | |
| if [ -f .stylelintrc.json ]; then | |
| echo "stylelint=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "stylelint=false" >> "$GITHUB_OUTPUT" | |
| echo "no .stylelintrc.json; stylesheets are not graded here" | |
| fi | |
| - name: Stylelint | |
| if: steps.configured.outputs.stylelint == 'true' | |
| run: | | |
| sheets=$(git ls-files '*.css' '*.scss' | grep -v node_modules || true) | |
| if [ -z "$sheets" ]; then | |
| echo "no stylesheets tracked" | |
| exit 0 | |
| fi | |
| # stylelint-config-standard extends stylelint-config-recommended, so | |
| # both have to be resolvable from wherever stylelint runs — `bunx | |
| # stylelint` alone brings neither, and fails on the extends rather | |
| # than on the CSS. They go in a scratch directory, and | |
| # --config-basedir points the resolution there, so a repository that | |
| # writes CSS still does not declare a linter it never imports. | |
| tools=$(mktemp -d) | |
| (cd "$tools" && bun add --silent stylelint@17.14.1 stylelint-config-standard@40.0.0) | |
| # shellcheck disable=SC2086 — the file list is deliberately split. | |
| "$tools/node_modules/.bin/stylelint" \ | |
| --config .stylelintrc.json --config-basedir "$tools" $sheets | |
| shell: | |
| name: shellcheck | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: List shell scripts | |
| id: scripts | |
| run: echo "files=$(git ls-files '*.sh' '*.bash' | tr '\n' ' ')" >> "$GITHUB_OUTPUT" | |
| # Gates at warning and above. The runners' ShellCheck version moves on | |
| # its own schedule and the info level moves with it — a fleet-wide gate | |
| # that fails when a runner image ships a new stylistic note is a gate | |
| # that breaks mains for reasons no one changed. Info findings still show | |
| # up for anyone running shellcheck locally. | |
| - name: ShellCheck every script | |
| if: steps.scripts.outputs.files != '' | |
| run: shellcheck --severity=warning ${{ steps.scripts.outputs.files }} | |
| api: | |
| name: hawk | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| # The one heavy job here, so it is the one that has to earn its run: it | |
| # drives the compiler over the whole workspace, and a pull request that | |
| # touches no Rust cannot change what it would say. | |
| needs: changes | |
| # Not on an edited title or body: nothing a description says changes what | |
| # the compiler sees, and this is the one job here that can run half an | |
| # hour. The rest are seconds and can afford to answer every event. | |
| if: needs.changes.outputs.rust == 'true' && github.event.action != 'edited' | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # Whether hawk applies is answered on the runner, after checkout: a | |
| # non-Rust repository has no manifest, and hawk's subject is a workspace | |
| # that builds binaries. This cannot be a job-level `if` with hashFiles(), | |
| # which reads a workspace that does not exist before checkout — such a | |
| # workflow fails to start at all, running none of its jobs. | |
| - name: Binary targets decide whether hawk applies | |
| id: bins | |
| run: | | |
| # A workspace that cannot be read here is not a finding: several | |
| # members resolve a sibling checkout that this job does not clone. | |
| if ! meta=$(cargo metadata --no-deps --format-version 1 2>/dev/null); then | |
| echo "count=0" >> "$GITHUB_OUTPUT" | |
| echo "::notice::cargo metadata could not resolve this workspace; hawk skipped" | |
| exit 0 | |
| fi | |
| count=$(printf '%s' "$meta" \ | |
| | jq '[.packages[].targets[] | select(.kind | index("bin"))] | length') | |
| echo "count=${count}" >> "$GITHUB_OUTPUT" | |
| # Heavy — it drives the compiler over the whole workspace — so the cache | |
| # earns its place, but only where the job will actually build. | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| if: steps.bins.outputs.count != '0' | |
| - name: Install hawk | |
| if: steps.bins.outputs.count != '0' | |
| run: | | |
| rustup toolchain install 1.98.0 --profile minimal | |
| curl --proto '=https' --tlsv1.2 -LsSf \ | |
| https://github.com/astral-sh/hawk/releases/latest/download/cargo-hawk-installer.sh | sh | |
| # Advisory, and written so it stays that way. hawk pins itself to one | |
| # compiler and refuses workspaces it cannot model — a duplicate lib | |
| # name, a lockfile it will not write under --locked — and none of that | |
| # is a finding about the code. The report lands in the log either way; | |
| # a repository that wants hawk to gate can say so in its own workflow. | |
| - name: Public-API hygiene | |
| if: steps.bins.outputs.count != '0' | |
| run: | | |
| cargo +1.98.0 hawk check \ | |
| || echo "::warning::hawk reported findings, or could not run here" | |