MCPcopy Create free account
hub / github.com/github/gh-aw / ResolveSHA

Method ResolveSHA

pkg/workflow/action_resolver.go:93–161  ·  view source on GitHub ↗

ResolveSHA resolves the SHA for a given action@version using GitHub CLI Returns the SHA and an error if resolution fails

(ctx context.Context, repo, version string)

Source from the content-addressed store, hash-verified

91// ResolveSHA resolves the SHA for a given action@version using GitHub CLI
92// Returns the SHA and an error if resolution fails
93func (r *ActionResolver) ResolveSHA(ctx context.Context, repo, version string) (string, error) {
94 resolverLog.Printf("Resolving SHA for action: %s@%s", repo, version)
95
96 // Create a cache key for tracking failed resolutions and cache lookups.
97 // Computed once here and reused below to avoid duplicate allocation.
98 cacheKey := formatActionCacheKey(repo, version)
99 r.usedCacheKeys[cacheKey] = true
100
101 // Check if we've already failed to resolve this action in this run
102 if r.failedResolutions[cacheKey] {
103 resolverLog.Printf("Skipping resolution for %s@%s: already failed in this run", repo, version)
104 return "", fmt.Errorf("previously failed to resolve %s@%s in this compilation run", repo, version)
105 }
106
107 // Check cache first using the pre-computed key to avoid a second key allocation.
108 if sha, found := r.cache.GetByCacheKey(cacheKey); found {
109 resolverLog.Printf("Cache hit for %s@%s: %s", repo, version, sha)
110 return sha, nil
111 }
112
113 resolverLog.Printf("Cache miss for %s@%s, checking embedded action pins", repo, version)
114
115 // Check embedded action pins for a semver-compatible version before making
116 // a network call. The embedded pins are the source-of-truth for known versions
117 // and are always available without network access. This avoids a ~1s gh-api
118 // subprocess for any action that is already covered by the embedded pin set.
119 requested := semverutil.EnsureVPrefix(version)
120 requestedVer := semverutil.ParseVersion(requested)
121 requestedIsPrecise := requestedVer != nil && requestedVer.IsPreciseVersion()
122
123 for _, pin := range actionpins.GetActionPinsByRepo(repo) {
124 pinVersion := semverutil.EnsureVPrefix(pin.Version)
125 if requestedIsPrecise {
126 if pinVersion != requested {
127 continue
128 }
129 } else if !semverutil.IsCompatible(pinVersion, requested) {
130 continue
131 }
132
133 resolverLog.Printf("Embedded pin hit for %s@%s → %s (%s)", repo, version, pin.SHA, pin.Version)
134 // Note: we intentionally do NOT call r.cache.Set() here. The embedded pins
135 // are always available in memory so there is nothing to persist, and writing
136 // to the on-disk cache would create root-owned files when compiling inside
137 // Docker containers (e.g. the Alpine CI test), preventing cleanup by the host.
138 return pin.SHA, nil
139 }
140
141 resolverLog.Printf("No embedded pin for %s@%s, querying GitHub API", repo, version)
142 resolverLog.Printf("This may take a moment as we query GitHub API at /repos/%s/git/ref/tags/%s", gitutil.ExtractBaseRepo(repo), version)
143
144 // Resolve using GitHub CLI
145 sha, err := r.resolveFromGitHub(ctx, repo, version)
146 if err != nil {
147 resolverLog.Printf("Failed to resolve %s@%s: %v", repo, version, err)
148 // Mark this resolution as failed for this compilation run
149 r.failedResolutions[cacheKey] = true
150 resolverLog.Printf("Marked %s as failed, will not retry in this run", cacheKey)

Calls 12

resolveFromGitHubMethod · 0.95
EnsureVPrefixFunction · 0.92
ParseVersionFunction · 0.92
GetActionPinsByRepoFunction · 0.92
IsCompatibleFunction · 0.92
ExtractBaseRepoFunction · 0.92
formatActionCacheKeyFunction · 0.85
GetByCacheKeyMethod · 0.80
IsPreciseVersionMethod · 0.80
PrintfMethod · 0.45
ErrorfMethod · 0.45
SetMethod · 0.45