Skip to content

fix(ci): the v-prefixed image alias must be {{raw}}, not v{{version}} (+ VERSION 0.9.5-rc2) - #2505

Merged
obasilakis merged 2 commits into
devfrom
fix/publish-images-prerelease-v-alias
Sep 2, 2026
Merged

fix(ci): the v-prefixed image alias must be {{raw}}, not v{{version}} (+ VERSION 0.9.5-rc2)#2505
obasilakis merged 2 commits into
devfrom
fix/publish-images-prerelease-v-alias

Conversation

@obasilakis

@obasilakis obasilakis commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Refs #2281 (DigitalOcean Marketplace packer bundle — this unblocks its build)
Refs #2280 (prebuilt images + pull-only hosted compose — the workflow this fixes)
Refs #2332 (Epic: one-click hosted install)

Closes nothing: each stays open on its own acceptance criteria.


Blocks the DigitalOcean snapshot. Found by cutting v0.9.5-rc1 — same family as #2499, one line over.

Two commits, deliberately batched: the workflow fix, and the VERSION bump to 0.9.5-rc2. Both are prerequisites for the same rc2 cut and need the same reviewer; dev is protected, so splitting them would buy a second full review cycle for a one-line file. The playbook already batches release-prep writes this way (Step 4 + Step 6a share one branch).

What happened

All five packages published 0.9.5-rc1 and sha-0f4d54d. No v0.9.5-rc1. Verified against the live registry:

trinity-backend        0.9.5-rc1, sha-0f4d54d
trinity-frontend       0.9.5-rc1, sha-0f4d54d
trinity-scheduler      0.9.5-rc1, sha-0f4d54d
trinity-mcp-server     0.9.5-rc1, sha-0f4d54d
trinity-agent-base     0.9.5-rc1, sha-0f4d54d

v{{version}} is a component pattern, so metadata-action drops it for a pre-release under the same documented rule that correctly drops {{major}}.{{minor}}:

"Pre-release (rc, beta, alpha) will only extend {{version}} (or {{raw}} if specified) as tag"

#2499 reasoned about that rule for {{major}}.{{minor}} and didn't carry it one line up. {{raw}} is the documented exception, and it keeps the v (v1.2.3v1.2.3).

Why it isn't cosmetic

It broke the marketplace build — the one thing the RC was cut for. packer/digitalocean/scripts/01-provision.sh feeds a single TRINITY_IMAGE_TAG to two consumers that need different strings the moment those strings diverge:

line 86:   git clone --depth 1 --branch "${TRINITY_IMAGE_TAG}"    # wants the GIT tag → v0.9.5-rc1
line 93:   docker pull ghcr.io/abilityai/trinity-${img}:${TAG}    # wants the IMAGE tag → 0.9.5-rc1
line 101:  docker pull ghcr.io/abilityai/trinity-agent-base:${TAG}

They're the same string only while this alias exists. Without it there is no value of image_tag that builds the snapshot: v0.9.5-rc1 fails both docker pulls, 0.9.5-rc1 fails the git clone.

#2280's comment predicted the shape of this exactly — "makes the release name and the image tag the same string, which is what anyone reading the releases page will type" — it just didn't account for the pre-release rule removing the alias on precisely the tags where nobody had looked yet.

It also silently degrades real releases' operator ergonomics: every doc and start.sh's own pin warning say TRINITY_IMAGE_TAG=v0.9.0, and start.sh:529 blames the operator's spelling when that 404s.

The change

- type=semver,pattern=v{{version}},enable=${{ github.event_name == 'push' }}
+ type=semver,pattern={{raw}},enable=${{ github.event_name == 'push' }}

v0.9.5v0.9.5 (identical for real releases) · v0.9.5-rc1v0.9.5-rc1 (currently nothing).

{{version}} and {{major}}.{{minor}} are untouched — the first is what a prerelease extends, the second is correctly withheld from one.

Verification

  • tests/unit/test_2471_publish_images_prerelease_latest.py extended to 5 tests, all passing. Verified to catch the bug: reverting the one-line change fails 2 of them.
  • The suite now pins the asymmetry in both directions — {{raw}} present, v{{version}} absent, and no hyphen guard on any semver pattern (an RC must stay pullable by its exact tag).
  • yaml.safe_load on the workflow — parses.
  • Behaviour confirmed against docker/metadata-action's documented pre-release rule, and against the live GHCR tag list above.

