Build and Publish Docker Images #660
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 }} |