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
name: CI
on:
push:
branches:
pull_request:
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
# The vendored libcurl/OpenSSL build (see the `curl` dependency in Cargo.toml)
# dominates a cold build, so a warm cache is the difference between a two
# minute job and a twenty minute one.
CARGO_INCREMENTAL: 0
jobs:
fmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all --check
# The feature matrix is the point of this job. PaperBoy builds in four shapes
# and each one has to stay both compiling *and* warning-free on its own:
#
# headless -- no front-end at all; the shape used in CI images and Docker
# tui -- the default, and what `cargo install paperboy` gives you
# gui -- tui + gui, what `--features gui` gives you
# gui-only -- the GUI without the terminal UI
#
# Without this job the non-default shapes rot silently: `gui-only` did not
# compile at all until the front-ends were split apart, because nothing ever
# built it. `-D warnings` is deliberate — the dead-code suppression in
# `main.rs` is keyed on the `tui` feature, and this is what proves the two
# front-end-complete configurations are still carrying full analysis.
check:
name: check (${{ matrix.name }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: headless
features: --no-default-features
- name: tui
features: ""
- name: gui
features: --features gui
- name: gui-only
features: --no-default-features --features gui
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.name }}
# eframe pulls in winit, which needs the X11/Wayland and xkbcommon headers
# at build time. The terminal and headless shapes need none of this, which
# is a large part of why the GUI is opt-in in the first place.
- name: Install GUI build dependencies
if: contains(matrix.features, 'gui')
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxkbcommon-dev libwayland-dev libx11-dev libxcursor-dev \
libxrandr-dev libxi-dev libgl1-mesa-dev
- run: cargo check ${{ matrix.features }} --all-targets
env:
RUSTFLAGS: -D warnings
# Every shape that is built is also tested. The GUI configurations were
# originally check-only, which left their 432 `gui::*` tests compiled but
# never run — a shape CI proves builds and nothing more. They need no display
# to run, so there was nothing bought by leaving them out.
#
# None of the four is redundant: headless is the only one proving the core
# passes with no front-end linked in (what a CI-image user installs), and
# gui-only is the only one proving the GUI stands on its own.
test:
name: test (${{ matrix.name }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: headless
features: --no-default-features
- name: tui
features: ""
- name: gui
features: --features gui
- name: gui-only
features: --no-default-features --features gui
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
key: test-${{ matrix.name }}
- name: Install GUI build dependencies
if: contains(matrix.features, 'gui')
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxkbcommon-dev libwayland-dev libx11-dev libxcursor-dev \
libxrandr-dev libxi-dev libgl1-mesa-dev
# `paperboy` is a binary crate with no lib target, so the unit tests are
# compiled into `src/main.rs` and plain `cargo test` is the only form that
# works (`--lib` fails outright).
- run: cargo test ${{ matrix.features }}