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.
Phase 4: a rename carries the queue, instead of stranding it
72797dcd4606a81d35fff03124fc1ba627cc1d60 · Keenan Nemetz · 16d ago · parent d798eaac
Phase 4: a rename carries the queue, instead of stranding it Queue rows are keyed by repository name rather than by the repository's stable id, so a rename left every queued job under a name no runner is ever told about — the lease filters by the names an account may run, and the old name no longer exists — and left the ref cursors behind, so the next reconciliation queued the current tip a second time. RenameRepo moves the runs, the cursors and the presence rows in one transaction, and `vole repo rename` calls it. A rename refuses a name that is already taken, so the unique index on (repo, ref, sha, workflow, job) cannot collide.
cmd/vole/main.go +7
| @@ -503,6 +503,13 @@ func cmdRepo(args []string) error { | |||
| 503 | 503 | if m, err := st.repos.Open(f.rest[1]); err == nil { | |
| 504 | 504 | _ = st.index.Upsert(m) | |
| 505 | 505 | } | |
| 506 | // The queue keys its rows by repository name, so it has to follow the rename or | ||
| 507 | // the jobs become unleaseable and the cursors forget which tips were built. | ||
| 508 | if st.runs != nil { | ||
| 509 | if err := st.runs.RenameRepo(f.rest[0], f.rest[1]); err != nil { | ||
| 510 | return err | ||
| 511 | } | ||
| 512 | } | ||
| 506 | 513 | fmt.Printf("renamed %s -> %s\n", f.rest[0], f.rest[1]) | |
| 507 | 514 | return nil | |
| 508 | 515 | ||