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.
Test the merge result before landing it
e5478085e5b53a2892d0649d6f07c6f0a5653378 · Keenan Nemetz · 11d ago · parent db5e4382
Test the merge result before landing it A protected branch could receive a non-fast-forward landing whose tree was never built: the gate asked for checks on the request head, and the merge commit was made at landing time. A pushed merge with the right parents but extra content was accepted too. Publish the merge commit under refs/vole/candidates/, test it as the base branch, and make the gate require its results. Approvals name the head and the base branch, so a moved base retests without a new approval. A merger who clicks while that run is still going waits for it instead of clicking again. A pushed merge commit now has to carry exactly the tree a clean merge would produce. Closes: 01M61QQ56TESQ1HTMB1Z5C3733
forge/access/acl_test.go +22
| @@ -275,3 +275,25 @@ func TestParseRejectsBadRoles(t *testing.T) { | |||
| 275 | 275 | t.Fatal("expected error for unknown entry role") | |
| 276 | 276 | } | |
| 277 | 277 | } | |
| 278 | |||
| 279 | // A combined result derived from a contributor head is still untrusted code. The | ||
| 280 | // runner's cache namespace has to treat it as the contributor's, or that build could | ||
| 281 | // seed the cache a protected branch uses. | ||
| 282 | func TestTrustNamespaceFollowsAContributorCandidate(t *testing.T) { | ||
| 283 | t.Parallel() | ||
| 284 | cases := map[string]string{ | ||
| 285 | "refs/heads/main": "direct", | ||
| 286 | "refs/heads/feature": "direct", | ||
| 287 | "refs/tags/v1.0.0": "direct", | ||
| 288 | "refs/heads/contrib/alice/fix": "contrib-alice", | ||
| 289 | "refs/vole/candidates/REQ/main-abc": "direct", | ||
| 290 | "refs/vole/candidates/contrib/alice/REQ/main-abc-def": "contrib-alice", | ||
| 291 | "refs/vole/candidates/contrib/alice": "direct", | ||
| 292 | "refs/vole/candidates/contrib/alice/": "contrib-alice", | ||
| 293 | } | ||
| 294 | for ref, want := range cases { | ||
| 295 | if got := TrustNamespace(ref); got != want { | ||
| 296 | t.Errorf("TrustNamespace(%q) = %q, want %q", ref, got, want) | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||