ci(rust): run the Rust workspace, which no workflow has ever built #442
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| # feat/ai-edition is a long-lived integration branch that PRs land on for | |
| # months at a time. Without it listed here, every one of those PRs merged with | |
| # no lint, no typecheck, no tests and no PR-title check. | |
| # | |
| # release/** is here for the same reason and it cost more: PRs #167, #168 and | |
| # #169 — 30k+ lines of deletion and refactor — merged into release/1.8.0 with | |
| # every one of those jobs skipped, because a release branch matched neither | |
| # pattern. A release branch is the LAST place to run a build unguarded. | |
| on: | |
| pull_request: | |
| branches: [main, feat/ai-edition, "release/**"] | |
| push: | |
| branches: [main, feat/ai-edition, "release/**"] | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup | |
| - run: npm run lint | |
| typecheck: | |
| name: Type Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup | |
| - run: npx tsc --noEmit | |
| typecheck-tests: | |
| name: Typecheck (tests) | |
| runs-on: ubuntu-latest | |
| # A RATCHET, not a gate. tsconfig.json includes only src + electron and | |
| # excludes **/*.test.ts, so no test file has ever been typechecked, and | |
| # vitest transpiles without checking — fixture types have drifted from the | |
| # schemas they claim to build for years. Failing on the whole backlog would | |
| # put a red X on every PR that nobody can fix, and a check everyone ignores | |
| # is worse than no check. So: fail only if the count GROWS. Lower BASELINE | |
| # whenever you fix some; delete this job's baseline logic at zero. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup | |
| - name: Typecheck tests against a baseline | |
| shell: bash | |
| env: | |
| BASELINE: 80 | |
| run: | | |
| set -uo pipefail | |
| COUNT=$(npx tsc -p tsconfig.test.json --noEmit 2>&1 | grep -c 'error TS' || true) | |
| { | |
| echo "## Test-file typecheck" | |
| echo "" | |
| echo "| | |" | |
| echo "|---|---|" | |
| echo "| Errors now | ${COUNT} |" | |
| echo "| Baseline | ${BASELINE} |" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| if [ "${COUNT}" -gt "${BASELINE}" ]; then | |
| echo "::error::Test-file type errors went ${BASELINE} -> ${COUNT}. Fix the new ones, or raise BASELINE in ci.yml with a reason." | |
| npx tsc -p tsconfig.test.json --noEmit 2>&1 | grep 'error TS' || true | |
| exit 1 | |
| fi | |
| if [ "${COUNT}" -lt "${BASELINE}" ]; then | |
| echo "::notice::Test-file type errors down to ${COUNT} (baseline ${BASELINE}). Lower BASELINE in ci.yml to lock the win in." | |
| fi | |
| docs: | |
| name: Docs | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # No ./.github/actions/setup: check-docs.mjs imports only node builtins, | |
| # so npm ci would be a minute of install for nothing. Node 22 is here for | |
| # import.meta.dirname (needs >= 20.11). | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - run: npm run docs:check | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup | |
| - run: npm run test | |
| - run: npm run test:browser:install | |
| - run: npm run test:browser | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup | |
| - run: npx vite build | |
| rust: | |
| name: Rust | |
| # windows-only by necessity, not preference: crates/compositor is D3D11 and links the | |
| # `windows` crate. There is nothing to run on ubuntu. | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| # Provisions include/ + lib/ at the FFMPEG_DIR that crates/.cargo/config.toml names. | |
| # bindgen and the linker both need them and the tree is gitignored, so without this a | |
| # runner cannot compile the workspace at all. Same pinned, SHA-256-verified archive the | |
| # packaged app ships — no second download path to keep in sync. | |
| - run: node scripts/fetch-ffmpeg.mjs | |
| # The test binary dlopens the same av*.dll set at run time; without them it dies with | |
| # STATUS_DLL_NOT_FOUND (0xc0000135) before a single test runs, which reads like a build | |
| # failure and isn't. This dir is the fixed one the script vendors to, so no second copy | |
| # of the FFMPEG_DIR lookup lives here. | |
| - run: Add-Content $env:GITHUB_PATH "$env:GITHUB_WORKSPACE\electron\native\bin\win32-x64" | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: crates | |
| # From crates/, not `--manifest-path` from the root: cargo reads .cargo/config.toml | |
| # relative to the working directory, and that file is what supplies FFMPEG_DIR and | |
| # LIBCLANG_PATH. Invoked from the root the build gets neither. | |
| # | |
| # --workspace, because `default-members = ["poc-d3d"]` means a bare `cargo test` would | |
| # quietly skip the library the app actually links and the napi addon it ships. | |
| # | |
| # --all-targets is what excludes doctests, and it has to: bindgen copies ffmpeg's C | |
| # doxygen comments verbatim into out/ffi.rs, so rustdoc finds 13 "examples" that are C | |
| # and fails to compile them as Rust. They are generated, not ours, and there is nothing | |
| # to fix in them. Everything else — lib, bins, integration tests — still runs. | |
| - run: cargo test --workspace --all-targets | |
| working-directory: crates | |
| semantic-pr: | |
| name: Validate PR title (semantic) | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: amannn/action-semantic-pull-request@v5 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| types: | | |
| feat | |
| fix | |
| chore | |
| refactor | |
| perf | |
| docs | |
| test | |
| build | |
| ci | |
| style | |
| revert | |
| requireScope: false |