name: Build and Publish

on:
  workflow_call:
    inputs:
      authenticate_with_ghcr:
        default: true
        type: boolean
        description: 'Whether to authenticate with DockerHub.'
      tag-prefix:
        required: true
        type: string
        description: 'The prefix to use for the Docker image tags.'
      php-versions-file:
        type: string
        default: 'scripts/conf/php-versions.yml'
        description: 'The path to the PHP versions file.'
      default-image-variation:
        type: string
        default: 'cli'
        description: 'The default PHP variation to use for the Docker image.'
      registry-repositories:
        type: string
        required: true
        description: 'The Docker registry repositories to push the images to. Separate multiple repositories with a comma (example: docker.io/serversideup/php,ghcr.io/serversideup/php)'
      release-type:
        type: string
        default: 'testing'
        description: 'The type of release to create. Options: testing, latest'
      push-to-registry:
        type: boolean
        default: true
        description: 'Whether to push the images to the registry.'

jobs:
  setup-matrix:
    runs-on: ubuntu-24.04
    outputs:
      php-version-map-json: ${{ steps.get-php-versions.outputs.php-version-map-json }}
    steps:
    - name: Check out code
      uses: actions/checkout@v4
    
    - name: Prepare PHP versions for the matrix. 😎
      run: |
        chmod +x ./scripts/get-php-versions.sh
        ./scripts/get-php-versions.sh
      env:
        SKIP_DOWNLOAD: false
    
    - name: Ensure our PHP Versions file exists.
      run: |
        if [ ! -f "${{ inputs.php-versions-file }}" ]; then
          echo "PHP Versions file does not exist. Exiting."
          exit 1
        else
          cat ${{ inputs.php-versions-file }}
        fi

    - name: Assemble PHP versions into the matrix. 😎
      id: get-php-versions
      run: |
        MATRIX_JSON=$(yq -o=json scripts/conf/php-versions.yml | jq -c '{include: [(.php_variations[] | {name, supported_os: (.supported_os // ["alpine", "bullseye", "bookworm"])} ) as $variation | .php_versions[] | .minor_versions[] | .patch_versions[] as $patch | .base_os[] as $os | select($variation.supported_os | if length == 0 then . else . | index($os.name) end) | {patch_version: $patch, base_os: $os.name, php_variation: $variation.name}]} | {include: (.include | sort_by(.patch_version | split(".") | map(tonumber) | . as $nums | ($nums[0]*10000 + $nums[1]*100 + $nums[2])) | reverse)}')
        echo "php-version-map-json=${MATRIX_JSON}" >> $GITHUB_OUTPUT
        echo "${MATRIX_JSON}" | jq '.'
  
    - name: Upload the php-versions.yml file
      uses: actions/upload-artifact@v4
      with:
        name: php-versions.yml
        path: ${{ inputs.php-versions-file }}

  docker-publish:
    needs: setup-matrix
    runs-on: ubuntu-24.04
    ## Use AWS runners
    # runs-on:
    #   - runs-on
    #   - runner=4cpu-linux-x64
    #   - run-id=${{ github.run_id }}
    strategy:
      matrix: ${{fromJson(needs.setup-matrix.outputs.php-version-map-json)}}

    steps:
      - name: Check out code.
        uses: actions/checkout@v4
  
      - name: Download PHP Versions file
        uses: actions/download-artifact@v4
        with:
          name: php-versions.yml
          path: ./artifacts
      
      - name: Move PHP Versions file
        run: mv ./artifacts/php-versions.yml ${{ inputs.php-versions-file }}
      
      ##
      # Docker build & publish
      ##
      - name: Login to DockerHub
        uses: docker/login-action@v3
        if: ${{ inputs.push-to-registry }}
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        if: ${{ inputs.push-to-registry && inputs.authenticate_with_ghcr }}
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: "📦 Assemble the Docker Tags"
        run: |
          chmod +x ./scripts/assemble-docker-tags.sh
          ./scripts/assemble-docker-tags.sh
        env:
          PHP_VERSIONS_FILE: "${{ inputs.php-versions-file }}"
          DEFAULT_IMAGE_VARIATION: ${{ inputs.default-image-variation }}
          PHP_BUILD_VERSION: ${{ matrix.patch_version }}
          PHP_BUILD_VARIATION: ${{ matrix.php_variation }}
          PHP_BUILD_BASE_OS: ${{ matrix.base_os }}
          DOCKER_TAG_PREFIX: ${{ inputs.tag-prefix }}
          DOCKER_REGISTRY_REPOSITORIES: ${{ inputs.registry-repositories }}
          RELEASE_TYPE: ${{ inputs.release-type }}
          GITHUB_RELEASE_TAG: ${{ github.ref_name }}
          GITHUB_REF_TYPE: ${{ github.ref_type }}

      - name: Set REPOSITORY_BUILD_VERSION
        id: set_version
        run: |
          if [ "${{ github.ref_type }}" == "tag" ]; then
            echo "🚀 Setting REPOSITORY_BUILD_VERSION to Tag"
            echo "REPOSITORY_BUILD_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
          else
            echo "👨‍🔬 Setting REPOSITORY_BUILD_VERSION to GIT Short SHA and GitHub Run ID"
            SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
            echo "REPOSITORY_BUILD_VERSION=git-${SHORT_SHA}-${{ github.run_id }}" >> $GITHUB_ENV
          fi

      - name: Build images
        uses: docker/build-push-action@v6
        with:
          file: src/variations/${{ matrix.php_variation }}/Dockerfile
          cache-from: type=gha
          cache-to: type=gha
          ## Run-on cache
          # cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
          # cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
          build-args: |
            BASE_OS_VERSION=${{ matrix.base_os }}
            PHP_VERSION=${{ matrix.patch_version }}
            PHP_VARIATION=${{ matrix.php_variation }}
            REPOSITORY_BUILD_VERSION=${{ env.REPOSITORY_BUILD_VERSION }}
          platforms: |
            linux/amd64
            linux/arm64/v8
          pull: true
          push: ${{ inputs.push-to-registry }}
          tags: ${{ env.DOCKER_TAGS }}
          outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=Supercharge your PHP experience with Docker images that are based off the official PHP images but are optimized to be run in production environments for Laravel and WordPress and more
