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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
name: CI
on:
push:
branches:
pull_request:
branches:
# Lets you re-run the CI manually from the Actions tab.
workflow_dispatch:
# Weekly so new security advisories are caught even without a push.
# Only the `audit` job runs on this trigger (see its `if:` guards below
# on `test`/`fmt`/`clippy`) — the test matrix and lint jobs would just
# re-check unchanged code and burn CI minutes for no new signal.
schedule:
- cron: "0 6 * * 1"
# Cancel in-progress runs of the same workflow on the same branch when
# new commits are pushed — saves CI minutes during rapid iteration.
# Scheduled runs are exempt: they share the main-branch concurrency group
# with ordinary push CI, so without this exemption a push to main while
# the weekly audit is running would silently cancel it — a cancellation
# isn't a failure, so nothing would go red and nobody would notice a
# newly published advisory going uncaught.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name != 'schedule' }}
env:
CARGO_TERM_COLOR: always
# The lexer + tests are warning-clean today; any new warning should
# block the merge until it's addressed.
RUSTFLAGS: "-D warnings"
jobs:
test:
name: cargo test (${{ matrix.label }})
runs-on: ubuntu-latest
# Scheduled runs only exist to re-check advisories against unchanged
# code (see the `audit` job) — skip the test matrix on that trigger.
if: github.event_name != 'schedule'
strategy:
fail-fast: false
matrix:
# Every feature combination the README tells users to install with.
# `fetch` and `svg` gate real code (the `--url` CLI branch, remote
# image fetching, SVG rasterization) that default-features-only CI
# would otherwise never compile.
include:
- features: ""
label: default
- features: "--features fetch"
label: fetch
- features: "--features svg"
label: svg
- features: "--all-features"
label: all
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry + build artifacts
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.label }}
- name: Build
run: cargo build --all-targets --verbose ${{ matrix.features }}
- name: Test (lib unit + integration + spec + stress + doc)
run: cargo test --all-targets --verbose ${{ matrix.features }}
- name: Doc tests
# Doesn't vary by feature — only run once, on the default entry.
if: matrix.features == ''
run: cargo test --doc --verbose
- name: CommonMark spec — surface full report in CI log
# Same suite as above, but re-runs the spec target with the
# per-section breakdown captured in the workflow log so any
# regression in spec compliance is visible without re-running
# CI locally. Doesn't vary by feature — only run once, on the
# default entry.
if: matrix.features == ''
run: cargo test --test commonmark_spec -- --nocapture
fmt:
name: cargo fmt --check
runs-on: ubuntu-latest
# Scheduled runs only exist to re-check advisories against unchanged
# code (see the `audit` job) — skip formatting checks on that trigger.
if: github.event_name != 'schedule'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting
run: cargo fmt --all --check
clippy:
name: cargo clippy
runs-on: ubuntu-latest
# Scheduled runs only exist to re-check advisories against unchanged
# code (see the `audit` job) — skip linting on that trigger.
if: github.event_name != 'schedule'
# The workflow-level RUSTFLAGS="-D warnings" (needed by `test`) would
# otherwise leak in here and promote every warn-level clippy lint to
# `error:`, making this advisory job's log misleadingly read "N errors"
# and silently inflating what "burn down the backlog" means. Do NOT
# delete this override — it is deliberate, not a stray empty value.
env:
RUSTFLAGS: ""
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache cargo registry + build artifacts
uses: Swatinem/rust-cache@v2
- name: Clippy (all targets, all features)
run: cargo clippy --all-targets --all-features
audit:
name: cargo audit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-audit
# Fetches a prebuilt binary instead of compiling cargo-audit's
# dependency tree (advisory parsing, index client, semver) from
# source on every run, which used to be the most expensive step
# in the workflow relative to its value.
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
- name: Audit dependencies
run: cargo audit