Skip to content

fix(ci): fix Windows image digest extraction and Docker daemon readiness#276

Merged
frostebite merged 2 commits intogame-ci:mainfrom
frostebite:fix/windows-build-pipeline
Mar 15, 2026
Merged

fix(ci): fix Windows image digest extraction and Docker daemon readiness#276
frostebite merged 2 commits intogame-ci:mainfrom
frostebite:fix/windows-build-pipeline

Conversation

@frostebite
Copy link
Copy Markdown
Member

@frostebite frostebite commented Mar 14, 2026

Summary

Fixes the Windows Docker image build pipeline, which has been failing on every run since ~Feb 18, 2026.

Root cause: The GitHub Actions windows-2022 runner image updated Docker to use the containerd image store, which returns a stripped-down docker inspect format. The Config.Image field used for digest extraction is completely absent in this format, causing every Windows build to fail at the "Report publication" step with Error: Input required and not supplied: digest.

Changes

1. Fix digest extraction (all 5 Windows workflows)

Replaces:

$Digest = $ImageDetails.Config.Image

With:

$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]

RepoDigests is present in both old and new Docker inspect formats and contains the actual registry digest after push.

Evidence from run logs:

  • Before Feb 18 (Docker 27.5.1, run 21906028620): Config.Image populated → builds succeeded
  • After Feb 18 (containerd image store, run 22401227174): Config.Image absent → every build fails with empty digest

2. Add Docker daemon readiness check (all 5 Windows workflows)

Adds a polling step before docker login that waits for the Docker service to be running and responsive. Works around actions/runner-images#13729, a confirmed regression where the Docker Engine service sometimes fails to start on windows-2022 runners.

The step is a no-op when Docker is already running (exits immediately). Can be removed once the upstream fix is deployed.

Files changed

  • .github/workflows/new-windows-base-image-requested.yml
  • .github/workflows/new-windows-hub-image-requested.yml
  • .github/workflows/new-windows-legacy-editor-image-requested.yml
  • .github/workflows/new-windows-post-2019-2-editor-image-requested.yml
  • .github/workflows/retry-windows-editor-image-requested.yml

Test plan

  • Verify RepoDigests[0] produces a valid sha256:... digest on a Windows build
  • Verify the Docker readiness step is a no-op on healthy runners
  • Confirm the retry loop stops after merge (builds report publication successfully)

🤖 Generated with Claude Code

Apply five targeted fixes across all Windows workflow files:

1. Add "Wait for Docker daemon" step before any docker commands to
   handle cases where the Docker service is not yet ready on Windows
   runners, preventing spurious login/pull failures.

2. Fix digest extraction to use RepoDigests instead of the incorrect
   Config.Image path, which returns the base image hash rather than
   the actual pushed image digest.

3. Handle "image already exists" gracefully in the retry workflow by
   extracting the existing digest and reporting success instead of
   failing the entire workflow.

4. Scope "Report failure" conditions to reference specific build step
   outcomes rather than using broad failure()/cancelled() checks that
   would misfire when unrelated steps (like report-publication) fail.

5. Fix missing $ prefixes in hub workflow's workflow_dispatch branch
   where github.event.inputs expressions were not being evaluated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Cat Gif

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

Five Windows GitHub workflows are updated with a new "Wait for Docker daemon" step that polls the Docker service with retries and starts it if stopped. Additionally, image digest extraction is modified to use RepoDigests instead of Config.Image, parsing the digest portion after the '@' separator.

Changes

Cohort / File(s) Summary
Windows Workflow Docker Daemon Checks
.github/workflows/new-windows-base-image-requested.yml, new-windows-hub-image-requested.yml, new-windows-legacy-editor-image-requested.yml, new-windows-post-2019-2-editor-image-requested.yml, retry-windows-editor-image-requested.yml
Adds PowerShell polling step to wait for Docker daemon readiness with 10 retries and 6-second delays; starts service if stopped; modifies image digest extraction from ImageDetails.Config.Image to RepoDigests[0] with '@' separator parsing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A rabbit in white whiskers did fidget and wait,
For Docker to wake—"Don't be late, do not be late!"
From Config to RepoDigests we trace,
Five workflows now run at a speedier pace! 🐰

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: fixing Windows image digest extraction and adding Docker daemon readiness checks.
Description check ✅ Passed The description is comprehensive and well-structured, detailing root causes, specific fixes, affected files, and a test plan. It exceeds the minimal template requirements significantly.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@frostebite
Copy link
Copy Markdown
Member Author

