# Release workflow — P5-03 (docker-only release path).
#
# Spec : docs/superpowers/specs/2026-05-05-p5-03-docker-only-release.md
# Plan : docs/superpowers/plans/2026-05-05-p5-03-docker-only-release.md
#
# What it does
#   * Triggered by either:
#       - tag push matching v[0-9]+.[0-9]+.[0-9]+ (real release), or
#       - workflow_dispatch (snapshot iteration without tagging).
#   * Cross-builds a multi-arch (linux/amd64,linux/arm64) image of the
#     server, with three agent binaries (linux amd64+arm64, windows amd64)
#     plus install.sh / install.ps1 / the systemd unit baked in under
#     /opt/restic-manager/dist (the read-only fallback path the server
#     handlers use when <DataDir>/... is empty).
#   * Pushes to zot OCI registry (docker.dcglab.co.uk).
#
# Tag fan-out
#   * tag push: :vX.Y.Z, :X.Y, :X
#   * tag push and X >= 1: also :latest
#   * workflow_dispatch: only :snapshot-<shortsha>; nothing else moves.

name: Release

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'
  workflow_dispatch:

env:
  REGISTRY: docker.dcglab.co.uk
  IMAGE_NAME: restic-manager

# Force bash as the default shell — see ci.yml header.
defaults:
  run:
    shell: bash

jobs:
  image:
    name: Build + push image
    runs-on: ubuntu-latest
    container:
      image: docker.dcglab.co.uk/ci-runner-go:2026-05-15
      credentials:
        username: ${{ secrets.ZOT_USERNAME }}
        password: ${{ secrets.ZOT_PASSWORD }}
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-qemu-action@v3
      - uses: docker/setup-buildx-action@v3

      - name: Log in to zot registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.ZOT_USERNAME }}
          password: ${{ secrets.ZOT_PASSWORD }}

      - name: Compute tags + version
        id: meta
        shell: bash
        run: |
          set -euo pipefail
          REG="${REGISTRY}/${IMAGE_NAME}"
          DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
          SHORT_SHA="${GITHUB_SHA::7}"

          if [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "${GITHUB_REF_TYPE}" = "tag" ]; then
            TAG="${GITHUB_REF_NAME}"            # vX.Y.Z
            VER="${TAG#v}"                       # X.Y.Z
            MAJOR="${VER%%.*}"
            MINOR="${VER#${MAJOR}.}"; MINOR="${MINOR%%.*}"

            TAGS="${REG}:${TAG}"
            TAGS="${TAGS},${REG}:${MAJOR}.${MINOR}"
            TAGS="${TAGS},${REG}:${MAJOR}"
            # Pre-1.0 holds back :latest by design; operators must
            # pin a version explicitly until v1.0.0.
            if [ "${MAJOR}" -ge 1 ]; then
              TAGS="${TAGS},${REG}:latest"
            fi
            VERSION="${TAG}"
          else
            TAGS="${REG}:snapshot-${SHORT_SHA}"
            VERSION="0.0.0-snapshot-${SHORT_SHA}"
          fi

          {
            echo "tags=${TAGS}"
            echo "version=${VERSION}"
            echo "date=${DATE}"
          } >> "${GITHUB_OUTPUT}"

      - name: Build + push
        uses: docker/build-push-action@v6
        with:
          context: .
          file: deploy/Dockerfile.server
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          build-args: |
            VERSION=${{ steps.meta.outputs.version }}
            COMMIT=${{ gitea.sha }}
            DATE=${{ steps.meta.outputs.date }}
          labels: |
            org.opencontainers.image.version=${{ steps.meta.outputs.version }}
            org.opencontainers.image.revision=${{ gitea.sha }}
            org.opencontainers.image.created=${{ steps.meta.outputs.date }}
