Build and push multi-arch images #49
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and push multi-arch images | |
on: | |
workflow_dispatch: | |
inputs: | |
gitRef: | |
description: Commit, tag or branch name to deploy | |
required: true | |
type: string | |
default: main | |
pushToRegistry: | |
description: Push to Registry. Set to false to test the build without pushing. | |
required: true | |
type: boolean | |
default: true | |
push: | |
branches: | |
- main | |
schedule: | |
- cron: '34 3 * * *' | |
jobs: | |
configure_builds: | |
name: Read configuration from build-matrix.json | |
runs-on: ubuntu-latest | |
outputs: | |
matrix: ${{ steps.set-matrix.outputs.matrix }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
show-progress: false | |
- id: set-matrix | |
run: echo "matrix=$(jq -c . < build-matrix.json)" >> $GITHUB_OUTPUT | |
# TODO: can we push the target arch into the build matrix to avoid duplicating these jobs? | |
build_and_push_amd64: | |
name: Build ruby_${{ join(matrix.version.rubyver, '.') }} for AMD64 and push to GHCR | |
runs-on: ubuntu-latest | |
needs: configure_builds | |
strategy: | |
matrix: ${{ fromJson(needs.configure_builds.outputs.matrix) }} | |
permissions: | |
packages: write | |
steps: | |
- name: Login to GHCR | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.gitRef || github.ref }} | |
show-progress: false | |
- uses: docker/setup-buildx-action@v3 | |
- id: calculate-image-tags | |
run: | | |
CREATED_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" | |
echo "createdDate=${CREATED_DATE}" >> $GITHUB_OUTPUT | |
- name: Generate Base Image Metadata | |
uses: docker/metadata-action@v5 | |
id: base-image-metadata | |
with: | |
flavor: | | |
latest=false | |
images: | | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-base | |
labels: | | |
org.opencontainers.image.title=govuk-ruby-base | |
org.opencontainers.image.authors=GOV.UK Platform Engineering | |
org.opencontainers.image.description=Base Image for GOV.UK Ruby-based Apps | |
org.opencontainers.image.source=https://github.com/alphagov/govuk-ruby-images | |
org.opencontainers.image.version=${{ join(matrix.version.rubyver, '.') }} | |
org.opencontainers.image.created=${{ steps.calculate-image-tags.outputs.createdDate }} | |
org.opencontainers.image.vendor=GDS | |
tags: | | |
type=semver,pattern={{raw}},suffix=-amd64,value=${{ join(matrix.version.rubyver, '.') }} | |
type=raw,value=latest-amd64,enable=${{ matrix.version.extra == 'latest' }} | |
type=sha,enable=true,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-amd64,format=short | |
type=sha,enable=true,priority=100,format=long,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-amd64 | |
- name: Generate Builder Image Metadata | |
uses: docker/metadata-action@v5 | |
id: builder-image-metadata | |
with: | |
flavor: | | |
latest=false | |
images: | | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder | |
labels: | | |
org.opencontainers.image.title=govuk-ruby-builder | |
org.opencontainers.image.authors=GOV.UK Platform Engineering | |
org.opencontainers.image.description=Builder Image for GOV.UK Ruby-based Apps | |
org.opencontainers.image.source=https://github.com/alphagov/govuk-ruby-images | |
org.opencontainers.image.version=${{ join(matrix.version.rubyver, '.') }} | |
org.opencontainers.image.created=${{ steps.calculate-image-tags.outputs.createdDate }} | |
org.opencontainers.image.vendor=GDS | |
tags: | | |
type=semver,pattern={{raw}},suffix=-amd64,value=${{ join(matrix.version.rubyver, '.') }} | |
type=raw,value=latest-amd64,enable=${{ matrix.version.extra == 'latest' }} | |
type=sha,enable=true,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-amd64,format=short | |
type=sha,enable=true,priority=100,format=long,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-amd64 | |
- id: build-base-image | |
uses: docker/build-push-action@v5 | |
with: | |
file: base.Dockerfile | |
context: . | |
push: ${{ inputs.pushToRegistry || true }} | |
platforms: "linux/amd64" | |
provenance: false | |
build-args: | | |
RUBY_MAJOR=${{ matrix.version.rubyver[0] }}.${{ matrix.version.rubyver[1] }} | |
RUBY_VERSION=${{ join(matrix.version.rubyver, '.') }} | |
RUBY_CHECKSUM=${{ matrix.version.checksum }} | |
tags: ${{ steps.base-image-metadata.outputs.tags }} | |
labels: ${{ steps.base-image-metadata.outputs.labels }} | |
- id: build-builder-image | |
uses: docker/build-push-action@v5 | |
with: | |
file: builder.Dockerfile | |
context: . | |
push: ${{ inputs.pushToRegistry || true }} | |
platforms: "linux/amd64" | |
provenance: false | |
build-args: | | |
RUBY_MAJOR=${{ matrix.version.rubyver[0] }}.${{ matrix.version.rubyver[1] }} | |
RUBY_VERSION=${{ join(matrix.version.rubyver, '.') }} | |
RUBY_CHECKSUM=${{ matrix.version.checksum }} | |
OWNER=${{ github.repository_owner }} | |
tags: ${{ steps.builder-image-metadata.outputs.tags }} | |
labels: ${{ steps.builder-image-metadata.outputs.labels }} | |
build_and_push_arm64: | |
name: Build ruby_${{ join(matrix.version.rubyver, '.') }} for ARM64 and push to GHCR | |
runs-on: ubuntu-latest | |
needs: configure_builds | |
strategy: | |
matrix: ${{ fromJson(needs.configure_builds.outputs.matrix) }} | |
permissions: | |
packages: write | |
steps: | |
- name: Login to GHCR | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.gitRef || github.ref }} | |
show-progress: false | |
- name: Set up QEMU for ARM64 build | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: arm64 | |
- uses: docker/setup-buildx-action@v3 | |
- id: calculate-image-tags | |
run: | | |
CREATED_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" | |
echo "createdDate=${CREATED_DATE}" >> $GITHUB_OUTPUT | |
- name: Generate Base Image Metadata | |
uses: docker/metadata-action@v5 | |
id: base-image-metadata | |
with: | |
flavor: | | |
latest=false | |
images: | | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-base | |
labels: | | |
org.opencontainers.image.title=govuk-ruby-base | |
org.opencontainers.image.authors=GOV.UK Platform Engineering | |
org.opencontainers.image.description=Base Image for GOV.UK Ruby-based Apps | |
org.opencontainers.image.source=https://github.com/alphagov/govuk-ruby-images | |
org.opencontainers.image.version=${{ join(matrix.version.rubyver, '.') }} | |
org.opencontainers.image.created=${{ steps.calculate-image-tags.outputs.createdDate }} | |
org.opencontainers.image.vendor=GDS | |
tags: | | |
type=semver,pattern={{raw}},suffix=-arm64,value=${{ join(matrix.version.rubyver, '.') }} | |
type=raw,value=latest-arm64,enable=${{ matrix.version.extra == 'latest' }} | |
type=sha,enable=true,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-arm64,format=short | |
type=sha,enable=true,priority=100,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-arm64,format=long | |
- name: Generate Builder Image Metadata | |
uses: docker/metadata-action@v5 | |
id: builder-image-metadata | |
with: | |
flavor: | | |
latest=false | |
images: | | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder | |
labels: | | |
org.opencontainers.image.title=govuk-ruby-builder | |
org.opencontainers.image.authors=GOV.UK Platform Engineering | |
org.opencontainers.image.description=Builder Image for GOV.UK Ruby-based Apps | |
org.opencontainers.image.source=https://github.com/alphagov/govuk-ruby-images | |
org.opencontainers.image.version=${{ join(matrix.version.rubyver, '.') }} | |
org.opencontainers.image.created=${{ steps.calculate-image-tags.outputs.createdDate }} | |
org.opencontainers.image.vendor=GDS | |
tags: | | |
type=semver,pattern={{raw}},suffix=-arm64,value=${{ join(matrix.version.rubyver, '.') }} | |
type=raw,value=latest-arm64,enable=${{ matrix.version.extra == 'latest' }} | |
type=sha,enable=true,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-arm64,format=short | |
type=sha,enable=true,priority=100,prefix=${{ join(matrix.version.rubyver, '.') }}-,suffix=-arm64,format=long | |
- id: build-base-image | |
uses: docker/build-push-action@v5 | |
with: | |
file: base.Dockerfile | |
context: . | |
push: ${{ inputs.pushToRegistry || true }} | |
platforms: "linux/arm64" | |
provenance: false | |
build-args: | | |
RUBY_MAJOR=${{ matrix.version.rubyver[0] }}.${{ matrix.version.rubyver[1] }} | |
RUBY_VERSION=${{ join(matrix.version.rubyver, '.') }} | |
RUBY_CHECKSUM=${{ matrix.version.checksum }} | |
tags: ${{ steps.base-image-metadata.outputs.tags }} | |
labels: ${{ steps.base-image-metadata.outputs.labels }} | |
- id: build-builder-image | |
uses: docker/build-push-action@v5 | |
with: | |
file: builder.Dockerfile | |
context: . | |
push: ${{ inputs.pushToRegistry || true }} | |
platforms: "linux/arm64" | |
provenance: false | |
build-args: | | |
RUBY_MAJOR=${{ matrix.version.rubyver[0] }}.${{ matrix.version.rubyver[1] }} | |
RUBY_VERSION=${{ join(matrix.version.rubyver, '.') }} | |
RUBY_CHECKSUM=${{ matrix.version.checksum }} | |
OWNER=${{ github.repository_owner }} | |
tags: ${{ steps.builder-image-metadata.outputs.tags }} | |
labels: ${{ steps.builder-image-metadata.outputs.labels }} | |
create_docker_manifests: | |
if: ${{ inputs.pushToRegistry || true }} | |
name: Create Docker Manifests for Ruby ${{ join(matrix.version.rubyver, '.') }} Images | |
needs: | |
- configure_builds | |
- build_and_push_amd64 | |
- build_and_push_arm64 | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: ${{ fromJson(needs.configure_builds.outputs.matrix) }} | |
permissions: | |
packages: write | |
steps: | |
- name: Login to GHCR | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ inputs.gitRef || github.ref }} | |
show-progress: false | |
- name: Create SHA manifest and push for Ruby Base Images | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }} \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }} | |
- name: Create SHA manifest and push for Ruby Builder Images | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }} \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }} | |
- name: Create Ruby Versioned manifest and push for Ruby Base Images | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }} \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:${{ join(matrix.version.rubyver, '.') }} | |
- name: Create Ruby Versioned manifest and push for Ruby Builder Images | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }} \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }}-${{ github.sha }}-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:${{ join(matrix.version.rubyver, '.') }} | |
- name: Create Latest manifest and push for Ruby Base Images | |
if: ${{ matrix.version.extra == 'latest' }} | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:latest \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:latest-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:latest-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-base:latest | |
- name: Create Latest manifest and push for Ruby Builder Images | |
if: ${{ matrix.version.extra == 'latest' }} | |
run: | | |
docker manifest create \ | |
ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:latest \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:latest-amd64 \ | |
--amend ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:latest-arm64 | |
docker manifest push ghcr.io/${{ github.repository_owner }}/govuk-ruby-builder:latest |