Skip to content

Commit 55116df

Browse files
authored
Merge pull request #152 from pi-hole/github-builder
Use https://github.com/docker/github-builder to build and push image
2 parents ad78db5 + 66b562f commit 55116df

2 files changed

Lines changed: 79 additions & 178 deletions

File tree

.github/workflows/ftl-build.yml

Lines changed: 73 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on:
77
- '**'
88
pull_request:
99
workflow_dispatch:
10+
release:
11+
types: [published]
1012
schedule:
1113
# 1:30am UTC every Sunday, has no particular significance
1214
- cron: "30 1 * * 0"
@@ -15,16 +17,22 @@ env:
1517
DOCKER_REGISTRY_IMAGE: ${{ secrets.DOCKERHUB_NAMESPACE }}/ftl-build
1618
GITHUB_REGISTRY_IMAGE: ghcr.io/${{ github.repository_owner }}/ftl-build
1719

20+
permissions:
21+
contents: read
22+
1823
jobs:
1924
smoke-tests:
2025
if: |
2126
github.event_name == 'push'
2227
|| (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
2328
|| github.event_name == 'workflow_dispatch'
2429
|| github.event_name == 'schedule'
30+
|| github.event_name == 'release'
2531
2632
outputs:
2733
DO_DEPLOY: ${{ steps.variables.outputs.DO_DEPLOY }}
34+
DOCKER_REGISTRY_IMAGE: ${{ env.DOCKER_REGISTRY_IMAGE }}
35+
GITHUB_REGISTRY_IMAGE: ${{ env.GITHUB_REGISTRY_IMAGE }}
2836
runs-on: ubuntu-latest
2937
steps:
3038
-
@@ -33,185 +41,76 @@ jobs:
3341
run: |
3442
echo "DO_DEPLOY=${{ github.event_name != 'pull_request' && secrets.DOCKERHUB_PASS != '' && github.actor != 'dependabot[bot]' }}" >> $GITHUB_OUTPUT
3543
36-
37-
build-and-test:
38-
needs: smoke-tests
39-
env:
40-
DO_DEPLOY: ${{ needs.smoke-tests.outputs.DO_DEPLOY }}
41-
strategy:
42-
fail-fast: false
43-
matrix:
44-
include:
45-
- platform: linux/amd64
46-
runner: ubuntu-24.04
47-
- platform: linux/386
48-
runner: ubuntu-24.04
49-
- platform: linux/arm/v6
50-
runner: ubuntu-24.04-arm
51-
- platform: linux/arm/v7
52-
runner: ubuntu-24.04-arm
53-
- platform: linux/arm64/v8
54-
runner: ubuntu-24.04-arm
55-
- platform: linux/riscv64
56-
runner: ubuntu-24.04
57-
runs-on: ${{ matrix.runner }}
58-
steps:
59-
-
60-
name: Prepare name for digest up/download
61-
run: |
62-
platform=${{ matrix.platform }}
63-
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
64-
-
65-
name: Checkout Repo
66-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
67-
-
68-
name: Docker meta (Docker Hub and GitHub Container Registry)
69-
id: meta
70-
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #v6.0.0
71-
with:
72-
github-token: ${{ secrets.GITHUB_TOKEN }}
73-
images: |
74-
${{ env.DOCKER_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
75-
${{ env.GITHUB_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
76-
foo/bar,enable=${{ github.event_name == 'workflow_dispatch' }}
77-
tags: |
78-
type=ref,event=branch,enable=${{ github.event_name != 'schedule' }}
79-
-
80-
name: Login to Docker Hub
81-
if: env.DO_DEPLOY == 'true'
82-
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
83-
with:
84-
registry: docker.io
85-
username: ${{ secrets.DOCKERHUB_USER }}
86-
password: ${{ secrets.DOCKERHUB_PASS }}
87-
88-
-
89-
name: Login to GitHub Container Registry
90-
if: env.DO_DEPLOY == 'true'
91-
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
92-
with:
93-
registry: ghcr.io
94-
username: ${{ github.repository_owner }}
95-
password: ${{ secrets.GITHUB_TOKEN }}
96-
-
97-
# Add support for more platforms with QEMU (optional)
98-
# https://github.com/docker/setup-qemu-action
99-
name: Set up QEMU
100-
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a #v4.0.0
101-
with:
102-
platforms: all
103-
-
104-
name: Set up Docker Buildx
105-
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd #v4.0.0
106-
-
107-
name: Build container and test-compile FTL
108-
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 #v7.0.0
109-
with:
110-
context: ftl-build
111-
platforms: ${{ matrix.platform }}
112-
push: false
113-
target: test
114-
tags: ${{ steps.meta.outputs.tags }}
115-
labels: ${{ steps.meta.outputs.labels }}
116-
-
117-
name: Push builder target and push by digest
118-
if: env.DO_DEPLOY == 'true'
119-
id: build_docker
120-
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 #v7.0.0
121-
with:
122-
context: ftl-build
123-
platforms: ${{ matrix.platform }}
124-
push: ${{ github.event_name != 'workflow_dispatch' }}
125-
target: build
126-
labels: ${{ steps.meta.outputs.labels }}
127-
outputs: |
128-
type=image,name=${{ env.DOCKER_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
129-
type=image,name=${{ env.GITHUB_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
130-
-
131-
name: Export digests
132-
if: env.DO_DEPLOY == 'true'
133-
run: |
134-
mkdir -p /tmp/digests/
135-
digest_docker="${{ steps.build_docker.outputs.digest }}"
136-
touch "/tmp/digests/${digest_docker#sha256:}"
44+
# FIXME: can't use env object in reusable workflow inputs: https://github.com/orgs/community/discussions/26671
13745
-
138-
name: Upload digest
139-
if: env.DO_DEPLOY == 'true'
140-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
141-
with:
142-
name: digests-${{ env.PLATFORM_PAIR }}
143-
path: /tmp/digests/*
144-
if-no-files-found: error
145-
retention-days: 1
46+
name: "Expose registry variables for reusable workflow"
47+
run: echo "Exposing env vars for reusable workflow"
14648

147-
# Merge all the digests into a single file
148-
# If we would push immediately above, the individual runners would overwrite each other's images
149-
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
150-
merge-and-deploy:
151-
if: needs.smoke-tests.outputs.DO_DEPLOY == 'true'
152-
runs-on: ubuntu-latest
49+
build-and-test:
50+
uses: docker/github-builder/.github/workflows/[email protected]
15351
needs:
154-
- build-and-test
15552
- smoke-tests
156-
steps:
157-
-
158-
name: Checkout Repo
159-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
160-
-
161-
name: Download digests
162-
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1
163-
with:
164-
path: /tmp/digests
165-
pattern: digests-*
166-
merge-multiple: true
167-
-
168-
name: Set up Docker Buildx
169-
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a #v4.0.0
170-
-
171-
name: Login to Docker Hub
172-
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
173-
with:
174-
registry: docker.io
53+
permissions:
54+
contents: read # same as global permissions
55+
with:
56+
setup-qemu: true
57+
cache: true
58+
cache-scope: build
59+
cache-mode: max
60+
context: ftl-build
61+
# fail-fast need https://github.com/docker/github-builder/pull/158 to be released
62+
#fail-fast: true
63+
output: image
64+
target: test
65+
platforms: linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/riscv64
66+
push: false
67+
meta-images: |
68+
${{ needs.smoke-tests.outputs.DOCKER_REGISTRY_IMAGE }}
69+
${{ needs.smoke-tests.outputs.GITHUB_REGISTRY_IMAGE }}
70+
71+
build-and-push:
72+
if: needs.smoke-tests.outputs.DO_DEPLOY == 'true'
73+
needs: [smoke-tests, build-and-test]
74+
uses: docker/github-builder/.github/workflows/[email protected]
75+
permissions:
76+
contents: read # same as global permissions
77+
id-token: write # for signing attestation(s) with GitHub OIDC Token
78+
packages: write # required to push to GHCR
79+
with:
80+
setup-qemu: true
81+
cache: true
82+
cache-scope: build
83+
cache-mode: max
84+
context: ftl-build
85+
# fail-fast need https://github.com/docker/github-builder/pull/158 to be released
86+
#fail-fast: true
87+
output: image
88+
target: build
89+
platforms: linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/riscv64
90+
push: true
91+
set-meta-labels: true
92+
meta-images: |
93+
${{ needs.smoke-tests.outputs.DOCKER_REGISTRY_IMAGE }}
94+
${{ needs.smoke-tests.outputs.GITHUB_REGISTRY_IMAGE }}
95+
# meta-tags:
96+
# type=schedule, pattern=nightly means that a "nightly" tag is applied when the workflow is triggered by a schedule event
97+
# type=raw,value=nightly means that a "nightly" tag is applied when the workflow is triggerd by a push to a branch (enabled only for master branch to avoid tagging every push to other branches with "nightly")
98+
# type=ref,event=branch means that a tag is applied when the workflow is triggered by a push to a branch (enabled only for non-master branches to avoid tagging every push to master branch with the branch name)
99+
# type=ref,event=tag means that a tag is applied when the workflow is triggered by a push to a tag
100+
meta-tags: |
101+
type=schedule,pattern=nightly
102+
type=raw,value=nightly,enable=${{ github.ref == 'refs/heads/master' }}
103+
type=ref,event=branch,enable=${{ github.ref != 'refs/heads/master' }}
104+
type=ref,event=tag
105+
meta-flavor: |
106+
latest=${{ startsWith(github.ref, 'refs/tags/') }}
107+
# FIXME: GHCR does not support the referrers API and spams the registry with sha-tagged images when cosigned: https://github.com/docker/github-builder/issues/109
108+
sign: false
109+
secrets:
110+
registry-auths: |
111+
- registry: docker.io
175112
username: ${{ secrets.DOCKERHUB_USER }}
176113
password: ${{ secrets.DOCKERHUB_PASS }}
177-
178-
-
179-
name: Login to GitHub Container Registry
180-
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
181-
with:
182-
registry: ghcr.io
114+
- registry: ghcr.io
183115
username: ${{ github.repository_owner }}
184116
password: ${{ secrets.GITHUB_TOKEN }}
185-
-
186-
name: Docker meta
187-
id: meta_docker
188-
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #v6.0.0
189-
with:
190-
images: |
191-
${{ env.DOCKER_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
192-
${{ env.GITHUB_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
193-
# We want to tag the image with the latest tag if the workflow was triggered by a tag
194-
flavor: |
195-
latest=${{ startsWith(github.ref, 'refs/tags/') }}
196-
# tags:
197-
# type=schedule means that a tag is applied when the workflow is triggered by a schedule event
198-
# type=ref,event=branch means that a tag is applied when the workflow is triggered by a push to a branch
199-
# type=ref,event=tag means that a tag is applied when the workflow is triggered by a push to a tag
200-
tags: |
201-
type=schedule,enable=${{ github.event_name == 'schedule' }}
202-
type=ref,event=branch,enable=${{ github.event_name != 'schedule' }}
203-
type=ref,event=tag
204-
-
205-
name: Create manifest list and push to repository DockerHub and GitHub Container Registry)
206-
working-directory: /tmp/digests
207-
run: |
208-
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
209-
$(printf '${{ env.GITHUB_REGISTRY_IMAGE }}@sha256:%s ' *)
210-
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
211-
$(printf '${{ env.DOCKER_REGISTRY_IMAGE }}@sha256:%s ' *)
212-
-
213-
name: Inspect images
214-
shell: bash
215-
run: |
216-
docker buildx imagetools inspect ${{ env.DOCKER_REGISTRY_IMAGE }}:${{ steps.meta_docker.outputs.version }}
217-
docker buildx imagetools inspect ${{ env.GITHUB_REGISTRY_IMAGE }}:${{ steps.meta_docker.outputs.version }}

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ All images are pushed to both Docker Hub (`pihole/ftl-build`) and GHCR (`ghcr.io
1616
## How does it get uploaded?
1717

1818
- GitHub Actions (`ftl-build.yml`):
19-
- Every `pull_request` event triggers a build (but does not push)
20-
- Every `workflow_dispatch` event triggers a build of the branch it is run against, and uploads a branch-based tag
21-
- Every `tag` event (e.g `v1`) triggers a build and uploads both `${{matrix.ARCH}}` and `v1-${{matrix.ARCH}}` tags
22-
- Schedule: 1:30am UTC every Sunday a build is triggered and a `${{matrix.ARCH}}` tag is uploaded
19+
- Every `pull_request` event triggers a test build (does not push)
20+
- Every branch `push` (except `master`) publishes the branch name as a tag
21+
- Every `workflow_dispatch` event triggers a build of the branch it is run against, and publishes the branch name as a tag
22+
- Every push to `master` publishes the `nightly` tag
23+
- Schedule: 1:30am UTC every Sunday a build is triggered and the `nightly` tag is published
24+
- Every published GitHub `release` (e.g. `v1`) publishes the release tag and `latest`

0 commit comments

Comments
 (0)