name: create-manifest
description: |
  Create and push a multi-platform Docker manifest from individual platform digests.
  Handles downloading digests, creating manifest lists, and pushing to registry.

inputs:
  digest_pattern:
    description: Glob pattern to match digest artifacts (e.g. "digests-linux-{amd64,arm64}")
    required: true
  tag_suffix:
    description: Suffix to add to all Docker tags (e.g. "-maxperf")
    required: false
    default: ""
  images:
    description: Container registry images (newline-separated)
    required: true
  registry_user:
    description: Registry username for authentication
    required: false
  registry_password:
    description: Registry password for authentication
    required: false

outputs:
  version:
    description: The version tag created for the manifest
    value: ${{ steps.meta.outputs.version }}
  tags:
    description: All tags created for the manifest
    value: ${{ steps.meta.outputs.tags }}

runs:
  using: composite
  steps:
    - run: mkdir -p digests
      shell: bash
    - name: Download digests
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      uses: forgejo/download-artifact@v4
      with:
        path: digests
        pattern: ${{ inputs.digest_pattern }}
        merge-multiple: true

    - name: Login to builtin registry
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
      with:
        registry: ${{ env.BUILTIN_REGISTRY }}
        username: ${{ inputs.registry_user }}
        password: ${{ inputs.registry_password }}

    - name: Set up Docker Buildx
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
      with:
        # Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
        driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
        endpoint: ${{ env.BUILDKIT_ENDPOINT || '' }}

    - name: Extract metadata (tags) for Docker
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      id: meta
      uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
      with:
        flavor: |
          latest=auto
          suffix=${{ inputs.tag_suffix }},onlatest=true
        tags: |
          type=semver,pattern={{version}},prefix=v
          type=semver,pattern={{major}}.{{minor}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.0.') }},prefix=v
          type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }},prefix=v
          type=ref,event=branch,prefix=${{ format('refs/heads/{0}', github.event.repository.default_branch) != github.ref && 'branch-' || '' }},
          type=ref,event=pr
          type=sha,format=short
        images: ${{ inputs.images }}
        # default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
      env:
        DOCKER_METADATA_ANNOTATIONS_LEVELS: index

    - name: Create manifest list and push
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      working-directory: digests
      shell: bash
      env:
        IMAGES: ${{ inputs.images }}
      run: |
        set -o xtrace
        IFS=$'\n'
        IMAGES_LIST=($IMAGES)
        ANNOTATIONS_LIST=($DOCKER_METADATA_OUTPUT_ANNOTATIONS)
        TAGS_LIST=($DOCKER_METADATA_OUTPUT_TAGS)
        for REPO in "${IMAGES_LIST[@]}"; do
            docker buildx imagetools create \
              $(for tag in "${TAGS_LIST[@]}"; do echo "--tag"; echo "$tag"; done) \
              $(for annotation in "${ANNOTATIONS_LIST[@]}"; do echo "--annotation"; echo "$annotation"; done) \
              $(for reference in *; do printf "$REPO@sha256:%s\n" $reference; done)
        done

    - name: Inspect image
      if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
      shell: bash
      env:
        IMAGES: ${{ inputs.images }}
      run: |
        set -o xtrace
        IMAGES_LIST=($IMAGES)
        for REPO in "${IMAGES_LIST[@]}"; do
          docker buildx imagetools inspect $REPO:${{ steps.meta.outputs.version }}
        done
