Skip to content

Build and Publish Docker Images #646

Build and Publish Docker Images

Build and Publish Docker Images #646

# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#name
name: Build and Publish Docker Images
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
schedule:
- cron: 0 2 * * MON
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobs
jobs:
# Set the build matrix
setmatrix:
name: Set Matrix
runs-on: ubuntu-latest
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idoutputs
outputs:
matrix: ${{ steps.setmatrix.outputs.matrix }}
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsteps
steps:
# https://github.com/marketplace/actions/setup-net-core-sdk
- name: Setup .NET SDK 8
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x
# https://github.com/marketplace/actions/checkout
- name: Checkout code
uses: actions/checkout@v4
# https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish
- name: Build CreateMatrix Tool
run: dotnet publish ./CreateMatrix/CreateMatrix.csproj --self-contained false --output ${{ runner.temp }}/publish
# Execute the compiled version to make sure that the build breaks for a non-0 exit code
- name: Run CreateMatrix Tool
run: ${{ runner.temp }}/publish/CreateMatrix matrix --version=./Make/Version.json --matrix=./Make/Matrix.json --update
# https://github.com/marketplace/actions/git-auto-commit
- name: Commit Version.json and Matrix.json
# Skip pull requests
if: ${{ github.event_name != 'pull_request' }}
uses: stefanzweifel/git-auto-commit-action@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
file_pattern: './Make/Version.json ./Make/Matrix.json'
commit_message: Update Version.json and Matrix.json
# Load Matrix.json from file
- name: Load Matrix JSON
id: setmatrix
run: |
# Load JSON from file
JSON=$(cat ./Make/Matrix.json)
echo "JSON:"
echo "$JSON"
# Convert the JSON to a single flat line to avoid having to escape the multiline output
echo "Flat JSON:"
FJSON=$(echo "$JSON" | jq --compact-output)
echo "$FJSON"
echo "matrix=${FJSON}" >> $GITHUB_OUTPUT
# Get version information after the new Version.json and Matrix.json files were comitted
getversion:
needs: setmatrix
name: Get Version
runs-on: ubuntu-latest
outputs:
SemVer2: ${{ steps.nbgv.outputs.SemVer2 }}
AssemblyVersion: ${{ steps.nbgv.outputs.AssemblyVersion }}
AssemblyFileVersion: ${{ steps.nbgv.outputs.AssemblyFileVersion }}
AssemblyInformationalVersion: ${{ steps.nbgv.outputs.AssemblyInformationalVersion }}
steps:
# Checkout code
# https://github.com/marketplace/actions/checkout
- name: Checkout
uses: actions/checkout@v4
with:
# Get all history for version calculation
fetch-depth: 0
# Run Nerdbank.GitVersioning
# https://github.com/marketplace/actions/nerdbank-gitversioning
- name: Run Nerdbank.GitVersioning tool
id: nbgv
uses: dotnet/nbgv@master
# Build and push docker images
buildpush:
needs: [setmatrix, getversion]
name: Build and Publish Docker Images
runs-on: ubuntu-latest
strategy:
# Keep building even if one job fails, helps with troubleshooting when there are multiple errors
fail-fast: false
# Limit number of concurrent builds
# Error: buildx failed with: ERROR: failed to solve: error writing layer blob: maximum timeout reached
max-parallel: 4
# https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs
matrix:
images: ${{ fromJson(needs.setmatrix.outputs.matrix).images }}
steps:
# https://github.com/marketplace/actions/checkout
- name: Checkout Code
uses: actions/checkout@v4
# https://github.com/marketplace/actions/docker-setup-qemu
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
# https://github.com/marketplace/actions/docker-setup-buildx
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
# https://github.com/marketplace/actions/docker-login
- name: Login to Docker Hub
# Skip pull requests
if: ${{ github.event_name != 'pull_request' }}
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# https://github.com/marketplace/actions/build-and-push-docker-images
# https://docs.docker.com/build/ci/github-actions/cache/
# https://github.com/moby/buildkit#github-actions-cache-experimental
- name: Build and Push Images
uses: docker/build-push-action@v6
with:
cache-from: type=gha,scope=${{ matrix.images.cachescope }}
cache-to: type=gha,mode=max,scope=${{ matrix.images.cachescope }}
context: Docker
file: Docker/${{ matrix.images.name }}.Dockerfile
platforms: linux/amd64,linux/arm64
# Push only if not a pull request and branch name matches current branch
push: ${{ (github.event_name != 'pull_request') && (github.ref_name == matrix.images.branch) }}
# Convert tag and args from array to multiline strings
tags: |-
${{ join(matrix.images.tags, '
') }}
build-args: |-
${{ join(matrix.images.args, '
') }}
LABEL_VERSION=${{ needs.getversion.outputs.SemVer2 }}
# Release
release:
name: Release
runs-on: ubuntu-latest
needs: [ buildpush, getversion ]
# Skip pull requests
if: ${{ github.event_name != 'pull_request' }}
steps:
# https://github.com/marketplace/actions/checkout
- name: Checkout Code
uses: actions/checkout@v4
# Create GitHub release
# https://github.com/marketplace/actions/gh-release
- name: Create GitHub release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
tag_name: ${{ needs.getversion.outputs.SemVer2 }}
prerelease: ${{ !endsWith(github.ref, 'refs/heads/main') }}
fail_on_unmatched_files: true
files: |
./Make/Version.json
./Make/Matrix.json
# Create a custom badge to report the build date
# Run this job at the end of the pipeline
datebadge:
needs: release
name: Build Date Badge
runs-on: ubuntu-latest
# Skip pull requests and only update on main branch
if: ${{ (github.event_name != 'pull_request') && (endsWith(github.ref, 'refs/heads/main')) }}
steps:
# Get date from environment as a variable
- id: date
run: |
echo "date=$(date)" >> $GITHUB_OUTPUT
# Create badge
# https://github.com/marketplace/actions/bring-your-own-badge
- name: Build Date Badge
uses: RubbaBoy/BYOB@v1
with:
name: lastbuild
label: Last Build
icon: github
status: ${{ steps.date.outputs.date }}
color: blue
github_token: ${{ secrets.GITHUB_TOKEN }}