Readiness & Safety Assessment

What's the actual fix vs defense-in-depth?

Fix 2 (digest extraction) is the root cause fix. The field $ImageDetails.Config.Image is null on Windows containers — it's a Linux Docker artifact that returns the base image's content hash, not the pushed image's digest. Replacing it with $ImageDetails[0].RepoDigests[0] (split on @ to get sha256:...) is the correct field per Docker API documentation. This single fix breaks the infinite retry loop at its first link: if the digest is correct, publication reports succeed, and none of the downstream failures ever trigger.

The other fixes are defense-in-depth:

  • Fix 1 (Docker daemon wait): Workaround for actions/runner-images#13729, a confirmed regression in windows-2022 runners where the Docker Engine service sometimes fails to start. A fix from GitHub is awaiting-deployment. This step is a no-op when Docker is already ready (adds 0 seconds of latency).
  • Fix 3 (image-already-exists handling): Safety net so that if a retry IS dispatched for an already-published image, it reports success instead of exit 1. This prevents future retry loops from other failure modes.
  • Fix 4 (report failure scoping): Prevents false failure reports when the build succeeded but backend reporting had a transient error. Changes condition from failure() (any step) to checking specific build step outcomes.
  • Fix 5 ($ prefix): Separate typo fix — {{ github.event.inputs.* }}${{ github.event.inputs.* }} in the hub workflow's workflow_dispatch branch.

Can this be tested before merge?

No integration testing is possible before merge. The Windows build workflows only execute via repository_dispatch (from versioning-backend) or workflow_dispatch (manual, but only works on the default branch). The test.yml CI workflow only triggers on Dockerfile/script changes, not workflow YAML changes.

However, all fixes are validatable by code review:

Fix Provably correct? Risk Evidence
Digest extraction ✅ Yes — Docker API docs confirm Config.Image ≠ pushed digest, RepoDigests does Very Low Wrong field is documented
Docker daemon wait ✅ Defensive, no-op when healthy Low npipe errors in run logs
Image-already-exists ✅ Mostly — new code path but existing behavior is demonstrably broken Low-Medium 30+ consecutive exit 1 failures in run history
Failure condition ✅ Yes — steps.*.outcome logic is straightforward Very Low 4+ runs confirmed false failure reports
$ prefix ✅ Trivial syntax fix Zero Obvious typo

Safety

  • No behavioral change to successful builds. All fixes only affect failure/error paths.
  • Worst-case regression for Fix 2: If RepoDigests is empty (image not pushed), the digest would be empty — same as the current broken behavior. But the push step always precedes the inspect step, so RepoDigests will be populated.
  • Worst-case regression for Fix 3: If docker pull of the existing image fails, the workflow would still fail — but with a better error message than the current exit 1.
  • Fix 1 has zero downside: If Docker is already running, the step completes in <1 second.

Recommendation

Merge-and-observe. The last 30+ Windows workflow runs on main have ALL failed. The current code is provably broken. These fixes address the documented failure modes with well-understood, low-risk changes. The digest extraction fix alone would resolve the primary infinite retry loop.

@webbertakken
Copy link
Copy Markdown
Member

  1. Docker daemon readiness: Prevents failures when the Docker service is not yet available on Windows runners

I don't think this has ever failed. Should we be fixing a non-issue?

  1. Digest extraction: Fixes incorrect image digest being reported to the backend.

Nice catch if that is indeed the case. Have you verified that it doesn't report the right hash?

  1. Retry workflow resilience: Handles pre-existing images gracefully instead of failing

This is currently failing by design. Because if an image already exists, the integrity of versioning backend isn't correct.

If the actual problem gets fixed, then this should not be a problem. This fix is then only hiding the problem allowing silent degredation of the system.

  1. Failure reporting accuracy: Scopes failure reports to actual build failures only

