Skip to content

Commit 3a63fd4

Browse files
authored
Merge pull request #69 from pi-hole/ftl-build/buildx
Use docker buildx for ftl-build containers
2 parents 2a6e5a3 + 3820c3d commit 3a63fd4

File tree

14 files changed

+282
-1006
lines changed

14 files changed

+282
-1006
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Login to container registries
2+
description: Login to container registries Docker Hub and GitHub Container Registry
3+
4+
inputs:
5+
# Actions cannot access secrets so pass them in as inputs
6+
docker_username:
7+
required: true
8+
description: The username to use to login to Docker Hub
9+
docker_password:
10+
required: true
11+
description: The password to use to login to Docker Hub
12+
ghcr_username:
13+
required: true
14+
description: The username to use to login to GitHub Container Registry
15+
ghcr_password:
16+
required: true
17+
description: The password to use to login to GitHub Container Registry
18+
19+
runs:
20+
using: "composite"
21+
steps:
22+
-
23+
name: Login to Docker Hub
24+
uses: docker/login-action@v2
25+
with:
26+
registry: docker.io
27+
username: ${{ inputs.docker_username }}
28+
password: ${{ inputs.docker_password }}
29+
-
30+
name: Login to GitHub Container Registry
31+
uses: docker/login-action@v2
32+
with:
33+
registry: ghcr.io
34+
username: ${{ inputs.ghcr_username }}
35+
password: ${{ inputs.ghcr_password }}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Merge and push
2+
description: Apply meta, create manifest, and push to container registry
3+
4+
inputs:
5+
imagename:
6+
required: true
7+
description: The name of the image to push
8+
platform:
9+
required: true
10+
description: The platform to push the image for
11+
registry:
12+
required: true
13+
description: The Registry to push the image to
14+
15+
runs:
16+
using: "composite"
17+
steps:
18+
-
19+
name: Docker meta
20+
id: meta_docker
21+
uses: docker/metadata-action@v4
22+
with:
23+
images: |
24+
${{ inputs.imagename }},enable=${{ github.event_name != 'workflow_dispatch' }}
25+
# We want to tag the image with the latest tag if the workflow was triggered by a tag
26+
flavor: |
27+
latest=${{ startsWith(github.ref, 'refs/tags/') }}
28+
# tags:
29+
# type=schedule means that a tag is applied when the workflow is triggered by a schedule event
30+
# type=ref,event=branch means that a tag is applied when the workflow is triggered by a push to a branch
31+
# type=ref,event=tag means that a tag is applied when the workflow is triggered by a push to a tag
32+
tags: |
33+
type=schedule,suffix=-${{ inputs.platform }},enable=${{ github.event_name == 'schedule' }}
34+
type=ref,event=branch,suffix=-${{ inputs.platform }},enable=${{ github.event_name != 'schedule' }}
35+
type=ref,event=tag,suffix=-${{ inputs.platform }}
36+
-
37+
name: Create manifest list and push to repository
38+
working-directory: /tmp/digests/${{ inputs.registry }}/${{ inputs.platform }}
39+
# When using composite actions, you have to specify the shell. As you
40+
# don’t specify a runner type in composite actions, you need to specify
41+
# the shell instead for each action.
42+
shell: bash
43+
run: |
44+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
45+
$(printf '${{ inputs.imagename }}@sha256:%s ' *)
46+
-
47+
name: Inspect image
48+
shell: bash
49+
run: |
50+
docker buildx imagetools inspect ${{ inputs.imagename }}:${{ steps.meta_docker.outputs.version }}

.github/workflows/ftl-build.yml

Lines changed: 150 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
name: ftl-build builds
22
on:
3-
pull_request:
4-
paths:
5-
- 'ftl-build/**'
6-
- '.github/workflows/ftl-build.yml'
73
push:
4+
# Run on all branches and tags, but only if the ftl-build directory or the
5+
# workflow itself changed. This is to avoid running the workflow on
6+
# unrelated changes.
7+
# Note that including the branch filter is necessary as otherwise (paths and tags alone),
8+
# the workflow would not run on pushes to branches that do not have a tag sticked to them.
89
tags:
910
- "**"
11+
branches:
12+
- "**"
1013
paths:
1114
- 'ftl-build/**'
1215
- '.github/workflows/ftl-build.yml'
@@ -15,83 +18,180 @@ on:
1518
# 1:30am UTC every Sunday, has no particular significance
1619
- cron: "30 1 * * 0"
1720

