π Enhancements
fix: guard summary jq against null Entrypoint/Cmd/Env Andriy Knysh (@aknysh) (#111)
## what- Guard the
Docker Inspectjob-summaryjqexpressions againstnullfields by wrapping each iterating expression with// []:.[0].Config.Entrypoint | join(" ")β(.[0].Config.Entrypoint // []) | join(" ").[0].Config.Cmd | join(" ")β(.[0].Config.Cmd // []) | join(" ").[0].Config.Env[] | ...β(.[0].Config.Env // [])[] | ....[0].RootFS.Layers | to_entries[] | ...β(.[0].RootFS.Layers // []) | to_entries[] | ...
why
The summary step (added in #98) feeds several docker inspect fields straight into jq's join, .[], and to_entries, all of which iterate their input. When an image defines no ENTRYPOINT (and/or no CMD/ENV), those fields are null in docker inspect, so jq aborts with:
jq: error (at inspect.json:79): Cannot iterate over null (null)
Under GitHub Actions' default bash --noprofile --norc -e -o pipefail shell, that non-zero exit fails the entire Docker Build step with exit code 5 β even though the image built and pushed successfully. Only the post-build job summary is broken, but the whole job (and thus the release) reports failure.
Every fixture in test/ is FROM nginx, which inherits a non-null entrypoint and cmd, so the summary path never exercised a null field. Any entrypoint-less image trips it β e.g. Atmos's FROM debian:trixie-slim image, whose release build hit exactly this:
proof
Entrypoint: null reproduces the failure with the old expression and is fixed by the new one; populated images are unaffected:
$ echo '[{"Config":{"Entrypoint":null}}]' | jq -r '.[0].Config.Entrypoint | join(" ")'
jq: error (at <stdin>:0): Cannot iterate over null (null) # exit 5
$ echo '[{"Config":{"Entrypoint":null}}]' | jq -r '(.[0].Config.Entrypoint // []) | join(" ")'
# exit 0, empty
$ echo '[{"Config":{"Entrypoint":["/bin/atmos"]}}]' | jq -r '(.[0].Config.Entrypoint // []) | join(" ")'
/bin/atmos # still worksreferences
- Regresses images without an
ENTRYPOINT/CMD/ENV; introduced by the structured summary in #98. - A regression fixture would need an entrypoint-less test image plus a summary-enabled (
inspect: true) run against the registry β happy to add as a follow-up if desired (the currenttest/*scenarios run withinspect: false).