Skip to content

chore(mise): update tool oxfmt (0.64.0 → 0.71.0) #1137

chore(mise): update tool oxfmt (0.64.0 → 0.71.0)

chore(mise): update tool oxfmt (0.64.0 → 0.71.0) #1137

Workflow file for this run

name: CI
on:
push:
# `renovate/**` is here because Renovate is configured for branch-based
# automerge (`:automergeBranch` in renovate.json5): it pushes the update to
# a branch and fast-forwards main once that branch's checks pass, WITHOUT
# ever opening a pull request. A push to such a branch matches neither
# `branches: [main]` nor `pull_request`, so before this entry those
# branches carried zero check runs — the only status on them was Renovate's
# own `renovate/stability-days` soak timer. That made the "CI is the gate"
# premise documented in renovate.json5 vacuous: an update could reach main
# having been verified by nothing but the 3-day wait.
branches: [main, "renovate/**"]
pull_request:
# Least privilege: CI only needs to read the repo.
permissions:
contents: read
# Cancel superseded runs on the same ref to save CI minutes.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# --- Action pinning policy -------------------------------------------------
# The toolchain (Rust, Node, pnpm) is installed by mise from the pinned
# versions in .mise/config.toml + .mise/mise.lock, via `jdx/mise-action`, which
# is pinned to a full commit SHA. The remaining third-party actions use
# major-version tags for readability; for a hardened setup, pin each to a full
# commit SHA (e.g. `actions/checkout@b4ffde6... # v4.2.2`) and let
# Renovate/Dependabot bump them. The `# vX` comments mark the intended pin.
# ---------------------------------------------------------------------------
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
fmt:
name: rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
# Every gate below is a mise task, so `mise run <task>` locally runs the
# exact same command as CI (`mise run ci` runs the whole matrix).
- run: mise run fmt-check
clippy:
name: clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
- run: mise run clippy
test:
name: test
runs-on: ubuntu-24.04
# The suite runs in seconds; anything approaching this is a hang. Bounded
# for the same reason as the `web` job below, and more sharply needed here:
# these tests spawn subprocesses and bind sockets, and a stub waiting on a
# request that never arrives blocks until its own deadline with no output.
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
with:
key: test
- run: mise run test
test-pg:
name: test-pg
runs-on: ubuntu-24.04
# Same suite as `test`, against the Postgres backend. The runner's Docker
# hosts the database; a per-test CREATE DATABASE keeps tests isolated.
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
with:
key: test-pg
- run: mise run test-pg
saml:
name: saml (feature-gated tests)
runs-on: ubuntu-24.04
# rust:bookworm brings its own toolchain + the apt packages samael's
# xmlsec backend needs at build time; mise is not used here.
container: rust:1-bookworm
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- name: Install xmlsec build dependencies
run: |
apt-get update
apt-get install -y --no-install-recommends \
libxmlsec1-dev libxml2-dev libxslt1-dev libssl-dev libltdl-dev \
pkg-config clang
# The rust:bookworm image ships rustc/cargo but not the clippy
# component; the other CI jobs get it via mise-action.
- run: rustup component add clippy
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
with:
key: saml
- run: cargo clippy -p domarinn-server --features saml --all-targets -- -D warnings
- run: cargo test -p domarinn-server --features saml
commit-messages:
name: commit messages parse for release-please
# A message release-please cannot parse is SKIPPED by it rather than
# reported, so the work it carries never reaches a changelog — and when it
# is the only commit since the last release, no release pull request is
# created at all. This is the gate; the lefthook commit-msg hook is the
# same checker run earlier, and skips when node deps are absent.
# Also runs on Renovate's automerge branches: those fast-forward onto main
# without ever being a pull request, so this is the only point at which
# their messages can be checked. Skipped on push to main itself — by then
# the commit has landed and there is nothing left to gate.
if: github.event_name == 'pull_request' || startsWith(github.ref, 'refs/heads/renovate/')
runs-on: ubuntu-24.04
timeout-minutes: 5
env:
MISE_DISABLE_TOOLS: rust
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
# Every commit in the pull request, not just the tip.
fetch-depth: 0
- uses: ./.github/actions/setup-web
# Guard on the guard: if the checker itself is wrong, the messages it
# blesses mean nothing.
# Both invocation paths on purpose: the first failure of this job was the
# pnpm wrapper forwarding a bare `--` as the filename, not the checker.
- name: Self-test the checker
run: |
node web/scripts/check-commit-msg.mjs --self-test
pnpm -C web run check-commit-msg -- --self-test
- name: Check every commit in this change
env:
# Both are empty on a push event — there is no pull_request payload.
BASE: ${{ github.event.pull_request.base.sha }}
HEAD: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
if [ -z "${BASE:-}" ]; then
# Renovate automerge branch: derive the range from main instead.
# `origin/main` is present because checkout above uses
# fetch-depth: 0, which fetches every branch. If it is somehow
# missing this fails loudly rather than checking an empty range —
# a gate that silently passes is worse than no gate.
BASE="$(git merge-base origin/main HEAD)"
HEAD="$(git rev-parse HEAD)"
fi
failed=0
msg="$(mktemp)"
for sha in $(git rev-list "$BASE..$HEAD"); do
git log -1 --format=%B "$sha" > "$msg"
if ! node web/scripts/check-commit-msg.mjs "$msg"; then
echo "::error::commit $sha has a message release-please cannot parse"
failed=1
fi
done
exit "$failed"
web-lint:
name: web lint
runs-on: ubuntu-24.04
timeout-minutes: 10
env:
# `mise run` auto-installs every tool in .mise/config.toml, which would
# pull in the Rust toolchain this job never uses — skip it.
MISE_DISABLE_TOOLS: rust
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
# Type-checked lint (--max-warnings=0).
- run: mise run web-lint
web-build:
name: web build (typecheck)
runs-on: ubuntu-24.04
timeout-minutes: 10
env:
MISE_DISABLE_TOOLS: rust
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
# This IS the typecheck gate: the task runs `tsc -b` before vite, so any
# type error fails here rather than in a separate step.
- run: mise run web-build
web-test:
name: web unit tests (vitest)
runs-on: ubuntu-24.04
# The suite takes seconds; anything approaching this is a hang, not
# slowness. Without a bound a wedged run burned ~14 minutes and still
# produced no logs, which is the worst of both — slow *and* undiagnosable.
timeout-minutes: 10
env:
MISE_DISABLE_TOOLS: rust
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
- run: mise run web-test
e2e:
name: web e2e (playwright)
runs-on: ubuntu-24.04
# The suite itself is fast; the budget is dominated by the chromium
# download. Bounded for the same reason as the `web` job — a wedged
# browser launch produces no logs, so it must fail rather than hang.
timeout-minutes: 15
env:
# Playwright drives a mock build (`VITE_MOCK=1`), served by the config's
# own `webServer`. No Rust backend is involved, so skip that toolchain.
MISE_DISABLE_TOOLS: rust
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: ./.github/actions/setup-web
# Only chromium: playwright.config.ts declares a single chromium project.
# `--with-deps` pulls the system shared libraries the CDN build needs.
- name: Install Playwright chromium
run: pnpm -C web exec playwright install --with-deps chromium
- run: mise run e2e
# The HTML report is the only way to diagnose a failure after the fact —
# the trace/screenshot artifacts are worthless if they stay on the runner.
- if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 # pin to SHA
with:
name: playwright-report
path: web/playwright-report/
retention-days: 7
schema-check:
name: schema is up to date
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
# Regenerates the schema and diffs it against the committed copy; the
# full logic lives in the `schema-check` task (.mise/config.toml) so the
# local run and CI can never drift apart.
- name: Fail on schema drift
run: mise run schema-check
gen-types-check:
name: generated TS types are up to date
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
# Regenerates the TypeScript DTOs and fails on any drift (including
# untracked new files); the full logic lives in the `gen-types-check`
# task (.mise/config.toml) so the local run and CI can never drift apart.
- name: Fail on generated-type drift
run: mise run gen-types-check
workflow-lint:
name: workflows pass zizmor
runs-on: ubuntu-24.04
# .lefthook.toml runs zizmor on staged workflow files pre-commit, but a
# fork PR never runs our hooks — on a public repo this job is the only
# thing standing between a malicious workflow edit and a merge.
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: zizmor
- run: mise run workflow-lint
musl-build:
name: static musl build (${{ matrix.target }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
# Both shipped targets build natively on a GitHub-hosted runner, so CI
# proves the static link for each one release.yml will publish. No
# cross-compilation and no QEMU: the aarch64 leg is a real arm64 host.
include:
- target: x86_64-unknown-linux-musl
runner: ubuntu-24.04
- target: aarch64-unknown-linux-musl
runner: ubuntu-24.04-arm
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # pin to SHA
with:
persist-credentials: false
- uses: jdx/mise-action@3c2e0cf82a5b2e5249f0d3635a4d83d0ae861518 # v4.2.5
with:
install_args: rust
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 # pin to SHA
with:
key: ${{ matrix.target }}
# musl-tools gives the C toolchain rusqlite's bundled SQLite (and the
# rustls crypto backend) need; cmake is a hedge for crypto backends.
- name: Install musl toolchain
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends musl-tools cmake
# The `musl-build` task adds the rustup target itself (mise's rust
# delegates to rustup) and then builds; same command locally and in CI.
# MUSL_TARGET defaults to the x86_64 triple, so a bare `mise run
# musl-build` on a dev machine keeps working unchanged.
- name: Build
env:
MUSL_TARGET: ${{ matrix.target }}
run: mise run musl-build
- name: Confirm the binary is static
run: file target/${{ matrix.target }}/release/domarinn || true