Skip to content

ci: binaries on demand, from whatever branch you pick - #52

Open
donislawdev wants to merge 1 commit into
mainfrom
ci/dev-build
Open

ci: binaries on demand, from whatever branch you pick#52
donislawdev wants to merge 1 commit into
mainfrom
ci/dev-build

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

Somebody reports a bug, the fix lands on a branch, and they want to try it before there is a release. Clicking Run workflow in the Actions tab builds that branch and leaves the binaries on the run page for fourteen days.

Three owner decisions

decision why
a choice input, default cli the command line binaries cross compile to five platforms on one runner in ~2 min; the window needs three real runners and CGO. gui and both are one click away when the report is about the window
no test gate the point is speed, and the branch already has its own CI on its own pull request. The note names the commit, so anybody can go read what CI said about it
14 days, not 90 an unsigned binary should not sit for a quarter of a year behind a link somebody can pass on as if it were official

Deliberately not shaped like a release

An archive from here must not be mistakable for one.

The name carries the commit, not the version - and that is not a style choice. internal/version is a const, so it cannot be stamped at link time, and a build from a fix branch reports whatever version that branch inherited. The file name is the only place that can tell the truth about which code this is: tfg_dev-08ac79d_linux_amd64.tar.gz.

Every archive carries UNOFFICIAL-BUILD.txt saying the same in words, for whoever unpacks it a month later with no memory of where it came from: not signed, no attestation, no bill of materials, and what the version string inside does and does not mean. It is a script rather than a heredoc because two jobs on four runners write it, and a note that says one thing in one archive and something else in the other is worse than no note.

Read-only permissions and no publishing step, so it cannot put anything on a release page even by accident.

Three guards, five mutations, all caught

The platform list is the one fact this shares with the release, so it is read out of both workflows and compared. A workflow that quietly built four platforms out of five would leave somebody's machine unserved and nothing would say so, because a missing platform looks like a build that did not run.

The other two are about the failure mode that actually matters here - a person trusting a file they should not. Nothing may be granted write, no step may mention a way to publish, and both packaging jobs must write the note, counted rather than found: one job losing its call would leave the other one proving nothing about it.

Measured, not assumed

The command line loop was extracted from the YAML and run against this tree: five targets packaged in 26 seconds, and the archive holds the binary, LICENSE, THIRD-PARTY-NOTICES.md, README.md and the note. YAML parses, every run: block passes bash -n, both jobs declare timeout-minutes, and every action is pinned to the same commits the release uses.

Full suite green, preflight --quick green on all twelve checks.

⚠️ Merging this needs the browser or a token with the workflow scope - gh pr merge refuses on changes under .github/workflows/.

🤖 Generated with Claude Code

Somebody reports a bug, the fix lands on a branch, and they want to try it
before there is a release. Clicking Run workflow builds that branch and leaves
the binaries on the run page for fourteen days.

Three owner decisions shape it. A choice input, defaulting to the command line
binaries only: those cross compile to five platforms on one runner in about two
minutes, while the window needs three real runners and CGO. No test gate,
because the whole point is speed and the branch has its own CI on its own pull
request. And fourteen days rather than the default ninety, because an unsigned
binary should not sit for a quarter of a year behind a link somebody can pass
on as if it were official.

It is deliberately not shaped like a release, so an archive from here cannot be
mistaken for one. The name carries the COMMIT rather than the version, and that
is not a style choice: internal/version is a const and cannot be stamped at
link time, so a build from a fix branch reports whatever version that branch
inherited. The file name is the only place that can tell the truth about which
code this is. Every archive also carries UNOFFICIAL-BUILD.txt saying the same
in words, for whoever unpacks it a month later with no memory of where it came
from - not signed, no attestation, and what the version string inside does and
does not mean. The note is a script rather than a heredoc because two jobs on
four runners write it, and a note that says one thing in one archive and
something else in the other is worse than no note.

Three guards, five mutations, all caught.

The platform list is the one fact this shares with the release, so it is read
out of both workflows and compared. A workflow that quietly built four of five
platforms would leave somebody's machine unserved, and nothing would say so,
because a missing platform looks like a build that did not run.

The other two are about the failure mode that matters here, which is a person
trusting a file they should not: nothing in this workflow may be granted write,
no step may mention a way to publish, and both packaging jobs must write the
note - counted rather than found, because one job losing its call would leave
the other one proving nothing about it.

Measured rather than assumed: the command line loop was run locally against
this tree and packaged all five targets in 26 seconds, and the archive holds
the binary, the licence, the notices, the readme and the note.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant