Skip to content

release.yml: fix gh CLI misuse in the post-retry size re-check #61

release.yml: fix gh CLI misuse in the post-retry size re-check

release.yml: fix gh CLI misuse in the post-retry size re-check #61

Workflow file for this run

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