ci: build, test, and run Signage inside a pinned Ekklesia on every change #7

Merged
Zayin_Admin merged 1 commits from ci/gitea-actions into main 2026-10-06 00:38:50 +00:00
Member

ci: build, test, and run Signage inside a pinned Ekklesia on every change

Step 1 of module CI. Signage had none: its tests passed while three defects shipped that appear only inside Ekklesia, in a real browser (#4, #5, #6). Step 2, a platform-published harness every module uses, is proposed in Ekklesia ADR 0047 (Ekklesia #59). Signage switches to it once it exists.

Jobs, for branch protection

Workflow CI (.gitea/workflows/ci.yml). Gitea reports each job as CI / <job> (pull_request) and CI / <job> (push).

Job What it proves
lint biome lint
typecheck the server, browser, and browser-test projects
test unit, browser, and display contract tests
build the platform's own gates against exactly this module set (boundary rules, module manifest, migrations), then the build
integration needs test and build. Builds the deployment image with the platform's Dockerfile, then runs the platform's split-topology smoke against it: pairs a kiosk display, restarts it on the same profile, and runs ci/display-scenarios (120 s watches)

How Signage gets a platform

  • ci/platform.env pins one platform commit.
  • ci/assemble.sh fetches the platform's main and refuses a pinned commit that is not on main, so CI only runs reviewed platform code. It then checks out by SHA and copies this checkout into modules/signage (tracked files only).
  • ci/pnpm-lock.yaml is the assembled workspace's lockfile, and every job installs with --frozen-lockfile. ci/update-lock.sh regenerates it with the platform's pinned pnpm. This is the instance repository's pattern.

Trust rules, as in the platform

  • actions pinned by full SHA: the platform's own checkout and setup-node pins;
  • persist-credentials: false on every checkout;
  • no secrets, and no pull_request_target;
  • permissions: contents: read, declared; the workflow header notes Gitea 1.24 ignores it.

⚠ It goes green only after Ekklesia #56 merges

  • The pinned commit f50e8f4 is the head of Ekklesia #56, which adds the display-device scenarios this job runs.
  • Until #56 merges, ci/assemble.sh fails with "the pinned platform commit … is not on the platform's main". That is the check working.
  • Ekklesia's default merge style is a merge commit, so after #56 merges, f50e8f4 is on main and this pin is valid without a change. If #56 is squashed instead, I'll re-pin to the squash commit.

Scenario list

ci/display-scenarios starts with two-pages, which passes on today's Signage. Pairing and a clean restart always run first. Each fix PR adds the scenario it makes pass:

  • #5 adds session-blip and stream-failure;
  • #6 adds stream-recycle.

Verified locally

In a workspace assembled exactly as CI does (Ekklesia f50e8f4 + this branch):

  • the frozen install passes;
  • lint, typecheck and test (198) pass;
  • the platform gates pass;
  • the build passes.

The harness, run against Signage with #4–#6 merged locally:

  • heartbeats 200;
  • the roster shows the kiosk offlineReady=true, cachedAssets=3;
  • pairing and restart pass. The full scenario run is still going.

🤖 Generated with Claude Code

## ci: build, test, and run Signage inside a pinned Ekklesia on every change Step 1 of module CI. Signage had none: its tests passed while three defects shipped that appear only inside Ekklesia, in a real browser (#4, #5, #6). Step 2, a platform-published harness every module uses, is proposed in Ekklesia ADR 0047 (Ekklesia #59). Signage switches to it once it exists. ### Jobs, for branch protection Workflow `CI` (`.gitea/workflows/ci.yml`). Gitea reports each job as `CI / <job> (pull_request)` and `CI / <job> (push)`. | Job | What it proves | |---|---| | `lint` | `biome lint` | | `typecheck` | the server, browser, and browser-test projects | | `test` | unit, browser, and display contract tests | | `build` | the platform's own gates against exactly this module set (boundary rules, module manifest, migrations), then the build | | `integration` | needs `test` and `build`. Builds the deployment image with the platform's Dockerfile, then runs the platform's split-topology smoke against it: pairs a kiosk display, restarts it on the same profile, and runs `ci/display-scenarios` (120 s watches) | ### How Signage gets a platform - `ci/platform.env` pins **one platform commit**. - `ci/assemble.sh` fetches the platform's `main` and **refuses a pinned commit that is not on `main`**, so CI only runs reviewed platform code. It then checks out by SHA and copies this checkout into `modules/signage` (tracked files only). - `ci/pnpm-lock.yaml` is the assembled workspace's lockfile, and every job installs with `--frozen-lockfile`. `ci/update-lock.sh` regenerates it with the platform's pinned pnpm. This is the instance repository's pattern. ### Trust rules, as in the platform - actions pinned by full SHA: the platform's own `checkout` and `setup-node` pins; - `persist-credentials: false` on every checkout; - no secrets, and no `pull_request_target`; - `permissions: contents: read`, declared; the workflow header notes Gitea 1.24 ignores it. ### ⚠ It goes green only after Ekklesia #56 merges - The pinned commit `f50e8f4` is the head of Ekklesia #56, which adds the display-device scenarios this job runs. - Until #56 merges, `ci/assemble.sh` fails with "the pinned platform commit … is not on the platform's main". That is the check working. - Ekklesia's default merge style is a merge commit, so after #56 merges, `f50e8f4` is on `main` and this pin is valid **without a change**. If #56 is squashed instead, I'll re-pin to the squash commit. ### Scenario list `ci/display-scenarios` starts with `two-pages`, which passes on today's Signage. Pairing and a clean restart always run first. Each fix PR adds the scenario it makes pass: - #5 adds `session-blip` and `stream-failure`; - #6 adds `stream-recycle`. ### Verified locally In a workspace assembled exactly as CI does (Ekklesia `f50e8f4` + this branch): - the frozen install passes; - `lint`, `typecheck` and `test` (198) pass; - the platform gates pass; - the build passes. The harness, run against Signage with #4–#6 merged locally: - heartbeats `200`; - the roster shows the kiosk `offlineReady=true, cachedAssets=3`; - pairing and restart pass. The full scenario run is still going. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ekklesia-bot added 1 commit 2026-10-06 00:12:11 +00:00
ci: build, test, and run Signage inside a pinned Ekklesia on every change
CI / lint (pull_request) Successful in 12s
CI / typecheck (pull_request) Successful in 15s
CI / test (pull_request) Successful in 19s
CI / build (pull_request) Successful in 18s
CI / integration (pull_request) Successful in 3m34s
3073baeb8b
Signage had no CI. Its tests passed while three defects shipped that
appear only inside Ekklesia, in a real browser. Every job now assembles
Signage into a pinned platform commit, as an instance does, and
installs that workspace with --frozen-lockfile:
- lint, typecheck, test: Signage's own checks;
- build: the platform's gates against exactly this module set (boundary
  rules, module manifest, migrations), then the build;
- integration: the deployment image from the platform's Dockerfile,
  then the platform's split-topology smoke. It pairs a kiosk display,
  restarts it on the same profile, and runs the scenarios in
  ci/display-scenarios.

The supporting files:
- ci/platform.env pins one platform commit. ci/assemble.sh fetches the
  platform's main and refuses a pinned commit that is not on it, so CI
  only runs reviewed platform code.
- ci/pnpm-lock.yaml is the assembled workspace's lockfile, regenerated
  with ci/update-lock.sh.

Same trust rules as the platform: actions pinned by SHA,
persist-credentials false, no secrets, no pull_request_target.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Zayin_Admin merged commit 914034dda0 into main 2026-10-06 00:38:50 +00:00
Zayin_Admin deleted branch ci/gitea-actions 2026-10-06 00:38:50 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Signage#7