fabrica

hanna/fabrica

ci(docker): build and publish the image to GHCR

452b717 · hanna committed on 2026-07-26

Add a workflow that builds the container image and pushes it to
ghcr.io/<owner>/<repo> on every push to main and every v* tag (plus manual
dispatch). Tags cover latest, the branch, semver, and the short SHA; builds use
the built-in GITHUB_TOKEN and a GHA layer cache. linux/amd64 only — the Rust
build is too heavy for QEMU-emulated arm64.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed by hannaSSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
1 files changed · +72 −0UnifiedSplit
.github/workflows/docker.yml +72 −0
@@ -0,0 +1,72 @@
1+# This Source Code Form is subject to the terms of the Mozilla Public
2+# License, v. 2.0. If a copy of the MPL was not distributed with this
3+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+#
5+# Build the container image and publish it to the GitHub Container Registry
6+# (ghcr.io/<owner>/<repo>) on every push to main and every version tag.
7+
8+name: docker
9+
10+on:
11+ push:
12+ branches: [main]
13+ tags: ["v*"]
14+ workflow_dispatch:
15+
16+# One in-flight build per ref; a newer push cancels the older run.
17+concurrency:
18+ group: docker-${{ github.ref }}
19+ cancel-in-progress: true
20+
21+jobs:
22+ build:
23+ runs-on: ubuntu-latest
24+ permissions:
25+ contents: read
26+ packages: write # push to GHCR with the built-in GITHUB_TOKEN
27+
28+ steps:
29+ - name: Checkout
30+ uses: actions/checkout@v4
31+
32+ - name: Set up Docker Buildx
33+ uses: docker/setup-buildx-action@v3
34+
35+ # Only authenticate when we intend to push (not on manual dry-runs of forks).
36+ - name: Log in to GHCR
37+ uses: docker/login-action@v3
38+ with:
39+ registry: ghcr.io
40+ username: ${{ github.actor }}
41+ password: ${{ secrets.GITHUB_TOKEN }}
42+
43+ - name: Derive image tags and labels
44+ id: meta
45+ uses: docker/metadata-action@v5
46+ with:
47+ images: ghcr.io/${{ github.repository }}
48+ tags: |
49+ type=ref,event=branch
50+ type=semver,pattern={{version}}
51+ type=semver,pattern={{major}}.{{minor}}
52+ type=semver,pattern={{major}}
53+ type=raw,value=latest,enable={{is_default_branch}}
54+ type=sha,format=short
55+
56+ - name: Build and push
57+ uses: docker/build-push-action@v6
58+ with:
59+ context: .
60+ push: true
61+ tags: ${{ steps.meta.outputs.tags }}
62+ labels: ${{ steps.meta.outputs.labels }}
63+ # linux/amd64 only: the image compiles the whole Rust workspace
64+ # (aws-lc-sys, vendored libgit2), so a QEMU-emulated arm64 build would
65+ # be prohibitively slow. Add linux/arm64 here with a native arm runner
66+ # if you need it.
67+ platforms: linux/amd64
68+ # A single-arch manifest — skip the extra provenance attestation that
69+ # otherwise adds an "unknown/unknown" entry to the package listing.
70+ provenance: false
71+ cache-from: type=gha
72+ cache-to: type=gha,mode=max