name: Build Marshall

permissions:
  contents: read
  packages: write

on:
  workflow_call:
  workflow_dispatch:

env:
  latest-stable-version: "focal"
  ghcr_image: "ghcr.io/benzine-framework/marshall"
  docker_hub_image: "benzine/marshall"

jobs:
  marshall-build:
    name: "Build"
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        ubuntu:
          - focal
          - jammy
          - lunar
          - mantic
          - noble
          - devel
          - rolling
          - latest
        platform:
          - linux/amd64
          - linux/arm64
    steps:
      - name: "Build: Prepare Environment Variables"
        id: environment
        run: |
          {
            echo "datetime=$(date +'%Y-%m-%d %H:%M:%S')"
            echo "date=$(date +'%Y-%m-%d')"
            echo "time=$(date +'%H:%M:%S')"
            echo "container_build_datetime=$(date -u +'%Y-%m-%dT%H:%M:%S.%3NZ')"
            echo "marshall_version=$(git rev-parse --short HEAD)"
            echo "marshall_build_date=$(date '+%Y-%m-%d %H:%M:%S')"
            echo "marshall_build_host=$(hostname)"
          } >> "$GITHUB_OUTPUT"

          {
            platform=${{ matrix.platform }}
            echo "platform_pair=${platform//\//-}"
          } >> "$GITHUB_ENV"

      - uses: actions/checkout@v4
        with:
          sparse-checkout: |
            marshall

      - uses: docker/setup-qemu-action@v2

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

      - name: "Setup: Login to Docker Hub"
        uses: docker/login-action@v3
        with:
          username: matthewbaggett
          password: ${{ secrets.DOCKER_HUB_PASSWORD }}

      - name: "Setup: Login to GHCR"
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: matthewbaggett
          password: ${{ secrets.GHCR_PASSWORD }}

      - name: "Setup: Docker meta"
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ env.ghcr_image }}
            ${{ env.docker_hub_image }}
          labels: |
            org.opencontainers.image.title=Marshall
            org.opencontainers.image.description=Multi-thread (marshalling..) docker base image built atop Ubuntu ${{ matrix.ubuntu }} & Runit
            org.opencontainers.image.vendor=Matthew Baggett
          flavor: |
            latest=auto
          tags: |
            ${{ matrix.ubuntu }}

      - name: "Build: Build Marshall for ${{ matrix.ubuntu }} on ${{ matrix.platform }}"
        uses: docker/build-push-action@v5
        id: build
        with:
          context: marshall
          platforms: ${{ matrix.platform }}
          labels: ${{ steps.meta.outputs.labels }}
          build-args: |
            MARSHALL_VERSION=${{ steps.environment.outputs.marshall_version }}
            MARSHALL_BUILD_DATE=${{ steps.environment.outputs.marshall_build_date }}
            MARSHALL_BUILD_HOST=${{ steps.environment.outputs.marshall_build_host }}
          cache-from: ${{ !env.ACT && 'type=gha,scope=marshall-${{ matrix.ubuntu }}' || '' }}
          cache-to: ${{ !env.ACT && 'type=gha,mode=max,scope=marshall-${{ matrix.ubuntu }}' || '' }}
          build-contexts: ubuntu:version=docker-image://ubuntu:${{ matrix.ubuntu }}
          outputs: |
            type=image,name=${{ env.ghcr_image }},push-by-digest=true,name-canonical=true,push=true

      - name: "Build: Export digest"
        run: |
          mkdir -p /tmp/digests
          digest="${{ steps.build.outputs.digest }}"
          touch "/tmp/digests/${digest#sha256:}"

      - name: "Build: Upload digest"
        uses: actions/upload-artifact@v3
        with:
          name: digests-${{ matrix.ubuntu }}
          path: /tmp/digests/*
          if-no-files-found: error
          retention-days: 1

  marshall-merge:
    runs-on: ubuntu-latest
    name: "Merge"
    needs: [marshall-build]
    strategy:
      fail-fast: false
      matrix:
        ubuntu:
          - focal
          - jammy
          - lunar
          - mantic
          - noble
          - devel
          - rolling
          - latest
    steps:
      - uses: docker/setup-buildx-action@v3

      - name: "Setup: Login to Docker Hub"
        uses: docker/login-action@v3
        with:
          username: matthewbaggett
          password: ${{ secrets.DOCKER_HUB_PASSWORD }}

      - name: "Setup: Login to GHCR"
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: matthewbaggett
          password: ${{ secrets.GHCR_PASSWORD }}

      - name: "Merge: Docker meta"
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ env.ghcr_image }}
            ${{ env.docker_hub_image }}
          labels: |
            org.opencontainers.image.title=Marshall
            org.opencontainers.image.description=Multi-thread (marshalling..) docker base image built atop Ubuntu ${{ matrix.ubuntu }} & Runit
            org.opencontainers.image.vendor=Matthew Baggett
          flavor: |
            latest=auto
          tags: |
            ${{ matrix.ubuntu }}

      - uses: hmarr/debug-action@v3

      - name: "Setup: Download ${{ matrix.ubuntu }} digests"
        uses: actions/download-artifact@v3
        with:
          path: /tmp/digests
          name: digests-${{ matrix.ubuntu }}

      - name: "Merge: Create ${{ matrix.ubuntu }} manifest list and push"
        working-directory: /tmp/digests
        shell: bash
        run: |
          set -o xtrace
          pwd
          ls -lah

          docker buildx imagetools \
            create \
              $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
              $(printf '${{ env.ghcr_image }}@sha256:%s ' *)

      - name: "Merge: Inspect image"
        run: |
          docker buildx imagetools inspect ${{ env.ghcr_image }}:${{ steps.meta.outputs.version }}

  marshall-tag-latest:
    name: "Tag Latest"
    runs-on: ubuntu-latest
    needs: [marshall-merge]
    strategy:
      fail-fast: false
      matrix:
        output_tag:
          - "benzine/marshall"
          - "gone/marshall"
          - "ghcr.io/benzine-framework/marshall"
    steps:
      - name: "Setup: Login to Docker Hub"
        uses: docker/login-action@v3
        with:
          username: matthewbaggett
          password: ${{ secrets.DOCKER_HUB_PASSWORD }}

      - name: "Setup: Login to GHCR"
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: matthewbaggett
          password: ${{ secrets.GHCR_PASSWORD }}

      - name: "Retag ${{ env.ghcr_image }}:${{ env.latest-stable-version }} to ${{ matrix.output_tag }}:bleeding"
        shell: bash
        run: |
          docker pull ${{ env.ghcr_image }}:${{ env.latest-stable-version }}
          docker tag ${{ env.ghcr_image }}:${{ env.latest-stable-version }} ${{ matrix.output_tag }}:bleeding
          docker push ${{ matrix.output_tag }}:bleeding

      - name: "Retag ${{ env.ghcr_image }}:${{ env.latest-stable-version }} to ${{ matrix.output_tag }}:latest"
        if: ${{ github.ref == 'refs/heads/main' }}
        shell: bash
        run: |
          docker pull ${{ env.ghcr_image }}:${{ env.latest-stable-version }}
          docker tag ${{ env.ghcr_image }}:${{ env.latest-stable-version }} ${{ matrix.output_tag }}:latest
          docker push ${{ matrix.output_tag }}:latest