release.yml: fix gh CLI misuse in the post-retry size re-check #61
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 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: | | |
| frontend/package-lock.json | |
| app/package-lock.json | |
| mastervault-mcp-server/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: npm ci | |
| - name: Install app dependencies | |
| working-directory: app | |
| run: npm ci | |
| - name: Install mastervault-mcp-server dependencies | |
| working-directory: mastervault-mcp-server | |
| run: npm ci | |
| - name: Lint frontend | |
| working-directory: frontend | |
| run: npm run lint | |
| - name: Typecheck frontend | |
| working-directory: frontend | |
| run: npx tsc -b | |
| - name: Typecheck app | |
| working-directory: app | |
| run: npx tsc -p tsconfig.json --noEmit | |
| - name: Test frontend | |
| working-directory: frontend | |
| run: npm test | |
| - name: Test app | |
| working-directory: app | |
| run: npm test | |
| - name: Build frontend | |
| working-directory: frontend | |
| run: npm run build | |
| - name: Build app | |
| working-directory: app | |
| run: npm run build | |
| - name: Build bundled mastervault-mcp-server (the copy ModelForge packages) | |
| working-directory: mastervault-mcp-server | |
| run: npm run build:bundled | |
| - name: Smoke-test the bundled mastervault-mcp-server over stdio | |
| working-directory: mastervault-mcp-server | |
| run: | | |
| set -euo pipefail | |
| mkdir -p /tmp/mastervault-ci-vault | |
| echo '# CI test vault' > /tmp/mastervault-ci-vault/_orientation.md | |
| printf '%s\n%s\n' \ | |
| '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"ci","version":"1"}}}' \ | |
| '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ | |
| | node dist-bundled/index.js /tmp/mastervault-ci-vault > worker-output.json | |
| cat worker-output.json | |
| test "$(grep -o 'mastervault_orient' worker-output.json | wc -l)" -ge 1 | |
| e2e: | |
| # Electron E2E tests spin up a real Electron process and a Vite preview | |
| # server per test, which is slower and flakier than the unit-test job | |
| # above — kept as its own job so a flaky e2e run never blocks/hides a | |
| # unit-test failure, and so it can be retried or skipped independently. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: | | |
| frontend/package-lock.json | |
| app/package-lock.json | |
| e2e/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: npm ci | |
| - name: Install app dependencies | |
| working-directory: app | |
| run: npm ci | |
| - name: Install e2e dependencies | |
| working-directory: e2e | |
| run: npm ci | |
| - name: Install Playwright browsers | |
| working-directory: e2e | |
| run: npx playwright install --with-deps chromium | |
| - name: Build frontend | |
| working-directory: frontend | |
| run: npm run build | |
| - name: Build app | |
| working-directory: app | |
| run: npm run build | |
| - name: Run e2e suite | |
| working-directory: e2e | |
| # Electron needs a real (or virtual) display even headless-ish, hence | |
| # xvfb — there's no way to launch a BrowserWindow without one on Linux. | |
| run: xvfb-run --auto-servernum npx playwright test | |
| - name: Upload Playwright report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report | |
| path: e2e/playwright-report | |
| retention-days: 7 | |
| rust: | |
| # lib/ (modelforge-native) is the napi-rs download engine used by | |
| # download-queue.ts. GitHub's ubuntu-latest runners ship rustup with a | |
| # default stable toolchain already installed, so this only needs to add | |
| # the two components fmt/clippy actually use. | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: lib | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install rustfmt and clippy | |
| run: rustup component add rustfmt clippy | |
| - uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| lib/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('lib/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Format check | |
| run: cargo fmt --check | |
| - name: Clippy | |
| run: cargo clippy --all-targets -- -D warnings | |
| - name: Build | |
| run: cargo build --release | |
| - name: Test | |
| run: cargo test | |
| python-recommender: | |
| # ml/hardware-recommender/ is a standalone project (its own venv, own | |
| # train/download-dataset scripts) that isn't part of the app's build — | |
| # only its *trained checkpoint* ships with the app | |
| # (app/python/artifacts/hardware_recommender.pt), loaded at runtime by | |
| # app/python/recommender_worker.py. This job is deliberately scoped to | |
| # what release publishing actually depends on: the recommender package's | |
| # own unit tests (data/feature encoding logic, no dataset or GPU needed) | |
| # and a smoke test that the packaged worker script can actually load the | |
| # shipped artifact and answer a request — never train.py or | |
| # download_dataset.py, which need a real (large) dataset pull. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: ml/hardware-recommender/requirements.txt | |
| - name: Install dependencies (CPU-only torch, matching the shipped runtime) | |
| working-directory: ml/hardware-recommender | |
| # torch's CPU wheels live on a separate index from the rest of | |
| # PyPI — installed in its own invocation, matching how | |
| # app/src/python-runtime-manager.ts installs it for the packaged | |
| # hardware-recommender venv, and avoiding a multi-gigabyte CUDA | |
| # wheel download on a GPU-less CI runner. | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install --only-binary=:all: --index-url https://download.pytorch.org/whl/cpu torch==2.13.0 | |
| python -m pip install --only-binary=:all: $(grep -v '^torch==' requirements.txt) | |
| - name: Run hardware-recommender unit tests | |
| working-directory: ml/hardware-recommender | |
| run: python -m pytest tests/ -q | |
| - name: Verify the packaged model artifact exists | |
| run: test -f app/python/artifacts/hardware_recommender.pt | |
| - name: Smoke-test the packaged recommender worker against the shipped artifact | |
| working-directory: app/python | |
| run: | | |
| printf '%s\n%s\n' \ | |
| '{"protocol":1,"id":"1","method":"health","params":{}}' \ | |
| '{"protocol":1,"id":"2","method":"recommend","params":{"model_params_b":7,"ram_gb":16,"vram_gb":8,"cpu_cores":8,"platform":"linux","gpu_backend":"cuda"}}' \ | |
| | python recommender_worker.py > worker-output.json | |
| cat worker-output.json | |
| test "$(grep -o '"ok": *true' worker-output.json | wc -l)" -eq 2 |