Skip to content

Commit 95ef75c

Browse files
committed
pipeline: skip resolve/reachability for local-path workflows
Local-path workflows are bailed out at diagnose time, but their action refs were still fed through the resolve and reachability phases because PartitionRefs found no matching lockfile entries. On mcv3-boot this caused 65 redundant HTTP calls (~6s) on every rerun. Fix: mark local-path workflows as Resolved=true before the partition loop so they never enter the network path. Also teach PartitionRefs to match bare-SHA refs against lockfile deps by SHA (not just by tag ref) for correctness in mixed-pinning repos. Result: mcv3-boot rerun drops from ~6s to ~200ms, 0 HTTP requests.
1 parent 76be3aa commit 95ef75c

3 files changed

Lines changed: 32 additions & 7 deletions

File tree

internal/pipeline/checks/parsed.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,22 @@ type ParsedWorkflow struct {
4040
}
4141

4242
// PartitionRefs splits refs into recorded (matching a lockfile entry by
43-
// NWO@Ref) and unrecorded (need network resolution). When an error
44-
// prevented loading refs or deps, everything is unrecorded.
43+
// NWO@Ref or NWO@SHA) and unrecorded (need network resolution). When an
44+
// error prevented loading refs or deps, everything is unrecorded.
4545
func (pw ParsedWorkflow) PartitionRefs() (recorded, unrecorded []parserlock.ActionRef) {
4646
if pw.LoadErr != nil || pw.DepsErr != nil {
4747
return nil, pw.Refs
4848
}
4949
if len(pw.Refs) == 0 {
5050
return nil, nil
5151
}
52-
haveDep := make(map[string]bool, len(pw.ExistingDeps))
52+
haveDep := make(map[string]bool, len(pw.ExistingDeps)*2)
5353
for _, d := range pw.ExistingDeps {
54-
haveDep[strings.ToLower(d.NWO)+"@"+d.Ref] = true
54+
nwo := strings.ToLower(d.NWO)
55+
haveDep[nwo+"@"+d.Ref] = true
56+
if d.SHA != "" {
57+
haveDep[nwo+"@"+strings.ToLower(d.SHA)] = true
58+
}
5559
}
5660
for _, r := range pw.Refs {
5761
if haveDep[strings.ToLower(r.Owner+"/"+r.Repo)+"@"+r.Ref] {
@@ -70,16 +74,17 @@ func (pw ParsedWorkflow) IsFullyRecorded() bool {
7074
return len(pw.Refs) == 0 || len(unrecorded) == 0
7175
}
7276

73-
// RecordedDeps returns the subset of ExistingDeps whose NWO@Ref matches
74-
// one of the given recorded refs.
77+
// RecordedDeps returns the subset of ExistingDeps whose NWO@Ref or
78+
// NWO@SHA matches one of the given recorded refs.
7579
func (pw ParsedWorkflow) RecordedDeps(recorded []parserlock.ActionRef) []dep.Dependency {
7680
refKeys := make(map[string]bool, len(recorded))
7781
for _, r := range recorded {
7882
refKeys[strings.ToLower(r.Owner+"/"+r.Repo)+"@"+r.Ref] = true
7983
}
8084
var out []dep.Dependency
8185
for _, d := range pw.ExistingDeps {
82-
if refKeys[d.Key()] {
86+
nwo := strings.ToLower(d.NWO)
87+
if refKeys[nwo+"@"+d.Ref] || refKeys[nwo+"@"+strings.ToLower(d.SHA)] {
8388
out = append(out, d)
8489
}
8590
}

internal/pipeline/run.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ func Run(ctx context.Context, opts RunOptions) (*RunResult, error) {
5858
recordedKeys := make(map[string]bool)
5959
if !opts.Rescan {
6060
for i := range parsed {
61+
// Local-path workflows are skipped at diagnose time; don't
62+
// waste network calls resolving their refs.
63+
if len(parsed[i].LocalPaths) > 0 {
64+
parsed[i].Resolved = true
65+
skippedRescan++
66+
continue
67+
}
6168
recorded, unrecorded := parsed[i].PartitionRefs()
6269
if len(parsed[i].Refs) == 0 || len(unrecorded) == 0 {
6370
parsed[i].Resolved = true

internal/pipeline/run_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ func TestPartitionRefs(t *testing.T) {
100100
wantRecordedLen: 2, // both sub-actions match the dep
101101
wantUnrecordLen: 0,
102102
},
103+
{
104+
name: "bare SHA ref matches by SHA",
105+
pw: checks.ParsedWorkflow{
106+
Refs: []parserlock.ActionRef{
107+
ref("actions", "checkout", "", "de0fac2e4500dabe0009e67214ff5f5447ce83dd"),
108+
},
109+
ExistingDeps: []dep.Dependency{
110+
mkDep("actions/checkout", "v6.0.2", "de0fac2e4500dabe0009e67214ff5f5447ce83dd"),
111+
},
112+
},
113+
wantRecordedLen: 1,
114+
wantUnrecordLen: 0,
115+
},
103116
}
104117
for _, tt := range tests {
105118
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)