Skip to content

CD (Release)

CD (Release) #59

Workflow file for this run

name: CD (Release)
on:
release:
types: [published]
workflow_dispatch:
inputs:
force_rebuild:
description: 'Force container rebuild'
required: true
type: choice
options: [yes, no]
schedule:
- cron: '30 12 * * *'
permissions:
packages: write
contents: read
env:
IMAGE_NAME: ${{ github.repository }}
DOCKER_FILE: alpine
jobs:
BuildImage:
name: Image Build & Publish
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout the latest tag
run: |
rev=$(git rev-list --tags --max-count=1)
tag=$(git describe --tags "$rev")
if [[ -z "$tag" ]] ; then
echo "::error::Can't find the latest tag"
exit 1
fi
echo -e "\033[34mRev:\033[0m $rev"
echo -e "\033[34mTag:\033[0m $tag"
git checkout "$tag"
- name: Prepare metadata for build
id: metadata
run: |
rev=$(git rev-list --tags --max-count=1)
version=$(git describe --tags "$rev" | tr -d 'v')
if [[ -z "$version" ]] ; then
echo "::error::Can't find version info"
exit 1
fi
docker_file=".docker/${{env.DOCKER_FILE}}.docker"
base_image=$(grep 'FROM ' $docker_file | grep -v 'builder' | sed 's#${REGISTRY}/##' | tail -1 | cut -f2 -d' ')
if [[ -z "$base_image" ]] ; then
echo "::error::Can't extract base image info"
exit 1
fi
echo "version=$version" >> $GITHUB_OUTPUT
echo "dockerfile=$docker_file" >> $GITHUB_OUTPUT
echo "baseimage=$base_image" >> $GITHUB_OUTPUT
echo -e "\033[34mVersion:\033[0m $version"
echo -e "\033[34mDockerfile:\033[0m $docker_file"
echo -e "\033[34mBase image:\033[0m $base_image"
- name: Check if build/rebuild is required
id: build_check
run: |
if [[ "$GITHUB_EVENT_NAME" == "release" ]] ; then
echo "build=true" >> $GITHUB_OUTPUT
exit 0
fi
if [[ "${{ github.event.inputs.force_rebuild }}" == "true" ]] ; then
echo "::warning::Rebuild is required (reason: forced rebuild)"
echo "build=true" >> $GITHUB_OUTPUT
exit 0
fi
echo -e "::group::\033[34mDownloading built image…\033[0m"
if ! docker pull ghcr.io/${{env.IMAGE_NAME}}:latest ; then
echo "::error::Can't download image ghcr.io/${{env.IMAGE_NAME}}:latest"
exit 1
fi
echo "::endgroup::"
echo -e "::group::\033[34mDownloading base image…\033[0m"
if ! docker pull ${{steps.metadata.outputs.baseimage}} ; then
echo "::error::Can't download image ${{steps.metadata.outputs.baseimage}}"
exit 1
fi
echo "::endgroup::"
base_layer=$(docker inspect "${{steps.metadata.outputs.baseimage}}" | jq -r '.[0].RootFS.Layers[-1]')
if [[ -z "$base_layer" ]] ; then
echo "::error::Can't extract layers info from base image"
exit 1
fi
if ! docker inspect "ghcr.io/${{env.IMAGE_NAME}}:latest" | jq -r '.[0].RootFS.Layers' | grep -q "$base_layer" ; then
echo "::warning::Rebuild image (reason: base image rebuilt)"
echo "build=true" >> $GITHUB_OUTPUT
exit 0
fi
- name: Build and push Docker images (Docker)
if: ${{ steps.build_check.outputs.build == 'true' }}
uses: docker/build-push-action@v6
with:
push: true
context: .
file: ${{steps.metadata.outputs.dockerfile}}
build-args: |
REGISTRY=docker.io
tags: |
${{env.IMAGE_NAME}}:${{steps.metadata.outputs.version}}
${{env.IMAGE_NAME}}:latest
- name: Build and push Docker images (GHCR)
if: ${{ steps.build_check.outputs.build == 'true' }}
uses: docker/build-push-action@v6
with:
push: true
context: .
file: ${{steps.metadata.outputs.dockerfile}}
build-args: |
REGISTRY=ghcr.io
tags: |
ghcr.io/${{env.IMAGE_NAME}}:${{steps.metadata.outputs.version}}
ghcr.io/${{env.IMAGE_NAME}}:latest
- name: Show info about built Docker image
if: ${{ steps.build_check.outputs.build == 'true' }}
uses: essentialkaos/docker-info-action@v1
with:
image: ghcr.io/${{env.IMAGE_NAME}}:latest
show-labels: true