ci: add GitHub Actions workflow for Rust and UI - #5
Conversation
The repo had no CI: nothing ran fmt, clippy, tests, typecheck or build on push or PR. Rust job runs cargo fmt --check, clippy --workspace --all-targets and test --workspace on ubuntu-latest, installing the webkit2gtk/libsoup stack that app/src-tauri needs plus libdbus-1-dev for deck-camera's keyring dependency, so --workspace covers every crate rather than skipping the Tauri app. UI job runs npm ci, tsc --noEmit, the vitest suite and the vite build. The test step uses an explicit `vitest run --passWithNoTests=false` rather than the `npm test` script, which is a bare `vitest` (watch mode), and a follow-up step asserts from the JSON report that tests were actually executed -- guarding the failure seen in PR #3, where the suite reported "no tests" and still exited 0. Clippy deliberately runs without -D warnings: app/src-tauri has 6 existing warnings that would fail the job on arrival. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughAdded a GitHub Actions workflow for Rust and UI checks on pull requests and pushes to ChangesContinuous integration validation
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)
22-22: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDisable persisted checkout credentials.
Both checkouts run dependency-managed code afterward and no later step uses authenticated Git access. Set
persist-credentials: falseon line 22 and line 73.Proposed fix
- - uses: actions/checkout@v5 + - uses: actions/checkout@v5 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ci.yml at line 22, Disable persisted checkout credentials for both actions/checkout@v5 steps: update .github/workflows/ci.yml lines 22-22 and 73-73 to set persist-credentials to false.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/workflows/ci.yml:
- Line 22: Disable persisted checkout credentials for both actions/checkout@v5
steps: update .github/workflows/ci.yml lines 22-22 and 73-73 to set
persist-credentials to false.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 859c0c1c-593f-4a3e-8f96-45ca180b3868
📒 Files selected for processing (2)
.github/workflows/ci.ymlapp/.gitignore
Lands the detailed spec and ADR that baton task 0e6c0c19 was gated on
("NEXT: detailed spec + ADR required before build"). Both were authored
2026-07-11 and had existed only as untracked files in a local working
tree — no branch, no remote, no copy anywhere.
- docs/adr/0001-deck-as-panel-host-for-mystira-ops-tooling.md (Proposed)
deck stays a generic panel-host; Mystira ops tooling is hosted as
bounded, individually-omissible panel modules on top of it. Establishes
docs/adr/NNNN-*.md as deck's ADR home.
- docs/specs/deck-ops-cockpit.md (Draft)
Design for the three R13 facets: a Dashboard cost/ops section (sluice
health + docket spend), the Cosmos Explorer + Migration Manager re-port,
and a Service-Manager story-gen batch-run monitor. Establishes
docs/specs/ as the home for deck design specs.
Re-grounded against dev @ bc0d1c5 before landing. The design is unchanged;
current-state evidence was corrected where deck had moved since July:
- §1.2 claimed the frontend could not typecheck due to dangling imports of
the removed panels. PR #3 removed that wiring; PR #5's CI proves the
build is green. Kept in corrected form — the extraction is still
unfinished, but the evidence is now behavioural: dead Dashboard
quick-actions falling through to the Service Manager, orphaned
StatisticsPanel/ExportPanel callers, live backends with no UI.
- §1.3 claimed outbound HTTP would be gated by a Tauri capability
addition. It would not: deck uses native reqwest, which
capabilities/default.json does not constrain. Now states the real
requirement — https + host allowlisting enforced in Rust.
- §1.1 records crates/deck-camera and the CI gates; §5.4 points at the
existing crates/deck-contracts/src/story_generator.rs.
Docs-only: no code, no CI surface touched.
What
Adds
.github/workflows/ci.yml. The repo had no CI at all —.github/workflows/did not exist, and nothing ran tests on push or PR.Two jobs, both on
ubuntu-latest, both withtimeout-minutes:cargo fmt --all --check,cargo clippy --workspace --all-targets,cargo test --workspaceapp/)npm ci,npx tsc --noEmit, vitest,npm run buildCaching:
Swatinem/rust-cache@v2for the cargo registry/git/target dir, andactions/setup-node@v5withcache: npmkeyed onapp/package-lock.json.Why now
During #3 the UI suite was running zero tests and still reporting success.
app/src/test/setup.tsbuilt a second JSDOM on top of vitest'sjsdomenvironment, sorenderwrote to one document whilescreenqueried another; the forks pool hung and printed "no tests" with a zero exit code. Three failing camera tests were invisible through three review rounds. That was fixed in #3 — but nothing would have caught it, and nothing would catch the next one.Guarding the silent-zero specifically
Two layers, both verified rather than assumed:
npx vitest run --passWithNoTests=falseinstead of thenpm testscript.npm testis a barevitest, i.e. watch mode — it only terminates under CI because vitest happens to detect$CI, which is too implicit to hang a merge gate on. I confirmed the flag produces a non-zero exit on an empty run before relying on it (a run matching no test files exits 1).--passWithNoTestsonly covers "no test files were found". It does not cover "files were collected but zero tests executed", which is closer to what actually happened in feat(camera): add private local viewer #3. So the test step also emits a JSON report and a follow-up step fails the job unlessnumTotalTests >= 1.I proved the gate bites rather than trusting a green check: a deliberate empty run on this branch turned the UI job red at the Test step (
No test files found, exiting with code 1), while the Rust job stayed green. That commit is not part of this PR.Verification
Both jobs ran green on this branch before the PR was opened (run 31391034448) — not just "the YAML parses":
cargo test --workspaceran 16 tests (5deck+ 3deck-camera+ 8deck-contracts). The Tauri crate compiles on Linux with the installed system deps.vitest executed 51 tests (51 passed)across 5 files, typecheck and build clean.Judgement calls
Tauri system deps are installed rather than scoping the Rust job.
app/src-tauriis a real Tauri 2 app, so the workspace needs the webkit2gtk/libsoup stack;deck-cameraadditionally pullskeyring → secret-service → libdbus-sys, hencelibdbus-1-dev. Scoping to-p deck-camera -p deck-contractswould have skipped the largest crate (28 source files) and the exact files carrying the known clippy warnings. Installing the deps costs ~30s and keeps--workspacehonest.Clippy runs without
-D warnings.app/src-tauricurrently has 6 warnings — 4 inservices/helpers.rs, 1 inservices/ports.rs, 1 inservices/status.rs. Denying warnings before fixing them would fail the job on arrival. There is a comment in the workflow saying to add-- -D warningsonce they are fixed, so the count cannot quietly grow.Noted, not fixed here
The reconnect/backoff and frame-inactivity-timeout logic in
crates/deck-camera/src/lib.rshas no test coverage. deck-camera's 3 tests only cover credential/locator validation. That is the most intricate logic in the crate and it is currently unguarded — worth its own PR.Also worth knowing:
app/src-tauri/gen/is generated by the Tauri build and is not covered by.gitignore, so it shows up as untracked after a local build. Left alone deliberately, as it is unrelated to CI.Summary by CodeRabbit
Chores
Refactor