The system needs to know not just the build failure, but also if it failed to upload

  1. Expression evaluation: Fixes broken workflow_dispatch parameter resolution in the hub workflow

Was it in fact broken? I remember rescheduling builds from the versioning page working fine.

Note that while this might be a good fix, it doesn't fix the actual problem the pipeline is suffering from.

I would suggest to first focus on solving the real issue at hand, get to a state where we can guarantee it can build all target platforms for all versions on all platforms without getting stuck halfway though.

I haven't checked the latest issue, but usually the issue is one of two things:

  1. that one of the images doesn't build correctly 15 times in a row, meaning there is something in the dockerfile or build dsetup that doesn't work for a specific version / target platform which should be fixed.

or

  1. some glitch in the system that breaks the self healing pattern.

Note, in the first four years, point 2 has never ever happened, because of the integrity of the system. With the introduction of some workflows and/or a non integer change to versioning backend, this record was broken.

See also my previous PR with attempted (partial) fix and comments on Discord about how to reason about it.

Remove fixes 3-5 to keep the PR focused on the two confirmed root causes:
- Fix 1: Docker daemon readiness check before build (all 5 workflows)
- Fix 2: Digest extraction via RepoDigests[0] instead of Config.Image (all 5 workflows)

Reverted changes:
- Fix 3: retry workflow "already exists" skip-build logic
- Fix 4: Report failure condition scoping (restored failure()||cancelled())
- Fix 5: Missing $ prefixes in hub workflow (debatable whether broken)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@frostebite
Copy link
Copy Markdown
Member Author

Thanks for the thorough review. You're right — I was over-scoping this. I've trimmed the PR down to only the two root cause fixes and dropped fixes 3/4/5 that were undermining the system's integrity. Also closed the versioning-backend PR (#80) — the scheduling system isn't the problem.

Here's what remains and the evidence:


Digest extraction — the actual root cause

Verified in run logs. The GitHub runner image update around Feb 17 (20260123.48420260217.39.1) switched Docker to the containerd image store, which returns a different docker inspect format.

Before Feb 18 (Docker 27.5.1, run 21906028620):

"Config": {
    "Hostname": "",
    "Domainname": "",
    "Image": "sha256:afe51f0a3f631c02630454c8a2ea6d3aacad16ecf7641cbe3dcab157993f2299",
    ...
}

Config.Image was populated → digest reported correctly → builds succeeded.

After Feb 18 (containerd image store, run 22401227174):

"Config": {
    "Cmd": ["c:\windows\system32\cmd.exe"],
    "Env": [...],
    "Shell": ["powershell.exe", "-Command"]
}

Config.Image is completely absent$Digest is null → digest= is empty → report-to-backend fails with:

Error: Input required and not supplied: digest

This error appears in every failing Windows run since Feb 18 across all target platforms.

The fix replaces $ImageDetails.Config.Image with ($ImageDetails[0].RepoDigests[0] -split '@')[1]. RepoDigests is present in both old and new Docker inspect formats and contains the actual registry digest after push.


Docker daemon readiness — secondary but real

The npipe errors do occur, though I understand this may not have been seen before the retry storm started. Evidence from retry runs:

  • Run 22481097847 (Feb 27): failed to connect to the docker API at npipe:////./pipe/docker_engine
  • Run 22469868033 (Feb 27): same error
  • Run 22464867135 (Feb 26): same error

This correlates with actions/runner-images#13729, a confirmed regression in windows-2022 runners. GitHub has a fix awaiting-deployment. The readiness step is a no-op when Docker is already running (adds 0 seconds of latency), and can be removed once the upstream fix is deployed. Happy to drop this too if you'd rather keep the PR minimal — the digest fix is what actually matters.


Dropped from PR

  • Retry "image exists" handling — you're right, failing by design preserves backend integrity
  • Report failure condition scoping — system needs to know about upload failures too
  • ${{ }} prefix fix — unverified impact, separate concern