After this lands

v0.9.5-rc1 is not re-cut — an RC tag is immutable by the playbook's own rule, since its images may already sit in a vendor queue. With VERSION already at 0.9.5-rc2 from this PR, the next step is just the tag push, then packer build -var image_tag=v0.9.5-rc2 — the first time that command can succeed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K9bL6DZ8QVyrSvPybp5ZuK

`v{{version}}` is a COMPONENT pattern, so docker/metadata-action drops it for a
pre-release under the same documented rule that correctly drops
`{{major}}.{{minor}}`: "Pre-release (rc, beta, alpha) will only extend
{{version}} (or {{raw}} if specified) as tag". `{{raw}}` is the documented
exception and keeps the `v`.

Observed on v0.9.5-rc1: all five packages published `0.9.5-rc1` and
`sha-0f4d54d`, and NO `v0.9.5-rc1`.

That is not cosmetic — it broke the marketplace build outright, which is the
one thing the RC was cut for. `packer/digitalocean/scripts/01-provision.sh`
feeds a single `TRINITY_IMAGE_TAG` to two consumers that need different
strings once they diverge:

    line 86:  git clone --depth 1 --branch "${TRINITY_IMAGE_TAG}"   -> v0.9.5-rc1
    line 93:  docker pull ghcr.io/abilityai/trinity-*:${TAG}        -> 0.9.5-rc1

They are the same string only while this alias exists, so its absence leaves
NO value of `image_tag` able to build the snapshot. #2280's own comment
predicted the failure ("makes the release name and the image tag the same
string, which is what anyone reading the releases page will type") — it just
did not account for the pre-release rule silently removing the alias.

`{{version}}` and `{{major}}.{{minor}}` are untouched: the first is what a
prerelease extends, the second is correctly withheld from one.

Guarded by tests/unit/test_2471_publish_images_prerelease_latest.py (extended
from the #2499 suite) — verified to fail against the pre-fix expression.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9bL6DZ8QVyrSvPybp5ZuK
Rides this PR rather than its own: `dev` is protected, so every write costs a
review cycle, and both changes are prerequisites for the same rc2 cut with the
same reviewer. The playbook already batches release-prep writes onto one
`chore/release-<semver>` branch (Step 4 + Step 6a) — splitting them here was
ceremony, not safety.

rc2 rather than a re-cut of rc1: an RC tag is immutable by the playbook's own
rule, because a snapshot built from it may already sit in a vendor queue.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9bL6DZ8QVyrSvPybp5ZuK
@obasilakis obasilakis changed the title fix(ci): the v-prefixed image alias must be {{raw}}, not v{{version}} fix(ci): the v-prefixed image alias must be {{raw}}, not v{{version}} (+ VERSION 0.9.5-rc2) Sep 2, 2026

@webmixgamer webmixgamer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed with /review, /cso --diff and /validate-pr: no critical findings.

  • Tests verified locally: 5 pass on the branch, and restoring the origin/dev workflow line fails exactly the 2 alias tests.
  • Bug reproduced against GHCR with an anonymous manifest inspect: trinity-backend:0.9.5-rc1 present, :v0.9.5-rc1 absent.
  • metadata-action rule confirmed in the vendor README ({{raw}} keeps the v on a pre-release); the four docker/* SHA pins resolve to the versions their comments claim.

One ask before merge: add Refs #2281 to the body, matching #2499 and #2471, so the PR is traceable to the listing it unblocks. A flow-doc paragraph for the pre-release tag set (hosted-install.md still describes release tags only) follows in a separate docs PR.

@obasilakis
obasilakis merged commit bb31eef into dev Sep 2, 2026
25 checks passed
webmixgamer added a commit that referenced this pull request Sep 2, 2026
)

Review artifacts from validating the publish-images `{{raw}}` alias fix:

- docs/memory/learnings.md: a tag-push-only workflow is never exercised
  by PR CI, so audit every sibling tag rule against the metadata-action
  pre-release rule and verify against the live registry after the first
  RC push (the #2499 -> #2505 incomplete-fix chain).
- docs/security-reports/cso-diff-2026-09-02-2505-*: diff-scoped CSO
  audit, zero findings; four docker/* action SHA pins verified against
  their version tags.

Refs #2281

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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