dragonfly/.github/workflows/reusable-container-workflow.yaml
2024-07-01 08:36:36 +00:00

206 lines
7.4 KiB
YAML

name: Reusable Container Build Workflow
on:
workflow_call:
inputs:
# Which suffix to look for with the Dockerfile. Can be dev or prod
build_type:
required: true
type: string
# For example 'alpha', for pre-release or weekly builds
tag:
required: false
type: string
# Is this a final release? Then we set this to true, so the 'latest' tag is updated
tag_latest:
required: false
type: boolean
# The container image dragonflydb/dragonfly
image:
required: true
type: string
# ghcr.io / hub.docker.com / quay.io / you name it
registry:
required: true
type: string
# Username used to login to the registry
registry_username:
required: true
type: string
# Do we have to fetch release assets? Then set this to true.
# Not required for build_type == dev, as they entirely build from source
# But for build_type == prod, as they're based on the release assets
fetch_release:
required: false
type: boolean
# Which version are we fetching? Should be identical to the release version.
# For example v0.12.0
release_version:
required: false
type: string
secrets:
# Password used to login to the registry
registry_password:
required: true
# Github Personal Access Token used to fetch assets from a release
GH_TOKEN:
required: false
jobs:
container-build:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- flavor: alpine
dockerfile: tools/packaging/Dockerfile.alpine
tag_main: false
- flavor: ubuntu
dockerfile: tools/packaging/Dockerfile.ubuntu
tag_main: true
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: true
- if: inputs.fetch_release
name: Fetch release asset
uses: dsaltares/fetch-gh-release-asset@1.1.2
with:
version: "tags/${{ inputs.release_version }}"
regex: true
file: "dragonfly-.*\\.tar\\.gz"
target: 'releases/'
token: ${{ secrets.GH_TOKEN }}
- if: inputs.fetch_release
name: Extract artifacts
run: |
echo "Event prerelease ${{ github.event.release.prerelease }}"
echo "Input prerelease ${{ github.event.inputs.PRERELEASE }}"
ls -l
ls -l releases
for f in releases/*.tar.gz; do tar xvfz $f -C releases; done
rm releases/*.tar.gz
- name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v3
with:
platforms: arm64,amd64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ inputs.registry_username }}
password: ${{ secrets.registry_password }}
- name: Docker meta
id: metadata
uses: docker/metadata-action@v5
with:
images: |
${{ inputs.image }}
tags: |
# will set tag 'latest' for ubuntu build on production push
# inputs.tag_latest will be true on when triggered by docker-release.yml
# matrix.tag_main will only be true for ubuntu flavor
type=raw,value=latest,enable=${{ matrix.tag_main && inputs.tag_latest }}
# set a tag like 'alpine' or 'ubuntu', if we're setting 'latest' during this build as well
type=raw,value=${{ matrix.flavor }},enable=${{ inputs.tag_latest }}
# will set tag like 'alpha' for ubuntu build, if inputs.tag is not empty
# but will set the non-flavored tag only, if matrix.tag_main is true
type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != 'false' && matrix.tag_main }}
# will set tag like 'alpha-(ubuntu|alpine)', if inputs.tag is not empty
type=raw,value=${{ inputs.tag }}-${{ matrix.flavor }},enable=${{ inputs.tag != 'false' }}
# will set tag like 'v0.12.0' for ubuntu build, if inputs.release_version is not empty
# but will set the non-flavored tag only, if matrix.tag_main is true
type=raw,value=${{ inputs.release_version }},enable=${{ matrix.tag_main && inputs.release_version != '' }}
# will set tag like 'v0.12.0-(ubuntu|alpine)', if inputs.release_version is not empty
type=raw,value=${{ inputs.release_version }}-${{ matrix.flavor }},enable=${{ inputs.release_version != '' }}
# build is broken based on platforms as load: true is not supported with multi-platform builds
- if: ${{ hashFiles(format('{0}-{1}', matrix.dockerfile, inputs.build_type)) }}
name: Build release image for amd64
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
build-args: |
QEMU_CPU=max,pauth-impdef=on
push: false
tags: |
${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
file: ${{ matrix.dockerfile }}-${{ inputs.build_type }}
cache-from: type=gha
cache-to: type=gha,mode=max
# only load AMD64 image for testing
load: true
- if: ${{ hashFiles(format('{0}-{1}', matrix.dockerfile, inputs.build_type)) }}
name: Build release image for arm64
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/arm64
build-args: |
QEMU_CPU=max,pauth-impdef=on
push: false
tags: |
${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
file: ${{ matrix.dockerfile }}-${{ inputs.build_type }}
cache-from: type=gha
cache-to: type=gha,mode=max
- if: ${{ hashFiles(format('{0}-{1}', matrix.dockerfile, inputs.build_type)) }}
name: Test Docker run
run: |
# docker run with port-forwarding
# install redis-tools
sudo apt-get install redis-tools -y
tag="${{ steps.metadata.outputs.tags }}"
# use the first tag if multiple tags are provided
if [[ $(echo "${tag}" | wc -l) -gt 1 ]]; then
echo "Multiple tags provided, using the first one"
tag=$(echo "${tag}" | head -n 1)
fi
echo "Testing ${tag}"
docker run -d -p 6379:6379 ${tag}
sleep 5
# ping with redis-cli and expect PONG
if [[ $(redis-cli -h localhost ping) != "PONG" ]]; then
echo "Redis ping failed"
exit 1
else
echo "Redis ping succeeded"
exit 0
fi
- if: ${{ hashFiles(format('{0}-{1}', matrix.dockerfile, inputs.build_type)) }}
name: Push release image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
build-args: |
QEMU_CPU=max,pauth-impdef=on
tags: |
${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
file: ${{ matrix.dockerfile }}-${{ inputs.build_type }}
cache-from: type=gha
cache-to: type=gha,mode=max