# @pdsjs/git-ci ## 0.5.2 ### Patch Changes - Updated dependencies - @pdsjs/core@2.5.2 - @pdsjs/git@0.1.5 ## 0.5.1 ### Patch Changes - Updated dependencies [542c4dc] - @pdsjs/core@2.5.1 - @pdsjs/git@0.1.4 ## 0.5.0 ### Minor Changes - 861663f: Startup no longer adopts a ref whose latest check is still `running`. A run cut off mid-flight leaves its check record half written, and adopting the ref told the daemon that ref was handled, so nothing ever finished the record and the check read `running` for good. The runner's own check records outlive its state file, so startup reads them: a ref left mid-run stays unadopted and runs again on the next event for that repository. ### Patch Changes - 04b15d0: The Jetstream re-exports are gone. `subscribeJetstream`, `jetstreamUrl` and `jetstreamWrite` were reachable from the package root, and nothing consumed them: the watch loop reads the repository's own firehose. `@pdsjs/appview` leaves the dependency list with them. - 0466ca6: `@pdsjs/git-ci` exports its record-key module under `./spec`. A reader that wants the latest check for one ref computes the key rather than paging the runner's history, and the derivation has to match the runner's exactly. The root entry pulls in the checkout, the daemon and the firehose reader, so a browser could not import it; `./spec` holds the key functions alone. - c3c4caa: A repository's config record carries two DID lists, `collaborators` and `reviewers`, read by `collaboratorsOf` and `reviewersOf`. A collaborator holds their own copy of the repository under the same name, and a reader that knows where to look can gather the open branches across every copy. atproto has no reverse index, so a copy names no upstream and an upstream finds no copy without being told. Neither list grants anything: nobody can write into somebody else's repo whatever they say. A pull request is a branch in one account's copy, identified by that account's DID and the ref name. The pair survives amend, rebase, force-push and a commit added on top, so a check or a review written against one version still names the work after any of them. A branch canonical main reaches is merged and one it does not is open, both read from the graph rather than from a stored state. The `dev.pdsjs.git.pull` lexicon describes what the author says about their own branch: a title, an optional `status` of draft or withdrawn, and a note. It is in the author's own repo and nothing is written to the repository it names. A push with no such record is still a pull request, titled by its tip commit. `dev.pdsjs.git.pulls` is the index a runner publishes of the records it has seen, under `pullsKey`, because atproto has no reverse index and the owner has no inbound address. The config may name several runners (`runnersOf`), and a reader unions their indexes, so one runner omitting a pull request does not bury it. The `dev.pdsjs.git.review` lexicon describes a verdict on one version of one pull request, published in the reviewer's own repo. `author` and `ref` name the pull request and `sha` names the version read, so a review of an earlier version still reads against the work and still says which version it answered. The verdicts are `approve`, `changesRequested` and `comment`. The browser reader gains `changedPaths`, `readRange` and `listRange`, which answer for two commits what `readCommit` and `listCommits` answer for one and for a ref. A pull request written over a dozen commits is one thing to read, and the paths it touches are one tree walk from its merge base rather than a diff per commit. The repository browser reads all of it on a pull request list. The model, and what is still unbuilt, is in `docs/plans/2026-08-24-pull-requests.md`. - 83083a5: Issues, as the model's one primitive: a `dev.pdsjs.git.issue` record in its filer's own repo names the repository, a record with `replyTo` answers one, and the repository owner's record with a `disposition` is what a reader shows as the issue's state. Nobody closes an issue; the owner states resolved, declined or reopened, attributed, and disagreement sits beside it. The latest word wins, so each of the three is answered by another one and none of them shuts a thread. The repository's own server lists the statements, reading the listed voices from their own servers and finding anybody else through its discovery index, and the repository browser lists threads, files, and replies with the session the reviews use. A thread reads its state as a pill, and a disposition reads as the event it is rather than as another comment. The list holds an Open tab and a Closed one, each a real address, and closed holds both of the words the owner settles a thread with, so the mark on a row still says which. Both lists draw through one row, so a size moves in one place. - 32db640: The pull request and issue lists are served by the repository's own server: `dev.pdsjs.git.listPulls` and `dev.pdsjs.git.listIssues`. The owner's copy is read through the server's browser, every collaborator the config names through a browser over their server, and anybody else through a discovery port that answers which records about the repository exist in accounts the config does not name. The first provider is Constellation, a hosted reverse index over the public firehose, asked once per collection on the path `subject.uri`; a deployment may pass its own port to `createGitExtension`, or null to read the listed voices alone. Open and merged are computed from the object graph on every read and stored nowhere. The repository browser asks its server for the two lists, where it read five servers itself. The runner is CI only. Its pull request index, issue index and push log (`dev.pdsjs.git.pulls`, `.issues`, `.versions`) and `PDSJS_CI_PULL_SOURCES` are gone, since the discovery port answers what the indexes did and the version numbers the push log fed left the interface. A check or comment written against a commit the branch has since replaced still reads as outdated, from the tips the checks and reviews themselves name. A push into a fork writes `upstream` on the pushed record, the repository record the copy was taken from, when the checkout's remotes say which that is. The repository's server asks its discovery index which copies name it and reads every branch of each, so a bare push into a fork is listed before its author has written a pull request record. An author still writes their own words from the page: a title, a note, and open, draft or withdrawn, as a `dev.pdsjs.git.pull` record in their own repo. The form appears for the account holding the branch and nobody else. - a56be28: A pull request is identified by the account whose copy holds the work and the ref that holds it, in place of the `Change-Id:` trailer. The pair costs nothing to compute, needs no hook in the author's push path, and survives the one case the trailer did not: a commit added on top of a branch gave the tip a new trailer, which detached every check and review keyed to the old one. `git-remote-atproto install-hook` and the `changeId` fields on the check, review and index records go with it. A `dev.pdsjs.git.review` record names `author` and `ref` instead, and its verdicts are `approve`, `changesRequested` and `comment`. A merged branch is read from the merge that brought it in: the merge commit's second parent is the tip merged and its first parents are main's trunk, so the branch's earliest commit outside that trunk is where the work began. A branch fast-forwarded into main leaves no such commit and opens at its tip alone. The vocabulary follows the concept where the concept matches. `contributors` becomes `collaborators` in the config record (`collaboratorsOf`), and `dev.pdsjs.git.offer` becomes `dev.pdsjs.git.pull`, which gains a `title`. Work from an account the repository has not named sorts into the one list, marked as coming from a fork. The repository browser serves the list at `//pulls`, with open and merged tabs, and one pull request at `//pull//` with its diffs under `/files`. None of these lexicons is published, so there is nothing to migrate. - f27dcf7: A git repository's record key is minted at creation, and its name is an ordinary field. The name was the key, so it was the identity, and renaming a repository changed its AT-URI: every review, pull request, issue and check naming it, every fork naming it upstream, and the reverse index all pointed at an address that no longer existed. The rule is that the name is an address and the key is an identity. Every public surface still takes a name, `resolveRepo` is the one place that turns one into a key, and everything below it works in keys. `dev.pdsjs.git.repo` already declared `key: 'any'` and already required `name`, so no record's value changes, only its key. `dev.pdsjs.git.renameRepo` writes that one field. A repository in a space keeps the name it has: the space is what an address resolves to and is keyed by that name. The config record moves to the repository's key, which the write guard already assumed when it joins the two. A collaborator's copy is found by the name the two copies share rather than by assuming their key matches. Pull request keys, check request keys and latest-check keys all derive from the repository's own key, so a rename leaves them where they are. `@pdsjs/git-ci` reads a repository's name from its record rather than from the firehose write's key, which a minted key would have matched against nothing. Its two key derivations are duplicated in the server and must agree, so the runner is deployed with it. Secret grants keep naming repositories the way a person writes them and resolve to a record key at startup, where a grant naming a repository the account does not hold is reported. Existing repositories are moved by `scripts/migrate-git-repo-keys.mjs`. The resolver finds an unmigrated repository unchanged, so a deploy can precede the migration. See `docs/plans/2026-09-04-stable-repo-keys.md`. - Updated dependencies [d66fcff] - Updated dependencies [05a11b4] - Updated dependencies [f79dd82] - Updated dependencies [c68858b] - Updated dependencies [04b15d0] - Updated dependencies [288063a] - Updated dependencies [c3c4caa] - Updated dependencies [bcb5758] - Updated dependencies [e0b38cd] - Updated dependencies [4fb8f23] - Updated dependencies [1cf113d] - Updated dependencies [04b15d0] - Updated dependencies [c4af198] - Updated dependencies [f777a2c] - Updated dependencies [a981627] - Updated dependencies [3febe1c] - Updated dependencies [ac5c8eb] - Updated dependencies [00bd461] - Updated dependencies [83083a5] - Updated dependencies [2c68bdc] - Updated dependencies [fe7ffe0] - Updated dependencies [211c7c8] - Updated dependencies [6cf84d5] - Updated dependencies [35f794f] - Updated dependencies [522071f] - Updated dependencies [32db640] - Updated dependencies [04b15d0] - Updated dependencies [cc4577b] - Updated dependencies [cc4577b] - Updated dependencies [f5aae7c] - Updated dependencies [cc4577b] - Updated dependencies [fe3c9ac] - Updated dependencies [b99acf8] - Updated dependencies [c1ec3d6] - Updated dependencies [04b15d0] - Updated dependencies [7c06024] - Updated dependencies [6935a55] - Updated dependencies [15c69af] - Updated dependencies [a56be28] - Updated dependencies [673ec05] - Updated dependencies [74819af] - Updated dependencies [4dfdbfa] - Updated dependencies [04b15d0] - Updated dependencies [aeb61f9] - Updated dependencies [04b15d0] - Updated dependencies [04b15d0] - Updated dependencies [f27dcf7] - Updated dependencies [c9e3550] - Updated dependencies [c01859b] - Updated dependencies [41df38b] - Updated dependencies [411b47b] - Updated dependencies [ca47f96] - Updated dependencies [861663f] - Updated dependencies [617df4a] - Updated dependencies [154e7d7] - Updated dependencies [10c91f6] - Updated dependencies [0e1bf66] - Updated dependencies [77eb9db] - Updated dependencies [76f5187] - Updated dependencies [b51250e] - Updated dependencies [799286b] - Updated dependencies [4adc49e] - Updated dependencies [e83838c] - Updated dependencies [9149663] - Updated dependencies [16ea1fe] - Updated dependencies [fd401a4] - Updated dependencies [93816a1] - Updated dependencies [3d475f8] - Updated dependencies [078c2df] - Updated dependencies [d5f111c] - @pdsjs/core@2.5.0 - @pdsjs/git@0.1.3 ## 0.4.0 ### Minor Changes - d307f57: The daemon reads each watched repository's refs at startup when its state file says nothing about them. Without that, a daemon whose state was lost read every ref in the record as new on the next event and started a run for each, so every tag ran its release workflow again. The first run now comes from a ref that moves after startup, which is what starting at the live head means. A repository whose record cannot be read is still watched, and its first event still runs it. - 2d0d653: The runner image carries the docker client and buildx, and the entrypoint puts the daemon's user in the group of a mounted docker socket. A deployment that mounts one can then run workflows that build, run and push container images, which previously needed a forge. The socket is the whole grant: a step commanding the host's daemon is root on that host, so mount it only where every contributor to every watched repository is trusted that far. Without the mount nothing changes and no step can reach a daemon. ### Patch Changes - Updated dependencies [d307f57] - Updated dependencies [2d0d653] - @pdsjs/core@2.4.3 ## 0.3.0 ### Minor Changes - c235e96: Workflow files may be YAML. A step is a shell script, and a block scalar carries one as written where a JSON string carries it as a single line of escaped newlines. The parser is YAML 1.2, which subsumes JSON, so existing `.json` workflows and the `.pdsjs/ci.json` fallback read unchanged. The workflows directory now reads `.yml`, `.yaml` and `.json`, and passes over anything else, so a README can sit beside the workflows it describes. ### Patch Changes - Updated dependencies [c235e96] - @pdsjs/core@2.4.2 ## 0.2.0 ### Minor Changes - fa1558c: The runner reads one workflow per file from `.pdsjs/workflows/*.json`, falling back to `.pdsjs/ci.json` when the directory is absent. Every workflow naming the moved ref runs and publishes its own check; the latest-check record holds one entry per workflow under the unchanged key, and the account checks endpoint flattens the entries, reading records from before entries existed as one entry. Workflows declare secrets by name, and the daemon grants them per repository from the file `PDSJS_CI_SECRETS` names; the runner's own credentials no longer reach any step's environment. The runner image is based on trixie so a repository under test can load prebuilt native addons that need glibc 2.38. ### Patch Changes - Updated dependencies [fa1558c] - @pdsjs/core@2.4.1 ## 0.1.1 ### Patch Changes - 4895bc1: A repository's owner can ask for a check run. The daemon listens on no port, so the request is a record: `dev.pdsjs.git.checkRequest` in the owner's own repo, which the firehose connection the daemon already holds carries to it. The record's authority is the authorisation, since only the owner can write into that repo, and the runner acts on a request only for a repository it watches. The record key is derived from the repository and the ref, so asking twice replaces the record rather than leaving one per click, and the state file remembers the version acted on so a replayed event starts no second run. `sha` is optional: without it the run takes whatever the ref points at when the daemon reads the repository record. - 0665ecc: Check record writes retry twice on a server error or a dropped connection before the run is abandoned. One transient failure on the outcome write used to leave the check `running` forever, indistinguishable from a runner that died mid-run. A client error, such as a failed swap, still throws at once. - Updated dependencies [ee6d696] - Updated dependencies [cb64c59] - Updated dependencies [54bec84] - Updated dependencies [922fb50] - Updated dependencies [68ad18f] - Updated dependencies [f716d9d] - Updated dependencies [68ad18f] - Updated dependencies [68ad18f] - Updated dependencies [ae02630] - Updated dependencies [68ad18f] - Updated dependencies [4c334b3] - Updated dependencies [86d8eb4] - Updated dependencies [6b79149] - Updated dependencies [8616855] - Updated dependencies [af8b1fd] - Updated dependencies [715c475] - @pdsjs/core@2.4.0 - @pdsjs/git@0.1.2