Skip to content

ci: gate pull requests on the end-to-end systemtest suite - #142

Open
Janne6565 wants to merge 3 commits into
mainfrom
ci/systemtest-pr-gate
Open

ci: gate pull requests on the end-to-end systemtest suite#142
Janne6565 wants to merge 3 commits into
mainfrom
ci/systemtest-pr-gate

Conversation

@Janne6565

Copy link
Copy Markdown
Member

Builds this PR's frontend image, installs a real Cosy from scratch with it, and runs the @core systemtest suite through the actual UI.

Depends on Magenta-Mause/Cosy-Systemtest#5, which adds the shared actions this workflow calls. Both branches are named ci/systemtest-pr-gate, so this PR's own run resolves that branch and exercises the new code — see the job summary for what it picked.

Rationale and design: docs/pr-gate.md.

How it works

The image is built locally and never pushed. Cosy's docker-compose.yml sets no pull_policy and install_cosy.sh runs a plain docker compose up -d, so compose's default missing policy uses a locally tagged image without contacting any registry. Hence: no packages: write, nothing left behind in ghcr, and fork PRs work (they get no secrets). The shared action asserts this rather than assuming it.

It also resolves and builds a matching cosy-backend branch when one exists. Cosy features are routinely cross-cutting — feat/custom-webhook-format exists in both repos right now — so testing a frontend PR against a released backend goes red for a reason the author cannot fix.

Dockerfile fix, and why it belongs here

28a2ce6 makes the image build from the committed lockfile. It previously copied only package.json and ran a bare bun install, so every build re-resolved caret ranges and two builds of the same commit could ship different dependency versions — while lint/test/type-check already used --frozen-lockfile.

That is a prerequisite, not a drive-by: the gate installs this image, and a non-reproducible image means an unchanged PR can flip red overnight on a dependency it never touched. That is exactly the kind of flake that gets a required check switched off.

The same commit drops the /temp/prod install. Nothing consumed it — builder takes /temp/dev/node_modules and the release stage is nginx serving the static dist — so it was a full dependency install for an artifact never read.

Note on selectors

docs/test-architecture.md in the systemtest repo says page objects track the released frontend, not main. The gate is the deliberate exception: a frontend PR installs an image built from that PR, so its page objects run against unreleased UI. That is the point — a selector break is caught here rather than at 02:30. When a change needs a new data-testid, put the systemtest change on a matching branch and the gate will resolve and run them together.

Scope and escape hatches

@core (6 spec files + the teardown assertion) by default; the full suite via the systemtest:full label. systemtest-skip skips the gate. A sibling can be pinned from the PR body with Backend-Ref: / Systemtest-Ref: — note that editing a PR body fires no workflow event, so push a commit after adding one.

The required check will be systemtest-gate, not systemtest: a skipped job reports nothing, and a required check that never reports blocks a PR forever.

🤖 Generated with Claude Code

Janne6565 and others added 2 commits August 6, 2026 01:38
The image copied only package.json and ran a bare `bun install`, so every build
re-resolved caret ranges and two builds of the same commit could ship different
dependency versions. lint/test/type-check already use --frozen-lockfile, so the
image and the checks could disagree.

That matters more now: the systemtest PR gate installs this image, and a
non-reproducible image means an unchanged pull request can flip red overnight on
a dependency it never touched.

Also drops the /temp/prod install. Nothing consumed it — `builder` takes
/temp/dev/node_modules and the release stage is nginx serving the static dist —
so it was a full dependency install for an artifact that was never read.

Co-Authored-By: Claude <noreply@anthropic.com>
Builds this PR's frontend image locally, installs a real Cosy from scratch with
it, and runs the @core suite through the actual UI. Cosy's compose file sets no
pull_policy, so a locally tagged image is used without any registry push — no
packages: write, nothing left in ghcr, and fork PRs work.

Also resolves and builds a matching cosy-backend branch when one exists, because
Cosy features are routinely cross-cutting and a frontend PR tested against a
released backend goes red for a reason its author cannot fix.

The required check is `systemtest-gate`, not `systemtest`: a skipped job reports
nothing and a required check that never reports blocks the PR forever. The gate
job is green on success or an allowlisted skip, red otherwise.

See docs/pr-gate.md in Magenta-Mause/Cosy-Systemtest.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 5, 2026 23:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a required end-to-end PR gate for Cosy-Frontend by building the PR’s frontend Docker image, installing a full Cosy instance with it, and running the @core UI-driven systemtest suite from Magenta-Mause/Cosy-Systemtest. It also makes the frontend image build reproducible by ensuring the committed Bun lockfile is used during Docker builds.

Changes:

  • Make Docker builds deterministic by copying bun.lock and using bun install --frozen-lockfile (and removing an unused production install stage).
  • Add a new systemtest workflow that builds frontend (and optionally matching backend) images locally, installs Cosy, runs @core systemtests, and uploads reports.
  • Add a systemtest-gate job intended for branch rulesets so the required check still reports even when the main systemtest job is skipped.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
Dockerfile Ensures reproducible dependency resolution in image builds via committed bun.lock + --frozen-lockfile.
.github/workflows/systemtest.yml Adds the PR-gating end-to-end systemtest workflow and the systemtest-gate reporting job.
Suppressed comments (2)

.github/workflows/systemtest.yml:70

  • FULL_SUITE reads PR labels, but on workflow_dispatch there is no pull_request payload. Guard the expression so manual runs default to @core cleanly.
          FULL_SUITE: ${{ contains(github.event.pull_request.labels.*.name, 'systemtest:full') }}

.github/workflows/systemtest.yml:280

  • systemtest-gate uses PR label context to decide whether a skipped run is allowlisted, but workflow_dispatch runs have no pull_request payload. Guard on event type so manual runs don't fail expression evaluation.
          SKIP_LABELLED: ${{ contains(github.event.pull_request.labels.*.name, 'systemtest-skip') }}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to +44
permissions:
contents: read

# Generous: a cold backend image build (rust cdylib + maven) plus a full install
# and the @core suite. See the wall-clock table in docs/pr-gate.md.
timeout-minutes: 75
if: ${{ !contains(github.event.pull_request.labels.*.name, 'systemtest-skip') }}
Adds the channel/report-published inputs and a push step so this gate's runs show
up in the dashboard's PR section. continue-on-error: telemetry must never decide
whether a pull request can merge — the verdict is the allowlist assertion above.

Skips itself with one INFO line when OTEL_INGEST_USER / OTEL_INGEST_PASSWORD are
absent, which is always the case on a fork PR and is the case in this repo until
those secrets are added. Nothing breaks; the runs simply do not appear.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants