colophon apply¶
Description¶
Carry what a commit asserted to the forge object it names
Read the commits a push added, take the Updates: trailers they carry, and
apply each to the issue, merge request or wiki page it names. This is the one
verb that runs when a merge lands rather than when a release is cut, so a
record outside the repository can be told what became of the work.
Nothing is inferred. A commit says what happened to a record or the record is
left alone, for the reason a Release-As: trailer exists: a tool cannot know
which merge finished a piece of work, and a record it marks done too early is
worse than one left stale, because a wrong record is trusted.
Usage¶
Run colophon apply --help for the authoritative, always-current flag set.
Flags¶
| Flag | Description | Default |
|---|---|---|
--from |
Commit the push started from. Empty, or the all-zero SHA a forge sends for a branch's first push, means the tip alone. | empty |
--to |
Commit the push ended at | HEAD |
--remote |
Git remote to read | origin |
--forge |
Forge the remote is on when its host does not say: gitlab, github or gitea. Same as forge in .colophon.yaml; both must agree when given. |
empty |
-C, --repo |
Path to the git repository | . |
The span¶
--from and --to are the commits a push added, which the CI environment
knows: on GitLab they are CI_COMMIT_BEFORE_SHA and CI_COMMIT_SHA.
This is deliberately not the span the release verbs use. plan and propose
ask what has landed since the last release; a run that acts on what a person
wrote must see exactly what this push carried, or a repository releasing
weekly would act on the whole week again on every merge.
What it writes¶
| Target | What happens |
|---|---|
| issue | a comment |
| merge request | a comment |
| wiki page | one frontmatter field is set; nothing else on the page is touched |
The syntax of the trailer, its targets and its keywords are in Commit trailers and annotations.
A wiki page whose frontmatter does not carry the field a keyword names is refused rather than grown one, and a page already carrying the value is reported as unchanged and not rewritten.
Running it twice¶
Safe. Each comment is posted under an idempotency key naming the commit that asserted it and the object it was about, and the forge provider returns the existing comment rather than posting a second. A later commit saying the same thing about the same object is a second comment, because it is a second assertion.
The key defends against a retry, not against two runs racing: it is not atomic, and two concurrent pushes asserting the same thing can both post.
What each forge can do¶
Every capability is optional and separately absent. An instruction the forge cannot carry is reported and skipped; the rest still apply.
| Forge | Issue comment | Merge request comment | Wiki |
|---|---|---|---|
| GitLab | yes | yes | yes |
| GitHub | yes | yes | yes |
| Gitea | no | no | yes |
| Bitbucket | no | yes | no |
Checked at go/forge v0.25.0 and its adapters. Bitbucket Cloud has no issue
tracker; Gitea's comment capability is not implemented in its adapter yet.
Output¶
One line per instruction, then a summary when anything wants attention:
applied #13
applied cicd/wikis/specs/0079-pipeline-churn — status set to IMPLEMENTED
unchanged cicd/wikis/specs/0080-other — status is already IMPLEMENTED
skipped !45 — this forge has no comment capability for merge request
failed phpboyscout/go/forge#23 — 403 forbidden
2 of 5 needed attention. The merge stands; nothing here failed the pipeline.
Exit code¶
Zero, even when a target failed. By the time this runs the merge has happened, and a red pipeline because an annotation did not post is worse signal than a yellow one. A non-zero exit means the run could not start at all: an unreadable manifest, an unrecognised forge, or a span the repository does not carry.