vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Require an image for every CI job
70b702649b875d841e294f5a085ca784d43e5bc4 · Keenan Nemetz · 15d ago · parent 7da9111e
Require an image for every CI job Runners now require an OCI runtime, and each workflow job must name either a registry image or an image-file definition under .vole/images. Definitions are validated at push time, pinned with the run, built locally by the runner, and cached by definition digest. Records and the run page carry the image and definition digest. Split the CI guide into workflows and runners, and add reference pages for workflow and image definition fields.
server/ssh/runner.go +11−2
| @@ -88,6 +88,12 @@ type runnerJob struct { | |||
| 88 | 88 | Workflow string `json:"workflow"` | |
| 89 | 89 | Job string `json:"job"` | |
| 90 | 90 | Steps []runnerStep `json:"steps"` | |
| 91 | // Image is a registry reference or "file:<name>". For the latter, ImageDefinition | ||
| 92 | // is the pinned recipe and ImageSHA is its digest; the runner builds it locally. | ||
| 93 | Image string `json:"image"` | ||
| 94 | ImageFile string `json:"image_file,omitempty"` | ||
| 95 | ImageDefinition string `json:"image_definition,omitempty"` | ||
| 96 | ImageSHA string `json:"image_sha,omitempty"` | ||
| 91 | 97 | // Artifacts are the declared patterns the runner expands and uploads after the | |
| 92 | 98 | // steps succeed. | |
| 93 | 99 | Artifacts []string `json:"artifacts,omitempty"` | |
| @@ -223,7 +229,9 @@ func (s *Server) serveRunner(ch xssh.Channel, user, accountID string) { | |||
| 223 | 229 | ID: run.ID, Repo: run.Repo, SHA: run.SHA, Attempt: run.Attempts, Branch: run.Branch, | |
| 224 | 230 | Ref: run.Ref, Workflow: run.Workflow, WorkflowSHA: run.WorkflowSHA, | |
| 225 | 231 | StepsSHA: run.StepsSHA, Job: run.Job, Artifacts: run.Artifacts, | |
| 226 | Tag: run.Tag, TagAnnotated: run.TagAnnotated, ReleaseArtifacts: run.ReleaseArtifacts, | ||
| 232 | Image: run.Image, ImageFile: run.ImageFile, ImageDefinition: run.ImageDefinition, | ||
| 233 | ImageSHA: run.ImageSHA, | ||
| 234 | Tag: run.Tag, TagAnnotated: run.TagAnnotated, ReleaseArtifacts: run.ReleaseArtifacts, | ||
| 227 | 235 | } | |
| 228 | 236 | if run.PagesPath != "" { | |
| 229 | 237 | ref := cfg.PagesRef | |
| @@ -333,7 +341,8 @@ func (s *Server) serveRunner(ch xssh.Channel, user, accountID string) { | |||
| 333 | 341 | // under the same rule as the log and the artifacts: written only while this | |
| 334 | 342 | // runner still holds the lease, so a runner that was overtaken leaves no claim | |
| 335 | 343 | // behind. | |
| 336 | if mirrored, err := cfg.Runs.RecordEnvironment(run.ID, owner, rec.OS, rec.Arch, rec.Image, rec.Runtime); err != nil { | ||
| 344 | if mirrored, err := cfg.Runs.RecordEnvironment(run.ID, owner, rec.OS, rec.Arch, | ||
| 345 | rec.Image, rec.ImageFile, rec.ImageSHA, rec.Runtime); err != nil { | ||
| 337 | 346 | _ = enc.Encode(runnerReply{Op: "finish", Error: err.Error()}) | |
| 338 | 347 | continue | |
| 339 | 348 | } else if !mirrored { | |