21+
env:
22+
DOCKER_REGISTRY_IMAGE: ${{ secrets.DOCKERHUB_NAMESPACE }}/ftl-build
23+
GITHUB_REGISTRY_IMAGE: ghcr.io/${{ github.repository_owner }}/ftl-build
24+
1825
jobs:
19-
build:
26+
build-and-test:
2027
runs-on: ubuntu-latest
2128
strategy:
2229
fail-fast: false
2330
matrix:
24-
ARCH: [aarch64, armv4t, armv5te, armv6hf, armv7hf, armv8a, x86_32, x86_64, x86_64-musl, riscv64]
31+
include:
32+
- platform: linux/amd64
33+
container: alpine:3.18
34+
- platform: linux/386
35+
container: alpine:3.18
36+
- platform: linux/arm/v5
37+
container: debian:stretch-slim
38+
- platform: linux/arm/v6
39+
container: debian:bullseye-slim
40+
- platform: linux/arm/v6
41+
container: alpine:3.18
42+
- platform: linux/arm/v7
43+
container: alpine:3.18
44+
- platform: linux/arm64/v8
45+
container: alpine:3.18
46+
- platform: linux/riscv64
47+
container: alpine:edge
48+
env:
49+
context: ${{ startsWith(matrix.container, 'alpine') && 'alpine' || 'debian' }}
2550
steps:
2651
-
2752
name: Checkout Repo
2853
uses: actions/checkout@v3
2954
-
30-
name: Set up Docker Buildx
31-
uses: docker/setup-buildx-action@v2
32-
-
33-
name: Docker meta
55+
name: Docker meta (Docker Hub and GitHub Container Registry)
3456
id: meta
3557
uses: docker/metadata-action@v4
3658
with:
59+
github-token: ${{ secrets.GITHUB_TOKEN }}
3760
images: |
38-
${{ secrets.DOCKERHUB_NAMESPACE }}/ftl-build,enable=${{ github.event_name != 'pull_request' }}
39-
ghcr.io/${{ github.repository_owner }}/ftl-build,enable=${{ github.event_name != 'pull_request' }}
40-
foo/bar,enable=${{ github.event_name == 'pull_request' }}
41-
flavor: |
42-
latest=false
61+
${{ env.DOCKER_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
62+
${{ env.GITHUB_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
63+
foo/bar,enable=${{ github.event_name == 'workflow_dispatch' }}
4364
tags: |
44-
type=ref,event=tag,suffix=-${{ matrix.ARCH }}
45-
type=ref,event=branch,suffix=-${{ matrix.ARCH }},enable=${{ github.event_name != 'schedule' }}
46-
type=ref,event=pr,suffix=-${{ matrix.ARCH }}
47-
type=raw,value=${{matrix.ARCH}},enable=${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule' }}
48-
-
49-
name: Login to DockerHub
50-
if: github.event_name != 'pull_request'
51-
uses: docker/login-action@v2
65+
type=ref,event=branch,enable=${{ github.event_name != 'schedule' }}
66+
-
67+
name: Login to DockerHub and GitHub Container Registry
68+
uses: ./.github/actions/login-repo
5269
with:
53-
username: ${{ secrets.DOCKERHUB_USER }}
54-
password: ${{ secrets.DOCKERHUB_PASS }}
70+
docker_username: ${{ secrets.DOCKERHUB_USER }}
71+
docker_password: ${{ secrets.DOCKERHUB_PASS }}
72+
ghcr_username: ${{ github.repository_owner }}
73+
ghcr_password: ${{ secrets.GITHUB_TOKEN }}
5574
-
56-
name: Login to GitHub Container Registry
57-
if: github.event_name != 'pull_request'
58-
uses: docker/login-action@v2
75+
# Add support for more platforms with QEMU (optional)
76+
# https://github.com/docker/setup-qemu-action
77+
name: Set up QEMU
78+
uses: docker/setup-qemu-action@v2
5979
with:
60-
registry: ghcr.io
61-
username: ${{ github.repository_owner }}
62-
password: ${{ secrets.GITHUB_TOKEN }}
80+
platforms: all
81+
-
82+
name: Set up Docker Buildx
83+
uses: docker/setup-buildx-action@v2
6384
-
64-
name: Build
85+
name: Build container and test-compile FTL
6586
uses: docker/build-push-action@v4
6687
with:
67-
context: ftl-build/${{ matrix.ARCH }}/.
88+
context: ftl-build/${{ env.context }}
89+
platforms: ${{ matrix.platform }}
6890
push: false
6991
target: tester
7092
tags: ${{ steps.meta.outputs.tags }}
7193
labels: ${{ steps.meta.outputs.labels }}
72-
# Caching disabled for now...
73-
# cache-from: type=gha,scope=${{ matrix.ARCH }}
74-
# cache-to: type=gha,scope=${{ matrix.ARCH }},mode=max
94+
build-args: |
95+
CONTAINER=${{ matrix.container }}
7596
-
76-
name: Build (all-in)
77-
if: matrix.ARCH == 'x86_64'
97+
name: Push builder target and push by digest (Docker Hub)
98+
id: build_docker
7899
uses: docker/build-push-action@v4
79100
with:
80-
context: ftl-build/${{ matrix.ARCH }}/.
81-
push: false
82-
target: tester-all-in
83-
tags: ${{ steps.meta.outputs.tags }}
101+
context: ftl-build/${{ env.context }}
102+
platforms: ${{ matrix.platform }}
103+
push: ${{ github.event_name != 'workflow_dispatch' }}
104+
target: builder
84105
labels: ${{ steps.meta.outputs.labels }}
106+
build-args: |
107+
CONTAINER=${{ matrix.container }}
108+
outputs: |
109+
type=image,name=${{ env.DOCKER_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
85110
-
86-
name: Push
87-
if: github.event_name != 'pull_request'
111+
name: Push builder target and push by digest (GitHub Container Registry)
112+
id: build_ghcr
88113
uses: docker/build-push-action@v4
89114
with:
90-
context: ftl-build/${{ matrix.ARCH }}/.
91-
push: true
115+
context: ftl-build/${{ env.context }}
116+
platforms: ${{ matrix.platform }}
117+
push: ${{ github.event_name != 'workflow_dispatch' }}
92118
target: builder
93-
tags: ${{ steps.meta.outputs.tags }}
94119
labels: ${{ steps.meta.outputs.labels }}
95-
# Caching disabled for now...
96-
# cache-from: type=gha,scope=${{ matrix.ARCH }}
97-
# cache-to: type=gha,scope=${{ matrix.ARCH }},mode=max
120+
build-args: |
121+
CONTAINER=${{ matrix.container }}
122+
outputs: |
123+
type=image,name=${{ env.GITHUB_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
124+
-
125+
name: Export digests
126+
run: |
127+
mkdir -p /tmp/digests/dockerhub/${{ env.context }}
128+
mkdir -p /tmp/digests/ghcr/${{ env.context }}
129+
digest_docker="${{ steps.build_docker.outputs.digest }}"
130+
touch "/tmp/digests/dockerhub/${{ env.context }}/${digest_docker#sha256:}"
131+
digest_ghcr="${{ steps.build_ghcr.outputs.digest }}"
132+
touch "/tmp/digests/ghcr/${{ env.context }}/${digest_ghcr#sha256:}"
133+
-
134+
name: Upload digest
135+
uses: actions/upload-artifact@v3
136+
with:
137+
name: digests
138+
path: /tmp/digests/*
139+
if-no-files-found: error
140+
retention-days: 1
141+
142+
# Merge all the digests into a single file
143+
# If we would push immediately above, the individual runners would overwrite each other's images
144+
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
145+
merge-and-deploy:
146+
runs-on: ubuntu-latest
147+
needs:
148+
- build-and-test
149+
steps:
150+
-
151+
name: Checkout Repo
152+
uses: actions/checkout@v3
153+
-
154+
name: Download digests
155+
uses: actions/download-artifact@v3
156+
with:
157+
name: digests
158+
path: /tmp/digests
159+
-
160+
name: Set up Docker Buildx
161+
uses: docker/setup-buildx-action@v2
162+
-
163+
name: Login to DockerHub and GitHub Container Registry
164+
uses: ./.github/actions/login-repo
165+
with:
166+
docker_username: ${{ secrets.DOCKERHUB_USER }}
167+
docker_password: ${{ secrets.DOCKERHUB_PASS }}
168+
ghcr_username: ${{ github.repository_owner }}
169+
ghcr_password: ${{ secrets.GITHUB_TOKEN }}
170+
-
171+
name: Collect and push (Alpine, Docker Hub)
172+
uses: ./.github/actions/merge-and-push
173+
with:
174+
imagename: ${{ env.DOCKER_REGISTRY_IMAGE }}
175+
platform: alpine
176+
registry: dockerhub
177+
-
178+
name: Collect and push (Debian, Docker Hub)
179+
uses: ./.github/actions/merge-and-push
180+
with:
181+
imagename: ${{ env.DOCKER_REGISTRY_IMAGE }}
182+
platform: debian
183+
registry: dockerhub
184+
-
185+
name: Collect and push (Alpine, GitHub Container Registry)
186+
uses: ./.github/actions/merge-and-push
187+
with:
188+
imagename: ${{ env.GITHUB_REGISTRY_IMAGE }}
189+
platform: alpine
190+
registry: ghcr
191+
-
192+
name: Collect and push (Debian, GitHub Container Registry)
193+
uses: ./.github/actions/merge-and-push
194+
with:
195+
imagename: ${{ env.GITHUB_REGISTRY_IMAGE }}
196+
platform: debian
197+
registry: ghcr

0 commit comments

Comments
 (0)