Repository navigation
T2 validation #0 @7f83544128e53b0705adf1cadba4cc0d2ef4c87b base:7f83544128e53b0705adf1cadba4cc0d2ef4c87b #100
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 | |
| run-name: "T2 validation #${{ inputs.pr || github.event.pull_request.number || 0 }} @${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} base:${{ inputs.base || github.event.pull_request.base.sha || github.sha }}" | |
| on: | |
| workflow_call: | |
| inputs: | |
| sha: | |
| required: true | |
| type: string | |
| base: | |
| required: true | |
| type: string | |
| pr: | |
| default: "0" | |
| type: string | |
| workflow_dispatch: | |
| inputs: | |
| pr: | |
| description: Sync pull request number | |
| required: true | |
| type: string | |
| sha: | |
| description: Complete candidate commit SHA | |
| required: true | |
| type: string | |
| base: | |
| description: Complete accepted main commit SHA | |
| required: true | |
| type: string | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ inputs.pr != '0' && inputs.pr || github.event.pull_request.number || inputs.sha || github.sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| privacy: | |
| name: Trusted privacy | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| actions: read | |
| steps: | |
| - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 | |
| with: | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 | |
| with: | |
| node-version: 24 | |
| - name: Verify minimal analytics overlay | |
| run: | | |
| node --test .github/t2code/*.test.mjs | |
| node .github/t2code/overlay.mjs verify | |
| check: | |
| needs: privacy | |
| name: Check | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| - name: Reject repository-owned PR assets | |
| run: | | |
| files="$(git ls-files .github/pr-assets)" | |
| if test -n "$files"; then | |
| printf 'PR evidence must be uploaded to GitHub, not committed:\n%s\n' "$files" >&2 | |
| exit 1 | |
| fi | |
| - name: Setup Vite+ | |
| uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1 | |
| with: | |
| node-version-file: package.json | |
| cache: false | |
| run-install: true | |
| - name: Ensure Electron runtime is installed | |
| run: vp run --filter @t3tools/desktop ensure:electron | |
| # Files/dependencies are repo-wide; export checks cover clean workspaces only. | |
| - name: Check unused code | |
| run: vp run knip:check | |
| - name: Check | |
| run: vp check | |
| - name: Typecheck | |
| run: vpr typecheck | |
| - name: Install browser secret helper build libraries | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config | |
| - name: Build desktop pipeline | |
| run: vp run build:desktop | |
| - name: Verify preload bundle output | |
| run: node apps/desktop/scripts/verify-preload-bundle.mjs | |
| # Each package sizes its own Vitest worker pool. Run one package at a time | |
| # so competing pools do not exhaust Shiki's per-line tokenization budget. | |
| test: | |
| needs: privacy | |
| name: Test | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| - name: Setup Vite+ | |
| uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1 | |
| with: | |
| node-version-file: package.json | |
| cache: false | |
| run-install: true | |
| - name: Ensure Electron runtime is installed | |
| run: vp run --filter @t3tools/desktop ensure:electron | |
| - name: Install browser secret helper build libraries | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config | |
| - name: Test preview artifact validation | |
| run: python3 -B .github/scripts/stage-preview-bundle.test.py | |
| - name: Test nightly release checks | |
| run: node --test .github/scripts/check-nightly-release.test.cjs | |
| - name: Test | |
| run: vp run --parallel --concurrency-limit 1 --filter '!t3' --filter '!@t3tools/monorepo' test | |
| # apps/server sets `fileParallelism: false`, so its 239 files run strictly | |
| # one at a time. Sharding spreads them over separate runners instead of | |
| # separate workers, so no two server test files ever share a machine and the | |
| # isolation that flag buys is preserved exactly. | |
| test_server: | |
| needs: privacy | |
| name: Test Server ${{ matrix.shard }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2, 3] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| - name: Setup Vite+ | |
| uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1 | |
| with: | |
| node-version-file: package.json | |
| cache: false | |
| run-install: true | |
| # No Electron setup here: `t3` (apps/server) has no Electron dependency | |
| # and none of its tests touch the runtime. Only the non-server `test` | |
| # job, which covers @t3tools/desktop, needs the download. | |
| - name: Test | |
| env: | |
| T3CODE_TRANSFER_BUDGET_REPORT_PATH: ${{ runner.temp }}/t3code-transfer-budget.md | |
| T3CODE_TRANSFER_BUDGET_RESULT_PATH: ${{ runner.temp }}/thread-transfer-result.json | |
| run: vp run --filter t3 test --shard ${{ matrix.shard }}/${{ strategy.job-total }} | |
| # src/server.test.ts writes the budget report, so exactly one shard | |
| # produces these files. Gating the upload on their presence keeps a | |
| # single `thread-transfer-results` artifact per run, which is the name | |
| # thread-transfer-report.yml resolves. | |
| - name: Detect transfer budget report | |
| id: transfer_budget | |
| if: always() | |
| run: | | |
| if test -f "${{ runner.temp }}/thread-transfer-result.json"; then | |
| echo "present=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "present=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Publish transfer budget report | |
| if: always() && steps.transfer_budget.outputs.present == 'true' | |
| run: | | |
| if test -f "${{ runner.temp }}/t3code-transfer-budget.md"; then | |
| tee -a "$GITHUB_STEP_SUMMARY" < "${{ runner.temp }}/t3code-transfer-budget.md" | |
| else | |
| echo "Transfer budget report was not produced." >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Upload thread transfer result | |
| if: always() && steps.transfer_budget.outputs.present == 'true' | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: thread-transfer-results | |
| path: ${{ runner.temp }}/thread-transfer-result.json | |
| if-no-files-found: ignore | |
| retention-days: 30 | |
| # Split out of Check and Test: both paid ~7-9s to install a Rust toolchain | |
| # for checks that take under 3s, on the critical path of every PR. | |
| rust: | |
| needs: privacy | |
| name: Rust | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable | |
| with: | |
| components: rustfmt | |
| - name: Check Rust formatting | |
| run: | | |
| for crate in resource-monitor kde-snap-shot hyprland-snap-shot; do | |
| cargo fmt --manifest-path "native/$crate/Cargo.toml" -- --check | |
| done | |
| - name: Test Rust crates | |
| run: | | |
| for crate in resource-monitor kde-snap-shot hyprland-snap-shot; do | |
| cargo test --locked --manifest-path "native/$crate/Cargo.toml" | |
| done | |
| release_smoke: | |
| needs: privacy | |
| name: Release Smoke | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha || github.sha }} | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| /* | |
| !/.repos/ | |
| sparse-checkout-cone-mode: false | |
| - name: Setup Vite+ | |
| uses: voidzero-dev/setup-vp@250f29ce396baf5e8f24498e17c0dfdebabc26eb # v1 | |
| with: | |
| node-version-file: package.json | |
| cache: false | |
| run-install: | | |
| args: | |
| - --filter=@t3tools/scripts... | |
| - name: Exercise release-only workflow steps | |
| run: | | |
| node scripts/release-smoke.ts | |
| node --test .github/t2code/*.test.mjs | |
| result: | |
| name: CI result | |
| needs: [privacy, check, test, test_server, rust, release_smoke] | |
| if: always() | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Require every check to pass | |
| env: | |
| RESULTS: ${{ toJSON(needs) }} | |
| run: | | |
| node -e 'const jobs=JSON.parse(process.env.RESULTS); if (Object.values(jobs).some(job=>job.result!=="success")) process.exit(1)' |