ci: gate pull requests into main on server and client checks #1

Merged
whitlocktech merged 1 commits from ci/add-pr-checks into main 2026-08-10 08:32:24 +00:00
Member

The repo's first PR, and the last piece of its Phase 0 bootstrap (website/MODULE_SYSTEM.md §2.7). The initial commit was pushed straight to main because an empty repo cannot take a pull request; everything after it goes through one, starting here.

What it does

Mirrors website's pr-checks.yml. This module is two npm packages shaped like that repo's server/ and client/, and it is loaded into that repo's process, so it is checked the same way: Node 20, npm ci (not install — it also proves the lockfile is in sync), tests, and the client build, with the same concurrency-cancel and the same PR Checks / * status pattern.

The package guard

There is no module code here yet — Phase 1 settles the API contract and Phase 3 is what extracts the UO half of website/ into this repo — so each half's gates are conditional on its package.json existing. Before the code lands the jobs report green with a notice saying exactly why; the moment a package.json appears they arm themselves with no edit to this file.

That is the same guard the installer repo ran through its own planning phase, and it beats both alternatives: leaving the repo ungated for however long Phases 1–2 take, or landing a workflow that red-Xes every governance and docs PR until there is code to check.

Landing it now also gets the status contexts to report once, which is what makes them selectable when the main branch-protection rule is configured. Running is not enforcing — that rule is a separate, one-time step in the Gitea UI, and the header comment records it.

Not here yet, deliberately

Three workflows have nothing to act on until Phase 3, so each lands with the code it checks:

  • the release workflow that publishes module-uo-<version>.tar.gz and its sha256 manifest;
  • the zero-internal-imports check (a module reaches core only through the documented API surface — enforced in CI, not by review);
  • the module's own frozen route manifest, which it generates once it owns routes.

Testing

Not runnable locally — a Gitea Actions workflow only proves itself by running. The guard logic is a plain [ -f … ] test, and both run: blocks are free of ${{ }} tokens, which is the thing that has silently skipped steps in this org's workflows before.


  • AI-assisted: written with Claude Code (Claude Opus 5)

🤖 Generated with Claude Code

https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8

The repo's first PR, and the last piece of its Phase 0 bootstrap ([`website/MODULE_SYSTEM.md` §2.7](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/website/MODULE_SYSTEM.md)). The initial commit was pushed straight to `main` because an empty repo cannot take a pull request; everything after it goes through one, starting here. ## What it does Mirrors [`website`'s `pr-checks.yml`](https://gitea.whitlocktech.com/RunicGateway/website/src/branch/main/.gitea/workflows/pr-checks.yml). This module is two npm packages shaped like that repo's `server/` and `client/`, and it is loaded into that repo's process, so it is checked the same way: Node 20, `npm ci` (not `install` — it also proves the lockfile is in sync), tests, and the client build, with the same concurrency-cancel and the same `PR Checks / *` status pattern. ## The package guard There is no module code here yet — Phase 1 settles the API contract and Phase 3 is what extracts the UO half of `website/` into this repo — so each half's gates are conditional on its `package.json` existing. Before the code lands the jobs report green with a notice saying exactly why; the moment a `package.json` appears they arm themselves with no edit to this file. That is the same guard the installer repo ran through its own planning phase, and it beats both alternatives: leaving the repo ungated for however long Phases 1–2 take, or landing a workflow that red-Xes every governance and docs PR until there is code to check. Landing it now also gets the status contexts to report once, which is what makes them selectable when the `main` branch-protection rule is configured. Running is not enforcing — that rule is a separate, one-time step in the Gitea UI, and the header comment records it. ## Not here yet, deliberately Three workflows have nothing to act on until Phase 3, so each lands with the code it checks: - the release workflow that publishes `module-uo-<version>.tar.gz` and its `sha256` manifest; - the zero-internal-imports check (a module reaches core only through the documented API surface — enforced in CI, not by review); - the module's own frozen route manifest, which it generates once it owns routes. ## Testing Not runnable locally — a Gitea Actions workflow only proves itself by running. The guard logic is a plain `[ -f … ]` test, and both `run:` blocks are free of `${{ }}` tokens, which is the thing that has silently skipped steps in this org's workflows before. --- - [x] AI-assisted: written with Claude Code (Claude Opus 5) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018ocYxQWk3EhZe5gWRJXFU8
wtclaude added 1 commit 2026-08-10 07:40:45 +00:00
ci(module-uo): gate pull requests into main on server and client checks
All checks were successful
PR Checks / server-tests (pull_request) Successful in 4s
PR Checks / client-build (pull_request) Successful in 3s
4a0d8f0873
Mirrors RunicGateway/website's pr-checks.yml, since this module is two npm
packages shaped like that repo's server/ and client/ and is loaded into that
repo's process: same Node 20, same npm ci + test + build, same concurrency
cancel and the same `PR Checks / *` status pattern for branch protection.

The repo has no module code yet — the API contract is settled in Phase 1 and
Phase 3 is what extracts the UO half of website/ into here — so each half's
gates are conditional on its package.json existing. Before the code lands the
jobs report green with a notice explaining why; the moment a package.json
appears they arm themselves with no edit to this file. That is the same guard
the installer repo used through its own planning phase, and it beats both
alternatives: leaving the repo ungated, or red-Xing every governance PR.

Landing it now also gets the status contexts reported once, which is what makes
them selectable when the `main` branch-protection rule is configured.

Deliberately not here yet, because there is nothing for them to act on until
Phase 3: the release workflow that publishes module-uo-<version>.tar.gz and its
sha256, the zero-internal-imports check, and the module's own frozen route
manifest. Each lands with the code it checks.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 439ca04773 into main 2026-08-10 08:32:24 +00:00
whitlocktech deleted branch ci/add-pr-checks 2026-08-10 08:32:25 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Module-uo#1
No description provided.