Merge pull request 'A repository the gitea module makes refuses an administrator's merge past its checks (issue 1141)' (#365) from fix/1141-admin-override into main
This commit was merged in pull request #365.
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 1141/AC1: a repository the program makes gets main's rule with an administrator's merge past a status refused,
|
||||||
|
// as every repository's main has had since 2026-10-07.
|
||||||
|
func TestNewRepositoryRefusesTheAdministratorsOverride(t *testing.T) {
|
||||||
|
f := newFake()
|
||||||
|
s, _ := syncer(t, f)
|
||||||
|
run(t, s, Value{"mesh-delivery": {Description: "d"}})
|
||||||
|
rule := f.repos["novox/mesh-delivery"].Rules[mainRule]
|
||||||
|
if rule["block_admin_merge_override"] != true {
|
||||||
|
t.Errorf("main lets an administrator merge past its statuses: %v", rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1141/AC2: a narrowed main rule that still lets an administrator override is not right: it is put right, its
|
||||||
|
// statuses kept, and a second pass changes nothing.
|
||||||
|
func TestNarrowedRuleLettingTheAdministratorOverrideIsPutRight(t *testing.T) {
|
||||||
|
f := newFake()
|
||||||
|
repo := f.add("novox/mesh-delivery", map[string]map[string]any{mainRule: {
|
||||||
|
"enable_push": false, "enable_push_whitelist": false, "push_whitelist_usernames": []any{},
|
||||||
|
"enable_merge_whitelist": true, "merge_whitelist_usernames": []any{tools},
|
||||||
|
"enable_status_check": true, "status_check_contexts": []any{"mesh/merge-gate", "mesh/repo-check", "other/x"},
|
||||||
|
"block_admin_merge_override": false,
|
||||||
|
}}, "main")
|
||||||
|
s, _ := syncer(t, f)
|
||||||
|
o := run(t, s, Value{"mesh-delivery": {Description: "d"}})
|
||||||
|
rule := repo.Rules[mainRule]
|
||||||
|
if rule["block_admin_merge_override"] != true {
|
||||||
|
t.Errorf("the administrator's override is still allowed: %v", rule)
|
||||||
|
}
|
||||||
|
for _, c := range []string{"mesh/merge-gate", "mesh/repo-check", "other/x"} {
|
||||||
|
if !has(strs(rule["status_check_contexts"]), c) {
|
||||||
|
t.Errorf("a status was dropped: %v", rule["status_check_contexts"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r := result(o, "mesh-delivery"); r.Did != DidPutRight {
|
||||||
|
t.Errorf("outcome %+v, want put right", r)
|
||||||
|
}
|
||||||
|
before := len(f.writes())
|
||||||
|
run(t, s, Value{"mesh-delivery": {Description: "d"}})
|
||||||
|
if got := f.writes(); len(got) != before {
|
||||||
|
t.Errorf("a second pass wrote %s", strings.Join(got[before:], ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -333,12 +333,14 @@ func statuses(rules ...rule) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// narrowed is main's rule of ADR 0398 §2 (protection.ts mainRuleBody): no push, only the tools' account merges,
|
// narrowed is main's rule of ADR 0398 §2 (protection.ts mainRuleBody): no push, only the tools' account merges,
|
||||||
// requiring the statuses (ADR 0428 §5). A field the forge keeps beside these is left as it is.
|
// requiring the statuses (ADR 0428 §5), and no administrator merging past them, as every repository's main has been
|
||||||
|
// since 2026-10-07 (issue 1141). A field the forge keeps beside these is left as it is.
|
||||||
func narrowed(r rule, toolsAccount string, also ...rule) map[string]any {
|
func narrowed(r rule, toolsAccount string, also ...rule) map[string]any {
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"enable_push": false, "enable_push_whitelist": false, "push_whitelist_usernames": []string{},
|
"enable_push": false, "enable_push_whitelist": false, "push_whitelist_usernames": []string{},
|
||||||
"enable_merge_whitelist": true, "merge_whitelist_usernames": []string{toolsAccount},
|
"enable_merge_whitelist": true, "merge_whitelist_usernames": []string{toolsAccount},
|
||||||
"enable_status_check": true, "status_check_contexts": statuses(append([]rule{r}, also...)...),
|
"enable_status_check": true, "status_check_contexts": statuses(append([]rule{r}, also...)...),
|
||||||
|
"block_admin_merge_override": true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +352,8 @@ func isRight(r rule, toolsAccount string) bool {
|
|||||||
if m := strList(r["merge_whitelist_usernames"]); len(m) != 1 || m[0] != toolsAccount {
|
if m := strList(r["merge_whitelist_usernames"]); len(m) != 1 || m[0] != toolsAccount {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return r["enable_status_check"] == true && hasAll(strList(r["status_check_contexts"]))
|
return r["enable_status_check"] == true && hasAll(strList(r["status_check_contexts"])) &&
|
||||||
|
r["block_admin_merge_override"] == true
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasAll(have []string) bool {
|
func hasAll(have []string) bool {
|
||||||
@@ -394,9 +397,6 @@ func (s *Syncer) putRight(ctx context.Context, owner, name string) (bool, error)
|
|||||||
if n, _ := r["required_approvals"].(float64); n > approvals {
|
if n, _ := r["required_approvals"].(float64); n > approvals {
|
||||||
approvals = n
|
approvals = n
|
||||||
}
|
}
|
||||||
if r["block_admin_merge_override"] == true {
|
|
||||||
body["block_admin_merge_override"] = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if approvals > 0 {
|
if approvals > 0 {
|
||||||
body["required_approvals"] = approvals
|
body["required_approvals"] = approvals
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ func TestStatusesAreAddedAndNeverDropped(t *testing.T) {
|
|||||||
more := f.add("novox/more", map[string]map[string]any{mainRule: {
|
more := f.add("novox/more", map[string]map[string]any{mainRule: {
|
||||||
"enable_push": false, "enable_merge_whitelist": true, "merge_whitelist_usernames": []any{tools},
|
"enable_push": false, "enable_merge_whitelist": true, "merge_whitelist_usernames": []any{tools},
|
||||||
"enable_status_check": true, "status_check_contexts": []any{"mesh/merge-gate", "mesh/repo-check", "mesh/delivery"},
|
"enable_status_check": true, "status_check_contexts": []any{"mesh/merge-gate", "mesh/repo-check", "mesh/delivery"},
|
||||||
|
"block_admin_merge_override": true, // right since issue 1141
|
||||||
}}, "main")
|
}}, "main")
|
||||||
s, _ := syncer(t, f)
|
s, _ := syncer(t, f)
|
||||||
o := run(t, s, Value{"only": {}, "more": {}})
|
o := run(t, s, Value{"only": {}, "more": {}})
|
||||||
|
|||||||
Reference in New Issue
Block a user