# Reusable workflow: Build Docker image and push to Gitea registry # Usage: uses: wectrl-net/ci-templates/.gitea/workflows/build-push.yaml@main name: Build & Push Docker Image on: workflow_call: inputs: image-name: description: "Full image name (e.g. git.wectrl.net/wectrl-net/my-service)" required: true type: string context: description: "Docker build context path" required: false type: string default: "." dockerfile: description: "Path to Dockerfile (relative to context)" required: false type: string default: "Dockerfile" platforms: description: "Target platforms (e.g. linux/amd64,linux/arm64). Default builds multi-arch — both clusters can pull the same manifest." required: false type: string default: "linux/amd64,linux/arm64" build-args: description: "Docker build args (newline-separated KEY=VALUE)" required: false type: string default: "" version: description: "Optional version for pinned dev tags (e.g. '123' produces 'dev-v123'). Only applies on dev branch." required: false type: string default: "" runner: description: "Runner label to use. Default is `amd64` (the k8s-runner-amd64 on the x86 builder node); arm64 leg is built via QEMU on the same host. Set to `ubuntu-latest` to fall back to the ARM runner — useful for Rust/heavy builds that benefit from native arm64." required: false type: string default: "amd64" secrets: REGISTRY_USER: required: true REGISTRY_TOKEN: required: true outputs: image-tag: description: "The sha-based image tag that was pushed" value: ${{ jobs.build.outputs.image-tag }} env-tag: description: "The environment tag that was pushed (prod, staging, dev, or dev-v{N})" value: ${{ jobs.build.outputs.env-tag }} jobs: build: name: Build & Push runs-on: ${{ inputs.runner }} container: image: catthehacker/ubuntu:act-22.04@sha256:52581951350bf4f1137d44883626850bdfa35a8e5318b95dcb22226caece3bc9 options: --privileged outputs: image-tag: ${{ steps.tag.outputs.tag }} env-tag: ${{ steps.tag.outputs.env-tag }} steps: - uses: actions/checkout@v4 - name: Compute image tag id: tag shell: bash run: | SHORT_SHA="${{ gitea.sha }}" SHORT_SHA="${SHORT_SHA:0:7}" echo "tag=sha-${SHORT_SHA}" >> "$GITEA_OUTPUT" # Determine environment tag from branch REF="${{ gitea.ref }}" VERSION="${{ inputs.version }}" case "$REF" in refs/heads/main|refs/heads/master) echo "env-tag=prod" >> "$GITEA_OUTPUT" ;; refs/heads/staging) echo "env-tag=staging" >> "$GITEA_OUTPUT" ;; refs/heads/dev) if [ -n "$VERSION" ]; then echo "env-tag=dev-v${VERSION}" >> "$GITEA_OUTPUT" else echo "env-tag=dev" >> "$GITEA_OUTPUT" fi ;; *) echo "env-tag=" >> "$GITEA_OUTPUT" ;; esac - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: git.wectrl.net username: ${{ secrets.REGISTRY_USER }} password: ${{ secrets.REGISTRY_TOKEN }} - name: Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ inputs.image-name }} tags: | type=sha,prefix=sha- type=raw,value=latest,enable={{is_default_branch}} type=raw,value=${{ steps.tag.outputs.env-tag }},enable=${{ steps.tag.outputs.env-tag != '' }} type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} # Install QEMU binfmt_misc handlers inside the dind sidecar so # buildx can emulate the non-native target arch. On the amd64 # runner this enables linux/arm64 builds; on the arm runner it # enables linux/amd64. No-op when only one platform is targeted. - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push uses: docker/build-push-action@v6 with: context: ${{ inputs.context }} file: ${{ inputs.context }}/${{ inputs.dockerfile }} platforms: ${{ inputs.platforms }} push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: ${{ inputs.build-args }} cache-from: type=registry,ref=${{ inputs.image-name }}:buildcache cache-to: type=registry,ref=${{ inputs.image-name }}:buildcache,mode=max