Files
webstudio/.github/workflows/main.yml
T
Oleg Isonen 4273b7001f refactor: Organize Builder development and test tooling (#6285)
## Outcome

Builder development, backend, E2E, and CI tooling now share one
ownership model: Builder defines named commands and backend modes, while
CI only schedules those commands.

## Technical choices

- Group shared Compose files, PostgreSQL initialization, and backend
helpers under `apps/builder/backend`.
- Resolve `compose.<mode>.yaml` by convention instead of maintaining
Compose filename lists in scripts and workflows.
- Keep persistent development and disposable test Compose projects
separate by default, while allowing the standard `COMPOSE_PROJECT_NAME`
override.
- Make schema snapshots invalidate from discovered migration sources and
backend files.
- Move E2E behavior recipes into named Builder commands; retain concise
root proxies for developer entry points.
- Let Vitest allocate available browser ports instead of maintaining a
cross-package port registry.
- Keep test-suite scheduling explicit in `main.yml`, but move executable
test commands to root package scripts.
- Move fixture-size enforcement from inline GitHub JavaScript into a
locally runnable repository script.

## Todo

- [x] Consolidate Builder backend and Compose ownership.
- [x] Add named development, E2E, schema-cache, Supabase, and CI-shard
commands.
- [x] Remove Compose topology and behavior flags from CI.
- [x] Remove the static Vitest browser-port registry.
- [x] Extract fixture-size checking from the workflow.
- [x] Verify migration bootstrap, snapshot-backed E2E, tests, builds,
types, formatting, lint, generated contracts, and workflow syntax.
- [x] Review documentation impact: updated the E2E developer guide; no
user-facing `docs/` content is affected.

## Verification

- Full package, CLI, Builder core, and Builder app test suites
- Full workspace typecheck
- Builder production build
- Schema-cache generation through the complete migration history
- Supabase migration compatibility
- Snapshot-backed Playwright animation workflow
- Backend regression tests, including demonstrated fail/pass coverage
- All four Compose mode configurations
- `oxfmt`, `oxlint`, package boundaries, generated API, and generated
docs checks
- `actionlint` and Bash syntax checks

The fixture-size checker preserves the existing Linux `du` thresholds.
Its three inputs build locally; macOS allocation sizes are not directly
comparable to the Linux CI thresholds, so CI remains the authoritative
size result.
2026-08-31 21:09:54 +02:00

257 lines
6.7 KiB
YAML

name: Main workflow
on:
push:
branches:
- main
pull_request:
pull_request_target:
types: [labeled]
# Keep pull_request_target label events from canceling pull_request checks.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.number || github.sha }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
ssg-artifact:
name: Packaged SSG Assets build
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
runs-on: ubuntu-24.04-arm
environment:
name: development
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/submodules-checkout
with:
submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}
- uses: ./.github/actions/ci-setup
- name: Build packaged SSG fixture
run: pnpm --filter webstudio test:ssg-package
tests:
name: tests (${{ matrix.environment }}, ${{ matrix.suite.name }})
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
environment:
- empty
- development
suite:
- name: packages
script: test:packages
browsers: chromium-firefox
- name: cli
script: test:cli
browsers: none
- name: builder-core
script: test:builder:core
browsers: chromium
- name: builder-app
script: test:builder:app
browsers: chromium
environment:
name: ${{ matrix.environment }}
env:
DATABASE_URL: postgres://
AUTH_SECRET: test
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/test-suite
with:
submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}
script: ${{ matrix.suite.script }}
browsers: ${{ matrix.suite.browsers }}
checks:
# Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
environment:
name: empty
env:
DATABASE_URL: postgres://
AUTH_SECRET: test
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
- name: Pnpm install
run: |
pnpm install
- run: |
pnpm oxfmt --check
- name: Lint
run: |
pnpm lint
- name: Package boundaries
run: |
pnpm check:package-boundaries
- name: Generated API contracts
run: |
pnpm check:generated-api
- name: Generated CLI docs
run: |
pnpm check:generated-docs
- name: Typecheck
run: |
pnpm -r typecheck
check-size:
# Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
runs-on: ubuntu-24.04-arm
environment:
name: development
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/submodules-checkout
with:
submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}
- uses: ./.github/actions/ci-setup
- run: pnpm --filter "{./fixtures/*}..." build
- run: pnpm check:fixture-sizes
builder-e2e-build:
name: builder-e2e build
# Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
runs-on: ubuntu-24.04
environment:
name: development
outputs:
shards: ${{ steps.build.outputs.shards }}
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- id: build
uses: ./.github/actions/builder-e2e-build
with:
submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}
supabase-migrations:
name: Supabase migrations
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
runs-on: ubuntu-24.04
environment:
name: empty
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/ci-setup
with:
run-scripts: "true"
- name: Apply migrations to Supabase PostgreSQL
run: pnpm --filter @webstudio-is/builder e2e:supabase-migrations
builder-e2e:
name: builder-e2e (${{ matrix.shard }})
# Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
timeout-minutes: 5
needs: builder-e2e-build
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.builder-e2e-build.outputs.shards) }}
environment:
name: development
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/builder-e2e-shard
with:
submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}
shard: ${{ matrix.shard }}
partition: ${{ matrix.partition }}