1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
name: CI
# Both jobs below are pure Rust (`cargo fmt`, `cargo clippy`, `cargo test`,
# `cargo check --workspace`). They can say nothing useful about a diff that
# contains no Rust, so the paths below skip the workflow entirely for those.
#
# The list is a blocklist (`paths-ignore`), never an allowlist (`paths`).
# An allowlist fails unsafe: a new crate, workspace member, or build script
# that nobody remembered to add would silently stop being built. A blocklist
# fails safe: anything unrecognized still runs the full build, and the worst
# case is a wasted run rather than an unvalidated merge.
#
# Two rules for anyone editing this list:
#
# 1. `.github/workflows/ci.yml` must never appear below. A change to the CI
# definition has to validate itself, otherwise a broken edit merges green
# because the workflow declined to run on its own change. The sibling
# workflows are listed individually for the same reason: a new workflow
# added later is NOT ignored by default.
# 2. `'**.md'` is only safe while no Markdown is compiled into the binary.
# Nothing in the workspace uses `include_str!`, `include_bytes!`, or
# `#[doc = include_str!(...)]` today. If that changes, narrow this entry
# so the embedded file is no longer ignored.
#
# GitHub applies these per file across the whole diff: the workflow is skipped
# only when EVERY changed file matches. A PR touching a doc and a `.rs` file
# still runs both jobs.
#
# NOTE ON BRANCH PROTECTION: `main` currently has no branch protection, so
# neither `ci` nor `msrv` is a required status check and a skipped run blocks
# nothing. If required status checks are ever enabled, this workflow-level
# `paths-ignore` must be migrated first: GitHub does not treat "not run" as
# "passed", so a doc-only PR would sit un-mergeable forever. The migration is
# either an always-reporting gate job that carries the required-check name and
# depends on the conditional Rust jobs, or per-step `if:` conditions driven by
# a cheap path-detection job. See issue #265.
#
# The two lists below are duplicated on purpose: GitHub Actions does not
# support YAML anchors and aliases, so they cannot be shared. Keep them in
# sync. Filtering only `pull_request` would leave the merge commit running on
# `main` the very build its PR had just skipped.
on:
push:
branches:
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- 'NOTICE'
- '.github/actions/**'
- '.github/workflows/release.yml'
- '.github/workflows/update_homebrew_formula.yml'
- '.github/workflows/debian_build.yml'
- '.github/workflows/launchpad_ppa.yml'
pull_request:
branches:
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- 'NOTICE'
- '.github/actions/**'
- '.github/workflows/release.yml'
- '.github/workflows/update_homebrew_formula.yml'
- '.github/workflows/debian_build.yml'
- '.github/workflows/launchpad_ppa.yml'
env:
CARGO_TERM_COLOR: always
jobs:
ci:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Cache cargo
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --check
- name: Run clippy
run: cargo clippy -- -D warnings
- name: Run tests
run: |
cargo test --lib --verbose
cargo test --tests --verbose -- --skip integration_test
msrv:
name: MSRV (cargo check on declared rust-version)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
# Read the MSRV from Cargo.toml so this job never drifts from the
# declared rust-version. The hard floor is 1.89 (rustyline 18 uses
# File::lock, stabilized in 1.89); the declared value tracks the
# Launchpad PPA build toolchain.
- name: Read MSRV from Cargo.toml
id: msrv
run: |
version=$(grep -m1 '^rust-version' Cargo.toml | sed -E 's/.*"([0-9.]+)".*/\1/')
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Declared MSRV: $version"
- name: Install Rust ${{ steps.msrv.outputs.version }} (declared MSRV)
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.msrv.outputs.version }}
- name: Cache cargo
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-msrv-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-msrv-
- name: Verify workspace builds on MSRV
run: cargo check --workspace --locked