Also closed versioning-backend#80 — the self-healing system works correctly once the builds stop failing.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/new-windows-base-image-requested.yml:
- Around line 157-158: Guard access to RepoDigests before indexing: check that
$ImageDetails[0].RepoDigests exists and has at least one element, then extract
$RepoDigest and split to get $Digest and validate $Digest is non-empty; if the
array is missing or the parsed digest is empty, log an error and exit non-zero
(or fail the job) instead of continuing. Update the same pattern where
$RepoDigest, $ImageDetails, $Digest, or RepoDigests are used in the listed
workflows.

In @.github/workflows/new-windows-legacy-editor-image-requested.yml:
- Around line 230-231: The code assumes $ImageDetails[0].RepoDigests[0] exists
and blindly sets $RepoDigest and $Digest; add defensive checks to validate
$ImageDetails and $ImageDetails[0].RepoDigests are non-null and non-empty before
accessing index 0, and if validation fails write a clear error and set the job
step to failure (e.g., throw/exit with non-zero) so we don't emit digest=$null;
update the logic around $RepoDigest and $Digest to only parse ($RepoDigest
-split '@')[1] after those checks and fail the step with a descriptive message
when digest extraction cannot be performed.

In @.github/workflows/new-windows-post-2019-2-editor-image-requested.yml:
- Around line 237-238: Add explicit guards before reading
$ImageDetails[0].RepoDigests and before using the -split '@' result: check that
$ImageDetails is non-null and has at least one element, that
$ImageDetails[0].RepoDigests exists and has Length -gt 0, and that ($RepoDigest
-split '@') returns at least two elements before accessing index [1] to assign
$Digest; apply the same checks to the identical pattern in the other 4 workflow
files.

In @.github/workflows/retry-windows-editor-image-requested.yml:
- Around line 169-170: Validate that ImageDetails[0].RepoDigests exists and has
at least one element before assigning $RepoDigest and ensure the split on '@'
yields two parts before assigning $Digest; specifically, guard access to
$ImageDetails and its RepoDigests array (check for $null and .Count -gt 0), only
set $RepoDigest = $ImageDetails[0].RepoDigests[0] when present, then perform the
($RepoDigest -split '@') and verify the resulting array has a second element
before assigning $Digest, otherwise handle the missing value (log/throw/set a
clear default) so downstream reporting does not get a silent empty value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1990e27-8a0b-4bf6-abef-5e0fa922db4e

📥 Commits

Reviewing files that changed from the base of the PR and between 1a94952 and 1ebe9d4.

📒 Files selected for processing (5)
  • .github/workflows/new-windows-base-image-requested.yml
  • .github/workflows/new-windows-hub-image-requested.yml
  • .github/workflows/new-windows-legacy-editor-image-requested.yml
  • .github/workflows/new-windows-post-2019-2-editor-image-requested.yml
  • .github/workflows/retry-windows-editor-image-requested.yml

Comment on lines +157 to +158
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify all affected workflows use unguarded RepoDigests indexing.
rg -n -C2 '\$RepoDigest = \$ImageDetails\[0\]\.RepoDigests\[0\]|\$Digest = \(\$RepoDigest -split '\''@'\''\)\[1\]' \
  .github/workflows/new-windows-base-image-requested.yml \
  .github/workflows/new-windows-hub-image-requested.yml \
  .github/workflows/new-windows-legacy-editor-image-requested.yml \
  .github/workflows/new-windows-post-2019-2-editor-image-requested.yml \
  .github/workflows/retry-windows-editor-image-requested.yml

Repository: game-ci/docker

Length of output: 4167


Guard RepoDigests before indexing across all image build workflows.

Lines 157–158 in .github/workflows/new-windows-base-image-requested.yml (and the same pattern in 4 other workflows) assume RepoDigests[0] exists without validation. If the array is empty or missing, the digest extraction silently fails, producing an empty value while the workflow continues to report success.

This pattern appears in:

  • .github/workflows/new-windows-base-image-requested.yml (157–158)
  • .github/workflows/new-windows-hub-image-requested.yml (163–164)
  • .github/workflows/new-windows-legacy-editor-image-requested.yml (230–231)
  • .github/workflows/new-windows-post-2019-2-editor-image-requested.yml (237–238)
  • .github/workflows/retry-windows-editor-image-requested.yml (169–170)

