fix(phpup): publish bundles under canonical tags, propagate annotations#87
Merged
Conversation
phpup push wrote each promoted manifest to a digest-prefix tag like 'sha256-<first12hex>' instead of the canonical '<version>-<phpver>-<ts>-<os>-<arch>' shape. Bundles landed on GHCR but were unreachable to lockfile-update, which queries the canonical tag and got 404, silently dropping the entry from bundles.lock. Switch PushAll to ListKeyed (which exposes the source manifest's io.buildrush.bundle.key annotation), derive the canonical (image-name, tag) pair from the key via canonicalRefFromBundleKey, and propagate BundleKey + SpecHash annotations to the destination so LookupBySpec also resolves on the promoted remote. Reproduces the failure that left main with redis 6.3.0 in the catalog but no 6.3.0 entries in bundles.lock or canonical GHCR tags after PR #76 merged: phpup push pushed redis 6.3.0 blobs+manifests under sha256-* tags, lockfile-update HEAD'd 'redis:6.3.0-8.5-nts-linux-x86_64' and got 404, and the canonical-tag listing on GHCR remained 6.2.0-only. Comment on the previous deriveTagForPromotion explicitly flagged this as a 'PR 6 will fix' stub that never landed. Updates push_test.go to assert canonical tags + propagated annotations, adds TestCanonicalRefFromBundleKey covering core/ext/error shapes, and fixes a stale ext-key example in registry/annotations.go that used the defunct '8.4-nts' joined PHPAbi format.
3 tasks
phramz
added a commit
that referenced
this pull request
Apr 27, 2026
actions/download-artifact's merge-multiple: true overwrote each cell's oci-layout/index.json (same relative path across all 20 artifacts), leaving the merged layout's index referencing only the last cell's manifests. Cell blob bytes survived in blobs/sha256/ but were unreferenced, so phpup push only saw a fraction of the manifests it should have promoted. Symptom seen post-merge of #87 (canonical-tag fix): the publish job's Promote step succeeded but only one redis 6.3.0 canonical tag landed on GHCR — the rest were the index.json entries that got overwritten during the merge. Update lockfile then 404'd on 9 of 10 redis 6.3.0 cells. Drop merge-multiple, let each artifact land in its own subdir under out/, and loop over them in the Promote step. Each phpup push call sees a complete per-cell index.json. Net work is identical (each manifest is still pushed once).
phramz
added a commit
that referenced
this pull request
Apr 27, 2026
…89) Manually-regenerated bundles.lock from `phpup lockfile-update` against ghcr.io/buildrush. Replaces the 8 existing `ext:redis:6.2.0:{8.1..8.4}:*` entries with the corresponding 6.3.0 entries, and adds 2 new `ext:redis:6.3.0:8.5:*` entries (8.5 was previously excluded for redis pre-#76). Brings main back to a fully consistent state — catalog, lockfile, and GHCR all agree on redis 6.3.0 — completing the work started in #76. The non-redis line-level churn in this diff is in-entry digest/spec_hash refresh from the multiple publish runs that fired during the chain of fixes (#85, #86, #87, #88). Bundle keys themselves are unchanged outside of redis. Per internal/testsuite/runner.go:345-346, manifest digests are non-reproducible across pushes because meta.json carries a build-time timestamp; this is expected behavior, not a regression. Why this is committed by hand rather than auto-committed by the publish job: the publish job's git push is rejected by the main-branch ruleset ("Changes must be made through a pull request"). A follow-up will either switch the auto-commit to a bot-PR flow or grant the publish identity a ruleset bypass; until then, version-bump PRs require this manual lockfile-update PR step.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
`phpup push` was writing every promoted manifest to a digest-prefix tag like `sha256-` instead of the canonical `----` shape. Bundles landed on GHCR but were unreachable to `phpup lockfile-update`, which queries the canonical tag and got 404 — silently dropping every entry from `bundles.lock`.
This PR fixes `PushAll` to:
How this surfaced
Post-merge of #76 (redis 6.2.0 → 6.3.0), the main-branch `publish` job promoted redis 6.3.0 bundles to GHCR under tags like `php-ext-redis:sha256-11ddf05509c9`. The `Update lockfile` step then queried `php-ext-redis:6.3.0-8.5-nts-linux-x86_64` (canonical), got 404 for all 10 redis 6.3.0 cells, and emitted them as warnings — leaving the regenerated `bundles.lock` without any 6.3.0 entries. Direct GHCR query confirms: redis canonical tags top out at `6.2.0-`, while 9 `sha256-` tags exist as orphans (the bundles ARE pushed, just not addressable).
The previous `deriveTagForPromotion` function's comment explicitly flagged this as a PR-4-era stub that "PR 6 will fix via manifest annotations" — that fix never landed in PR #71 (the actual PR 6/6).
Verification
Local round-trip test `TestPushAll_RoundTrip_LayoutToInProcessRegistry` seeds a layout with two annotated manifests (php-core + php-ext-redis), runs `PushAll` against an in-process OCI registry, and verifies:
Plus `TestCanonicalRefFromBundleKey` covers all key shapes (core, ext, tool-rejection, malformed input).
`make check` green; full `internal/build` test suite passes.
After this lands
The next push to main will trigger `publish`. With this fix, the 10 redis 6.3.0 cells get pushed to GHCR under canonical tags, `lockfile-update` finds them, and `bundles.lock` finally gets the `ext:redis:6.3.0:*` entries that PR #76 needed. Main returns to a fully consistent state.
Note: the `Commit lockfile (if changed)` step still hits the repository ruleset (`Changes must be made through a pull request`) — that's a separate concern (filed conceptually; needs a follow-up PR to either bot-create-PR or ruleset-bypass). For this fix, after merge a maintainer can manually re-run `phpup lockfile-update` locally and open a one-line bundles.lock PR.
Related