Skip to content

Guard the write path against transcript sources; stop the phantom store (#327) #446

Guard the write path against transcript sources; stop the phantom store (#327)

Guard the write path against transcript sources; stop the phantom store (#327) #446

Workflow file for this run

name: CI
on:
push:
branches: [main, "v*"]
# No branch filter: every pull request is checked regardless of its base.
# A filter here silently skips CI for PRs targeting a release branch, which
# is exactly when the checks matter most.
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- run: npm ci --legacy-peer-deps
- run: npm run typecheck
# The "no unscoped corpus query" rule from src/lib/scope.ts, machine-checked.
# There is no ESLint in this repo; this is a plain Node script.
#
# --inventory prints every documented exception beside the alias list the
# checker itself derived. Off by default (a hundred lines on every local
# run is noise); on here, so the log keeps a diffable record and a reason
# drifting away from its SQL shows up in the diff.
- run: npm run check:scope -- --inventory
- run: npm run test:coverage
# Bundles the Worker without deploying (no auth/network). Catches build
# or config errors that typecheck and tests miss. A fresh checkout has no
# .wrangler/ redirect, so this reads wrangler.jsonc directly.
- name: Build check (wrangler dry-run)
run: npx wrangler deploy --dry-run
# The desktop app bundles the Worker with its own esbuild script, which
# otherwise only runs on a release tag. It reads the Worker source
# directly, so a source move can break the desktop build while the tests
# and the wrangler dry-run above stay green. Catch that here instead of at
# tag time.
- name: Build check (desktop worker bundle)
working-directory: installer
run: npm ci && npm run bundle-worker
- name: Post coverage comment on PR
if: github.event_name == 'pull_request'
uses: davelosert/vitest-coverage-report-action@v2
# The desktop app is Rust, and nothing above compiles it — the suite, the
# wrangler dry-run and the worker bundle are all JavaScript. Without this job
# a PR can turn the Tauri app into something that does not build and still go
# green, with the failure surfacing only when an `installer-v*` tag kicks off
# installer-release.yml. That is the most expensive place to find it.
#
# Runs on the two platforms the app ships on, matching installer-release.yml.
# That is deliberate rather than a cost decision: `detect_obsidian`
# (commands.rs) selects its body with `cfg(target_os)`, so a Linux runner
# would compile a fallback branch that never ships while never compiling the
# Windows branch at all — under-reporting real breakage and able to fail on
# code no user runs. macOS and Windows also need no system packages (WebKit
# and WebView2 are provided by the OS and the runner image), so there is no
# apt list here to drift out of step with a runner upgrade.
desktop:
strategy:
# Report both platforms. Without this a macOS failure cancels the Windows
# job and hides whatever it would have found.
fail-fast: false
matrix:
platform: [macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
timeout-minutes: 45
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: installer/src-tauri -> target
# Root deps first: the esbuild bundle resolves the Worker's own
# dependencies from the repository root, not from installer/.
- run: npm ci --legacy-peer-deps
- run: npm ci
working-directory: installer
# build.rs panics unless worker-dist/ exists, so the bundle has to run
# before cargo touches the crate.
- name: Bundle Worker (required by build.rs)
working-directory: installer
run: npm run bundle-worker
# installer/src is excluded from the root tsconfig, and `tsc --noEmit`
# otherwise runs only inside `npm run build` on an installer-v* tag. The
# i18n catalogs are typed against a closed interface; this is what makes
# a missing key a failure on the PR rather than at release time.
- name: Typecheck desktop UI
working-directory: installer
run: npx tsc --noEmit
# `cargo check` proved the crate compiles; the Rust tests pin index
# naming, storage estimates, and binding preservation, and ran only on
# release tags before this.
- name: Test desktop app
run: cargo test --manifest-path installer/src-tauri/Cargo.toml