Skip to content
Merged
Show file tree
Hide file tree
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
247 changes: 73 additions & 174 deletions .github/workflows/ftl-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- '**'
pull_request:
workflow_dispatch:
release:
types: [published]
schedule:
# 1:30am UTC every Sunday, has no particular significance
- cron: "30 1 * * 0"
Expand All @@ -15,16 +17,22 @@ env:
DOCKER_REGISTRY_IMAGE: ${{ secrets.DOCKERHUB_NAMESPACE }}/ftl-build
GITHUB_REGISTRY_IMAGE: ghcr.io/${{ github.repository_owner }}/ftl-build

permissions:
contents: read

jobs:
smoke-tests:
if: |
github.event_name == 'push'
|| (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
|| github.event_name == 'workflow_dispatch'
|| github.event_name == 'schedule'
|| github.event_name == 'release'

outputs:
DO_DEPLOY: ${{ steps.variables.outputs.DO_DEPLOY }}
DOCKER_REGISTRY_IMAGE: ${{ env.DOCKER_REGISTRY_IMAGE }}
GITHUB_REGISTRY_IMAGE: ${{ env.GITHUB_REGISTRY_IMAGE }}
runs-on: ubuntu-latest
steps:
-
Expand All @@ -33,185 +41,76 @@ jobs:
run: |
echo "DO_DEPLOY=${{ github.event_name != 'pull_request' && secrets.DOCKERHUB_PASS != '' && github.actor != 'dependabot[bot]' }}" >> $GITHUB_OUTPUT


build-and-test:
needs: smoke-tests
env:
DO_DEPLOY: ${{ needs.smoke-tests.outputs.DO_DEPLOY }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-24.04
- platform: linux/386
runner: ubuntu-24.04
- platform: linux/arm/v6
runner: ubuntu-24.04-arm
- platform: linux/arm/v7
runner: ubuntu-24.04-arm
- platform: linux/arm64/v8
runner: ubuntu-24.04-arm
- platform: linux/riscv64
runner: ubuntu-24.04
runs-on: ${{ matrix.runner }}
steps:
-
name: Prepare name for digest up/download
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
-
name: Checkout Repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
-
name: Docker meta (Docker Hub and GitHub Container Registry)
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #v6.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
images: |
${{ env.DOCKER_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
${{ env.GITHUB_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
foo/bar,enable=${{ github.event_name == 'workflow_dispatch' }}
tags: |
type=ref,event=branch,enable=${{ github.event_name != 'schedule' }}
-
name: Login to Docker Hub
if: env.DO_DEPLOY == 'true'
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASS }}

-
name: Login to GitHub Container Registry
if: env.DO_DEPLOY == 'true'
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
# Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a #v4.0.0
with:
platforms: all
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd #v4.0.0
-
name: Build container and test-compile FTL
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 #v7.0.0
with:
context: ftl-build
platforms: ${{ matrix.platform }}
push: false
target: test
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-
name: Push builder target and push by digest
if: env.DO_DEPLOY == 'true'
id: build_docker
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 #v7.0.0
with:
context: ftl-build
platforms: ${{ matrix.platform }}
push: ${{ github.event_name != 'workflow_dispatch' }}
target: build
labels: ${{ steps.meta.outputs.labels }}
outputs: |
type=image,name=${{ env.DOCKER_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
type=image,name=${{ env.GITHUB_REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
-
name: Export digests
if: env.DO_DEPLOY == 'true'
run: |
mkdir -p /tmp/digests/
digest_docker="${{ steps.build_docker.outputs.digest }}"
touch "/tmp/digests/${digest_docker#sha256:}"
# FIXME: can't use env object in reusable workflow inputs: https://github.com/orgs/community/discussions/26671
-
name: Upload digest
if: env.DO_DEPLOY == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
name: "Expose registry variables for reusable workflow"
run: echo "Exposing env vars for reusable workflow"

# Merge all the digests into a single file
# If we would push immediately above, the individual runners would overwrite each other's images
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
merge-and-deploy:
if: needs.smoke-tests.outputs.DO_DEPLOY == 'true'
runs-on: ubuntu-latest
build-and-test:
uses: docker/github-builder/.github/workflows/build.yml@v1.4.0
needs:
- build-and-test
- smoke-tests
steps:
-
name: Checkout Repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
-
name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
-
name: Set up Docker Buildx
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a #v4.0.0
-
name: Login to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
registry: docker.io
permissions:
contents: read # same as global permissions
with:
setup-qemu: true
cache: true
cache-scope: build
cache-mode: max
context: ftl-build
# fail-fast need https://github.com/docker/github-builder/pull/158 to be released
#fail-fast: true
output: image
target: test
platforms: linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/riscv64
push: false
meta-images: |
${{ needs.smoke-tests.outputs.DOCKER_REGISTRY_IMAGE }}
${{ needs.smoke-tests.outputs.GITHUB_REGISTRY_IMAGE }}

build-and-push:
if: needs.smoke-tests.outputs.DO_DEPLOY == 'true'
needs: [smoke-tests, build-and-test]
uses: docker/github-builder/.github/workflows/build.yml@v1.4.0
permissions:
contents: read # same as global permissions
id-token: write # for signing attestation(s) with GitHub OIDC Token
packages: write # required to push to GHCR
with:
setup-qemu: true
cache: true
cache-scope: build
cache-mode: max
context: ftl-build
# fail-fast need https://github.com/docker/github-builder/pull/158 to be released
#fail-fast: true
output: image
target: build
platforms: linux/amd64,linux/386,linux/arm/v6,linux/arm/v7,linux/arm64,linux/riscv64
push: true
set-meta-labels: true
meta-images: |
${{ needs.smoke-tests.outputs.DOCKER_REGISTRY_IMAGE }}
${{ needs.smoke-tests.outputs.GITHUB_REGISTRY_IMAGE }}
# meta-tags:
# type=schedule, pattern=nightly means that a "nightly" tag is applied when the workflow is triggered by a schedule event
# 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")
# 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)
# type=ref,event=tag means that a tag is applied when the workflow is triggered by a push to a tag
meta-tags: |
type=schedule,pattern=nightly
type=raw,value=nightly,enable=${{ github.ref == 'refs/heads/master' }}
type=ref,event=branch,enable=${{ github.ref != 'refs/heads/master' }}
type=ref,event=tag
meta-flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/') }}
# 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
sign: false
secrets:
registry-auths: |
- registry: docker.io
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASS }}

-
name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
registry: ghcr.io
- registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Docker meta
id: meta_docker
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf #v6.0.0
with:
images: |
${{ env.DOCKER_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
${{ env.GITHUB_REGISTRY_IMAGE }},enable=${{ github.event_name != 'workflow_dispatch' }}
# We want to tag the image with the latest tag if the workflow was triggered by a tag
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/') }}
# tags:
# type=schedule means that a tag is applied when the workflow is triggered by a schedule event
# type=ref,event=branch means that a tag is applied when the workflow is triggered by a push to a branch
# type=ref,event=tag means that a tag is applied when the workflow is triggered by a push to a tag
tags: |
type=schedule,enable=${{ github.event_name == 'schedule' }}
type=ref,event=branch,enable=${{ github.event_name != 'schedule' }}
type=ref,event=tag
-
name: Create manifest list and push to repository DockerHub and GitHub Container Registry)
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.GITHUB_REGISTRY_IMAGE }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.DOCKER_REGISTRY_IMAGE }}@sha256:%s ' *)
-
name: Inspect images
shell: bash
run: |
docker buildx imagetools inspect ${{ env.DOCKER_REGISTRY_IMAGE }}:${{ steps.meta_docker.outputs.version }}
docker buildx imagetools inspect ${{ env.GITHUB_REGISTRY_IMAGE }}:${{ steps.meta_docker.outputs.version }}
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ All images are pushed to both Docker Hub (`pihole/ftl-build`) and GHCR (`ghcr.io
## How does it get uploaded?

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