2025-04-16 18:54:36 +01:00
name : Release Docker Image
2025-04-24 17:24:28 +01:00
concurrency :
2025-04-17 14:35:16 +01:00
group : "release-image-${{ github.ref }}"
2025-04-16 18:54:36 +01:00
on :
pull_request :
push :
paths-ignore :
2025-04-24 17:24:28 +01:00
- "*.md"
- "**/*.md"
- ".gitlab-ci.yml"
- ".gitignore"
- "renovate.json"
- "debian/**"
- "docker/**"
- "docs/**"
2025-04-16 18:54:36 +01:00
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch :
env :
2025-04-24 17:24:28 +01:00
BUILTIN_REGISTRY : forgejo.ellis.link
BUILTIN_REGISTRY_ENABLED : "${{ ((vars.BUILTIN_REGISTRY_USER && secrets.BUILTIN_REGISTRY_PASSWORD) || (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)) && 'true' || 'false' }}"
2025-04-16 18:54:36 +01:00
jobs :
define-variables :
runs-on : ubuntu-latest
outputs :
images : ${{ steps.var.outputs.images }}
images_list : ${{ steps.var.outputs.images_list }}
build_matrix : ${{ steps.var.outputs.build_matrix }}
steps :
- name : Setting variables
uses : https://github.com/actions/github-script@v7
id : var
with :
script : |
const githubRepo = '${{ github.repository }}'.toLowerCase()
const repoId = githubRepo.split('/')[1]
2025-04-24 17:24:28 +01:00
2025-04-16 18:54:36 +01:00
core.setOutput('github_repository', githubRepo)
const builtinImage = '${{ env.BUILTIN_REGISTRY }}/' + githubRepo
let images = []
if (process.env.BUILTIN_REGISTRY_ENABLED === "true") {
images.push(builtinImage)
}
core.setOutput('images', images.join("\n"))
core.setOutput('images_list', images.join(","))
const platforms = ['linux/amd64', 'linux/arm64']
core.setOutput('build_matrix', JSON.stringify({
2025-04-24 17:24:28 +01:00
platform: platforms,
2025-04-16 18:54:36 +01:00
include: platforms.map(platform => { return {
platform,
slug: platform.replace('/', '-')
}})
}))
build-image :
2025-04-18 14:09:09 +01:00
runs-on : dind
2025-04-16 18:54:36 +01:00
container : ghcr.io/catthehacker/ubuntu:act-latest
needs : define-variables
permissions :
contents : read
packages : write
attestations : write
id-token : write
strategy :
2025-04-24 17:24:28 +01:00
matrix :
{
"include" :
[
{ "platform": "linux/amd64", "slug": "linux-amd64" },
{ "platform": "linux/arm64", "slug": "linux-arm64" },
] ,
"platform": [ "linux/amd64" , "linux/arm64" ] ,
}
2025-04-16 18:54:36 +01:00
steps :
- name : Echo strategy
run : echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}'
- name : Echo matrix
run : echo '${{ toJSON(matrix) }}'
- name : Checkout repository
uses : actions/checkout@v4
with :
persist-credentials : false
2025-04-18 22:38:17 +01:00
- run : |
if ! command -v rustup &> /dev/null ; then
curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y
echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
fi
- uses : https://github.com/cargo-bins/cargo-binstall@main
- run : cargo binstall timelord-cli@3.0.1
2025-04-16 18:54:36 +01:00
- name : Set up Docker Buildx
uses : docker/setup-buildx-action@v3
- name : Set up QEMU
uses : docker/setup-qemu-action@v3
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name : Login to builtin registry
uses : docker/login-action@v3
with :
2025-04-24 17:24:28 +01:00
registry : ${{ env.BUILTIN_REGISTRY }}
username : ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
password : ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
2025-04-16 18:54:36 +01:00
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name : Extract metadata (labels, annotations) for Docker
id : meta
uses : docker/metadata-action@v5
with :
images : ${{needs.define-variables.outputs.images}}
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
env :
DOCKER_METADATA_ANNOTATIONS_LEVELS : manifest,index
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
# It will not push images generated from a pull request
- name : Get short git commit SHA
id : sha
run : |
calculatedSha=$(git rev-parse --short ${{ github.sha }})
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV
- name : Get Git commit timestamps
run : echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
2025-04-18 22:38:17 +01:00
- name : Set up timelord
uses : actions/cache/restore@v3
with :
path : /timelord/
key : timelord-v0 # Cache is already split per runner
- name : Run timelord to set timestamps
run : timelord sync --source-dir . --cache-dir /timelord/
- name : Save timelord
uses : actions/cache/save@v3
with :
path : /timelord/
key : timelord-v0
2025-04-16 18:54:36 +01:00
- name : Build and push Docker image by digest
id : build
uses : docker/build-push-action@v6
with :
context : .
file : "docker/Dockerfile"
build-args : |
CONDUWUIT_VERSION_EXTRA=${{ env.COMMIT_SHORT_SHA }}
2025-04-25 02:47:48 +01:00
COMMIT_SHA=${{ github.sha }})
REMOTE_URL=${{github.event.repository.html_url }}
REMOTE_COMMIT_URL=${{github.event.head_commit.url }}
2025-04-16 18:54:36 +01:00
platforms : ${{ matrix.platform }}
labels : ${{ steps.meta.outputs.labels }}
annotations : ${{ steps.meta.outputs.annotations }}
2025-04-18 21:05:17 +01:00
cache-from : type=gha
cache-to : type=gha,mode=max
2025-04-16 18:54:36 +01:00
sbom : true
outputs : type=image,"name=${{ needs.define-variables.outputs.images_list }}",push-by-digest=true,name-canonical=true,push=true
env :
SOURCE_DATE_EPOCH : ${{ env.TIMESTAMP }}
# For publishing multi-platform manifests
- name : Export digest
run : |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
2025-04-24 17:24:28 +01:00
touch "/tmp/digests/${digest#sha256:}"
2025-04-16 18:54:36 +01:00
- name : Upload digest
2025-04-17 12:06:45 +01:00
uses : forgejo/upload-artifact@v4
2025-04-16 18:54:36 +01:00
with :
name : digests-${{ matrix.slug }}
path : /tmp/digests/*
if-no-files-found : error
retention-days : 1
2025-04-24 17:24:28 +01:00
2025-04-16 18:54:36 +01:00
merge :
2025-04-18 14:09:09 +01:00
runs-on : dind
2025-04-16 18:54:36 +01:00
container : ghcr.io/catthehacker/ubuntu:act-latest
needs : [ define-variables, build-image]
steps :
- name : Download digests
2025-04-17 12:06:45 +01:00
uses : forgejo/download-artifact@v4
2025-04-16 18:54:36 +01:00
with :
path : /tmp/digests
pattern : digests-*
merge-multiple : true
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name : Login to builtin registry
uses : docker/login-action@v3
with :
2025-04-24 17:24:28 +01:00
registry : ${{ env.BUILTIN_REGISTRY }}
username : ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
password : ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
2025-04-16 18:54:36 +01:00
- name : Set up Docker Buildx
uses : docker/setup-buildx-action@v3
- name : Extract metadata (tags) for Docker
id : meta
uses : docker/metadata-action@v5
with :
tags : |
type=semver,pattern=v{{version}}
type=semver,pattern=v{{major}}.{{minor}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.0.') }}
type=semver,pattern=v{{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
2025-04-18 22:24:35 +01:00
type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) 1= github.ref && 'branch-' || '' }}
2025-04-16 18:54:36 +01:00
type=ref,event=pr
type=sha,format=long
images : ${{needs.define-variables.outputs.images}}
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
env :
2025-04-24 17:24:28 +01:00
DOCKER_METADATA_ANNOTATIONS_LEVELS : index
2025-04-16 18:54:36 +01:00
- name : Create manifest list and push
working-directory : /tmp/digests
env :
IMAGES : ${{needs.define-variables.outputs.images}}
shell : bash
run : |
IFS=$'\n'
IMAGES_LIST=($IMAGES)
ANNOTATIONS_LIST=($DOCKER_METADATA_OUTPUT_ANNOTATIONS)
TAGS_LIST=($DOCKER_METADATA_OUTPUT_TAGS)
for REPO in "${IMAGES_LIST[@]}"; do
docker buildx imagetools create \
$(for tag in "${TAGS_LIST[@]}"; do echo "--tag"; echo "$tag"; done) \
$(for annotation in "${ANNOTATIONS_LIST[@]}"; do echo "--annotation"; echo "$annotation"; done) \
$(for reference in *; do printf "$REPO@sha256:%s\n" $reference; done)
done
- name : Inspect image
env :
IMAGES : ${{needs.define-variables.outputs.images}}
shell : bash
run : |
IMAGES_LIST=($IMAGES)
for REPO in "${IMAGES_LIST[@]}"; do
docker buildx imagetools inspect $REPO:${{ steps.meta.outputs.version }}
done