Skip to content

Label the ESP-IDF version on both ESP images - #28

Merged
hacker-cb merged 2 commits into
masterfrom
label-idf-version
Aug 24, 2026
Merged

Label the ESP-IDF version on both ESP images#28
hacker-cb merged 2 commits into
masterfrom
label-idf-version

Conversation

@hacker-cb

Copy link
Copy Markdown
Contributor

Closes #26.

A consumer that pins these images by digest — the only pin nothing can move
underneath it — deliberately does not keep the tag, so the tag is the one place it
cannot read the ESP-IDF version from. Until now the answer lived only inside the
image, behind a 3.6–7.5 GB pull. The Matter half already had a registry-readable
pin (org.opencontainers.image.revision carries ESP_MATTER_REF); the IDF half
had nothing, since org.opencontainers.image.version there is 24.04, inherited
from the ubuntu base.

Both images now carry dev.jethome.idf.version, in the same dev.jethome.*
family the host image uses.

Where the value comes from

esp-idf already has it — IDF_BASE_TAG, which names its own base. It only
needed re-declaring after FROM, or the LABEL would have expanded to the empty
string without Docker objecting.

esp-matter takes a new IDF_VERSION arg. Not because the label needs it —
Docker inherits a base image's LABELs, so building on this repository's esp-idf
carries the label down by itself. What inheritance cannot do is check the value,
and it carries nothing at all when BASE_IMAGE points somewhere else. CI passes
that base as a digest, and a digest names no version, so the value comes from
images/versions.json, taken from the same base_tag the digest was resolved
from.

That is the same value written twice, which is safe because the checker already
refuses a variant built with a version its own tag does not name — setting
IDF_VERSION to v5.5.5 on the variant tagged idf-v5.4.1-matter-v1.4.2 fails
./scripts/check-versions.sh, verified.

The label is asserted, not declared

Both verification layers already ran idf.py --version and printed it. Both now
compare it for equality against the labelled version, so an image whose label
contradicts its contents fails to build rather than shipping. Equality rather than
a substring, because *v5.4.1* also matches v5.4.11 — and the failure message
names both the expected and the reported value, since a build arg is not otherwise
visible in the log.

esp-idf asserts only when IDF_BASE_TAG is a version. Its README offers
latest and minor-line tags such as v5.3 as valid bases for a custom build, and
an alias never equals the release it resolves to, so an unconditional comparison
would fail builds that are perfectly valid. The skip is announced in the log
rather than silent, and it applies locally only: CI always passes an exact version
from images/versions.json, so every published image is asserted. The label then
repeats whatever was passed — which means a label shaped like an exact version is
exactly the one that was checked.

Documentation held to the same bar

  • The registry-side recipe needs the platform key —
    {{ index (index .Image "linux/amd64").Config.Labels … }} — because these tags
    are multi-arch indexes, and .Image.Config on an index is a template error
    rather than an answer. Both forms were run against the published images.
  • The docker image inspect variant is marked as reading the local daemon, not
    the registry.
  • Every custom-build recipe that overrides BASE_IMAGE now passes IDF_VERSION
    beside it — in the image README and in CLAUDE.md — or the build asserts the
    default version and fails after the expensive SDK install.

What was not verified locally

espressif/idf:v5.5.5 would not pull on the machine this was written on, so
neither ESP image was built here. What that leaves, and how it was covered:

  • the exact output shape (one line, ESP-IDF v<version>) was read from the master
    run's logs for four combinations — both IDF versions × both images × both
    architectures;
  • the assertion's own logic was exercised in a plain container against a match, a
    mismatch, an alias and an empty answer;
  • ./scripts/lint.sh (hadolint included), ./scripts/check-versions.sh, the
    matrix generator and an offline link check are green.

This pull request is the real check: it builds both images on both
architectures. If an assertion is wrong, it fails in the verification layer, which
prints the expected and the reported value side by side.

Note on the checks

images/versions.json is in every image workflow's paths: filter, so this also
rebuilds host and platformio. That is the documented trade of keeping the version
data in one file.

Closes #26.

A consumer that pins these images by digest - the only pin nothing can move
underneath it - deliberately does not keep the tag, so the tag is the one place
it cannot read the version from. Until now that left no cheap way to check which
ESP-IDF an image carries: the answer existed only inside it, behind a 3.6-7.5 GB
pull. The Matter half already had the registry-readable half of this
(org.opencontainers.image.revision carries ESP_MATTER_REF); the IDF half had
nothing, since org.opencontainers.image.version there is 24.04, inherited from
the ubuntu base.

Both images now carry `dev.jethome.idf.version`, in the same family the host
image uses.

