Add ESP-IDF v5.5.5 with Matter 1.5.1 and 1.6, pinned by commit - #15
Conversation
Adds rather than replaces: the idf-v5.4.1 line and its Matter v1.4.2 variant keep building while projects still pin them. Both are non-primary, so they publish only their own version tags; latest and sha-<commit> follow ESP-IDF v5.5.5 with Matter 1.6. images/versions.json records why they are still there and what to do about it later - the published tags survive in GHCR regardless, they just stop being rebuilt once the entries go. Both Matter branches want exactly ESP-IDF v5.5.5 (checked against each branch's README), so the two variants share one base and esp-idf is built once for them. Matter 1.6 is primary because it carries the newer specification; 1.5 stays available under its own tag for anyone who needs 1.5.1 for certification. After PR-3 this is a data edit: three entries in images/versions.json and the matching ARG defaults, with check-versions.sh verifying they agree. It also confirmed the tags do not collide - none is a prefix of another, which matters because digests are downloaded by glob. Verified locally: ./scripts/build.sh esp-idf reports ESP-IDF v5.5.5, Python 3.12.3, pytest 9.1.1. ESP-Matter is not buildable on this machine (~50 GB), but PR-4 means CI now builds it on the pull request, on the very ESP-IDF this branch produces - which is the first time a version bump gets checked as the pair it will become. The chip table in the ESP-IDF README was stale in two directions: it never listed ESP32-C2, and v5.5.5 promotes ESP32-C5 and ESP32-C61 out of preview. Taken from `idf.py --list-targets` in the built image rather than from the release notes. The ESP-Matter chip table is left alone - that branch's README publishes no such list, so there is nothing to verify it against.
…t tags Publishing several variants of one image exposed three things that could not happen when each image had exactly one. A failing variant withheld every variant's tags. esp-matter-manifest depends on esp-matter-build as a whole, so the legacy v1.4.2 leg breaking - and it builds from a moving branch with unpinned submodules - would skip the manifest for the new primary too: latest stays on the old release while the new images sit in GHCR untagged, with their legs green. The manifest jobs now run under !cancelled() with an explicit prepare check, so each leg publishes its own tags and fails only on its own missing digests. Non-primary variants had no immutable tag. Only the primary got sha-<commit>; everything else had a version tag that imagetools create rewrites on every push. A consumer pinned to idf-v5.4.1 who hit a regression from a routine rebuild had no name for the build that used to work. Every variant now also gets <version>-sha-<commit>. The README told users to pin matter-v1.5 if the specification matters. It does not mean what it looks like: ESP-Matter publishes no git tags, so the image is built from branch release/v1.5, whose HEAD already carries specification v1.5.1 - checked against that branch's own README - and will carry v1.5.2 in time, under the same image tag. Documented, with the command that reports what an image actually contains. Pinning the upstream commit is the real fix and is tracked separately. Also from the review: the chip table now says it describes the primary version - ESP32-C5 and C61 are supported in 5.5.x but preview in 5.4.x, which this same commit keeps publishing - and the preview targets are found with `idf.py --preview --list-targets`, not `--list-targets`, which prints only the supported set. Verified against the built image both ways.
There was a problem hiding this comment.
Pull request overview
This PR expands the repo’s Docker image “version matrix” to publish ESP-IDF v5.5.5 and ESP-Matter variants for Matter 1.5 and 1.6, while keeping the existing v5.4.1 / Matter v1.4.2 line building for compatibility. It updates both the Dockerfile defaults and the CI manifest/tagging logic to support multiple concurrently published variants.
Changes:
- Add new ESP-IDF (
idf-v5.5.5) and ESP-Matter (idf-v5.5.5-matter-v1.6primary,...-v1.5non-primary) variants toimages/versions.jsonwhile retaining the older v5.4.1/v1.4.2 variants. - Bump default build ARGs in the ESP-IDF and ESP-Matter Dockerfiles to the new primary versions.
- Adjust CI manifest job conditions and tag publication so non-primary variants also get an immutable
...-sha-...tag and manifest jobs aren’t withheld by unrelated variant failures; update documentation accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| images/versions.json | Adds new esp-idf/esp-matter build variants (v5.5.5 + Matter 1.5/1.6) and documents keeping legacy variants building. |
| images/esp-matter/README.md | Documents multi-variant publishing behavior and clarifies how tags relate to upstream Matter branches. |
| images/esp-matter/Dockerfile | Updates default base/tag ARGs to ESP-IDF v5.5.5 and Matter v1.6. |
| images/esp-idf/README.md | Documents multi-version publishing and clarifies supported-chip table scope relative to the primary version. |
| images/esp-idf/Dockerfile | Updates default ESP-IDF base tag to v5.5.5. |
| CLAUDE.md | Updates repo CI/tagging guidance to reflect multi-variant builds and immutable per-variant sha tags. |
| .github/workflows/platformio.yml | Adjusts manifest job condition and adds per-variant immutable sha tagging. |
| .github/workflows/esp-idf.yml | Adjusts manifest job condition and adds per-variant immutable sha tagging for esp-idf and esp-matter. |
Suppressed comments (2)
images/esp-matter/README.md:65
- The recommended immutable tag format is shown as
...-sha-<commit>, but the workflows only publish...-sha-<7 chars>(short SHA). Adjusting the placeholder here improves accuracy.
- `latest` moves when the primary does, which happens on a version bump. Pin the
version tag if the Matter specification matters to you, and
`idf-v<idf-ver>-matter-v<matter-ver>-sha-<commit>` if you need the exact build —
the version tag is rewritten on every rebuild.
.github/workflows/esp-idf.yml:468
- The comment uses
sha-<commit>/<version>-sha-<commit>placeholders, but the job tags use a 7-character short SHA (${GITHUB_SHA:0:7}). Keeping the comment consistent with the implementation reduces the chance of mistaken documentation elsewhere.
# Only the primary variant moves `latest` and the bare `sha-<commit>`.
# Every variant gets `<version>-sha-<commit>`: the version tag itself is
# rewritten on every push, so without it a consumer pinned to a
# non-primary variant has no name for the build they were running.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot caught that every tag table and comment wrote sha-<commit> while the
workflows publish ${GITHUB_SHA:0:7}. A reader following the docs would look for a
full-length SHA tag that has never existed. Replaced throughout, with one concrete
example in each tag table so the format is unambiguous. This one predates the
series - it was on the follow-up list from the documentation pass.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Suppressed comments (1)
images/esp-matter/README.md:71
- The
docker runexample expands$ESP_MATTER_PATHin the host shell before Docker runs the container, so on most hosts it will be empty and the command will fail. Usesh -c(orbash -lc) inside the container so$ESP_MATTER_PATHis resolved there.
`docker run --rm <image> git -C $ESP_MATTER_PATH rev-parse HEAD`.
The matter-v1.5 tag carried specification v1.5.1, and the CSA list confirms 1.5.1 is the current release of that line. Two separate problems: the name was wrong, and nothing stopped it going wrong again. Renamed to idf-v5.5.5-matter-v1.5.1, and every variant now pins the exact upstream commit. ESP-Matter publishes no git tags - only moving release/* branches - so a branch names a line rather than a release: release/v1.5 carried v1.5 at one commit and v1.5.1 at another, and would carry v1.5.2 under the same image tag. The Dockerfile fetches the pinned SHA instead of cloning the branch, which GitHub serves as a shallow fetch (verified: 6.9 MB of .git, and the checked-out commit matches the requested one inside a container build). Submodules need no pin of their own - their commits are recorded in the tree, so fixing the superproject fixes all of it. The pin lives in a `pin` field rather than `args`, because the checker requires every args value to appear in the image tag and a SHA never will. What it checks instead: the value is a full 40-character SHA, and the Dockerfile declares that ARG - a pin naming an argument that does not exist would be dropped by Docker and the build would quietly take the default. scripts/update-matter-ref.sh reports where each pin sits against its branch head and advances them on --write, so picking up upstream work is an edit with a diff rather than a side effect of the next rebuild. Verified both directions. The resulting commit is also recorded as org.opencontainers.image.revision, so `docker image inspect` answers "what is in here" without starting the container.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Suppressed comments (2)
scripts/check-versions.sh:162
- The pin SHA validation is too permissive: the glob pattern
[0-9a-f]*)only checks the first character is hex, so a 40-character string likeaZZ...would pass the length check and be accepted as a “commit SHA”. Also, check-versions currently doesn’t enforce that all variants pass the same set ofpinkeys as the primary variant, so a missing pin would silently fall back to the Dockerfile default and break reproducibility.
while IFS='|' read -r variant_tag arg value; do
[ -n "${arg}" ] || continue
case "${value}" in
[0-9a-f]*) [ "${#value}" -eq 40 ] || problem "${image}: variant '${variant_tag}' pins ${arg} to '${value}', which is not a full 40-character commit SHA" ;;
*) problem "${image}: variant '${variant_tag}' pins ${arg} to '${value}', which is not a commit SHA" ;;
esac
images/versions.json:89
- PR metadata describes the target as “Matter 1.5 and 1.6” and the table lists an
idf-v5.5.5-matter-v1.5tag, but versions.json introducesidf-v5.5.5-matter-v1.5.1(andESP_MATTER_VERSION: v1.5.1). Please confirm whether the intended published tag should be...-v1.5or...-v1.5.1, and align the PR description/title accordingly (or adjust the tag here if the PR text is correct).
"tag": "idf-v5.5.5-matter-v1.5.1",
"primary": false,
"base_tag": "idf-v5.5.5",
"upstream_branch": "release/v1.5",
"args": {
"ESP_MATTER_VERSION": "v1.5.1"
},
Four findings, one of them the same class I had already fixed for the manifest jobs and missed one job over. esp-matter-build still hung off esp-idf-build under an implicit success(). With two ESP-IDF variants, a failing legacy leg marks that whole job failed and would skip every Matter variant - including ones whose own base built fine and whose digest artifact is sitting right there. Same treatment as the manifest jobs: !cancelled() with an explicit prepare check, so each leg resolves its own base and fails by itself if it is missing. CLAUDE.md now states this as the rule for anything downstream of a multi-variant build, rather than as a fact about manifest jobs. The pin checks were weaker than the arg checks they sit next to: - `[0-9a-f]*` as a shell pattern constrains only the first character, so `44dfffd…zzzz` passed the preflight and would have failed later at git fetch. Checked against `*[!0-9a-f]*` now, and the length separately. - The primary variant's pin was never compared with the Dockerfile ARG default - the exact invariant the ordinary args loop exists to hold. After `update-matter-ref.sh --write`, CI would build the new commit while ./scripts/build.sh checked out the old one. - A variant with no `pin` at all emitted no row, so the loop could not see it: the Dockerfile would fall back to the primary's commit and publish one variant's tree under another's tag. Same key-set rule as args. Each verified by breaking it: a non-hex pin, an advanced pin with a stale ARG default, and a variant with its pin removed are all reported.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.
Suppressed comments (2)
scripts/update-matter-ref.sh:63
mktempwithout a template is not portable (it fails on BSD/macOS), and ifjqfails the script will exit (due toset -e) leaving the temp file behind. Using a template based on${VERSIONS}and cleaning up on failure makes--writesafer and more cross-platform.
tmp=$(mktemp)
jq --arg t "${tag}" --arg h "${head}" \
'(.images[].builds[] | select(.tag == $t) | .pin.ESP_MATTER_REF) = $h' \
"${VERSIONS}" >"${tmp}"
mv "${tmp}" "${VERSIONS}"
scripts/check-versions.sh:173
versions-matrix.shmergesargsandpininto onebuild_argsmap, so any overlapping key would be silently overridden (jq object+prefers the RHS).check-versions.shvalidatesargsandpinseparately, but doesn’t currently fail fast on collisions between the two key sets, which could lead to publishing an unexpectedly configured image under a tag.
# A variant with no `pin` at all emits no row above, so the loop cannot catch
# it - and the Dockerfile would fall back to the primary's commit, publishing
# one variant's tree under another variant's tag. Same key-set rule as `args`.
The target of this series: ESP-IDF v5.5.5 with ESP-Matter 1.5.1 and 1.6. Both
Matter branches want exactly v5.5.5 — checked against each branch's own README — so
the two variants share one base and ESP-IDF is built once for them.
Adds rather than replaces. The
idf-v5.4.1line and its Matter v1.4.2 variantkeep building while projects still pin them;
images/versions.jsonrecords why andwhat to do later. Dropping them stops the rebuilds, not the tags — anything already
published survives in GHCR regardless.
idf-v5.5.5latestidf-v5.4.1idf-v5.5.5-matter-v1.6latestidf-v5.5.5-matter-v1.5.1idf-v5.4.1-matter-v1.4.2After PR-3 the bump itself is a data edit — three entries and the matching
ARGdefaults, with
check-versions.shverifying they agree and confirming no tag is aprefix of another (digests are downloaded by glob).
What multiple variants exposed
Three problems that could not exist while each image had exactly one variant. All
found by review, all fixed here.
A failing variant withheld every variant's tags.
esp-matter-manifestdependson
esp-matter-buildas a whole, so the legacy v1.4.2 leg breaking — and it buildsfrom a moving branch with unpinned submodules — would skip the manifest for the new
primary too.
lateststays on the old release, the new images sit in GHCRuntagged, and their own legs are green. The manifest jobs now run under
!cancelled()with an explicitpreparecheck: each leg publishes its own tagsand fails only on its own missing digests.
Non-primary variants had nothing to roll back to. Only the primary got
sha-<commit>; the rest had a version tag thatimagetools createrewrites onevery push. Someone pinned to
idf-v5.4.1who hit a regression from a routinerebuild had no name for the build that used to work. Every variant now also gets
<version>-sha-<commit>.matter-v1.5did not mean specification 1.5 — and this is now fixed ratherthan documented. ESP-Matter publishes no git tags, only moving
release/*branches, so a branch names a line:
release/v1.5carried specification v1.5 atone commit and v1.5.1 at another, which is what the branch head holds today and
what the image actually contained.
Two changes, since the wrong name and the moving target are separate problems:
idf-v5.5.5-matter-v1.5.1, matching what is inside. CSA lists1.5.1 as the current release of that line.
shallowly instead of cloning a branch, so a rebuild reproduces the same tree
rather than picking up whatever landed upstream since. Submodules need no pin of
their own — their commits are recorded in the tree, so fixing the superproject
fixes all of it.
The pin lives in a
pinfield rather thanargs, because the checker requiresevery
argsvalue to appear in the image tag and a SHA never will. What it checksinstead: a full 40-character SHA, and that the Dockerfile declares that
ARG— apin naming an argument that does not exist would be dropped by Docker, and the
build would quietly take the default.
scripts/update-matter-ref.shreports where each pin sits against its branch headand advances it on
--write, so picking up upstream work is an edit with a diff.The commit is also recorded as an OCI label:
Verified that GitHub serves a shallow fetch of an arbitrary SHA (6.9 MB of
.git),and that inside a container build the checked-out commit matches the requested
one.
Documentation
The chip table now states it describes the primary version: ESP32-C5 and
ESP32-C61 are supported in 5.5.x but preview in 5.4.x, which this same commit
keeps publishing. It was also missing ESP32-C2 entirely, which predates this bump.
And preview targets are not printed by
idf.py --list-targets— that prints thesupported set only.
idf.py --preview --list-targetsis the one that addslinux,esp32h21,esp32h4. Verified both ways against the built image.Verification
./scripts/build.sh esp-idf→ESP-IDF v5.5.5, Python 3.12.3, pytest 9.1.1idf.py --list-targetsin that image, not from release notes./scripts/check-versions.shgreen; generated matrices inspected (6 esp-matterlegs, 4 esp-idf legs, correct
primaryflags and shared base)update-matter-ref.shreports a stale pinand restores it with
--write; the shallow fetch by SHA confirmed inside acontainer build
it on this pull request — on the very ESP-IDF this branch produces. This is the
first version bump in the repository's history that is checked as the pair it
will become, rather than discovered on master.
Reviewed by
codex-review(xhigh) — no findings. Thecode-reviewworkflow (high) — tendefects, all confirmed, the three above being the substantial ones.
Note this run is the most expensive of the series: six ESP-Matter legs (three
variants × two platforms) at ~8 minutes each, plus four ESP-IDF legs. If that turns
out to be too much per pull request, building only the primary variant on PRs is a
one-line condition — worth deciding on real numbers rather than in advance.