Skip to content

Commit

Permalink
ci(#49): initial revision
Browse files Browse the repository at this point in the history
implement a github actions workflow for building multi-arch Docker images

- `docker-build.yml` defines the job to build Docker images
    - it is only run for the `main` branch, release tags, and for PRs
        that change a relevant file
- `platforms.yml` configures multi-arch builds when using `buildx bake`
    - it is stored in a separate compose file so that slow
        cross-platform builds aren't always run locally

Signed-off-by: Bryant Finney <bryant.finney@outlook.com>
  • Loading branch information
bryant-finney committed Oct 22, 2023
1 parent 2b017f7 commit a8c41dc
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 1 deletion.
115 changes: 115 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
# Summary: Use Docker buildx to bake and push a multi-arch Docker image.
# Image Tagging Rules:
# - `latest` is always the latest commit on `main`
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: 🐳 Docker

# run this workflow for...
# - each push to `main`
# - each release tag (starting with `v`)
# - each pull request that changes a relevant file
on:
push:
tags: v*
branches:
- main

pull_request:
paths:
- .github/workflows/docker-build.yml
- Dockerfile
- docker-compose.yml
- platforms.yml
- poetry.lock

# ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

jobs:
build-and-push:
name: Build and push Docker image

env:
CI_REGISTRY_IMAGE: ghcr.io/${{ github.repository }}
PYTHON_VERSION: "3.11"

runs-on: ubuntu-latest

steps:
- name: ↗️ Checkout code
uses: actions/checkout@v4
with:
fetch-tags: true

- name: 🔐 Log in to ghcr.io
if: github.triggering_actor == github.repository_owner
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: 🧰 Set up QEMU
uses: docker/setup-qemu-action@v3
with:
# note: needs to include all platforms in `platforms.yml`
platforms: linux/amd64,linux/arm64

- name: 🛠️ Set up Docker Buildx
id: setup-builder
uses: docker/setup-buildx-action@v3

# configure the tagging schema for this project
- name: 🌐 Docker meta
id: meta # referenced in the next step
env:
# label the image with the PR URL if it was built from a PR
# otherwise, label the image with the URL to the branch or tag
PYSPRY_IMAGE_URL: ${{ github.event_name == 'pull_request' &&
format('{0}/{1}/pull/{2}', github.server_url, github.repository, github.event.number) ||
format('{0}/{1}/tree/{2}', github.server_url, github.repository, github.ref_name) }}

# link the image to the commit that triggered the build
PYSPRY_IMAGE_SOURCE: >-
${{ format('{0}/{1}/commit/{2}', github.server_url, github.repository, github.sha) }}
uses: docker/metadata-action@v4
with:
# note: the target of `docker buildx bake` is the service name in docker-compose.yml
bake-target: dev

images: ${{ env.CI_REGISTRY_IMAGE }}/dev

# ref: https://github.com/opencontainers/image-spec/blob/93f6e658/annotations.md#pre-defined-annotation-keys
labels: |
org.opencontainers.image.title=${{ github.repository }}
org.opencontainers.image.description=Provide dependencies for development and testing
org.opencontainers.image.source=${{ env.PYSPRY_IMAGE_SOURCE }}
org.opencontainers.image.url=${{ env.PYSPRY_IMAGE_URL }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,format=short,prefix=
- name: 🏗️ Build and push Docker images
env:
# ref: https://github.com/bryant-finney/pyspry/blob/2b017f7e/docker-compose.yml#L17-L20
PYSPRY_BRANCH_TAG: ${{ steps.meta.outputs.version }}

uses: docker/bake-action@v4
with:
builder: ${{ steps.setup-builder.outputs.name }}
# extend `docker-compose.yml` with 'platforms.yml' for multi-arch builds
# additionally, the bake file configures labels and tags for the build
files: |-
docker-compose.yml
platforms.yml
${{ steps.meta.outputs.bake-file }}
pull: true
push: true
targets: dev
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ services:
UID: ${UID:-1000}
GID: ${GID:-1000}
PYTHON_VERSION: ${PYTHON_VERSION:-3.11}
context: .
tags:
- &commit-tag ${CI_REGISTRY_IMAGE}/dev:${PYSPRY_TAG}
- ${CI_REGISTRY_IMAGE}/dev:${PYSPRY_BRANCH_TAG}
target: dev
x-bake:
cache-from:
- type=registry,ref=${CI_REGISTRY_IMAGE}/dev/cache:${PYSPRY_BRANCH_TAG}
- type=registry,ref=${CI_REGISTRY_IMAGE}/dev:${PYSPRY_BRANCH_TAG}
- type=registry,ref=python:${PYTHON_IMAGE_VERSION:-3.11}-slim

cache-to: type=registry,ref=${CI_REGISTRY_IMAGE}/dev/cache:${PYSPRY_BRANCH_TAG}
Expand Down
6 changes: 6 additions & 0 deletions platforms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# set platforms for multi-arch builds in a separate compose file to shorten local build times
services:
dev:
build:
x-bake:
platforms: ["linux/amd64", "linux/arm64"]

0 comments on commit a8c41dc

Please sign in to comment.