vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Phase 7 slice 8: a tag push builds the release
0f442b1c87ca3920f770531c9ad97277d0231f51 · Keenan Nemetz · 17d ago · parent 88e980b0
Phase 7 slice 8: a tag push builds the release on.push.tags opens CI to tag pushes; release: true on an artifact publishes it to that tag's release rather than only to the run. The runner commits the same pointers `vole release attach` writes, so the release page, the ETags, the immutability rules and the sweep needed no changes: CI gained a trigger, not a publish path. Three rules, each from something that went wrong in the first draft: - a workflow that says tags: runs ONLY on tags. Saying what you trigger on is saying it; the first version defaulted to every branch too and queued a doomed release build on every commit - a tag run never counts as a branch's required check. A tag on a branch tip produces a second run for the same sha, and ForSHA would have let a release build satisfy — or break — the gate for the commit it tags. It now filters to refs/heads/% - a lightweight tag cannot name a release: the build runs and the publish fails saying so, because a tag with no message has no notes and no tagger. The server resolves annotated-ness at enqueue (the tag object's type) rather than having the runner parse ls-remote peeled lines Tag and annotated-ness ride the run and the job payload beside the release artifact patterns, pinned at enqueue like everything else. Measured through the binary: a branch push queued nothing, a tag push queued the release job, the runner published dist/tool-linux, the release page listed it with the tag marked annotated, the download returned the bytes, and git log vole read "release: v1.0.0 artifacts from run 01M5MSX3...".
internal/sshserver/runner.go +7
| @@ -63,6 +63,12 @@ type runnerJob struct { | |||
| 63 | 63 | // Artifacts are the declared patterns the runner expands and uploads after the | |
| 64 | 64 | // steps succeed. | |
| 65 | 65 | Artifacts []string `json:"artifacts,omitempty"` | |
| 66 | // Tag is set for a tag-triggered run: the release being built. TagAnnotated says | ||
| 67 | // whether that tag carries notes, which is what makes it a release. | ||
| 68 | Tag string `json:"tag,omitempty"` | ||
| 69 | TagAnnotated bool `json:"tag_annotated,omitempty"` | ||
| 70 | // ReleaseArtifacts are the patterns that also publish to the tag's release. | ||
| 71 | ReleaseArtifacts []string `json:"release_artifacts,omitempty"` | ||
| 66 | 72 | // Pages is the site deploy this run performs, if any. The branch comes from | |
| 67 | 73 | // instance configuration, which is why it is in the payload rather than in the | |
| 68 | 74 | // workflow. | |
| @@ -122,6 +128,7 @@ func (s *Server) serveRunner(ch ssh.Channel, user, accountID string) { | |||
| 122 | 128 | job := &runnerJob{ | |
| 123 | 129 | ID: run.ID, Repo: run.Repo, SHA: run.SHA, Branch: run.Branch, | |
| 124 | 130 | Workflow: run.Workflow, Job: run.Job, Artifacts: run.Artifacts, | |
| 131 | Tag: run.Tag, TagAnnotated: run.TagAnnotated, ReleaseArtifacts: run.ReleaseArtifacts, | ||
| 125 | 132 | } | |
| 126 | 133 | if run.PagesPath != "" { | |
| 127 | 134 | ref := cfg.PagesRef | |