Files
anki/.github/workflows/ci.yml
Luc Mcgrady fc5103bc33 chore(ci):Use commit SHAs for github actions (#4916)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

<!-- Fixes #123 / Closes #123 / Refs #123 -->
closes #4722

## Summary / motivation (required)

<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->
I used this nice script I found:
https://gist.github.com/onnimonni/3462f958c7d235417863651974514525

For the reasons behind this change see:
- #4722

## Steps to reproduce (required, use N/A if not applicable)

<!-- Steps to reproduce: how to trigger the bug in the broken state (the
"before").
 - Mainly for bugfixes;
    - For bugs: numbered steps before the fix. For non-bugs: write N/A.
 - use N/A for features, refactors, docs, chore, etc.
-->
(N/A)

## How to test (required)

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->
See it run in my repo here:
https://github.com/Luc-Mcgrady/anki/actions/runs/26718877866

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->
## Before / after behavior (optional)

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

<!-- Screenshot or short video -->

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-06-02 10:35:32 -03:00

319 lines
10 KiB
YAML

name: CI
on:
workflow_dispatch:
push:
branches: [main, 'release/**']
pull_request:
branches: [main]
types: [opened, synchronize, reopened, labeled]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
env:
N2_OUTPUT_PROGRESS: "1"
N2_OUTPUT_SUCCESS: "1"
jobs:
minilints:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
with:
fetch-depth: 0
filter: blob:none
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 #v1
- name: Run minilints
run: cargo run -p minilints -- check /tmp/minilints.stamp
env:
CONTRIBUTORS_BYPASS_EMAILS: ${{ vars.CONTRIBUTORS_BYPASS_EMAILS }}
# Lightweight formatting checks (no build outputs needed).
# Uses individual tool installs instead of setup-anki to stay fast.
format:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 #v1
- name: Install uv
uses: astral-sh/setup-uv@94527f2e458b27549849d47d273a16bec83a01e9 #v7
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4
with:
node-version: '20'
- name: Install n2
run: tools/install-n2
env:
RUSTFLAGS: "--cap-lints warn"
- name: Install just
uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b #v3
- name: Run format checks
run: just fmt
# Linux runs on every PR and push to main.
check-linux:
runs-on: ubuntu-24.04
name: check (linux)
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
- name: Restore cargo cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
~/.cargo/bin
~/.cargo/.crates.toml
~/.cargo/.crates2.json
key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
restore-keys: cargo-${{ runner.os }}-
- name: Restore build output cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-Linux-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}
restore-keys: |
build-Linux-${{ github.event.pull_request.number || 'main' }}-
build-Linux-main-
build-Linux-
- name: Setup build environment
uses: ./.github/actions/setup-anki
- name: Install just
uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b #v3
- name: Symlink node_modules
run: ln -sf out/node_modules .
- name: Restore coverage baseline
if: github.event_name == 'pull_request'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out/coverage
key: coverage-baseline-linux-${{ github.sha }}
restore-keys: coverage-baseline-linux-
- name: Move restored baseline aside
if: github.event_name == 'pull_request'
run: test -d out/coverage && mv out/coverage out/coverage-baseline || true
- name: Build, lint, and test
env:
ONLINE_TESTS: "1"
run: |
just build
just lint
just test --coverage
- name: Cache coverage baseline
if: github.ref_name == 'main'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out/coverage
key: coverage-baseline-linux-${{ github.sha }}
- name: Check coverage regression
if: github.event_name == 'pull_request'
run: python3 tools/coverage/check-coverage-regression.py out/coverage-baseline out/coverage
- name: Run e2e tests
run: just test-e2e
- name: Upload Playwright report
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4
with:
name: playwright-report
path: out/e2e-report/
retention-days: 7
- name: Ensure libs importable
env:
SKIP_RUN: "1"
run: ./run
- name: Check Rust dependencies
if: github.event_name == 'pull_request'
id: rust-deps
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 #v47.0.5
with:
files: |
Cargo.lock
**/Cargo.toml
.deny.toml
- uses: EmbarkStudios/cargo-deny-action@8f84122a46a358a27cb0625d85ad60ab436a1b87 #v2
if: github.event_name != 'pull_request' || steps.rust-deps.outputs.any_changed == 'true'
# out/pyenv contains a venv with absolute Python paths that break
# across runs. out/build.ninja is regenerated by configure each time.
# Remove both before saving so the cache stays portable.
- name: Clean non-cacheable state
if: always()
shell: bash
run: |
rm -rf out/pyenv
rm -f out/build.ninja
- name: Save build output cache
if: always()
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-Linux-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}
# Runs on pushes to main or on PRs with the check:macos label.
check-macos:
if: >-
github.event_name == 'push'
|| github.event_name == 'workflow_dispatch'
|| contains(github.event.pull_request.labels.*.name, 'check:macos')
runs-on: macos-latest
name: check (macos)
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
with:
submodules: true
- name: Restore cargo cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
~/.cargo/bin
~/.cargo/.crates.toml
~/.cargo/.crates2.json
key: cargo-macOS-${{ hashFiles('Cargo.lock') }}
restore-keys: cargo-macOS-
- name: Restore build output cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-macOS-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}
restore-keys: |
build-macOS-${{ github.event.pull_request.number || 'main' }}-
build-macOS-main-
build-macOS-
- name: Setup build environment
uses: ./.github/actions/setup-anki
- name: Install just
uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b #v3
- name: Symlink node_modules
run: ln -sf out/node_modules .
- name: Build, lint, and test
run: |
just build
just wheels
just lint
just test
- name: Clean non-cacheable state
if: always()
shell: bash
run: |
rm -rf out/pyenv
rm -f out/build.ninja
- name: Save build output cache
if: always()
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-macOS-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}
# Runs on pushes to main or on PRs with the check:windows label.
check-windows:
if: >-
github.event_name == 'push'
|| github.event_name == 'workflow_dispatch'
|| contains(github.event.pull_request.labels.*.name, 'check:windows')
runs-on: windows-latest
name: check (windows)
# Colocate CARGO_HOME and TEMP on D: to keep all I/O on the same fast
# local disk.
env:
CARGO_HOME: D:\cargo-home
TEMP: D:\tmp
TMP: D:\tmp
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4
with:
submodules: true
- name: Prepare D:\ directories
shell: bash
run: mkdir -p /d/cargo-home /d/tmp
- name: Restore cargo cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: |
D:\cargo-home\registry\index
D:\cargo-home\registry\cache
D:\cargo-home\git\db
D:\cargo-home\bin
D:\cargo-home\.crates.toml
D:\cargo-home\.crates2.json
key: cargo-Windows-${{ hashFiles('Cargo.lock') }}
restore-keys: cargo-Windows-
- name: Restore build output cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-Windows-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}
restore-keys: |
build-Windows-${{ github.event.pull_request.number || 'main' }}-
build-Windows-main-
build-Windows-
- name: Setup build environment
uses: ./.github/actions/setup-anki
- name: Install just
uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b #v3
- name: Build, lint, and test
run: |
just build
just lint
just test
# Also remove node_modules on Windows — file-locking corrupts the cache.
- name: Clean non-cacheable state
if: always()
shell: bash
run: |
rm -rf out/pyenv out/node_modules
rm -f out/build.ninja
- name: Save build output cache
if: always()
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 #v4
with:
path: out
key: build-Windows-${{ github.event.pull_request.number || 'main' }}-${{ github.run_id }}