| name: CI |
| |
| on: |
| pull_request: |
| branches: [main] |
| push: |
| branches: [main] |
| workflow_dispatch: |
| |
| concurrency: |
| group: ci-${{ github.workflow }}-${{ github.ref }} |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} |
| |
| permissions: |
| contents: read |
| |
| jobs: |
| # Planning and every selected Linux surface share one runner, so the core |
| # workflow consumes one automatic job without dropping affected coverage. |
| test: |
| runs-on: ubuntu-latest |
| timeout-minutes: 120 |
| steps: |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
| with: |
| fetch-depth: 0 |
| persist-credentials: false |
| |
| - id: plan |
| name: Select affected test surfaces |
| env: |
| BASE_SHA: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }} |
| HEAD_SHA: ${{ github.event_name == 'push' && github.sha || github.event.pull_request.head.sha }} |
| run: | |
| # PR checks may predate later main changes, so the single core job also |
| # validates the exact merged delta. Dispatches and unavailable history |
| # fail safe to every surface. |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] || [[ "$BASE_SHA" =~ ^0+$ ]] || ! git cat-file -e "${BASE_SHA}^{commit}"; then |
| node scripts/ci-test-plan.mjs --full >> "$GITHUB_OUTPUT" |
| else |
| node scripts/ci-test-plan.mjs --base "$BASE_SHA" --head "$HEAD_SHA" >> "$GITHUB_OUTPUT" |
| fi |
| |
| - name: Test CI planner |
| run: node --test --test-concurrency=1 scripts/ci-test-plan.test.mjs |
| |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 |
| if: steps.plan.outputs.code == 'true' || steps.plan.outputs.astryx_surface == 'true' || steps.plan.outputs.cli_package == 'true' |
| with: |
| node-version: '24' |
| cache: npm |
| |
| - name: Select the release npm toolchain |
| if: steps.plan.outputs.cli_package == 'true' |
| run: npm install --global --no-audit --no-fund "$(node -p 'require("./package.json").packageManager')" |
| |
| - name: Restore Electron artifact cache |
| if: steps.plan.outputs.code == 'true' |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 |
| with: |
| path: ~/.cache/electron |
| key: electron-${{ runner.os }}-${{ hashFiles('package-lock.json') }} |
| restore-keys: electron-${{ runner.os }}- |
| |
| - name: Install Linux runtime dependencies |
| if: steps.plan.outputs.runtime_sandbox == 'true' |
| run: sudo apt-get update && sudo apt-get install -y ripgrep bubblewrap |
| |
| # Ubuntu 24.04 hosted runners gate unprivileged user namespaces through |
| # AppArmor, which otherwise makes bwrap fail while configuring loopback. |
| - name: Enable bubblewrap user namespaces |
| if: steps.plan.outputs.runtime_sandbox == 'true' |
| run: | |
| if [[ -e /proc/sys/kernel/apparmor_restrict_unprivileged_userns ]]; then |
| sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 |
| fi |
| if [[ -e /proc/sys/kernel/unprivileged_userns_clone ]]; then |
| sudo sysctl -w kernel.unprivileged_userns_clone=1 |
| fi |
| |
| - name: Install dependencies |
| if: steps.plan.outputs.code == 'true' || steps.plan.outputs.cli_package == 'true' |
| run: npm ci |
| |
| - name: Lint |
| if: steps.plan.outputs.code == 'true' |
| run: npm run lint |
| |
| - name: Check formatting |
| if: steps.plan.outputs.code == 'true' |
| run: npm run format:check |
| |
| - name: Check Windows test inventory |
| continue-on-error: true |
| run: npm run windows:inventory |
| |
| - name: Build |
| if: steps.plan.outputs.code == 'true' |
| run: npm run build |
| |
| - name: Typecheck |
| if: steps.plan.outputs.code == 'true' |
| run: npm run typecheck |
| |
| - name: Astryx surface inventory |
| if: steps.plan.outputs.astryx_surface == 'true' |
| run: npm run astryx:surface-inventory |
| |
| - name: Astryx theme drift |
| if: steps.plan.outputs.code == 'true' |
| run: npm run astryx:theme -- --check |
| |
| - name: Knip (apps/desktop) |
| if: steps.plan.outputs.code == 'true' |
| run: npx knip --workspace apps/desktop |
| |
| - name: Knip (packages/ui) |
| if: steps.plan.outputs.code == 'true' |
| run: npx knip --workspace packages/ui |
| |
| - name: Linux sandbox smoke |
| if: steps.plan.outputs.runtime_sandbox == 'true' |
| env: |
| MAKA_REQUIRE_LINUX_SANDBOX_SMOKE: '1' |
| run: npm exec -w @maka/runtime -- node --test dist/__tests__/linux-sandbox-smoke.test.js |
| |
| - name: Run affected standard workspace tests |
| if: steps.plan.outputs.standard_workspaces != '' |
| env: |
| STORAGE_STRESS: ${{ steps.plan.outputs.storage_stress }} |
| WORKSPACES: ${{ steps.plan.outputs.standard_workspaces }} |
| run: | |
| if [[ "$STORAGE_STRESS" == "true" ]]; then |
| export MAKA_STORAGE_STRESS=1 |
| fi |
| node scripts/run-workspace-tests-parallel.mjs --concurrency=3 --workspaces="$WORKSPACES" |
| |
| - name: Run Runtime Host tests |
| if: steps.plan.outputs.runtime_host == 'true' |
| run: npm --workspace @maka/runtime-host run test:dist |
| |
| - name: Ensure xvfb |
| if: steps.plan.outputs.e2e == 'true' |
| run: command -v xvfb-run >/dev/null 2>&1 || { sudo apt-get update && sudo apt-get install -y xvfb; } |
| |
| - name: Desktop e2e |
| if: steps.plan.outputs.e2e == 'true' |
| run: xvfb-run -a npm exec -w @maka/desktop -- playwright test --config e2e/playwright.config.ts |
| |
| - name: Alignment audit |
| if: steps.plan.outputs.e2e == 'true' |
| run: xvfb-run -a node scripts/audit-alignment.mjs |
| |
| - name: Install Playwright Chromium |
| if: steps.plan.outputs.storybook == 'true' |
| run: npx playwright install --with-deps chromium |
| |
| - name: Build Storybook |
| if: steps.plan.outputs.storybook == 'true' |
| run: npm --workspace @maka/desktop run build-storybook |
| |
| - name: Storybook smoke |
| if: steps.plan.outputs.storybook == 'true' |
| run: npm --workspace @maka/desktop run smoke:storybook |
| |
| - name: Build CLI release candidate |
| if: steps.plan.outputs.cli_package == 'true' |
| run: npm run release:cli:pack |
| |
| - name: Validate installed CLI release candidate |
| if: steps.plan.outputs.cli_package == 'true' |
| run: npm run release:cli:smoke |