Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .github/workflows/image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Publish the walgit container image (Containerfile) to GitHub Container Registry as
# ghcr.io/<owner>/<repo>, for linux/amd64 and linux/arm64. Each architecture builds
# natively on a runner of its own architecture — no emulation — and the two are merged
# into one multi-arch tag.
#
# Publishes the repository's default branch (tags: latest, <branch>, sha-<short>) and
# version tags v* (tags: <version>, <major>.<minor>). Pull requests build both
# architectures without pushing, so a broken Containerfile shows up before merge.
name: image

on:
push:
branches: ["**"]
tags: ["v*"]
pull_request:
paths: [Containerfile, Cargo.toml, Cargo.lock, rust-toolchain.toml, "crates/**", "web/**", .github/workflows/image.yml]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: image-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
IMAGE: ghcr.io/${{ github.repository }}
PUBLISH: ${{ github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/v')) }}

jobs:
build:
# Branch pushes other than the default branch have nothing to publish.
if: github.event_name != 'push' || github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/v')
strategy:
fail-fast: true
matrix:
include:
- { platform: linux/amd64, runner: ubuntu-24.04 }
- { platform: linux/arm64, runner: ubuntu-24.04-arm }
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v5
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
if: env.PUBLISH == 'true'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
- id: build
uses: docker/build-push-action@v6
with:
context: .
file: Containerfile
platforms: ${{ matrix.platform }}
build-args: WALGIT_BUILD_SHA=${{ github.sha }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
outputs: ${{ env.PUBLISH == 'true' && format('type=image,name={0},push-by-digest=true,name-canonical=true,push=true', env.IMAGE) || 'type=cacheonly' }}
- name: Record the digest
if: env.PUBLISH == 'true'
run: |
mkdir -p "${{ runner.temp }}/digests"
d="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${d#sha256:}"
- uses: actions/upload-artifact@v4
if: env.PUBLISH == 'true'
with:
name: digest-${{ strategy.job-index }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1

publish:
needs: build
if: github.event_name != 'pull_request' && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/v'))
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
steps:
- uses: actions/download-artifact@v5
with:
pattern: digest-*
merge-multiple: true
path: ${{ runner.temp }}/digests
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=sha,prefix=sha-
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Merge the architectures into one tag
working-directory: ${{ runner.temp }}/digests
run: |
mapfile -t tags < <(jq -r '.tags[] | "-t", .' <<< "$DOCKER_METADATA_OUTPUT_JSON")
sources=()
for d in *; do sources+=("${IMAGE}@sha256:${d}"); done
docker buildx imagetools create "${tags[@]}" "${sources[@]}"
- name: Inspect
run: docker buildx imagetools inspect "${{ env.IMAGE }}:sha-${GITHUB_SHA::7}"