diff --git a/.gitea/workflows/docker-publish-split.yml b/.gitea/workflows/docker-publish-split.yml index a0d6295..017dc3f 100644 --- a/.gitea/workflows/docker-publish-split.yml +++ b/.gitea/workflows/docker-publish-split.yml @@ -526,12 +526,33 @@ jobs: - build-variant-omos - build-variant-with-pi - build-variant-omos-with-pi - if: ${{ github.ref_type == 'tag' || inputs.promote_latest == 'true' }} + # Skip on cache-hit base builds: when need_build=false, base-latest + # already points at the same digest as base-, so the retag is + # a tautology and any transient failure of it is purely cosmetic. + # Manual workflow_dispatch with promote_latest=true overrides this + # gate as an escape hatch (e.g., if base-latest got hand-deleted). + if: | + inputs.promote_latest == 'true' || + (github.ref_type == 'tag' && needs.base-decide.outputs.need_build == 'true') runs-on: ubuntu-latest container: image: catthehacker/ubuntu:act-latest steps: - - uses: imjasonh/setup-crane@v0.4 + # Direct pinned install instead of imjasonh/setup-crane@v0.4. The + # action's bootstrap script calls api.github.com/.../releases/latest + # to discover the crane version, which periodically rate-limits and + # produces tag=null → download from .../download/null/... → 404 → + # 'gzip: unexpected end of file' → exit 2. Pinning removes the + # runtime dependency on GitHub API entirely. Bump CRANE_VERSION + # deliberately when you want updates. + - name: Install crane (pinned) + env: + CRANE_VERSION: v0.21.6 + run: | + set -eux + curl -fsSL "https://github.com/google/go-containerregistry/releases/download/${CRANE_VERSION}/go-containerregistry_Linux_x86_64.tar.gz" \ + | tar -xz -C /usr/local/bin crane + crane version - name: Login (crane) run: | crane auth login docker.io \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c955fc..d6bb3d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ Tags follow `v{opencode_version}[letter]` — bare tag for the first build on a ## Unreleased +CI hardening for the `promote-base-latest` job. No image-side changes — these are workflow-only edits and won't trigger a tag. + +- **Replaced `imjasonh/setup-crane@v0.4` with a direct pinned crane install.** The action's bootstrap script calls `api.github.com/.../releases/latest` to discover what crane version to install. That call periodically rate-limits and produces `tag=null` → the action downloads `releases/download/null/...` → 404 → `gzip: unexpected end of file` → exit 2. Hit this on the v1.15.3 release run (cosmetic failure — base-latest was already correct). Now we curl + extract crane v0.21.6 directly into `/usr/local/bin/`. Bump `CRANE_VERSION` deliberately when wanting updates, same pattern as the other GitHub-sourced binaries in the Dockerfile layer. +- **Gated `promote-base-latest` on `need_build == 'true'`.** When the base layer hash hasn't changed (cache-hit on the existing `base-` from a previous run), `base-latest` already points at the correct digest, so the retag is a tautology. Skipping in that case removes a class of cosmetic failure (no-op-that-fails). Manual `workflow_dispatch` with `promote_latest: true` overrides the gate as an escape hatch for hand-recovery scenarios. Tagged releases that genuinely rebuild the base still promote as before. + ## v1.15.3 — 2026-05-16 opencode 1.15.0 → 1.15.3 bump (three upstream patch releases).