Skip to content

Docker Build and Push #188

Docker Build and Push

Docker Build and Push #188

Workflow file for this run

name: Docker Build and Push
run-name: >-
${{ github.workflow }}${{ github.event_name == 'workflow_dispatch' && format(' [{0}] {1}:{2}', inputs.run_key, inputs.branch, inputs.choice) || '' }}
permissions:
contents: write
packages: write
on:
workflow_dispatch:
inputs:
branch:
type: choice
description: Target branch to build/push for
required: true
default: develop
options:
- develop
- master
choice:
type: choice
description: Trigger build and optionally bump version
required: true
default: none
options:
- none
- major
- minor
- patch
run_key:
type: string
description: Correlation id (optional)
required: false
default: ""
push:
branches:
- develop
jobs:
docker-build:
runs-on: ubuntu-latest
if: >-
(
github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop'
) && (
github.event_name != 'push' || github.actor != 'github-actions[bot]'
) && (
github.event_name != 'push' ||
github.event.head_commit.message == null ||
!startsWith(github.event.head_commit.message, 'ci: bump version v')
)
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Create and use multi-platform builder
run: |
docker buildx create --name multiarch --use --bootstrap
docker buildx inspect multiarch
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-unknown-linux-musl,aarch64-unknown-linux-musl,wasm32-unknown-unknown
- name: Detect runner image/libc
id: runner_env
shell: bash
run: |
set -euo pipefail
echo "image_os=${ImageOS:-unknown}" >> "$GITHUB_OUTPUT"
echo "image_version=${ImageVersion:-unknown}" >> "$GITHUB_OUTPUT"
if command -v ldd >/dev/null 2>&1; then
glibc="$(ldd --version 2>/dev/null | head -n1 | awk '{print $NF}')"
else
glibc="unknown"
fi
echo "glibc=${glibc:-unknown}" >> "$GITHUB_OUTPUT"
- name: Cache cargo tools
id: cache-tools
uses: actions/cache@v4
with:
path: |
~/.cargo/bin
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-${{ steps.runner_env.outputs.image_os }}-${{ steps.runner_env.outputs.image_version }}-${{ steps.runner_env.outputs.glibc }}-cargo-tools-v2
restore-keys: |
${{ runner.os }}-${{ steps.runner_env.outputs.image_os }}-${{ steps.runner_env.outputs.image_version }}-${{ steps.runner_env.outputs.glibc }}-cargo-tools-
- name: Install cross
run: |
if ! command -v cross &> /dev/null; then
cargo install cross --git https://github.com/cross-rs/cross
fi
- name: Install trunk
run: |
if ! command -v trunk &> /dev/null; then
RUSTFLAGS="" cargo install trunk --locked
fi
- name: Install wasm-bindgen-cli
run: |
if ! command -v wasm-bindgen &> /dev/null; then
cargo install wasm-bindgen-cli
fi
- name: Install cargo-edit
run: |
if ! command -v cargo-set-version &> /dev/null; then
cargo install cargo-edit --locked
fi
- name: Cache cargo registry and dependencies
id: cache-cargo-deps
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
key: ${{ runner.os }}-${{ steps.runner_env.outputs.image_os }}-${{ steps.runner_env.outputs.image_version }}-${{ steps.runner_env.outputs.glibc }}-cargo-deps-v2-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('**/Cargo.toml') }}
restore-keys: |
${{ runner.os }}-${{ steps.runner_env.outputs.image_os }}-${{ steps.runner_env.outputs.image_version }}-${{ steps.runner_env.outputs.glibc }}-cargo-deps-v2-${{ hashFiles('**/Cargo.lock') }}-
${{ runner.os }}-${{ steps.runner_env.outputs.image_os }}-${{ steps.runner_env.outputs.image_version }}-${{ steps.runner_env.outputs.glibc }}-cargo-deps-v2-
${{ runner.os }}-cargo-deps-
- name: Cache Docker buildx
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Cache frontend dist
id: cache-frontend
uses: actions/cache@v4
with:
path: frontend/dist
key: ${{ runner.os }}-frontend-${{ hashFiles('frontend/**/*', 'shared/**/*') }}-${{ hashFiles('frontend/Cargo.toml', 'frontend/Trunk.toml') }}
restore-keys: |
${{ runner.os }}-frontend-
- name: Cache cross-compilation tools
uses: actions/cache@v4
with:
path: |
~/.cross
~/.rustup/toolchains/*/lib/rustlib/x86_64-unknown-linux-musl
~/.rustup/toolchains/*/lib/rustlib/aarch64-unknown-linux-musl
key: ${{ runner.os }}-cross-${{ hashFiles('**/Cargo.lock') }}-v2
restore-keys: |
${{ runner.os }}-cross-
- name: Cache built resources
id: cache-resources
uses: actions/cache@v4
with:
path: |
resources/*.ts
key: ${{ runner.os }}-resources-${{ hashFiles('resources/*.jpg') }}-v1
restore-keys: |
${{ runner.os }}-resources-
- name: Install ffmpeg (only if resources not cached)
if: steps.cache-resources.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y ffmpeg
- name: Bump patch version (develop)
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
run: ./bin/inc_version.sh
- name: Set version (manual)
if: github.event_name == 'workflow_dispatch'
shell: bash
run: |
CHOICE='${{ github.event.inputs.choice }}'
case "${CHOICE:-none}" in
none) echo "Skipping version bump" ;;
major) ./bin/inc_version.sh m ;;
minor) ./bin/inc_version.sh p ;;
patch) ./bin/inc_version.sh ;;
*) echo "🧨 Error: Unsupported option"; exit 1 ;;
esac
- name: Commit version bump (local)
id: version_commit
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
shell: bash
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
FILES=(Cargo.lock backend/Cargo.lock backend/Cargo.toml frontend/Cargo.toml shared/Cargo.toml)
for f in "${FILES[@]}"; do
if [ -f "$f" ]; then
git add "$f"
fi
done
if git diff --cached --quiet; then
echo "did_commit=false" >> "$GITHUB_OUTPUT"
exit 0
fi
VERSION="$(grep '^version' backend/Cargo.toml | head -n1 | cut -d'"' -f2)"
if [ -n "${VERSION}" ]; then
git commit -m "ci: bump version v${VERSION}"
else
git commit -m "ci: bump version"
fi
echo "did_commit=true" >> "$GITHUB_OUTPUT"
- name: Extract branch name
shell: bash
id: extract_branch
run: |
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
echo "branch=${{ inputs.branch }}" >> "$GITHUB_OUTPUT"
else
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT"
fi
- name: Make build script executable
run: chmod +x ./bin/build_docker.sh
- name: Build and push Docker images
env:
GITHUB_IO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO_OWNER: ${{ github.repository_owner }}
FRONTEND_CACHE_HIT: ${{ steps.cache-frontend.outputs.cache-hit }}
CARGO_DEPS_CACHE_HIT: ${{ steps.cache-cargo-deps.outputs.cache-hit }}
BUILDX_CACHE_FROM: type=local,src=/tmp/.buildx-cache
BUILDX_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new,mode=max
run: ./bin/build_docker.sh ${{ steps.extract_branch.outputs.branch }}
- name: Push version bump
if: success() && steps.version_commit.outputs.did_commit == 'true'
shell: bash
run: |
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
BRANCH='${{ inputs.branch }}'
else
BRANCH="${GITHUB_REF#refs/heads/}"
fi
if [[ "${BRANCH}" != "develop" && "${BRANCH}" != "master" ]]; then
echo "Skipping push: unsupported branch '${BRANCH}'"
exit 0
fi
git push origin "HEAD:${BRANCH}"
- name: Move buildx cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache || true