-
Notifications
You must be signed in to change notification settings - Fork 5
159 lines (138 loc) · 5.01 KB
/
Copy pathbuild.yml
File metadata and controls
159 lines (138 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
name: Build & Publish Image
# Builds the production image and pushes it to the GitHub Container Registry.
#
# push to main -> :main, :edge, :sha-<commit>
# tag v1.2.3 -> :1.2.3, :1.2, :1, :latest
# tag v1.2.3-rc.1 -> :1.2.3-rc.1 (prereleases never take :latest)
#
# This workflow does not trigger on its own. ci.yml calls it from its `publish`
# job, which runs only after every check has passed — so nothing reaches the
# registry from a commit that failed CI. Because it is called rather than
# separately triggered, the github context here is the original push event, so
# branch and tag names resolve normally.
#
# workflow_dispatch is kept as a manual escape hatch for re-publishing an image
# (for example after a registry hiccup). It bypasses the CI gate by design.
#
# amd64 and arm64 are built in parallel on native runners and joined into a
# single multi-arch manifest. The `ubuntu-24.04-arm` runner is free for
# public repositories only. Drop the arm64 entry from the matrix if you
# fork this somewhere private.
on:
workflow_call:
workflow_dispatch:
env:
REGISTRY: ghcr.io
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build ${{ matrix.platform }}
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps:
# GHCR only accepts lowercase names; repository owners may be mixed case.
- name: Prepare image name and platform slug
env:
PLATFORM: ${{ matrix.platform }}
run: |
echo "IMAGE=${REGISTRY}/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
echo "PLATFORM_SLUG=${PLATFORM//\//-}" >> $GITHUB_ENV
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to the container registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract image metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.IMAGE }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@v7
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
provenance: false
cache-from: type=gha,scope=${{ env.PLATFORM_SLUG }}
cache-to: type=gha,mode=max,scope=${{ env.PLATFORM_SLUG }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
env:
DIGEST: ${{ steps.build.outputs.digest }}
run: |
mkdir -p /tmp/digests
touch "/tmp/digests/${DIGEST#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digests-${{ env.PLATFORM_SLUG }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
name: Publish manifest
needs: [ build ]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Prepare image name
run: echo "IMAGE=${REGISTRY}/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
- name: Download digests
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to the container registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract image metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.IMAGE }}
# latest=auto applies :latest to stable semver tags only, so a
# prerelease like v1.2.3-rc.1 never becomes :latest.
flavor: latest=auto
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix=sha-
type=raw,value=edge,enable={{is_default_branch}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${IMAGE}@sha256:%s " *)
- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE}:${{ steps.meta.outputs.version }}"