Merge pull request #186 from lidge-jun/codex/ui-polish-wp3-typography #783
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 | |
| permissions: | |
| contents: read | |
| on: | |
| push: | |
| branches: [main, dev] | |
| schedule: | |
| - cron: '17 3 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| sha: | |
| description: 'Full 40-char SHA to check out and test (release candidate gate)' | |
| required: false | |
| type: string | |
| concurrency: | |
| # Dispatched candidate runs share the release-candidate ref, so key the group | |
| # on the input SHA too — otherwise a second candidate cancels the first. | |
| group: ci-${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.sha || '' }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| name: test (${{ matrix.os }}, node ${{ matrix.node }}, npm ${{ matrix.npm }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| node: '22.23.0' | |
| npm: '11.18.0' | |
| - os: ubuntu-latest | |
| node: '24.17.0' | |
| npm: '12.0.0' | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 | |
| with: | |
| ref: ${{ github.event.inputs.sha || github.sha }} | |
| - name: Assert the checked-out SHA is the dispatched one | |
| if: ${{ github.event.inputs.sha != '' && github.event.inputs.sha != null }} | |
| shell: bash | |
| env: | |
| WANT: ${{ github.event.inputs.sha }} | |
| run: | | |
| ACTUAL=$(git rev-parse HEAD) | |
| if [ "$WANT" != "$ACTUAL" ]; then | |
| echo "dispatch asked for $WANT but checked out $ACTUAL" | |
| exit 1 | |
| fi | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| # npm's content-addressed cache is npm-version agnostic, so sharing it | |
| # across the npm 11/12 matrix legs on the same OS is intentional. | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| ui/package-lock.json | |
| - name: Structure line-count drift (fast fail) | |
| run: node scripts/refresh-structure-line-counts.mjs --check | |
| - name: Pin npm | |
| run: npm install -g npm@${{ matrix.npm }} | |
| - name: Install root deps | |
| run: npm ci | |
| - name: Provider registry generated-file drift | |
| run: node scripts/generate-provider-types.mjs --check | |
| - name: Native dependency smoke | |
| run: npm run test:native-deps | |
| - name: Install ui deps | |
| run: npm --prefix ui ci --no-audit --no-fund | |
| - name: Install policy contract | |
| run: npm run test:install-policy | |
| - name: npm 12 pending-script oracle | |
| if: matrix.npm == '12.0.0' | |
| run: npm run test:install-policy:npm12 | |
| - name: Typecheck | |
| run: npm run typecheck | |
| - name: Typecheck tests | |
| run: npm run typecheck:tests | |
| - name: Test inventory | |
| run: npm run test:inventory | |
| - name: Build server (tsc emit) | |
| run: npm run build:server | |
| - name: Build cli (tsc emit) | |
| run: npm run build:cli | |
| - name: Build ui | |
| run: npm --prefix ui run build | |
| - name: Run tests | |
| run: npm test | |
| timeout-minutes: 20 | |
| - name: Lint package.json | |
| if: matrix.os == 'ubuntu-latest' && matrix.npm == '11.18.0' | |
| run: npm run lint:pkg | |
| - name: Audit root production dependencies | |
| if: matrix.os == 'ubuntu-latest' && matrix.npm == '11.18.0' | |
| run: node scripts/audit-gate.mjs --audit-level high --omit dev | |
| - name: Audit UI build dependencies | |
| if: matrix.os == 'ubuntu-latest' && matrix.npm == '11.18.0' | |
| run: node scripts/audit-gate.mjs --prefix ui --audit-level high | |
| - name: Package install smoke | |
| run: npm run test:package-install | |
| timeout-minutes: 15 | |
| - name: Global install, update, and package-local OAuth smoke | |
| run: npm run test:package-global-update | |
| timeout-minutes: 15 | |
| - name: CLI smoke (grok --help) | |
| run: node bin/ima2.js grok --help | |
| - name: CLI smoke (video --help) | |
| run: node bin/ima2.js video --help | |
| - name: CLI smoke (capabilities) | |
| run: node bin/ima2.js capabilities --json | |
| - name: CLI smoke (--version) | |
| run: node bin/ima2.js --version | |
| - name: Graceful shutdown (SIGINT clean exit) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| node server.js & | |
| SERVER_PID=$! | |
| sleep 3 | |
| kill -SIGINT $SERVER_PID 2>/dev/null || true | |
| TIMEOUT=10; while kill -0 $SERVER_PID 2>/dev/null && [ $TIMEOUT -gt 0 ]; do sleep 1; TIMEOUT=$((TIMEOUT-1)); done | |
| if kill -0 $SERVER_PID 2>/dev/null; then | |
| echo "::error::Server did not exit within 10s after SIGINT" | |
| kill -9 $SERVER_PID 2>/dev/null || true | |
| exit 1 | |
| fi | |
| wait $SERVER_PID | |
| EXIT_CODE=$? | |
| echo "Server exited with code $EXIT_CODE" | |
| if [ $EXIT_CODE -ne 0 ]; then | |
| echo "::warning::Server exited with non-zero code $EXIT_CODE (may be signal-based exit)" | |
| fi | |
| - name: Verify install scripts in sync | |
| if: matrix.os == 'ubuntu-latest' && matrix.npm == '11.18.0' | |
| run: | | |
| diff scripts/install-mac.sh site/public/install-mac.sh | |
| diff scripts/install-linux.sh site/public/install-linux.sh | |
| diff scripts/install-windows.ps1 site/public/install-windows.ps1 | |
| - name: Publish dry-run | |
| if: matrix.os == 'ubuntu-latest' && matrix.npm == '11.18.0' | |
| run: npm run publish:dry-run | |
| # Windows is a supported install target, so its coverage is kept — but it is | |
| # off the release path. The two Windows legs were the slowest thing on the | |
| # board and they gated every release cut, while the only failure they ever | |
| # produced was EPERM in a test's own `rmSync` teardown on a temp dir the OS | |
| # had not released yet. That is a Windows filesystem behaviour, not a defect | |
| # in the shipped package, and it blocked releases that were otherwise green | |
| # on every other leg. | |
| # | |
| # `schedule` only: never on push, and never on the workflow_dispatch that | |
| # release.yml uses for its candidate gate. A regression here is caught within | |
| # a day and fixed on its own merit instead of stopping a release. | |
| windows: | |
| name: windows (node ${{ matrix.node }}, npm ${{ matrix.npm }}) | |
| if: github.event_name == 'schedule' | |
| runs-on: windows-latest | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - node: '22.23.0' | |
| npm: '11.18.0' | |
| - node: '24.17.0' | |
| npm: '12.0.0' | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| ui/package-lock.json | |
| - name: Pin npm | |
| run: npm install -g npm@${{ matrix.npm }} | |
| - name: Install root deps | |
| run: npm ci | |
| - name: Native dependency smoke | |
| run: npm run test:native-deps | |
| - name: Install ui deps | |
| run: npm --prefix ui ci --no-audit --no-fund | |
| - name: Typecheck | |
| run: npm run typecheck | |
| - name: Build server (tsc emit) | |
| run: npm run build:server | |
| - name: Build cli (tsc emit) | |
| run: npm run build:cli | |
| - name: Build ui | |
| run: npm --prefix ui run build | |
| - name: Run tests | |
| run: npm test | |
| timeout-minutes: 20 | |
| - name: Package install smoke | |
| run: npm run test:package-install | |
| timeout-minutes: 15 | |
| - name: CLI smoke (--version) | |
| run: node bin/ima2.js --version | |
| - name: CLI smoke (capabilities) | |
| run: node bin/ima2.js capabilities --json | |
| e2e: | |
| name: frontend e2e (ubuntu) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '22.23.0' | |
| cache: npm | |
| cache-dependency-path: | | |
| package-lock.json | |
| ui/package-lock.json | |
| - name: Install root deps | |
| run: npm ci | |
| - name: Install ui deps | |
| run: npm --prefix ui ci --no-audit --no-fund | |
| - name: Install Playwright Chromium | |
| run: npx --prefix ui playwright install --with-deps chromium | |
| - name: Build ui | |
| run: npm --prefix ui run build | |
| - name: Run frontend e2e | |
| run: npm --prefix ui run test:e2e | |
| - name: Upload e2e failure artifacts | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: e2e-failure-context | |
| path: ui/test-results/ | |
| if-no-files-found: ignore | |
| retention-days: 7 |