Skip to content

Commit b5d030e

Browse files
ci: publish images to GHCR on every main merge (#459)
The publish workflow only triggered on v* tags, and no tag has ever been pushed — so ghcr.io/milvus-io/talon-* did not exist and every reference to those images (docker-compose, Helm values, kubernetes manifests, docs) was dead. Publishing sha-* and latest tags from every merge to main makes the default branch continuously installable. latest now tracks main only: the tag-triggered raw latest line also fired on prereleases (v1.2.3-rc.1), and with two publishers the three matrix jobs could race a concurrent tag and main run into a mixed latest across images. flavor latest=false pins the single source. The docker-build smoke job becomes PR-only — a merge to main runs the real, publishing build, and running both would double the most expensive job for no extra signal. Cache writes move to the main-branch publish (PR- and tag-scoped cache entries are unreadable elsewhere and would only churn the 10GB Actions cache quota). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 42ffecd commit b5d030e

2 files changed

Lines changed: 32 additions & 11 deletions

File tree

.github/workflows/ci.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,10 @@ jobs:
261261
name: docker image build
262262
runs-on: ubuntu-latest
263263
# Smoke-build every container image on PRs (no push) so a broken Dockerfile
264-
# fails CI. Publishing to GHCR happens separately on tags (release-images.yml).
264+
# fails CI. A merge to main runs the real, publishing build in
265+
# release-images.yml instead — running both would double the most expensive
266+
# job in the repo for no extra signal, so this job is PR-only.
267+
if: github.event_name == 'pull_request'
265268
steps:
266269
- uses: actions/checkout@v4
267270
- uses: docker/setup-buildx-action@v3
@@ -272,30 +275,33 @@ jobs:
272275
# The latency lab is a standalone stack; validate it parses too.
273276
docker compose -f deploy/testenv/docker-compose.yml config --quiet
274277
docker compose -f deploy/testenv/docker-compose.yml --profile tools config --quiet
278+
# The builds read the main-seeded layer cache (written by
279+
# release-images.yml on every merge) but do not write. This sacrifices
280+
# layer reuse between pushes of one PR (entries written from a PR are
281+
# only readable within that PR) to keep mode=max exports from churning
282+
# the repository's 10GB Actions cache quota, which is already saturated
283+
# by the rust-cache entries every other job depends on.
275284
- name: Build coordinator image
276285
uses: docker/build-push-action@v6
277286
with:
278287
context: .
279288
file: deploy/docker/coordinator.Dockerfile
280289
push: false
281290
cache-from: type=gha,scope=coordinator
282-
cache-to: type=gha,scope=coordinator,mode=max
283291
- name: Build worker image
284292
uses: docker/build-push-action@v6
285293
with:
286294
context: .
287295
file: deploy/docker/worker.Dockerfile
288296
push: false
289297
cache-from: type=gha,scope=worker
290-
cache-to: type=gha,scope=worker,mode=max
291298
- name: Build fuse image
292299
uses: docker/build-push-action@v6
293300
with:
294301
context: .
295302
file: deploy/docker/fuse.Dockerfile
296303
push: false
297304
cache-from: type=gha,scope=fuse
298-
cache-to: type=gha,scope=fuse,mode=max
299305

300306
helm:
301307
name: helm chart

.github/workflows/release-images.yml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,24 @@ name: Release images
22

33
# Build and publish the Talon container images to GHCR.
44
#
5-
# On a version tag (vX.Y.Z) each image is pushed to
6-
# ghcr.io/<owner>/talon-<binary> with semver, major.minor, sha, and `latest`
7-
# tags. Pull requests do NOT run this workflow — the docker-build job in ci.yml
8-
# already smoke-builds every image (no push) on PRs.
5+
# Merges to main publish ghcr.io/<owner>/talon-<binary> with `latest` and
6+
# `sha-<short>` tags, so the images the compose files, Helm chart, and docs
7+
# reference always track the default branch. `latest` always converges on the
8+
# newest merged commit; rapid merges may coalesce queued runs (the per-ref
9+
# concurrency group keeps one pending slot), so an intermediate commit is not
10+
# guaranteed its own sha-* image. A version tag (vX.Y.Z) additionally
11+
# publishes semver and major.minor tags; `latest` tracks main only, so a tag
12+
# publish racing a main publish can never leave `latest` mixed across the
13+
# three images. Pull requests do NOT run this workflow — the docker-build job
14+
# in ci.yml already smoke-builds every image (no push).
915

1016
on:
1117
push:
18+
branches:
19+
- main
1220
tags:
1321
- "v*"
14-
# Allow a manual publish of `latest` from the default branch.
22+
# Allow a manual publish from the default branch.
1523
workflow_dispatch:
1624

1725
# Least-privilege: only the GHCR push needs package write; the built-in
@@ -55,12 +63,16 @@ jobs:
5563
uses: docker/metadata-action@v5
5664
with:
5765
images: ghcr.io/${{ github.repository_owner }}/talon-${{ matrix.image }}
66+
# latest=false disables the implicit `latest` that semver tags would
67+
# otherwise add (it would also fire on prereleases like v1.2.3-rc.1);
68+
# `latest` comes only from the default-branch line below.
69+
flavor: |
70+
latest=false
5871
tags: |
5972
type=semver,pattern={{version}}
6073
type=semver,pattern={{major}}.{{minor}}
6174
type=sha
6275
type=raw,value=latest,enable={{is_default_branch}}
63-
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
6476
6577
- name: Build and push
6678
uses: docker/build-push-action@v6
@@ -71,4 +83,7 @@ jobs:
7183
tags: ${{ steps.meta.outputs.tags }}
7284
labels: ${{ steps.meta.outputs.labels }}
7385
cache-from: type=gha,scope=${{ matrix.image }}
74-
cache-to: type=gha,scope=${{ matrix.image }},mode=max
86+
# Only main seeds the shared layer cache: entries written from tag
87+
# refs are unreadable by other refs, so writing them would only churn
88+
# the repository's 10GB Actions cache quota.
89+
cache-to: ${{ github.ref == 'refs/heads/main' && format('type=gha,scope={0},mode=max', matrix.image) || '' }}

0 commit comments

Comments
 (0)