@@ -241,8 +241,8 @@ Format of the action JSON files:
241241
242242 logger := newActionLogger (* verbose , * keepLogsFlag )
243243
244- // Build Docker images etc.
245- err = prepareAction (ctx , action )
244+ // Fetch Docker images etc.
245+ err = prepareAction (ctx , action , logger )
246246 if err != nil {
247247 return errors .Wrap (err , "Failed to prepare action" )
248248 }
@@ -393,14 +393,14 @@ func validateActionDefinition(def []byte) error {
393393 return errs .ErrorOrNil ()
394394}
395395
396- func prepareAction (ctx context.Context , action Action ) error {
396+ func prepareAction (ctx context.Context , action Action , logger * actionLogger ) error {
397397 // Build any Docker images.
398398 for _ , step := range action .Steps {
399399 if step .Type == "docker" {
400400 // Set digests for Docker images so we don't cache action runs in 2 different images with
401401 // the same tag.
402402 var err error
403- step .ImageContentDigest , err = getDockerImageContentDigest (ctx , step .Image )
403+ step .ImageContentDigest , err = getDockerImageContentDigest (ctx , step .Image , logger )
404404 if err != nil {
405405 return errors .Wrap (err , "Failed to get Docker image content digest" )
406406 }
@@ -417,14 +417,35 @@ func prepareAction(ctx context.Context, action Action) error {
417417// have been pulled from or pushed to a registry. See
418418// https://windsock.io/explaining-docker-image-ids/ under "A Final Twist" for a good
419419// explanation.
420- func getDockerImageContentDigest (ctx context.Context , image string ) (string , error ) {
420+ func getDockerImageContentDigest (ctx context.Context , image string , logger * actionLogger ) (string , error ) {
421421 // TODO!(sqs): is image id the right thing to use here? it is NOT the
422422 // digest. but the digest is not calculated for all images (unless they are
423423 // pulled/pushed from/to a registry), see
424424 // https://github.com/moby/moby/issues/32016.
425425 out , err := exec .CommandContext (ctx , "docker" , "image" , "inspect" , "--format" , "{{.Id}}" , "--" , image ).CombinedOutput ()
426426 if err != nil {
427- return "" , fmt .Errorf ("error inspecting docker image (try `docker pull %q` to fix this): %s" , image , bytes .TrimSpace (out ))
427+ if ! strings .Contains (string (out ), "No such image" ) {
428+ return "" , fmt .Errorf ("error inspecting docker image %q: %s" , image , bytes .TrimSpace (out ))
429+ }
430+ logger .Infof ("Pulling Docker image %q...\n " , image )
431+ pullCmd := exec .CommandContext (ctx , "docker" , "image" , "pull" , image )
432+ prefix := fmt .Sprintf ("docker image pull %s" , image )
433+ pullCmd .Stdout = logger .InfoPipe (prefix )
434+ pullCmd .Stderr = logger .ErrorPipe (prefix )
435+
436+ err = pullCmd .Start ()
437+ if err != nil {
438+ return "" , fmt .Errorf ("error pulling docker image %q: %s" , image , err )
439+ }
440+ err = pullCmd .Wait ()
441+ if err != nil {
442+ return "" , fmt .Errorf ("error pulling docker image %q: %s" , image , err )
443+ }
444+ }
445+ out , err = exec .CommandContext (ctx , "docker" , "image" , "inspect" , "--format" , "{{.Id}}" , "--" , image ).CombinedOutput ()
446+ // This time, the image MUST be present, so the issue must be something else.
447+ if err != nil {
448+ return "" , fmt .Errorf ("error inspecting docker image %q: %s" , image , bytes .TrimSpace (out ))
428449 }
429450 id := string (bytes .TrimSpace (out ))
430451 if id == "" {
0 commit comments