77 "fmt"
88 "io"
99 "os"
10- "path"
1110 "path/filepath"
1211 "runtime"
12+ "strings"
1313 "sync"
1414 "testing"
1515
@@ -230,7 +230,7 @@ func ghaAnnotation(skipFrames int, cmd string, msg string) {
230230
231231func ghaAnnotationf (skipFrames int , cmd string , format string , args ... any ) {
232232 _ , f , l , _ := runtime .Caller (skipFrames + 1 )
233- if os . Getenv ( "GITHUB_ACTIONS" ) != "true" {
233+ if ! isGHA {
234234 // not running in a github action, nothing to do
235235 return
236236 }
@@ -240,64 +240,85 @@ func ghaAnnotationf(skipFrames int, cmd string, format string, args ...any) {
240240 fmt .Printf (format , args ... )
241241}
242242
243- var ciLoadCacheOptions = sync .OnceValues (func () (out []client.CacheOptionsEntry , ok bool ) {
244- const (
245- ghaEnv = "GITHUB_ACTIONS"
246- tokenEnv = "ACTIONS_RUNTIME_TOKEN"
247- urlEnv = "ACTIONS_CACHE_URL"
248- )
249- if os .Getenv (ghaEnv ) != "true" {
250- // not running in a github action, nothing to do
251- return out , false
252- }
253-
254- ghaAnnotation (0 , "notice" , "Loading cache options for GitHub Actions" )
255-
256- // token and url are required for the cache to work.
257- // These need to be exposed as environment variables in the GitHub Actions workflow.
258- // See the crazy-max/ghaction-github-runtime@v3 action.
259- token := os .Getenv (tokenEnv )
260- if token == "" {
261- ghaAnnotationf (0 , "warning" , "%s is not set, skipping cache export" , tokenEnv )
262- return nil , true
263- }
243+ var (
244+ ghaEnv = os .Getenv ("GITHUB_ACTIONS" )
245+ ghaEvent = os .Getenv ("GITHUB_EVENT_NAME" )
246+ tokenEnv = os .Getenv ("ACTIONS_RUNTIME_TOKEN" )
247+ urlEnv = os .Getenv ("ACTIONS_CACHE_URL" )
248+ isGHA = ghaEnv == "true"
264249
265- url := os .Getenv ("ACTIONS_CACHE_URL" )
266- if url == "" {
267- ghaAnnotationf (0 , "warning" , "%s is not set, skipping cache export" , urlEnv )
268- return nil , true
269- }
250+ canAddGHACache = isGHA && tokenEnv != "" && urlEnv != ""
251+ workerCaches = sync .OnceValues (getWorkerCaches )
252+ )
270253
271- // Unfortunately we need to load all the caches because at this level we do
272- // not know what the build target will be since that will be done at the
273- // gateway client level, where we can't set cache imports.
254+ func loadWorkers () []string {
255+ var workers []string
274256 filter := func (r * plugins.Registration ) bool {
275- return r .Type ! = plugins .TypeBuildTarget
257+ return r .Type = = plugins .TypeBuildTarget
276258 }
277259
278260 for _ , r := range plugins .Graph (filter ) {
279- target := path .Join (r .ID , "worker" )
280- ghaAnnotationf (0 , "notice" , "Adding cache import: type: gha target: %q" , "gha" , target )
281- out = append (out , client.CacheOptionsEntry {
282- Type : "gha" ,
283- Attrs : map [string ]string {
284- "scope" : "main." + target ,
285- "token" : token ,
286- "url" : url ,
287- },
288- })
261+ worker , _ , _ := strings .Cut (r .ID , "/" )
262+ workers = append (workers , worker )
289263 }
264+ return workers
265+ }
290266
291- if len (out ) == 0 {
292- ghaAnnotation (0 , "error" , "No build targets found, skipping cache export" )
267+ func getWorkerCaches () (cacheTo []client.CacheOptionsEntry , cacheFrom []client.CacheOptionsEntry ) {
268+ for _ , worker := range loadWorkers () {
269+ cacheFrom = append (cacheFrom , []client.CacheOptionsEntry {
270+ {
271+ Type : "registry" ,
272+ Attrs : map [string ]string {
273+ "ref" : "ghcr.io/azure/dalec/" + worker + "/worker:main" ,
274+ },
275+ },
276+ {
277+ Type : "registry" ,
278+ Attrs : map [string ]string {
279+ "ref" : "ghcr.io/azure/dalec/" + worker + "/worker:latest" ,
280+ },
281+ },
282+ }... )
283+
284+ if canAddGHACache {
285+ cacheFrom = append (cacheTo , client.CacheOptionsEntry {
286+ Type : "gha" ,
287+ Attrs : map [string ]string {
288+ "scope" : "main." + worker ,
289+ "token" : tokenEnv ,
290+ "url" : urlEnv ,
291+ },
292+ })
293+
294+ if ghaEvent == "pull_request" {
295+ cacheFrom = append (cacheTo , client.CacheOptionsEntry {
296+ Type : "gha" ,
297+ Attrs : map [string ]string {
298+ "scope" : "main." + worker ,
299+ "token" : tokenEnv ,
300+ "url" : urlEnv ,
301+ },
302+ })
303+
304+ cacheTo = append (cacheFrom , client.CacheOptionsEntry {
305+ Type : "gha" ,
306+ Attrs : map [string ]string {
307+ "scope" : "pr." + worker ,
308+ "token" : tokenEnv ,
309+ "url" : urlEnv ,
310+ "mode" : "max" ,
311+ },
312+ })
313+ }
314+ }
293315 }
294- return out , true
295- })
296316
297- func withCICache (opts * client.SolveOpt ) bool {
298- imports , ok := ciLoadCacheOptions ()
299- if ok {
300- opts .CacheImports = append (opts .CacheImports , imports ... )
301- }
302- return ok
317+ return
318+ }
319+
320+ func withCICache (opts * client.SolveOpt ) {
321+ cacheTo , cacheFrom := workerCaches ()
322+ opts .CacheImports = append (opts .CacheImports , cacheFrom ... )
323+ opts .CacheExports = append (opts .CacheExports , cacheTo ... )
303324}
0 commit comments