feat(view): build pins #6

Merged
jmoran merged 9 commits from feat/build-pins into feat/dev-forge 2026-10-24 14:57:19 +00:00
Owner

Build pins: mark a commit as a build worth keeping, see the pins as a lineage, and optionally move the project demo to it.

What it is

A pin is a git ref, refs/builds/<label>, holding an annotated tag: the commit, who pinned it and when, a note, and two trailers (Parent: when you name one, Source: for the pull, branch or commit it came from). Git is the whole record. Pinning runs no check and wakes no agent.

The project demo is a third app environment beside production and previews. It serves one commit at <slug>--demo.<domain>, with a copy of production's data, from the ref refs/demo. No ref, no demo. A push cannot move refs/demo; only the forge does.

How to use it

  1. On Branches, press Pin build on a branch row, or Pin a build in the Builds card. On a pull request, press Pin build in its header.
  2. The form fills the commit and source, and offers the next label (v1 then v2, 2a then 2b).
  3. Add a note. Leave Parent on Automatic, or pick a pin to hang it under.
  4. On an app, tick "Update the project demo to this build" to deploy the demo at that commit. The pin stands even if the demo does not move.

The Builds card on Branches draws every pin as a tree. A pin hangs under the parent you named, else under the nearest pin in its history (the ancestor pin that contains the most other pins). A fork's first pins hang under its parent repository's nearest pin, marked owner/name:label. The branch graph marks pinned commits, and the pin the demo serves carries a demo badge that links to it.

API

  • GET /api/v1/repos/:owner/:name/builds lists pins, newest first.
  • POST /api/v1/repos/:owner/:name/builds with { label, sha, note?, parent?, source? } pins one (rw scope).
  • PUT /api/v1/repos/:owner/:name/demo with { sha } moves the demo; DELETE clears it.

Rules

  • Writers pin. Readers and stranger forms are refused. Mirrors refuse: pin in a fork.
  • Labels are letters, digits, dot, dash and underscore, up to 40. Taken labels and non-commits are refused.
  • Setting the demo needs a verified email, and agents are refused.
  • demo is no longer a valid app slug, so <slug>--demo reads one way.

Tests

New test/build-pins.test.ts and test/apps-demo.test.ts, both in the gate. Every gate file on this branch: 2312 pass, 4 fail; those four fail on main too (claim link host, outside spend, board, New forge door).

Stacked on feat/dev-forge.

Build pins: mark a commit as a build worth keeping, see the pins as a lineage, and optionally move the project demo to it. ## What it is A pin is a git ref, `refs/builds/<label>`, holding an annotated tag: the commit, who pinned it and when, a note, and two trailers (`Parent:` when you name one, `Source:` for the pull, branch or commit it came from). Git is the whole record. Pinning runs no check and wakes no agent. The project demo is a third app environment beside production and previews. It serves one commit at `<slug>--demo.<domain>`, with a copy of production's data, from the ref `refs/demo`. No ref, no demo. A push cannot move `refs/demo`; only the forge does. ## How to use it 1. On Branches, press Pin build on a branch row, or Pin a build in the Builds card. On a pull request, press Pin build in its header. 2. The form fills the commit and source, and offers the next label (v1 then v2, 2a then 2b). 3. Add a note. Leave Parent on Automatic, or pick a pin to hang it under. 4. On an app, tick "Update the project demo to this build" to deploy the demo at that commit. The pin stands even if the demo does not move. The Builds card on Branches draws every pin as a tree. A pin hangs under the parent you named, else under the nearest pin in its history (the ancestor pin that contains the most other pins). A fork's first pins hang under its parent repository's nearest pin, marked `owner/name:label`. The branch graph marks pinned commits, and the pin the demo serves carries a demo badge that links to it. ## API - `GET /api/v1/repos/:owner/:name/builds` lists pins, newest first. - `POST /api/v1/repos/:owner/:name/builds` with `{ label, sha, note?, parent?, source? }` pins one (rw scope). - `PUT /api/v1/repos/:owner/:name/demo` with `{ sha }` moves the demo; `DELETE` clears it. ## Rules - Writers pin. Readers and stranger forms are refused. Mirrors refuse: pin in a fork. - Labels are letters, digits, dot, dash and underscore, up to 40. Taken labels and non-commits are refused. - Setting the demo needs a verified email, and agents are refused. - `demo` is no longer a valid app slug, so `<slug>--demo` reads one way. ## Tests New `test/build-pins.test.ts` and `test/apps-demo.test.ts`, both in the gate. Every gate file on this branch: 2312 pass, 4 fail; those four fail on main too (claim link host, outside spend, board, New forge door). Stacked on `feat/dev-forge`.
A writer pins a commit under refs/builds/<label>: an annotated tag with
a note and Parent and Source trailers. No check runs and no agent wakes.
Branches leads with a Builds card: each pin under its named parent, else
under the nearest pin in its history, and a fork's first pins under its
parent repository's. Pin build sits on each branch row and on a pull
request's head; the branch graph marks pinned commits.
A fork's first pin hangs from the nearest of its parent repository's pins
in its history, by the same rule as inside one repository.
An app's demo runs one commit at <slug>--demo with a copy of production's
data. The runtime rebuilds it from refs/demo on boot, lists it after
production in its status, and every page that names an environment says
demo. The slug demo is reserved so <theirs>--demo stays unambiguous.
setDemo moves refs/demo under a lease to a commit a verified writer chose,
announces app.demo and deploys the demo; clearDemo deletes the ref and
tears the environment down. A mirror refuses, a non-commit is refused, an
agent may not pin, and the pre-receive hook keeps refs/demo out of reach of
a push. PUT and DELETE /api/v1/repos/:owner/:name/demo call them.
On an app, Update the project demo to this build calls setDemo after the
pin lands; the pin stands even when the demo does not move. The Builds
card marks the demo's pin and links its address.
jmoran merged commit 81a8db81ef into feat/dev-forge 2026-10-24 14:57:19 +00:00
jmoran deleted branch feat/build-pins 2026-10-24 14:57:20 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jmoran/forge-jay!6
No description provided.