# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.

name: Create and publish Docker images

on:
  push:
    branches:
      - main          # Primary branch (Big-AGI Open)
    tags:
      - 'v2.*'        # Stable releases (v2.0.0, v2.1.0, etc.)

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # Build job: runs on native runners for each platform (no QEMU emulation)
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: linux/amd64
            runner: ubuntu-latest
          - platform: linux/arm64
            runner: ubuntu-24.04-arm

    runs-on: ${{ matrix.runner }}
    name: Build ${{ matrix.platform }}
    timeout-minutes: 30

    permissions:
      contents: read
      packages: write

    steps:
      - name: Prepare
        run: |
          platform=${{ matrix.platform }}
          echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
          echo "IMAGE_NAME_LC=${IMAGE_NAME,,}" >> $GITHUB_ENV

      - name: Checkout repository
        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
        with:
          fetch-depth: 1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

      - name: Log in to the Container registry
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata for Docker
        id: meta
        uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          labels: |
            org.opencontainers.image.title=Big-AGI Open
            org.opencontainers.image.description=Big-AGI Open - Multi-model AI workspace for experts who need to think broader, decide smarter, and build with confidence.
            org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
            org.opencontainers.image.documentation=https://big-agi.com

      - name: Build and push by digest
        id: build
        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
        with:
          context: .
          file: Dockerfile
          platforms: ${{ matrix.platform }}
          labels: ${{ steps.meta.outputs.labels }}
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}
          build-args: |
            NEXT_PUBLIC_GA4_MEASUREMENT_ID=${{ secrets.GA4_MEASUREMENT_ID }}
            NEXT_PUBLIC_BUILD_HASH=${{ github.sha }}
            NEXT_PUBLIC_BUILD_REF_NAME=${{ github.ref_name }}
          outputs: type=image,push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true
          provenance: false
          cache-from: type=gha,scope=${{ github.repository }}-${{ matrix.platform }}
          cache-to: type=gha,scope=${{ github.repository }}-${{ matrix.platform }},mode=max

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

      - name: Upload digest
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: digests-${{ env.PLATFORM_PAIR }}
          path: ${{ runner.temp }}/digests/*
          if-no-files-found: error
          retention-days: 1

  # Merge job: combines platform-specific images into a unified multi-arch manifest
  merge:
    name: Merge manifests
    runs-on: ubuntu-latest
    timeout-minutes: 10
    needs: build

    permissions:
      contents: read
      packages: write

    steps:
      - name: Prepare
        run: echo "IMAGE_NAME_LC=${IMAGE_NAME,,}" >> $GITHUB_ENV

      - name: Download digests
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          path: ${{ runner.temp }}/digests
          pattern: digests-*
          merge-multiple: true

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

      - name: Log in to the Container registry
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            # Development: main branch
            type=raw,value=development,enable=${{ github.ref == 'refs/heads/main' }}

            # Latest: v2.x releases (safe default)
            type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v2.') }}

            # Stable: v2.x releases (alias)
            type=raw,value=stable,enable=${{ startsWith(github.ref, 'refs/tags/v2.') }}

            # Version tags (v2.0.0, 2.0.0)
            type=ref,event=tag
            type=semver,pattern={{version}}

      - name: Create manifest list and push
        working-directory: ${{ runner.temp }}/digests
        run: |
          docker buildx imagetools create \
            $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
            --annotation='index:org.opencontainers.image.title=Big-AGI Open' \
            --annotation='index:org.opencontainers.image.description=Big-AGI Open - Multi-model AI workspace for experts who need to think broader, decide smarter, and build with confidence.' \
            --annotation='index:org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}' \
            --annotation='index:org.opencontainers.image.documentation=https://big-agi.com' \
            $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}@sha256:%s ' *)

      - name: Inspect image
        run: |
          docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LC }}:${{ steps.meta.outputs.version }}