name: Publish and Sign Container Image
on:
  workflow_call:
    inputs:
      go-version:
        required: true
        type: string
      quay_image_name:
        required: false
        type: string
      ghcr_image_name:
        required: false
        type: string
      docker_image_name:
        required: false
        type: string
      platforms:
        required: true
        type: string
      push:
        required: true
        type: boolean
      target:
        required: false
        type: string

    secrets:
      quay_username:
        required: false
      quay_password:
        required: false
      ghcr_username:
        required: false
      ghcr_password:
        required: false
      docker_username:
        required: false
      docker_password:
        required: false

    outputs:
      image-digest:
        description: "sha256 digest of container image"
        value: ${{ jobs.publish.outputs.image-digest }}

permissions: {}

env:
  # a workaround to disable harden runner
  STEP_SECURITY_HARDEN_RUNNER: ${{ vars.disable_harden_runner }}

jobs:
  publish:
    permissions:
      contents: read
      packages: write # Used to push images to `ghcr.io` if used.
      id-token: write # Needed to create an OIDC token for keyless signing
    runs-on: ubuntu-24.04
    outputs:  
      image-digest: ${{ steps.image.outputs.digest }}
    steps:
      - name: Harden the runner (Audit all outbound calls)
        if: ${{ vars.disable_harden_runner != 'true' }}
        uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
        with:
          egress-policy: audit

      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ github.ref_type == 'tag'}}

      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        if: ${{ github.ref_type != 'tag'}}

      - name: Setup Golang
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
        with:
          go-version: ${{ inputs.go-version }}
          cache: false

      - name: Install cosign
        uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1

      - name: Setup QEMU
        uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
        with:
          image: tonistiigi/binfmt@sha256:d3b963f787999e6c0219a48dba02978769286ff61a5f4d26245cb6a6e5567ea3 #qemu-v10.0.4

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
        with:
          # buildkit v0.28.1
          driver-opts: |
            image=moby/buildkit@sha256:a82d1ab899cda51aade6fe818d71e4b58c4079e047a0cf29dbb93b2b0465ea69
            

      - name: Setup tags for container image as a CSV type
        run: |
          IMAGE_TAGS=$(for str in \
            ${{ inputs.quay_image_name }} \
            ${{ inputs.ghcr_image_name }} \
            ${{ inputs.docker_image_name}}; do
            echo -n "${str}",;done | sed 's/,$//')

          echo $IMAGE_TAGS
          echo "TAGS=$IMAGE_TAGS" >> $GITHUB_ENV

      - name: Setup image namespace for signing, strip off the tag
        run: |
          TAGS=$(for tag in \
            ${{ inputs.quay_image_name }} \
            ${{ inputs.ghcr_image_name }} \
            ${{ inputs.docker_image_name}}; do
            echo -n "${tag}" | awk -F ":" '{print $1}' -;done)
          
            echo $TAGS
            echo 'SIGNING_TAGS<<EOF' >> $GITHUB_ENV
            echo $TAGS >> $GITHUB_ENV
            echo 'EOF' >> $GITHUB_ENV

      - name: Login to Quay.io
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
        with:
          registry: quay.io
          username: ${{ secrets.quay_username }}
          password: ${{ secrets.quay_password }}
        if: ${{ inputs.quay_image_name && inputs.push }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
        with:
          registry: ghcr.io
          username: ${{ secrets.ghcr_username }}
          password: ${{ secrets.ghcr_password }}
        if: ${{ inputs.ghcr_image_name && inputs.push }}

      - name: Login to dockerhub Container Registry
        uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
        with:
          username: ${{ secrets.docker_username }}
          password: ${{ secrets.docker_password }}
        if: ${{ inputs.docker_image_name && inputs.push }}

      - name: Set up build args for container image
        run: |
            echo "GIT_TAG=$(if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi)" >> $GITHUB_ENV
            echo "GIT_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
            echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
            echo "GIT_TREE_STATE=$(if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi)" >> $GITHUB_ENV

      - name: Free Disk Space (Ubuntu)
        uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
        with:
          large-packages: false
          docker-images: false
          swap-storage: false
          tool-cache: false

      - name: Build and push container image
        id: image
        uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f #v7.1.0
        with:
          context: .
          platforms: ${{ inputs.platforms }}
          push: ${{ inputs.push }}
          tags: ${{ env.TAGS }}
          target: ${{ inputs.target }}
          provenance: false
          sbom: false
          build-args: |
            GIT_TAG=${{env.GIT_TAG}}
            GIT_COMMIT=${{env.GIT_COMMIT}}
            BUILD_DATE=${{env.BUILD_DATE}}
            GIT_TREE_STATE=${{env.GIT_TREE_STATE}}

      - name: Sign container images
        run: |
          for signing_tag in $SIGNING_TAGS; do
            cosign sign \
            -a "repo=${{ github.repository }}" \
            -a "workflow=${{ github.workflow }}" \
            -a "sha=${{ github.sha }}" \
            -y \
            "$signing_tag"@${{ steps.image.outputs.digest }}
          done
        if: ${{ inputs.push }}
