Skip to content

Commit 799143a

Browse files
authored
Create test.yml
1 parent 7f8ce07 commit 799143a

1 file changed

Lines changed: 205 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
name: Tests
2+
3+
# Runs on every push/PR touching the daemon, the greeter, or the UI, plus a
4+
# manual trigger. Three independent jobs (daemon / greeter / ui) so a
5+
# failure in one surface doesn't hide failures in the others, and so they
6+
# run in parallel rather than one long serial pipeline.
7+
#
8+
# This workflow is CI quality gates ONLY (fmt / clippy / lint / unit tests).
9+
# It does not produce a release build or any downloadable artifact — that's
10+
# build.yml, which only runs after code actually lands (push to main or a
11+
# version tag) or on manual dispatch.
12+
on:
13+
push:
14+
branches: [main]
15+
pull_request:
16+
branches: [main]
17+
workflow_dispatch:
18+
19+
env:
20+
CARGO_TERM_COLOR: always
21+
22+
jobs:
23+
# ── daemon (Rust, no GUI toolkit deps — pure tokio + std) ─────────────────
24+
daemon:
25+
name: daemon (cargo fmt / clippy / test)
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Install Rust
31+
uses: dtolnay/rust-toolchain@stable
32+
with:
33+
components: rustfmt, clippy
34+
35+
- name: Cache cargo registry & build artifacts
36+
uses: Swatinem/rust-cache@v2
37+
with:
38+
workspaces: daemon
39+
40+
- name: cargo fmt --check
41+
working-directory: daemon
42+
run: cargo fmt --check
43+
44+
# --deny warnings: clippy found real, deny-by-default bugs in this
45+
# codebase before (identical if/else branches in pam_auth.rs) — this
46+
# flag is what makes clippy actually enforce that class of issue in
47+
# CI instead of only warning locally.
48+
- name: cargo clippy
49+
working-directory: daemon
50+
run: cargo clippy --all-targets -- -D warnings
51+
52+
- name: cargo test
53+
working-directory: daemon
54+
run: cargo test --all-targets
55+
56+
# ── greeter (Rust + Tauri v2 — needs the GTK/WebKitGTK dev headers) ───────
57+
greeter:
58+
name: greeter (cargo fmt / clippy / check)
59+
runs-on: ubuntu-latest
60+
steps:
61+
- uses: actions/checkout@v4
62+
63+
- name: Install Rust
64+
uses: dtolnay/rust-toolchain@stable
65+
with:
66+
components: rustfmt, clippy
67+
68+
# Tauri v2's official Linux CI dependency list — without these,
69+
# anything that links webkit2gtk-sys / gtk-sys / javascriptcoregtk-sys
70+
# fails at the `cc`/`pkg-config` step, not at a Rust type-checking
71+
# step, which is a much more confusing failure to debug from a log.
72+
- name: Install Tauri Linux build dependencies
73+
run: |
74+
sudo apt-get update
75+
sudo apt-get install -y \
76+
libwebkit2gtk-4.1-dev \
77+
libgtk-3-dev \
78+
librsvg2-dev \
79+
libsoup-3.0-dev \
80+
libjavascriptcoregtk-4.1-dev \
81+
libayatana-appindicator3-dev \
82+
patchelf \
83+
build-essential \
84+
curl \
85+
wget \
86+
file
87+
88+
- name: Cache cargo registry & build artifacts
89+
uses: Swatinem/rust-cache@v2
90+
with:
91+
workspaces: greeter
92+
93+
- name: cargo fmt --check
94+
working-directory: greeter
95+
run: cargo fmt --check
96+
97+
# NOTE: `tauri::generate_context!()` (called from main.rs) resolves
98+
# `bundle.icon` in tauri.conf.json and needs that file to actually
99+
# exist at *compile* time — for cargo clippy/check/test, not just
100+
# `tauri build`. tauri.conf.json points icon at
101+
# "../config/images/icon.png" (a real, always-present file in this
102+
# repo) precisely so this step never needs an extra "prepare icons"
103+
# step before it — a previous revision pointed it at a generated
104+
# "icons/icon.png" that only existed after tauri build's
105+
# beforeBuildCommand ran, which made plain `cargo clippy` fail here
106+
# with "failed to open icon ... No such file or directory".
107+
- name: cargo clippy
108+
working-directory: greeter
109+
run: cargo clippy --all-targets -- -D warnings
110+
111+
# `cargo test` (not just `check`) here too: greeter/src/main.rs has
112+
# its own unit tests for the system-status parsers (any_interface_up,
113+
# parse_battery_info, parse_amixer_volume) that don't need a display
114+
# or real hardware to run in CI.
115+
- name: cargo test
116+
working-directory: greeter
117+
run: cargo test --all-targets
118+
119+
# ── UI (Solid.js) ──────────────────────────────────────────────────────
120+
ui:
121+
name: ui (lint / test / build)
122+
runs-on: ubuntu-latest
123+
steps:
124+
- uses: actions/checkout@v4
125+
126+
- name: Install Node.js
127+
uses: actions/setup-node@v4
128+
with:
129+
node-version: '20'
130+
# NOTE: deliberately NOT using `cache: npm` / `cache-dependency-path`
131+
# here. actions/setup-node's built-in npm cache HARD-FAILS this
132+
# entire step ("Some specified paths were not resolved, unable to
133+
# cache dependencies") if the lockfile path doesn't resolve to an
134+
# existing file — which is exactly what happened here twice.
135+
# ui/package-lock.json and greeter/package-lock.json are committed
136+
# to this repo (generated via `npm install --package-lock-only`),
137+
# so that *shouldn't* trigger — but this class of failure is bad
138+
# enough (it aborts the job before a single line of project code
139+
# runs) that caching is done manually below instead, via
140+
# actions/cache, which degrades to "no cache hit" rather than
141+
# failing the job if a lockfile is ever briefly missing/renamed.
142+
143+
- name: Cache npm dependencies
144+
uses: actions/cache@v4
145+
with:
146+
path: ui/node_modules
147+
key: ${{ runner.os }}-npm-ui-${{ hashFiles('ui/package-lock.json') }}
148+
restore-keys: |
149+
${{ runner.os }}-npm-ui-
150+
151+
# `npm ci` requires ui/package-lock.json to exist and match
152+
# package.json exactly — it is committed in this repo. If it's ever
153+
# missing (e.g. a bad merge), fall back to `npm install` instead of
154+
# hard-failing the job, so "ui can't install npm" can never again be
155+
# the single point of failure for the whole workflow — it just loses
156+
# the reproducible-install guarantee for that one run instead, with a
157+
# visible warning.
158+
- name: Install dependencies
159+
working-directory: ui
160+
run: |
161+
if [ -f package-lock.json ]; then
162+
npm ci
163+
else
164+
echo "::warning::ui/package-lock.json is missing — falling back to 'npm install'. Commit the lockfile (npm install --package-lock-only) to fix this properly."
165+
npm install
166+
fi
167+
168+
- name: Formatting check (Prettier)
169+
working-directory: ui
170+
run: npm run format:check
171+
172+
- name: Lint (ESLint + eslint-plugin-solid)
173+
working-directory: ui
174+
run: npm run lint
175+
176+
- name: Unit tests (Vitest + @solidjs/testing-library)
177+
working-directory: ui
178+
run: npm run test
179+
180+
- name: Type-check + production build
181+
working-directory: ui
182+
run: npm run build
183+
184+
- name: Upload build artifact
185+
uses: actions/upload-artifact@v4
186+
with:
187+
name: ui-dist
188+
path: ui/dist
189+
retention-days: 7
190+
191+
# Convenience job so branch protection can require one green check
192+
# ("all-checks-passed") instead of hand-listing all three matrix jobs by
193+
# name, which silently stops protecting anything if a job is renamed.
194+
all-checks-passed:
195+
name: All checks passed
196+
runs-on: ubuntu-latest
197+
needs: [daemon, greeter, ui]
198+
if: always()
199+
steps:
200+
- name: Fail if any dependency job failed
201+
run: |
202+
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
203+
echo "One or more required jobs failed."
204+
exit 1
205+
fi

0 commit comments

Comments
 (0)