Add presence checks before accessing RepoDigests[0] and validate the parsed digest is non-empty:

Proposed hardening
           $MetaData = docker inspect unityci/base:windows-${{ steps.buildParameters.outputs.repoVersionFull }}
           $ImageDetails = $MetaData | ConvertFrom-Json
-          $RepoDigest = $ImageDetails[0].RepoDigests[0]
-          $Digest = ($RepoDigest -split '@')[1]
+          if (-not $ImageDetails -or -not $ImageDetails[0].RepoDigests -or $ImageDetails[0].RepoDigests.Count -eq 0) {
+            Write-Error "RepoDigest not found after push."
+            exit 1
+          }
+          $RepoDigest = $ImageDetails[0].RepoDigests[0]
+          $Digest = ($RepoDigest -split '@')[1]
+          if (-not $Digest) {
+            Write-Error "Failed to parse digest from RepoDigest: $RepoDigest"
+            exit 1
+          }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
if (-not $ImageDetails -or -not $ImageDetails[0].RepoDigests -or $ImageDetails[0].RepoDigests.Count -eq 0) {
Write-Error "RepoDigest not found after push."
exit 1
}
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
if (-not $Digest) {
Write-Error "Failed to parse digest from RepoDigest: $RepoDigest"
exit 1
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/new-windows-base-image-requested.yml around lines 157 -
158, Guard access to RepoDigests before indexing: check that
$ImageDetails[0].RepoDigests exists and has at least one element, then extract
$RepoDigest and split to get $Digest and validate $Digest is non-empty; if the
array is missing or the parsed digest is empty, log an error and exit non-zero
(or fail the job) instead of continuing. Update the same pattern where
$RepoDigest, $ImageDetails, $Digest, or RepoDigests are used in the listed
workflows.

Comment on lines +230 to +231
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

head -n 250 .github/workflows/new-windows-legacy-editor-image-requested.yml | tail -n 30

Repository: game-ci/docker

Length of output: 1444


🏁 Script executed:

sed -n '200,240p' .github/workflows/new-windows-legacy-editor-image-requested.yml

Repository: game-ci/docker

Length of output: 3005


🏁 Script executed:

sed -n '1,50p' .github/workflows/new-windows-legacy-editor-image-requested.yml

Repository: game-ci/docker

Length of output: 1494


🏁 Script executed:

rg -A3 "RepoDigest" .github/workflows/

Repository: game-ci/docker

Length of output: 2659


🏁 Script executed:

rg "ConvertFrom-Json" .github/workflows/ -B2 -A5

Repository: game-ci/docker

Length of output: 4701


Add null/empty checks before accessing and parsing RepoDigests.

Lines 230-231 assume digest data exists without validation. If RepoDigests is empty or the property is missing, the array access returns $null, and splitting $null produces unexpected results. This causes $Digest to be $null, silently writing invalid metadata (digest=$null) to GITHUB_OUTPUT and corrupting downstream reporting. The same vulnerable pattern exists across five workflow files:

  • new-windows-legacy-editor-image-requested.yml
  • new-windows-post-2019-2-editor-image-requested.yml
  • retry-windows-editor-image-requested.yml
  • new-windows-hub-image-requested.yml
  • new-windows-base-image-requested.yml

Add validation before parsing: check that $ImageDetails and $ImageDetails[0].RepoDigests are non-empty, and fail the step if digest extraction fails.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/new-windows-legacy-editor-image-requested.yml around lines
230 - 231, The code assumes $ImageDetails[0].RepoDigests[0] exists and blindly
sets $RepoDigest and $Digest; add defensive checks to validate $ImageDetails and
$ImageDetails[0].RepoDigests are non-null and non-empty before accessing index
0, and if validation fails write a clear error and set the job step to failure
(e.g., throw/exit with non-zero) so we don't emit digest=$null; update the logic
around $RepoDigest and $Digest to only parse ($RepoDigest -split '@')[1] after
those checks and fail the step with a descriptive message when digest extraction
cannot be performed.

Comment on lines +237 to +238
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/new-windows-post-2019-2-editor-image-requested.yml | sed -n '230,250p'

Repository: game-ci/docker

Length of output: 1083


🏁 Script executed:

head -n 235 .github/workflows/new-windows-post-2019-2-editor-image-requested.yml | tail -n 100

Repository: game-ci/docker

Length of output: 6618


🏁 Script executed:

rg "RepoDigests\|docker inspect" -B 3 -A 3 --type yaml

Repository: game-ci/docker

Length of output: 206


🏁 Script executed:

rg "RepoDigests" -B 3 -A 3

Repository: game-ci/docker

Length of output: 40


🏁 Script executed:

find .github/workflows -name "*.yml" -exec grep -l "docker inspect" {} \;

Repository: game-ci/docker

Length of output: 358


🏁 Script executed:

grep -n "RepoDigest\|-split '@'" .github/workflows/new-windows-base-image-requested.yml .github/workflows/new-windows-hub-image-requested.yml .github/workflows/new-windows-legacy-editor-image-requested.yml .github/workflows/retry-windows-editor-image-requested.yml

Repository: game-ci/docker

Length of output: 969


🏁 Script executed:

grep -n "if.*RepoDigests\|if.*-split\|error\|try\|catch" .github/workflows/new-windows-base-image-requested.yml | head -20

Repository: game-ci/docker

Length of output: 235


Add explicit guards before accessing RepoDigests array and parsing digest.

Lines 237-238 lack null/length checks. Add validation that $ImageDetails[0].RepoDigests is not empty and that the split operation produces at least 2 elements before accessing index [1]. This pattern appears identically in 5 workflow files and should be hardened across all of them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/new-windows-post-2019-2-editor-image-requested.yml around
lines 237 - 238, Add explicit guards before reading $ImageDetails[0].RepoDigests
and before using the -split '@' result: check that $ImageDetails is non-null and
has at least one element, that $ImageDetails[0].RepoDigests exists and has
Length -gt 0, and that ($RepoDigest -split '@') returns at least two elements
before accessing index [1] to assign $Digest; apply the same checks to the
identical pattern in the other 4 workflow files.

Comment on lines +169 to +170
$RepoDigest = $ImageDetails[0].RepoDigests[0]
$Digest = ($RepoDigest -split '@')[1]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd -t f "retry-windows-editor-image-requested.yml" --exec cat -n {}

Repository: game-ci/docker

Length of output: 40


🏁 Script executed:

git ls-files | grep -i "retry-windows-editor-image-requested"

Repository: game-ci/docker

Length of output: 116


🏁 Script executed:

cat -n .github/workflows/retry-windows-editor-image-requested.yml | sed -n '150,190p'

Repository: game-ci/docker

Length of output: 2828


Add validation before accessing RepoDigests array.

Lines 169–170 access nested array elements without guards. If docker inspect returns incomplete data or RepoDigests is empty, $RepoDigest becomes $null, causing $Digest to be $null and silently outputting an empty value downstream in the reporting step. Add checks to verify RepoDigests is non-empty and the split produces the expected parts before proceeding.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/retry-windows-editor-image-requested.yml around lines 169
- 170, Validate that ImageDetails[0].RepoDigests exists and has at least one
element before assigning $RepoDigest and ensure the split on '@' yields two
parts before assigning $Digest; specifically, guard access to $ImageDetails and
its RepoDigests array (check for $null and .Count -gt 0), only set $RepoDigest =
$ImageDetails[0].RepoDigests[0] when present, then perform the ($RepoDigest
-split '@') and verify the resulting array has a second element before assigning
$Digest, otherwise handle the missing value (log/throw/set a clear default) so
downstream reporting does not get a silent empty value.

@frostebite frostebite changed the title fix(ci): resolve Windows Docker build pipeline failures fix(ci): fix Windows image digest extraction and Docker daemon readiness Mar 15, 2026
Copy link
Copy Markdown
Member

@webbertakken webbertakken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revision and the super clean explanation!

LGTM!

@frostebite frostebite merged commit 81d5923 into game-ci:main Mar 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants