From 18b522184f734a9ce9111c6ec22a4f9daeaceb72 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 24 Oct 2026 15:03:14 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Read=20a=20change's=20manifest=20as=20the?= =?UTF-8?q?=20indexer=20reads=20it,=20so=20a=20fallback=20to=20a=20predefi?= =?UTF-8?q?ned=20key=20is=20not=20unreadable=20for=20the=20catalogue's=20p?= =?UTF-8?q?redefined.json=20the=20assigner=20never=20holds:=20a=20group=20?= =?UTF-8?q?touching=20pacman=20or=20xterm=20failed=20its=20composition=20o?= =?UTF-8?q?n=20it=20(ADR=200348=20=C2=A77,=20issue=201751)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catalogue-835bf22b-xterm.module.json | 236 ++++++++++++++++++ .../cmd/mesh-delivery-assigner/world.go | 4 +- .../cmd/mesh-delivery-assigner/world_test.go | 23 ++ 3 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/testdata/catalogue-835bf22b-xterm.module.json diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/testdata/catalogue-835bf22b-xterm.module.json b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/testdata/catalogue-835bf22b-xterm.module.json new file mode 100644 index 0000000..b65be8e --- /dev/null +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/testdata/catalogue-835bf22b-xterm.module.json @@ -0,0 +1,236 @@ +{ + "module": "xterm", + "version": "1", + "moved": true, + "capabilities": [ + "package-manager" + ], + "requires": [ + "x11-display" + ], + "claims": [ + { + "name": "node-terminal-emulator", + "scope": "node", + "serves": [ + "open" + ] + } + ], + "tools": [ + "xterm_font", + "xterm_colours" + ], + "config": { + "face": { + "type": "string", + "description": "The font family xterm draws with, as fc-list names it: JetBrainsMono Nerd Font, because research 026/04 chose it for its glyphs the prompt uses. A family the machine does not have falls back to the nearest installed face (xterm_font says which).", + "pattern": "[A-Za-z0-9 ._-]{1,64}", + "default": "JetBrainsMono Nerd Font" + }, + "size": { + "type": "number", + "description": "The size of xterm's text, in points: 12 reads well on a screen of about 100 DPI, and a denser screen needs a larger size.", + "minimum": 6, + "maximum": 72, + "predefined": "font-size", + "default": 12 + }, + "save-lines": { + "type": "number", + "description": "How many lines of scrollback xterm keeps per terminal: 10000 holds a long build log, and each line costs memory in every open terminal.", + "minimum": 0, + "maximum": 1000000, + "default": 10000 + }, + "term-name": { + "type": "string", + "description": "The TERM value xterm sets for the programs it runs: xterm-256color, because the palette has 256 colours and every program knows the name.", + "pattern": "[A-Za-z0-9._-]{1,64}", + "default": "xterm-256color" + }, + "render-font": { + "type": "boolean", + "description": "Whether xterm draws with fontconfig faces (true) or the old X core fonts (false): true, because the face is a fontconfig family and core fonts cannot show it.", + "default": true + }, + "bold-mode": { + "type": "boolean", + "description": "Whether xterm draws bold text by overstriking the normal face (true): false, because the face has a real bold style and overstriking blurs it.", + "default": false + }, + "always-bold-mode": { + "type": "boolean", + "description": "Whether xterm overstrikes bold even where the face has a bold style (true): false, for the same reason as bold-mode.", + "default": false + }, + "allow-bold-fonts": { + "type": "boolean", + "description": "Whether xterm may use the face's bold style for bold text (true): true, so bold text is drawn with the real bold weight.", + "default": true + }, + "background": { + "type": "string", + "description": "The terminal's background colour, as #rrggbb: black, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#000000" + }, + "foreground": { + "type": "string", + "description": "The terminal's text colour, as #rrggbb: a light grey, easier on the eyes than white on black.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#a8a8a8" + }, + "color0": { + "type": "string", + "description": "Palette entry 0, the normal black, as #rrggbb: #000000, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#000000" + }, + "color1": { + "type": "string", + "description": "Palette entry 1, the normal red, as #rrggbb: #9e1828, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#9e1828" + }, + "color2": { + "type": "string", + "description": "Palette entry 2, the normal green, as #rrggbb: #008800, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#008800" + }, + "color3": { + "type": "string", + "description": "Palette entry 3, the normal yellow, as #rrggbb: #d2bb4b, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#d2bb4b" + }, + "color4": { + "type": "string", + "description": "Palette entry 4, the normal blue, as #rrggbb: #414171, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#414171" + }, + "color5": { + "type": "string", + "description": "Palette entry 5, the normal magenta, as #rrggbb: #963c59, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#963c59" + }, + "color6": { + "type": "string", + "description": "Palette entry 6, the normal cyan, as #rrggbb: #418179, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#418179" + }, + "color7": { + "type": "string", + "description": "Palette entry 7, the normal white, as #rrggbb: #bebebe, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#bebebe" + }, + "color8": { + "type": "string", + "description": "Palette entry 8, the bright black, as #rrggbb: #666666, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#666666" + }, + "color9": { + "type": "string", + "description": "Palette entry 9, the bright red, as #rrggbb: #bc5766, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#bc5766" + }, + "color10": { + "type": "string", + "description": "Palette entry 10, the bright green, as #rrggbb: #61a171, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#61a171" + }, + "color11": { + "type": "string", + "description": "Palette entry 11, the bright yellow, as #rrggbb: #e7db52, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#e7db52" + }, + "color12": { + "type": "string", + "description": "Palette entry 12, the bright blue, as #rrggbb: #5085af, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#5085af" + }, + "color13": { + "type": "string", + "description": "Palette entry 13, the bright magenta, as #rrggbb: #a97a99, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#a97a99" + }, + "color14": { + "type": "string", + "description": "Palette entry 14, the bright cyan, as #rrggbb: #6ba4a4, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#6ba4a4" + }, + "color15": { + "type": "string", + "description": "Palette entry 15, the bright white, as #rrggbb: #ffffff, as both workstations ran it.", + "pattern": "#[0-9a-fA-F]{6}", + "default": "#ffffff" + }, + "copy-binding": { + "type": "string", + "description": "The key combination that copies the selection to the clipboard, in X translation syntax: Ctrl Shift ~Alt C, so a plain Ctrl+C still interrupts the program. It holds no colon, backslash or line break, which would end the resource.", + "pattern": "[^:\\\\\\n]+", + "default": "Ctrl Shift ~Alt C" + }, + "paste-binding": { + "type": "string", + "description": "The key combination that pastes the clipboard, in X translation syntax: Ctrl Shift ~Alt V, the pair of copy-binding. It holds no colon, backslash or line break, which would end the resource.", + "pattern": "[^:\\\\\\n]+", + "default": "Ctrl Shift ~Alt V" + } + }, + "items": [ + { + "collection": "environment", + "name": "terminal", + "attributes": { + "kind": "variable", + "name": "TERMINAL" + }, + "template": "files/env-terminal" + }, + { + "collection": "shell:xresources:normal", + "name": "xresources-normal", + "template": "files/xresources-normal" + } + ], + "resources": [ + { + "id": "package", + "type": "package", + "package": "xterm" + } + ], + "build": { + "artifacts": [ + { + "name": "tools", + "kind": "bundle", + "language": "go", + "system": "arch", + "from": "cmd/xterm-tools", + "binary": "xterm-tools", + "loads": [ + "xterm-tools" + ] + }, + { + "name": "files", + "kind": "archive", + "from": "files" + } + ] + } +} diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go index fcd91d8..57cbbb4 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go @@ -148,7 +148,9 @@ func (w *world) manifest(ctx context.Context, get getter, digest string) parsed m, err := delivery.DecodeManifest(value) if err != nil { p = parsed{err: err.Error()} - } else if man, err := catalogue.ParseManifest([]byte(m.JSON)); err != nil { + } else if man, err := catalogue.ParseManifestForInputs([]byte(m.JSON)); err != nil { + // Read as the indexer reads it (issue 1751): a value falling back to a predefined key is judged by the merge gate + // in the catalogue, against the predefined.json at its root that this process never holds (ADR 0348 §7). p = parsed{module: m.Module, err: err.Error()} } else { p = parsed{module: m.Module, manifest: man} diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go index ee3a8e3..5211c7a 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go @@ -2,6 +2,7 @@ package main import ( "context" + "os" "slices" "strings" "testing" @@ -88,3 +89,25 @@ func TestAChangeWaitsForItsManifests(t *testing.T) { t.Errorf("an unreadable manifest: waits %q, change %+v", waits, ch) } } + +// A manifest of the change whose config value falls back to a predefined key (novox/hq ADR 0348 §7) is read, not +// unreadable for the catalogue's predefined.json the assigner never holds: the merge gate judges the fallback in the +// catalogue, and the indexer reads it the same way (catalogue.ParseManifestForInputs, issue 1751). A group whose +// mesh-catalog member touched pacman and xterm failed its composition on this (group check 18df81380db3). The manifest is +// xterm's module.json from mesh-catalog at 835bf22b. +func TestAManifestFallingBackToAPredefinedKeyIsReadable(t *testing.T) { + raw, err := os.ReadFile("testdata/catalogue-835bf22b-xterm.module.json") + if err != nil { + t.Fatal(err) + } + if !strings.Contains(string(raw), `"predefined"`) { + t.Fatal("the fixture names no predefined key") + } + f := fakeManifests{} + xterm := f.add(t, "xterm", string(raw)) + ch, waits := newWorld().change(context.Background(), f.get, delivery.Candidate{Group: "g", HeadsHash: "0123456789ab", + Pulls: []delivery.CandidatePull{pull("novox/mesh-catalog", 1, map[string]delivery.CandidateModule{"xterm": {FP2: fp('b'), Manifest: xterm}})}}, nil) + if waits != "" || ch.Unreadable["xterm"] != "" || ch.Manifests["xterm"].Module != "xterm" { + t.Errorf("xterm: waits %q, unreadable %q, want read", waits, ch.Unreadable["xterm"]) + } +} From 991589fdd20a14ee51839a77fad1a2d39ced2741 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 24 Oct 2026 16:41:39 +0200 Subject: [PATCH 2/2] A try of a branch accepts a mesh-sdk pin at the head of mesh-sdk's branch of the same name, so a milestone's repositories can be tried before their pull requests (issue 1921) --- .../cmd/mesh-delivery-checker/forge.go | 25 ++++++++++ .../internal/check/case.go | 20 ++++++++ .../internal/check/pins.go | 44 ++++++++++++++++ .../internal/check/pins_test.go | 50 +++++++++++++++++++ .../internal/check/try.go | 3 ++ .../mesh-delivery-checker/manifest_test.go | 2 +- modules/mesh-delivery-checker/module.json | 3 +- 7 files changed, 145 insertions(+), 2 deletions(-) diff --git a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/forge.go b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/forge.go index b3aabfa..79b4345 100644 --- a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/forge.go +++ b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/forge.go @@ -20,6 +20,8 @@ const ( getFileTool = "gitea.gitea_get_file" compareTool = "gitea.gitea_compare" commitsTool = "gitea.gitea_commits" + // gitea_list_branches answers {branches: [{name, commit}]}, every branch with the commit it points at. + branchesTool = "gitea.gitea_list_branches" ) // notFoundStatus is the 404 of the forge's error, `Gitea API : `. @@ -102,3 +104,26 @@ func (f forgeReads) FullSHA(_ context.Context, repository, commit string) (strin } return a.Commits[0].SHA, nil } + +// BranchHeads is the commit each branch of the repository points at. +func (f forgeReads) BranchHeads(_ context.Context, repository string) (map[string]string, error) { + owner, repo := ownerRepo(repository) + raw, err := f.ask(branchesTool, map[string]string{"owner": owner, "repo": repo}) + if err != nil { + return nil, err + } + var a struct { + Branches *[]struct { + Name string `json:"name"` + Commit string `json:"commit"` + } `json:"branches"` + } + if err := json.Unmarshal(raw, &a); err != nil || a.Branches == nil { + return nil, fmt.Errorf("the answer of %s is not {branches: [{name, commit}]}: %v", branchesTool, err) + } + heads := map[string]string{} + for _, b := range *a.Branches { + heads[b.Name] = b.Commit + } + return heads, nil +} diff --git a/modules/mesh-delivery-checker/internal/check/case.go b/modules/mesh-delivery-checker/internal/check/case.go index 22850d4..1c99029 100644 --- a/modules/mesh-delivery-checker/internal/check/case.go +++ b/modules/mesh-delivery-checker/internal/check/case.go @@ -3,6 +3,7 @@ package check import ( "fmt" "maps" + "slices" "sort" "strings" "sync" @@ -40,6 +41,9 @@ type Case struct { Queued time.Time // Try narrows a try's check (its level, its tests); nil for a pull request's. Try *TryOptions + + notesMu sync.Mutex + notes []string // Progress says what the check is doing, so a check that ran past its bound names the step it was stuck at. Progress *Progress // Kind is what asked the check (KindNew, KindNodes, KindTrunk): a re-judge after a trunk move is asked on the build @@ -148,3 +152,19 @@ func (t *Trunks) Heads() map[string]string { defer t.mu.Unlock() return maps.Clone(t.heads) } + +// note puts a word of the check's way on the case, for a try's line (issue 1921). +func (c *Case) note(s string) { + c.notesMu.Lock() + defer c.notesMu.Unlock() + if !slices.Contains(c.notes, s) { + c.notes = append(c.notes, s) + } +} + +// Notes are the words noted on the case, in the order they were noted. +func (c *Case) Notes() []string { + c.notesMu.Lock() + defer c.notesMu.Unlock() + return slices.Clone(c.notes) +} diff --git a/modules/mesh-delivery-checker/internal/check/pins.go b/modules/mesh-delivery-checker/internal/check/pins.go index c07a8c4..1de0a6e 100644 --- a/modules/mesh-delivery-checker/internal/check/pins.go +++ b/modules/mesh-delivery-checker/internal/check/pins.go @@ -6,6 +6,7 @@ import ( "fmt" "path" "regexp" + "sort" "strings" ) @@ -36,6 +37,8 @@ type Forge interface { OnTrunk(ctx context.Context, repository, commit string) (bool, error) // FullSHA is the 40-digit sha of a commit named by its first 12 digits. FullSHA(ctx context.Context, repository, commit string) (string, error) + // BranchHeads is the commit every branch of a repository points at, by branch name (issue 1921). + BranchHeads(ctx context.Context, repository string) (map[string]string, error) } var pseudoVersion = regexp.MustCompile(`-([0-9a-f]{12})$`) @@ -93,6 +96,18 @@ func (st *state) checkPinsOf(ctx context.Context, t *target) verdictPtr { if onTrunk { continue } + if st.c.Try != nil { + // A try only (issue 1921): a repository tried on a branch that mesh-sdk shares by name (a milestone's branch across + // repositories) is built with that branch's mesh-sdk head, which no group pull request holds before the pull requests exist. + branch, err := st.sameBranchPin(ctx, t, pin) + if err != nil { + return failed(forgeMachine(err, t.node), fmt.Sprintf("%s#%d: whether mesh-sdk %s is the head of a branch cannot be told: %v%s", t.pull.Repository, t.pull.Number, pin, err, unheardWords(err))) + } + if branch != "" { + st.c.note(fmt.Sprintf("pin accepted: head of mesh-sdk %s", branch)) + continue + } + } nor := "the group has no mesh-sdk pull request" if sdk != nil { nor = "the head of the group's mesh-sdk pull request is " + short12(sdk.Head) @@ -103,6 +118,35 @@ func (st *state) checkPinsOf(ctx context.Context, t *target) verdictPtr { return nil } +// sameBranchPin names the branch of the tried repository that points at the tried head and that mesh-sdk also has, at the +// commit the pin names; empty when there is none. +func (st *state) sameBranchPin(ctx context.Context, t *target, pin string) (string, error) { + mine, err := st.j.Forge.BranchHeads(ctx, t.pull.Repository) + if err != nil { + return "", err + } + var same []string + for name, head := range mine { + if head == t.pull.Head && name != "main" { + same = append(same, name) + } + } + if len(same) == 0 { + return "", nil + } + sdk, err := st.j.Forge.BranchHeads(ctx, SDKRepository) + if err != nil { + return "", err + } + sort.Strings(same) + for _, name := range same { + if h, ok := sdk[name]; ok && strings.HasPrefix(h, pin) { + return name, nil + } + } + return "", nil +} + // failureVerdict is a verdict of failure the check ends with. // pinHint is added to the failure of a Go member's fetch that names mesh-sdk while the group holds a mesh-sdk pull request: diff --git a/modules/mesh-delivery-checker/internal/check/pins_test.go b/modules/mesh-delivery-checker/internal/check/pins_test.go index c9c2bb1..189d058 100644 --- a/modules/mesh-delivery-checker/internal/check/pins_test.go +++ b/modules/mesh-delivery-checker/internal/check/pins_test.go @@ -18,6 +18,15 @@ type fakeForge struct { onTrunk map[string]bool // by commit prefix err error errAt map[string]error // by ref: a read at that ref fails with it + // branches are the branches of a repository with the commit each points at. + branches map[string]map[string]string +} + +func (f *fakeForge) BranchHeads(_ context.Context, repository string) (map[string]string, error) { + if f.err != nil { + return nil, f.err + } + return f.branches[repository], nil } func (f *fakeForge) File(_ context.Context, repository, path, ref string) (string, error) { @@ -346,3 +355,44 @@ func TestAMeshLabHeadGetsACheck(t *testing.T) { t.Fatalf("mesh-lab was not fetched: %+v", fetched) } } + +// sameBranchBench is a try of mesh-delivery's feat/r6 at head1 whose go.mod pins the SDK at pin, with the SDK's feat/r6 at head2. +func sameBranchBench(t *testing.T, pin string) (*bench, *Case) { + b := groupBench(t, pin) + b.ex.Forge.(*fakeForge).branches = map[string]map[string]string{ + repoA: {"main": trunkA, "feat/r6": head1}, + repoSDK: {"main": "cb54756c3865" + strings.Repeat("0", 28), "feat/r6": head2}, + } + c := caseOf(t, pullOf(repoA, 7, head1)) + c.Try = &TryOptions{} + return b, c +} + +func TestATryPinnedToTheHeadOfTheSDKBranchOfTheTriedBranchPasses(t *testing.T) { // 1921/AC1 + b, c := sameBranchBench(t, head2[:12]) + if v := b.judge(t, c).Verdict; v.State != delivery.VerdictPass { + t.Fatalf("verdict = %+v", v) + } + if n := c.Notes(); len(n) != 1 || n[0] != "pin accepted: head of mesh-sdk feat/r6" { + t.Errorf("notes = %q", n) + } +} + +func TestATryPinnedToAnotherCommitIsStillRefused(t *testing.T) { // 1921/AC2 + b, c := sameBranchBench(t, "9aaa5c80ac5c") + v := b.judge(t, c).Verdict + if v.State != delivery.VerdictFail || !strings.Contains(v.Failed.Words, "9aaa5c80ac5c") || !strings.Contains(v.Failed.Words, "neither on mesh-sdk's trunk nor the group's head") { + t.Fatalf("verdict = %+v", v) + } + if len(c.Notes()) != 0 { + t.Errorf("notes = %q", c.Notes()) + } +} + +func TestAMergeCheckWithTheSameBranchPinIsStillRefusedWithoutAGroupPullRequest(t *testing.T) { // 1921/AC3 + b, _ := sameBranchBench(t, head2[:12]) + v := b.judge(t, caseOf(t, pullOf(repoA, 7, head1))).Verdict // no Try: a pull request's check + if v.State != delivery.VerdictFail || !strings.Contains(v.Failed.Words, "the group has no mesh-sdk pull request") { + t.Fatalf("verdict = %+v", v) + } +} diff --git a/modules/mesh-delivery-checker/internal/check/try.go b/modules/mesh-delivery-checker/internal/check/try.go index 812773b..5f0be8b 100644 --- a/modules/mesh-delivery-checker/internal/check/try.go +++ b/modules/mesh-delivery-checker/internal/check/try.go @@ -329,6 +329,9 @@ func (tr *Tryer) run(ctx context.Context, key string) { t.Took = t.Ended.Sub(t.Started).Round(time.Second).String() t.Levels, t.Machines = v.Levels, v.Machines t.Said = Report(v, cs, cs.Pulls[0], out.Builds, out.Slowest, out.Judged) + for _, n := range cs.Notes() { + t.Said += " | " + n + } switch { case !judged || IsNodesFailure(v): t.State = TryError diff --git a/modules/mesh-delivery-checker/manifest_test.go b/modules/mesh-delivery-checker/manifest_test.go index c6af543..8df57af 100644 --- a/modules/mesh-delivery-checker/manifest_test.go +++ b/modules/mesh-delivery-checker/manifest_test.go @@ -103,7 +103,7 @@ func TestManifestDeclarations(t *testing.T) { // 1678/AC1 } // 1887/A5b: the checker reads nothing of the controller's plans-building (ADR 0483 superseded by ADR 0525 §7), calls no // build module's tool and holds no capacity: it puts check asks on the Go and Node build seats (ADR 0525 §1, §4). - if want := []string{"gitea.gitea_commits", "gitea.gitea_compare", "gitea.gitea_get_file"}; !reflect.DeepEqual(sorted(m.Invokes), want) { + if want := []string{"gitea.gitea_commits", "gitea.gitea_compare", "gitea.gitea_get_file", "gitea.gitea_list_branches"}; !reflect.DeepEqual(sorted(m.Invokes), want) { t.Errorf("invokes = %v, want only the forge's reads for a mesh-sdk pin (ADR 0484 clause 9)", m.Invokes) } if want := []string{"node-build-go", "node-build-node"}; !reflect.DeepEqual(sorted(m.Uses), want) { diff --git a/modules/mesh-delivery-checker/module.json b/modules/mesh-delivery-checker/module.json index 67c97f2..c53c7b5 100644 --- a/modules/mesh-delivery-checker/module.json +++ b/modules/mesh-delivery-checker/module.json @@ -47,7 +47,8 @@ "invokes": [ "gitea.gitea_commits", "gitea.gitea_compare", - "gitea.gitea_get_file" + "gitea.gitea_get_file", + "gitea.gitea_list_branches" ], "own-secrets": {