getActionPin returns the pinned reference for the given repo, using GHES-compatible v3.x pins for artifact actions when c.ghesArtifactCompat is true. This is the preferred call site for code running inside a Compiler method, since it automatically honours the per-compilation GHES compat flag withou
(repo string)
| 92 | // any existing entry and mark it as "used" for orphan pruning. This ensures compiler-generated |
| 93 | // action references (e.g., actions/cache/save in notify steps) are tracked. |
| 94 | func (c *Compiler) getActionPin(repo string) string { |
| 95 | if c.ghesArtifactCompat { |
| 96 | if pin, ok := ghesArtifactCompatPins[repo]; ok { |
| 97 | actionPinsLog.Printf("GHES compat: using %s@%s instead of latest", repo, pin.version) |
| 98 | return actionpins.FormatPinnedActionReference(repo, pin.sha, pin.version) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | // Check the cache for any existing entry for this repo (regardless of version). |
| 103 | // Compiler-generated actions don't specify versions, so prefer a cached entry only |
| 104 | // when it is at least as new as the latest embedded pin. |
| 105 | cache := c.GetSharedActionCache() |
| 106 | resolver := c.GetSharedActionResolver() |
| 107 | latestEmbedded, hasEmbedded := getLatestActionPinByRepo(repo) |
| 108 | if cache != nil { |
| 109 | if cacheKey, entry, found := cache.FindAnyEntryForRepo(repo); found { |
| 110 | if hasEmbedded { |
| 111 | cachedVersion := semverutil.ParseVersion(entry.Version) |
| 112 | embeddedVersion := semverutil.ParseVersion(latestEmbedded.Version) |
| 113 | if cachedVersion == nil { |
| 114 | actionPinsLog.Printf("Ignoring cache entry with unparseable cached version for compiler-generated action %s: cache=%s embedded=%s", |
| 115 | repo, entry.Version, latestEmbedded.Version) |
| 116 | return actionpins.FormatPinnedActionReference(repo, latestEmbedded.SHA, latestEmbedded.Version) |
| 117 | } |
| 118 | if embeddedVersion == nil { |
| 119 | actionPinsLog.Printf("Using cached version for compiler-generated action %s because embedded version is unparseable: cache=%s embedded=%s", |
| 120 | repo, entry.Version, latestEmbedded.Version) |
| 121 | if resolver != nil { |
| 122 | resolver.MarkCacheKeyAsUsed(cacheKey) |
| 123 | } |
| 124 | return actionpins.FormatPinnedActionReference(repo, entry.SHA, entry.Version) |
| 125 | } |
| 126 | if embeddedVersion.IsNewer(cachedVersion) { |
| 127 | actionPinsLog.Printf("Ignoring stale cache entry for compiler-generated action %s: cache=%s embedded=%s", |
| 128 | repo, entry.Version, latestEmbedded.Version) |
| 129 | return actionpins.FormatPinnedActionReference(repo, latestEmbedded.SHA, latestEmbedded.Version) |
| 130 | } |
| 131 | // Equal or newer cached versions intentionally fall through to the cache entry below. |
| 132 | } |
| 133 | // Mark this cache key as used so it won't be pruned as orphaned |
| 134 | if resolver != nil { |
| 135 | resolver.MarkCacheKeyAsUsed(cacheKey) |
| 136 | } |
| 137 | return actionpins.FormatPinnedActionReference(repo, entry.SHA, entry.Version) |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | // Fall back to embedded pins if no suitable cache entry exists |
| 142 | return getActionPin(repo) |
| 143 | } |
| 144 | |
| 145 | // getCachedActionPinFromResolver returns the pinned action reference for repo, |
| 146 | // preferring dynamic resolution via resolver over the embedded pins. |