@@ -670,6 +670,7 @@ If you know what you're doing and would like to suppress this warning, use one o
670670 this . _dotenvVariables = await this . initProducerReportsDotenvVariables ( writeStreams , Utils . expandVariables ( this . _variables ) ) ;
671671 const expanded = Utils . unscape$$Variables ( Utils . expandVariables ( { ...this . _variables , ...this . _dotenvVariables } ) ) ;
672672 const imageName = this . imageName ( expanded ) ;
673+ const imagePlatform = this . imagePlatform ( expanded ) ;
673674 const helperImageName = argv . helperImage ;
674675 const safeJobName = this . safeJobName ;
675676
@@ -682,7 +683,7 @@ If you know what you're doing and would like to suppress this warning, use one o
682683 }
683684
684685 if ( imageName ) {
685- await this . pullImage ( writeStreams , imageName ) ;
686+ await this . pullImage ( writeStreams , imageName , imagePlatform ) ;
686687
687688 const buildVolumeName = this . buildVolumeName ;
688689 const tmpVolumeName = this . tmpVolumeName ;
@@ -971,6 +972,11 @@ If you know what you're doing and would like to suppress this warning, use one o
971972 dockerCmd += `--user ${ imageUser } ` ;
972973 }
973974
975+ const imagePlatform = this . imagePlatform ( expanded ) ;
976+ if ( imagePlatform ) {
977+ dockerCmd += `--platform ${ imagePlatform } ` ;
978+ }
979+
974980 if ( this . argv . containerEmulate ) {
975981 const runnerName : string = this . argv . containerEmulate ;
976982
@@ -1213,6 +1219,13 @@ If you know what you're doing and would like to suppress this warning, use one o
12131219 return Utils . expandText ( image [ "docker" ] [ "user" ] , vars ) ;
12141220 }
12151221
1222+ private imagePlatform ( vars : { [ key : string ] : string } = { } ) : string | null {
1223+ const image = this . jobData [ "image" ] ;
1224+ if ( ! image ) return null ;
1225+ if ( ! image [ "docker" ] ) return null ;
1226+ return Utils . expandText ( image [ "docker" ] [ "platform" ] , vars ) ;
1227+ }
1228+
12161229 get imageEntrypoint ( ) : string [ ] | null {
12171230 const image = this . jobData [ "image" ] ;
12181231
@@ -1254,21 +1267,33 @@ If you know what you're doing and would like to suppress this warning, use one o
12541267 }
12551268 }
12561269
1257- private async pullImage ( writeStreams : WriteStreams , imageToPull : string ) {
1270+ private async pullImage ( writeStreams : WriteStreams , imageToPull : string , imagePlatform : string | null = null ) {
12581271 const pullPolicy = this . argv . pullPolicy ;
1272+ const platformArgs = imagePlatform ? [ "--platform" , imagePlatform ] : [ ] ;
1273+ const platformSuffix = imagePlatform ? ` (${ imagePlatform } )` : "" ;
12591274 const actualPull = async ( ) => {
12601275 await this . validateCiDependencyProxyServerAuthentication ( imageToPull ) ;
12611276 const time = process . hrtime ( ) ;
1262- await Utils . spawn ( [ this . argv . containerExecutable , "pull" , imageToPull ] ) ;
1277+ await Utils . spawn ( [ this . argv . containerExecutable , "pull" , imageToPull , ... platformArgs ] ) ;
12631278 const endTime = process . hrtime ( time ) ;
1264- writeStreams . stdout ( chalk `${ this . formattedJobName } {magentaBright pulled} ${ imageToPull } in {magenta ${ prettyHrtime ( endTime ) } }\n` ) ;
1279+ writeStreams . stdout ( chalk `${ this . formattedJobName } {magentaBright pulled} ${ imageToPull } ${ platformSuffix } in {magenta ${ prettyHrtime ( endTime ) } }\n` ) ;
12651280 this . refreshLongRunningSilentTimeout ( writeStreams ) ;
12661281 } ;
12671282
12681283 if ( pullPolicy === "always" ) {
12691284 await actualPull ( ) ;
12701285 return ;
12711286 }
1287+ // The `image inspect` cache check is platform-agnostic — a different-arch
1288+ // variant of the same image name will satisfy it, causing the requested
1289+ // platform to silently differ from what's actually on disk. Force a pull
1290+ // when a specific platform was requested so the matching manifest is
1291+ // guaranteed locally. Pulls are idempotent: if the variant is already
1292+ // cached, `docker pull` short-circuits with "Image is up to date".
1293+ if ( imagePlatform ) {
1294+ await actualPull ( ) ;
1295+ return ;
1296+ }
12721297 try {
12731298 await Utils . spawn ( [ this . argv . containerExecutable , "image" , "inspect" , imageToPull ] ) ;
12741299 } catch {
0 commit comments