esp-idf has the value already - IDF_BASE_TAG, which names its own base - and only
needs it re-declared after FROM, or the LABEL would expand to the empty string
without Docker objecting. esp-matter takes a new IDF_VERSION arg. Not because the
label needs it - Docker inherits a base image's LABELs, so building on this
repository's esp-idf would carry the label down by itself - but because
inheritance cannot *check* the value, and carries nothing at all when BASE_IMAGE
points elsewhere. CI passes that base as a digest, and a digest names no version,
so the value comes from images/versions.json, taken from the same `base_tag` the
digest was resolved from. That is the same value written twice, which is safe
because the checker refuses a variant built with a version its own tag does not
name: setting IDF_VERSION to v5.5.5 on the variant tagged idf-v5.4.1-matter-v1.4.2
fails ./scripts/check-versions.sh, verified.

**The label is asserted, not declared.** Both verification layers already ran
`idf.py --version` and printed it; both now compare it for equality against the
labelled version, so an image whose label contradicts its contents fails to build
rather than shipping. Equality rather than a substring, because `*v5.4.1*` also
matches v5.4.11 - and with the expected value in the failure message, since a
build arg is not otherwise visible in the log.

esp-idf asserts only when IDF_BASE_TAG *is* a version. Its README offers `latest`
and minor-line tags like `v5.3` as valid bases, and an alias never equals the
release it resolves to, so a strict comparison would have failed builds that are
perfectly valid. The skip is announced rather than silent, and applies locally
only: CI always passes an exact version, so every published image is asserted.

The docs get the same treatment as the code. The registry-side recipe needs the
platform key - `{{ index (index .Image "linux/amd64").Config.Labels … }}` - because
these tags are multi-arch indexes and `.Image.Config` on an index is a template
error, not an answer; both forms were run against the published images. The
`docker image inspect` variant is marked as reading the local daemon rather than
the registry. And every custom-build recipe that overrides BASE_IMAGE now passes
IDF_VERSION beside it, in the image README and in CLAUDE.md, or the build asserts
the default version and fails after the expensive SDK install.

Note on what was NOT verified locally: `espressif/idf:v5.5.5` would not pull here
(Surge intercepts traffic in TUN mode and drops the connection around 400 MB,
while that image carries a single 3.4 GB layer), so neither ESP image was built on
this machine. The exact output shape - one line, `ESP-IDF v<version>` - was read
out of the master run's logs for four combinations: both IDF versions, both
images, both architectures. The assertion's own logic was exercised in a plain
container against a match, a mismatch, an alias and an empty answer. The build
itself is checked by the pull request, which builds both images on both
architectures.
Copilot AI lite review requested due to automatic review settings August 24, 2026 03:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a registry-readable label for the ESP-IDF version to both ESP images (esp-idf and esp-matter), and strengthens verification so the label is asserted against idf.py --version during the build. This fits the repo’s goal of publishing Docker images with metadata that consumers can validate without pulling multi-GB layers.

Changes:

  • Add dev.jethome.idf.version label to images/esp-idf/Dockerfile and images/esp-matter/Dockerfile.
  • Pass IDF_VERSION for esp-matter builds via images/versions.json, and assert it matches the SDK-reported version.
  • Document how to read the label from the registry (and locally) in both image READMEs, and update CLAUDE.md guidance.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
images/versions.json Adds IDF_VERSION to esp-matter build args so CI can label/assert even when the base is referenced by digest.
images/esp-matter/README.md Documents reading the IDF version label and updates custom-build instructions to include IDF_VERSION.
images/esp-matter/Dockerfile Introduces IDF_VERSION ARG, labels it, and asserts idf.py --version matches.
images/esp-idf/README.md Documents how to read dev.jethome.idf.version from the registry and locally, plus assertion semantics.
images/esp-idf/Dockerfile Adds the IDF version label and asserts it matches idf.py --version (with alias-skip behavior).
CLAUDE.md Updates repo-wide CI/build documentation to reflect the new IDF_VERSION flow for esp-matter.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread images/esp-idf/Dockerfile Outdated
Comment thread images/esp-matter/README.md
Comment thread CLAUDE.md
… docs

Copilot's three points on #28.

The `case` glob `v[0-9]*.[0-9]*.[0-9]*` was not the test its own comment
described: `*` swallows anything, so `v5.5.5-rc1` and `v5.5.5-dirty` were taken
for exact versions and asserted against - the opposite of what that branch exists
for. An anchored `[[ =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]` says it exactly; bash is
already this image's SHELL. Verified against v5.5.5, v5.5.5-rc1, v5.5.5-dirty,
v5.x.y, v5.3, latest and v5.10.12.

The esp-matter custom-build recipe used the same `v<version>` placeholder for
IDF_VERSION and ESP_MATTER_VERSION, which invites copying one value into both;
they are now `v<idf-version>` and `v<matter-version>`, and the base tag matches.
CLAUDE.md's local recipe said `IDF_VERSION=<version>` with no leading `v`, which
would have produced a confusing assertion failure - it now shows the form the SDK
reports.
Copilot AI review requested due to automatic review settings August 24, 2026 03:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread images/esp-matter/Dockerfile
@hacker-cb
hacker-cb merged commit 4ff001c into master Aug 24, 2026
23 checks passed
@hacker-cb
hacker-cb deleted the label-idf-version branch August 24, 2026 03:32
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.

Label the ESP-IDF version on the esp-idf and esp-matter images

2 participants