blob: 7a18a1d924c1fb5b731a7523ae53cef86950f516 [file]
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -D warnings
jobs:
# Whether this push or pull request changes only Markdown outside the code, which cannot
# change what builds (scripts/docs-only.sh says which files those are). The jobs below, all but `corpus`, skip on a yes; a job skipped by its
# condition reports success, so a required check does not sit waiting for it. Anything
# the diff cannot answer, a first push or a rewritten base, runs everything.
changes:
name: changes
runs-on: ubuntu-latest
outputs:
docs_only: ${{ steps.diff.outputs.docs_only }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- id: diff
env:
BASE: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
# judged by the base's copy of the script, so a change to it cannot skip the
# job that tests it; a base without one runs everything
if judge=$(git show "$BASE:scripts/docs-only.sh") &&
files=$(git diff --name-only --no-renames "$BASE" "$GITHUB_SHA") &&
printf '%s\n' "$files" | sh -c "$judge"; then
echo "docs_only=true" >> "$GITHUB_OUTPUT"
echo "only Markdown changed; the build and test jobs skip"
else
echo "docs_only=false" >> "$GITHUB_OUTPUT"
fi
# The pre-commit gate, as `make check` runs it locally, plus the two checks that need
# cargo extensions. Actions are pinned by commit; the comment says which release.
check:
name: check (linux)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
components: rustfmt, clippy
# wasm32-unknown-unknown: dm-web's build script builds the browser reader
targets: wasm32-unknown-unknown, wasm32-wasip2, x86_64-pc-windows-gnu
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
# Ubuntu's AppArmor lets an unprivileged process create a user namespace but not map
# its uid in it, so no confined test could run. A laptop installs the amem profile in
# packaging/apparmor; the tests' own probe is unshare, not amem, so this throwaway VM
# turns the restriction off instead
- run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- run: make check
# the embedded PostgreSQL for the ledger tests lists its releases through GitHub's
# API; unauthenticated, a runner's address is soon refused
env:
GITHUB_TOKEN: ${{ github.token }}
- uses: taiki-e/install-action@5488ac5a951645ce95062214902ac4b6bc1a1037 # v2.87.32
with:
tool: cargo-machete
- run: make machete
# The same tests on Windows. Portability between the two is a stated goal, so a change
# that passes on one and not the other does not merge.
windows:
name: test (windows)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
targets: wasm32-unknown-unknown, wasm32-wasip2
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
# The companion test loads an unpacked extension, which Google Chrome's own builds
# refuse; the Windows image has no Chromium or Chrome for Testing, so this fetches
# the stable Chrome for Testing and names it in CHROME
- name: Chrome for Testing
shell: pwsh
run: |
$known = Invoke-RestMethod https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
$url = ($known.channels.Stable.downloads.chrome | Where-Object platform -eq 'win64').url
Invoke-WebRequest $url -OutFile "$env:RUNNER_TEMP\chrome.zip"
Expand-Archive "$env:RUNNER_TEMP\chrome.zip" -DestinationPath "$env:RUNNER_TEMP\chrome"
"CHROME=$env:RUNNER_TEMP\chrome\chrome-win64\chrome.exe" >> $env:GITHUB_ENV
- run: cargo test --workspace
# the embedded PostgreSQL for the ledger tests lists its releases through GitHub's
# API; unauthenticated, a runner's address is soon refused
env:
GITHUB_TOKEN: ${{ github.token }}
# The same tests on macOS, which is also the only place the Seatbelt backend's tests
# that run sandbox-exec are compiled and run.
macos:
name: test (macos)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: macos-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
targets: wasm32-unknown-unknown, wasm32-wasip2
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- run: cargo test --workspace
# the embedded PostgreSQL for the ledger tests lists its releases through GitHub's
# API; unauthenticated, a runner's address is soon refused
env:
GITHUB_TOKEN: ${{ github.token }}
# dm-core must build for the browser, or the reader and the plugins cannot.
wasm:
name: build (wasm32)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- run: make wasm-check
# The Markdown the demo reads, checked as the demo reads it (scripts/corpus-check.sh).
# It runs on every change, a docs-only one included: docs/ and examples/decisions/ are
# the demo's record, and a heading renamed there breaks a golden question or an eval.
corpus:
name: corpus
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- run: make corpus-check
# The rust-version in Cargo.toml, built with that release of Rust (`make msrv-check`), so
# the declared minimum cannot fall behind what the locked dependencies need.
# RUSTUP_TOOLCHAIN outranks rust-toolchain.toml, which would otherwise fetch stable and
# its targets the first time anything runs cargo or rustc.
msrv:
name: build (msrv)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: msrv
run: echo "version=$(sed -n 's/^rust-version = "\(.*\)"$/\1/p' Cargo.toml)" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: ${{ steps.msrv.outputs.version }}
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
env:
RUSTUP_TOOLCHAIN: ${{ steps.msrv.outputs.version }}
- run: make msrv-check
env:
RUSTUP_TOOLCHAIN: ${{ steps.msrv.outputs.version }}
# Advisories, licences, duplicate versions, sources. Configured in deny.toml. The
# cargo-deny action is not on the ASF allow-list, so the tool is installed instead.
deny:
name: dependencies
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: taiki-e/install-action@5488ac5a951645ce95062214902ac4b6bc1a1037 # v2.87.32
with:
tool: cargo-deny
- run: make deny
# Line coverage against COVERAGE_MIN in the Makefile, which is a ratchet. The lcov
# report is attached to the run for anyone who wants to look at the lines.
coverage:
name: coverage
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
components: llvm-tools-preview
targets: wasm32-unknown-unknown, wasm32-wasip2
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- uses: taiki-e/install-action@5488ac5a951645ce95062214902ac4b6bc1a1037 # v2.87.32
with:
tool: cargo-llvm-cov
# the confined tests run here too, as in the check job
- run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- run: make coverage
# the embedded PostgreSQL for the ledger tests lists its releases through GitHub's
# API; unauthenticated, a runner's address is soon refused
env:
GITHUB_TOKEN: ${{ github.token }}
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: lcov
path: target/lcov.info
# The browser tests: the pages driven by Chromium in the Playwright image, as
# `make e2e` runs them, with every page's screenshots attached to the run for review.
e2e:
name: e2e (chromium)
needs: changes
if: ${{ !cancelled() && needs.changes.outputs.docs_only != 'true' }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # 2026-07-16, the commit the ASF allow-list pins
with:
toolchain: stable
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
- run: make e2e
env:
CI: 'true'
- if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: e2e-screenshots
path: |
e2e/screenshots/
e2e/playwright-report/
retention-days: 14