mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-12 16:25:51 +00:00
Skipping the whole matrix job via a job-level `if` collapses it to a
single check with the unevaluated name template ("test (\${{
matrix.artifact }})") instead of expanding to "test (base)"/"test (pr)",
since there's no matrix context to fill in when the job never runs. That
check never matches a required-status-check pinned to "test (pr)", so
PRs that skip backend/puterjs testing block forever waiting on a check
that will never be reported. Gate the steps instead so the matrix always
expands with stable names, doing no real work when irrelevant.
150 lines
5.0 KiB
YAML
150 lines
5.0 KiB
YAML
name: Backend Tests
|
|
|
|
# Always triggers so it can be a required PR check; the `changes` job below
|
|
# decides whether backend/extension paths actually changed (test-only changes
|
|
# match the same globs, since tests are co-located with the code), and every
|
|
# other job is skipped — not absent — when they didn't, which still satisfies
|
|
# a required check. puter.js SDK changes are covered by puterjs-tests.yaml.
|
|
on:
|
|
pull_request:
|
|
types: [opened, synchronize, reopened]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
changes:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
backend: ${{ steps.filter.outputs.backend }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: dorny/paths-filter@v3
|
|
id: filter
|
|
with:
|
|
filters: |
|
|
backend:
|
|
- 'src/backend/**'
|
|
- 'extensions/**'
|
|
- 'tools/**'
|
|
- 'package.json'
|
|
- 'package-lock.json'
|
|
- 'tsconfig.json'
|
|
- 'tsconfig.build.json'
|
|
- '.github/workflows/backend-tests.yaml'
|
|
|
|
# `tsconfig.build.json` builds with `noCheck: true`, so nothing else in CI
|
|
# runs the type checker and a missing export compiles to `undefined`,
|
|
# surfacing only when the call is finally reached at runtime. This diffs
|
|
# against tools/typecheck-baseline.json and fails only on *new* errors.
|
|
#
|
|
# The consuming repo runs an equivalent gate, but only once someone bumps the
|
|
# submodule pointer — too late to keep the error off this repo's default
|
|
# branch. Hence a gate here, on this repo's own pull requests.
|
|
#
|
|
# Its own job rather than a step in `test`: that one runs a base/PR matrix for
|
|
# coverage comparison, and the check only needs the PR ref, once.
|
|
typecheck:
|
|
needs: changes
|
|
if: needs.changes.outputs.backend == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '24'
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Type check (new errors only)
|
|
run: npm run typecheck
|
|
|
|
# `needs.changes` gates the steps below, not this job, on purpose: a
|
|
# job-level `if` on a matrix job skips the whole job as one unexpanded
|
|
# check ("test (${{ matrix.artifact }})", literally, since there's no
|
|
# matrix context to fill it in) instead of the two real per-artifact
|
|
# checks a required rule pins to ("test (base)" / "test (pr)") — so the
|
|
# required check never gets reported and the PR blocks forever. Letting
|
|
# the matrix always expand keeps the check names stable either way.
|
|
test:
|
|
needs: changes
|
|
# Overrides the default matrix naming, which would otherwise bake the
|
|
# base/head branch name (matrix.ref) into the check name — making it a
|
|
# different string on every PR and impossible to pin as a required check.
|
|
name: test (${{ matrix.artifact }})
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- ref: ${{ github.base_ref }}
|
|
artifact: base
|
|
- ref: ${{ github.head_ref }}
|
|
artifact: pr
|
|
|
|
steps:
|
|
- name: Checkout ${{ matrix.ref }}
|
|
if: needs.changes.outputs.backend == 'true'
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ matrix.ref }}
|
|
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
|
|
|
- name: Set up Node.js
|
|
if: needs.changes.outputs.backend == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '24'
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
if: needs.changes.outputs.backend == 'true'
|
|
run: npm ci
|
|
|
|
- name: Run backend tests with coverage
|
|
if: needs.changes.outputs.backend == 'true'
|
|
run: npm run test:backend -- --coverage
|
|
env:
|
|
CI: 'true'
|
|
|
|
- name: Upload coverage artifact
|
|
if: needs.changes.outputs.backend == 'true' && !cancelled()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: backend-coverage-${{ matrix.artifact }}
|
|
path: src/backend/coverage/
|
|
retention-days: 14
|
|
|
|
report-coverage:
|
|
needs: [changes, test]
|
|
if: always() && needs.changes.outputs.backend == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Download PR coverage
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: backend-coverage-pr
|
|
path: src/backend/coverage
|
|
|
|
- name: Download base coverage
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: backend-coverage-base
|
|
path: coverage-base
|
|
|
|
- name: Report coverage on PR
|
|
uses: davelosert/vitest-coverage-report-action@v2
|
|
with:
|
|
json-summary-path: src/backend/coverage/coverage-summary.json
|
|
json-final-path: src/backend/coverage/coverage-final.json
|
|
json-summary-compare-path: coverage-base/coverage-summary.json
|