Skip to content

Commit a213a9b

Browse files
DockerBuild: tie Claude DayStamp mixing to Dockerfile content, not -Claude flag
The daily cache-busting DayStamp added in 1ced9ca was mixed into the image hash only when -Claude was on the command line. That breaks the two-step TeamCity pattern that shares a Claude Dockerfile between PrepareImage (-BuildImage, no -Claude) and a main runner step (-NoBuildImage -Claude): the two invocations compute different content hashes, so docker run in the main step tries to pull a tag that was never built or pushed and fails with an ACR "unauthorized" HEAD. Observed on Metalama_Metalama20261_MetalamaConsolidated_Claude #643 — Step 3 built build-396451cf73a3fde5, Step 4 looked for build-dcaec122766f2bab. Pre-1ced9ca builds of the same config produced identical hashes across both steps. Key the DayStamp decision off the Dockerfile body instead: if the file contains "update.timestamp" (i.e. it uses the daily-invalidation layer emitted by TimestampComponent), rotate the hash; otherwise don't. Both steps read the same Dockerfile, so they now agree on the tag. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f90b1ae commit a213a9b

2 files changed

Lines changed: 20 additions & 6 deletions

File tree

DockerBuild.ps1

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,16 @@ try
760760
}
761761

762762
# Generate content-based hash for image tag.
763-
# In Claude mode, mix in $script:DayStamp so the tag rotates daily
764-
# and picks up fresh @latest npm installs.
765-
$hashDayStamp = if ($Claude) { $script:DayStamp } else { $null }
763+
# Mix $script:DayStamp in whenever the Dockerfile bakes in the
764+
# update.timestamp cache-invalidation layer (which itself rotates
765+
# daily). Keying this off the Dockerfile content — not the -Claude
766+
# runtime flag — keeps PrepareImage (-BuildImage, typically no
767+
# -Claude) and the main step (-NoBuildImage -Claude) in sync when
768+
# they share a Dockerfile; otherwise the two steps compute
769+
# different tags and docker run tries to pull a tag that was never
770+
# built or pushed.
771+
$dockerfileBody = Get-Content $dockerfileFullPath -Raw -ErrorAction SilentlyContinue
772+
$hashDayStamp = if ($dockerfileBody -and $dockerfileBody -match 'update\.timestamp') { $script:DayStamp } else { $null }
766773
$contentHash = Get-ContentHash `
767774
-DockerfilePath $dockerfileFullPath `
768775
-ContextDirectory $dockerContextDirectory `

src/PostSharp.Engineering.BuildTools/Resources/DockerBuild.ps1

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,16 @@ try
760760
}
761761

762762
# Generate content-based hash for image tag.
763-
# In Claude mode, mix in $script:DayStamp so the tag rotates daily
764-
# and picks up fresh @latest npm installs.
765-
$hashDayStamp = if ($Claude) { $script:DayStamp } else { $null }
763+
# Mix $script:DayStamp in whenever the Dockerfile bakes in the
764+
# update.timestamp cache-invalidation layer (which itself rotates
765+
# daily). Keying this off the Dockerfile content — not the -Claude
766+
# runtime flag — keeps PrepareImage (-BuildImage, typically no
767+
# -Claude) and the main step (-NoBuildImage -Claude) in sync when
768+
# they share a Dockerfile; otherwise the two steps compute
769+
# different tags and docker run tries to pull a tag that was never
770+
# built or pushed.
771+
$dockerfileBody = Get-Content $dockerfileFullPath -Raw -ErrorAction SilentlyContinue
772+
$hashDayStamp = if ($dockerfileBody -and $dockerfileBody -match 'update\.timestamp') { $script:DayStamp } else { $null }
766773
$contentHash = Get-ContentHash `
767774
-DockerfilePath $dockerfileFullPath `
768775
-ContextDirectory $dockerContextDirectory `

0 commit comments

Comments
 (0)