Skip to content

fix(ci): the commit hook offered a scope it rejects #178

fix(ci): the commit hook offered a scope it rejects

fix(ci): the commit hook offered a scope it rejects #178

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main, v3-new-architect]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
COREPACK_ENABLE_DOWNLOAD_PROMPT: 0
jobs:
typescript:
name: TypeScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: corepack enable
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test
# Its own job rather than a step in `typescript`, because it is the slowest thing in CI by an order
# of magnitude: it runs a full OpenNext build and boots `workerd`. Failing it should not delay the
# lint and typecheck feedback, and passing it should not be waited on by them.
web-e2e:
name: Web e2e
# Pinned to Linux, and it must stay pinned: ADR-0023 makes Linux the visual baseline platform
# because font rasterisation differs per OS. The baselines in `apps/web/e2e/__screenshots__/linux/`
# were recorded here and are compared here; moving this job to another OS silently stops comparing
# them, because `visual.spec.ts` skips off Linux rather than failing.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: corepack enable
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: pnpm
- run: pnpm install --frozen-lockfile
# Only chromium, and `--with-deps` for the system libraries a headless browser needs on a bare
# runner. Playwright pins its own browser build, which is what makes a baseline stable enough to
# be worth having (ADR-0023) — so this must not be replaced by a system Chrome.
- name: Install the pinned browser
run: pnpm --filter @nport/web exec playwright install --with-deps chromium
# `playwright.config.ts` builds through OpenNext and serves the real Worker, so there is no
# separate build step here. That is deliberate: this tier exists to test the artifact that
# deploys, and the first thing it caught was 33 pages that 404 only from the Worker.
- run: pnpm test:e2e
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: apps/web/playwright-report/
retention-days: 7
# ── Recording the visual baselines ────────────────────────────────────────────────
#
# **On this runner, or not at all.** ADR-0023 pins baselines to Linux because font rasterisation
# differs per OS, and the job above is where they are compared — so they have to be produced by
# the same image and the same architecture. A baseline recorded in a Playwright container on an
# arm64 laptop fails every run here, which is the churn the original objection to screenshot tests
# was about.
#
# Triggered by a marker in the commit message rather than `workflow_dispatch`, because a dispatch
# only appears once the workflow is on the default branch and v3 is not there yet. Recording is
# rare and deliberate — a handful of times in the project's life — so a marker is the right weight.
#
# It uploads rather than commits. A workflow that pushes screenshots into the tree would be a
# workflow that can rewrite what it is being judged against; a human downloads the artifact, looks
# at the images, and commits them. `docs/TESTING.md` § Frontend e2e has the review rule.
#
# **`always()` is load-bearing.** Without it this step only runs when the job is green — which
# is to say, only when the baselines already match and there is nothing to record. The one
# time it worked was the first, when no baseline existed and the spec skipped. The moment a
# baseline legitimately changed, the compare failed, this was skipped, and re-recording became
# impossible (`docs/ROADMAP.md`, defect 51).
- name: Record the visual baselines
if: always() && contains(github.event.head_commit.message, '[record-baselines]')
env:
NPORT_VISUAL: "1"
run: pnpm --filter @nport/web exec playwright test visual.spec.ts --update-snapshots
- uses: actions/upload-artifact@v4
if: always() && contains(github.event.head_commit.message, '[record-baselines]')
with:
name: visual-baselines-linux
path: apps/web/e2e/__screenshots__/
retention-days: 7
if-no-files-found: error
rust:
name: Rust (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Linux on pull requests; all three on pushes to a long-lived branch. Windows
# process handling and macOS linking are where cross-platform breakage shows up,
# and neither is worth paying for on every push to a feature branch.
os: >-
${{ github.event_name == 'push'
&& fromJSON('["ubuntu-latest", "macos-latest", "windows-latest"]')
|| fromJSON('["ubuntu-latest"]') }}
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/install-capnp
# `apps/desktop/src-tauri` is a workspace member, so a root `cargo clippy` builds it
# on every platform. macOS and Windows have their WebView in the OS; Linux does not,
# and the failure is a `pkg-config` error from `gobject-sys` several hundred lines
# into an otherwise normal build. WebKitGTK is the only Linux WebView there is.
- name: Install the Linux WebView and GTK development headers
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libxdo-dev \
libssl-dev
# rust-toolchain.toml pins the exact version, and rustup honours it.
- run: rustup show active-toolchain || rustup toolchain install
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --all -- --check
- run: cargo clippy --all-targets --all-features -- -D warnings
# `--all-targets`, matching clippy above. Without it, `cargo test` skips tests that live
# inside examples — and `crates/protocol/examples/support/proxy.rs` holds the 11 chunked
# transfer-coding tests written for a bug that reached a browser as a page of binary
# garbage. Verified: plain `cargo test --all-features` runs none of them.
- run: cargo test --all-targets --all-features
# `--all-targets` skips doctests, so they need their own run. Nothing has one yet; the step
# exists so the first one added is not silently unrun.
- run: cargo test --doc --all-features
- name: Documentation consistency
if: runner.os == 'Linux'
run: cargo xtask verify-docs
deny:
name: cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check all