evOo-local/.github/MERGE_GATES.md
cynarAI 5cd1bc906f ci: Product CI merge gate and Autopilot auto-merge (#84)
* ci: add Product CI merge gate and Autopilot auto-merge path

Aggregate lint, typecheck, builds, unit, Postgres journeys, and Web E2E
into a single Product CI check for branch protection. Soft-fail artifact
uploads and skip headless macOS screenshots so infra noise does not block
merge. Add autopilot/auto-merge workflow and MERGE_GATES.md.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): keep autopilot auto-merge inert without label

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): run autopilot auto-merge on self-hosted runner

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(ci): free stale E2E ports before Playwright bind on Linux

Self-hosted evoo-ci runners can retain listeners on harness ports
(3110 API, 5180 web, 4321 marketing, 3111 device control) after a
failed run, causing EADDRINUSE before the next job. Add a guarded
free-e2e-ports.sh that uses fuser on Linux only and never touches
live dev ports 3100/5173. Wire it into the Playwright workflow and
the E2E harness with clear logging.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): stabilize message More menu Escape in hover E2E

The desktop hover spec assumed Escape always closed the first page-level
menu within one keypress. On self-hosted Chromium the Copy menu could stay
open while the rail remained visible, failing getByRole('menu') count.

Wait for the Copy item to prove the menu opened, then retry Escape until
that item hides while asserting the More control stays on the hover rail.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

* fix(web): retry sign-up navigation in Playwright helpers

Late-suite specs can miss the sign-up heading when Vite is still
warming on self-hosted runners. Retry goto until the form renders
instead of failing once at the default timeout.

Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
2026-09-24 00:57:10 +02:00

67 lines
3.0 KiB
Markdown

# CI merge gates
This repository splits continuous integration into **product** checks that should block merge and **infra** checks that provide signal without blocking Autopilot merges.
## Required for merge (product)
Configure branch protection on `main` to require exactly one status check from the `ci` workflow:
| Check name | Workflow | What it covers |
| --- | --- | --- |
| **Product CI** | `ci.yml` | Lint, Typecheck, Production builds, Unit tests, Postgres journeys, Web E2E |
The aggregate `Product CI` job fails when any of those product jobs fail. Individual job names remain visible on the pull request for debugging.
Optional but recommended repository settings:
- Enable **Allow auto-merge**
- Enable **Automatically delete head branches** after merge
## Infra-only (never required)
These workflows may fail without blocking product delivery. Do **not** add them to required status checks.
| Check / workflow | Why infra |
| --- | --- |
| `macOS setup screenshot (infra)` (`desktop-macos-screenshot.yml`) | Native screenshot capture; skips when the runner has no display |
| Playwright / desktop artifact uploads | Soft-fail (`continue-on-error`) when GitHub artifact quota is exhausted |
| `publish-server-image.yml` (PR paths) | Docker image validation for infra changes |
| `mobile Android screenshots` | Manual `workflow_dispatch` only |
| `nightly verification` | Scheduled visual regression |
| `manual topology verification` | Manual smoke |
| `release-desktop.yml` | Tag-driven release pipeline |
| `publish-playwright-report.yml` | Report publishing helper |
## Autopilot auto-merge
Workflow: `.github/workflows/autopilot-auto-merge.yml` (informational — **not** a required check)
1. Open a pull request from an Autopilot/cloud agent.
2. Add label **`autopilot`** or **`automerge`**.
3. Wait until **Product CI** is green on the head commit.
4. The workflow runs `gh pr merge --auto --squash`. GitHub merges when branch protection is satisfied (required checks green, reviews if configured).
### Dry-run mode
Set repository variable `AUTOPILOT_MERGE_DRY_RUN` to `true` to log the merge command without enabling auto-merge.
### Optional secret: `AUTOPILOT_MERGE_TOKEN`
Most repositories can rely on the built-in `GITHUB_TOKEN` (`pull-requests: write`).
Add a fine-grained PAT or GitHub App installation token as **`AUTOPILOT_MERGE_TOKEN`** when auto-merge is rejected because branch protection requires a human actor or bypass permission the default token lacks.
Minimum scopes:
- Pull requests: read and write
- Contents: read (if merge commits need it under your rules)
After adding the secret, remove `AUTOPILOT_MERGE_DRY_RUN` or set it to `false`.
## One-time branch protection checklist (maintainer)
1. Settings → Branches → `main` → Require status checks before merging.
2. Search for **Product CI** and select only that check.
3. Remove **macOS setup screenshot**, artifact-only jobs, and other infra workflows from required checks if they were added earlier.
4. Enable **Allow auto-merge** if Autopilot should merge without manual clicking.