feat(reusable): forward runtime_version as RUNTIME_VERSION build-arg (#12)
Closes the cascade cache trap that bit us 5x today. Each cascade rebuild ran against the same Dockerfile + requirements.txt content, producing the same docker layer cache key — so even though publish-runtime had just shipped a new version, pip install hit the cached layer with the OLD version. Mechanism: - Reusable workflow now accepts optional `runtime_version` input - Forwarded as `--build-arg RUNTIME_VERSION=$VERSION` to docker build - Templates that declare `ARG RUNTIME_VERSION` get cache-key invalidation per-version (different ARG value → different cache key → fresh pip install layer) - Templates that don't declare the ARG silently ignore it (no breakage; phased rollout) Pairs with molecule-core PR #2181 (PyPI propagation wait + path filter expansion). Together: cascade waits until PyPI serves the new version, then fires with the version, templates rebuild against that exact version with cache invalidation. No more "I shipped 0.1.X but image installs 0.1.X-1." Phase 2 (separate PRs in template repos): each template's caller forwards `${{ github.event.client_payload.runtime_version }}` and each Dockerfile declares `ARG RUNTIME_VERSION` near pip install. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6409d65106
commit
9c7f4f5542
26
.github/workflows/publish-template-image.yml
vendored
26
.github/workflows/publish-template-image.yml
vendored
@ -40,6 +40,19 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
runtime_version:
|
||||
description: >-
|
||||
molecule-ai-workspace-runtime version to install. Forwarded
|
||||
as RUNTIME_VERSION docker build-arg. When unset, the
|
||||
Dockerfile's requirements.txt pin is used. Cascade-triggered
|
||||
builds forward client_payload.runtime_version here so each
|
||||
rebuild has a unique build-arg → unique cache key →
|
||||
guaranteed fresh `pip install`. Solves the
|
||||
"cascade rebuilt but image still has old runtime" cache
|
||||
trap that bit us repeatedly on 2026-04-27.
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
outputs:
|
||||
image:
|
||||
description: "Full image reference that was pushed (with :latest tag)"
|
||||
@ -177,6 +190,14 @@ jobs:
|
||||
tags: ${{ steps.tags.outputs.image }}:sha-${{ steps.tags.outputs.sha }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
# RUNTIME_VERSION is empty by default. When the cascade fires
|
||||
# (or workflow_dispatch is invoked with a version), it's the
|
||||
# exact runtime version about to be installed. Forwarded as a
|
||||
# build-arg so Dockerfiles that declare `ARG RUNTIME_VERSION`
|
||||
# get cache-key invalidation per-version. Templates that
|
||||
# don't declare the ARG silently ignore it (no breakage).
|
||||
build-args: |
|
||||
RUNTIME_VERSION=${{ inputs.runtime_version }}
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
@ -221,7 +242,8 @@ jobs:
|
||||
- name: Push image to GHCR (post-smoke)
|
||||
# Now that the smoke test passed, push both tags. build-push-action
|
||||
# reuses the cached build from the load step above, so this is fast
|
||||
# — it's effectively a layer push, not a rebuild.
|
||||
# — it's effectively a layer push, not a rebuild. Same build-args
|
||||
# passed for cache key consistency.
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
@ -233,6 +255,8 @@ jobs:
|
||||
${{ steps.tags.outputs.image }}:sha-${{ steps.tags.outputs.sha }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
RUNTIME_VERSION=${{ inputs.runtime_version }}
|
||||
labels: |
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user