1name: Image
2
3on:
4 push:
5 branches: [main] # main → :main and :sha-xxxx tags
6 tags: ['v*.*.*'] # v1.4.0 → :1.4.0 :1.4 :latest
7 pull_request: # PRs: build only, no push
8
9env:
10 REGISTRY: ghcr.io
11 IMAGE: ${{ github.repository }} # owner/repo (lowercased by metadata-action)
12
13jobs:
14 image:
15 runs-on: ubuntu-latest
16 permissions:
17 contents: read # checkout
18 packages: write # push to ghcr.io
19 steps:
20 - uses: actions/checkout@v7
21
22 - name: Log in to GHCR
23 if: github.event_name != 'pull_request' # no push on PRs
24 uses: docker/login-action@v4
25 with:
26 registry: ${{ env.REGISTRY }}
27 username: ${{ github.actor }} # who triggered the run
28 password: ${{ secrets.GITHUB_TOKEN }} # no PAT needed
29
30 - name: Tags & labels
31 id: meta # referenced below
32 uses: docker/metadata-action@v6
33 with:
34 images: ${{ env.REGISTRY }}/${{ env.IMAGE }}
35 tags: |
36 type=ref,event=branch # :main
37 type=ref,event=pr # :pr-12
38 type=semver,pattern={{version}} # :1.4.0
39 type=semver,pattern={{major}}.{{minor}} # :1.4
40 type=sha # :sha-9fceb02
41
42 - uses: docker/setup-qemu-action@v4 # emulate arm64 on x86
43 - uses: docker/setup-buildx-action@v4 # BuildKit builder
44
45 - name: Build & push
46 uses: docker/build-push-action@v7
47 with:
48 context: . # Dockerfile folder
49 platforms: linux/amd64,linux/arm64 # multi-arch (e.g. Oracle ARM VM)
50 push: ${{ github.event_name != 'pull_request' }}
51 tags: ${{ steps.meta.outputs.tags }}
52 labels: ${{ steps.meta.outputs.labels }}
53 cache-from: type=gha # reuse layers from last run
54 cache-to: type=gha,mode=max
55 provenance: true # supply-chain attestation