name: Build and Upload GCP guest-agent container

on:
  workflow_dispatch:
  schedule:
    - cron: "0 4 * * 2" # Every Tuesday at 4am UTC

env:
  REGISTRY: ghcr.io

jobs:
  build-gcp-guest-agent:
    runs-on: ubuntu-22.04
    permissions:
      contents: read
      packages: write

    steps:
      - name: Get latest release of guest-agent
        id: latest-release
        run: |
          latest=$(curl -fsSL https://api.github.com/repos/GoogleCloudPlatform/guest-agent/releases/latest | jq -r .tag_name)
          echo "Latest version of guest-agent is $latest"
          echo "latest=$latest" | tee -a "$GITHUB_OUTPUT"

      - name: Make tag a valid semver
        id: latest-release-semver
        run: |
          semver="${{ steps.latest-release.outputs.latest }}"
          beforeDot="${semver%%.*}"
          afterDot="${semver#*.}"
          afterDotEvaluated=$((afterDot))
          semver="v${beforeDot}.${afterDotEvaluated}.0"
          echo "Semver tag of guest-agent is $semver"
          echo "latest=$semver" | tee -a "$GITHUB_OUTPUT"

      - name: Check if the tag is newer than our last build
        id: needs-build
        run: |
          apiURL="https://ghcr.io/v2/edgelesssys/gcp-guest-agent"
          tokenJSON=$(curl -fsSL  "https://ghcr.io/token?scope=repository:edgelesssys/gcp-guest-agent:pull")
          token=$(jq -r '.token' <<< "$tokenJSON")
          tokenHeader=(-H "Authorization: Bearer ${token}")

          tags=$(curl -fsSL "${tokenHeader[@]}" "${apiURL}/tags/list")
          semverUpstream="${{ steps.latest-release-semver.outputs.latest }}"

          rebuild=false

          if [[ $(jq -r '.tags | index("latest")' <<< "$tags") == 'null' ]]; then
            rebuild=true
          elif [[ $(jq -r '.tags | index("${{ steps.latest-release-semver.outputs.latest }}")' <<< "$tags") == 'null' ]]; then
            rebuild=true
          else
            digestLatest=$(curl -fsSL "${tokenHeader[@]}" "${apiURL}/manifests/latest" | jq -r '.config.digest')
            digestSemver=$(curl -fsSL "${tokenHeader[@]}" "${apiURL}/manifests/${semverUpstream}" | jq -r '.config.digest')
            if [[ "$digestLatest" != "$digestSemver" ]]; then
              rebuild=true
            fi
          fi

          if [[ $rebuild == false ]]; then
            echo "Latest tag $latestTag is already built, exiting"
            echo "out=false" | tee -a "$GITHUB_OUTPUT"
            exit 0
          fi
          echo "Latest tag $latestTag is older than ${semverUpstream}, building"
          echo "out=true" | tee -a "$GITHUB_OUTPUT"

      - name: Checkout GoogleCloudPlatform/guest-agent
        if: steps.needs-build.outputs.out == 'true'
        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
        with:
          repository: "GoogleCloudPlatform/guest-agent"
          ref: refs/tags/${{ steps.latest-release.outputs.latest }}
          path: "guest-agent"

      - name: Checkout Constellation
        if: steps.needs-build.outputs.out == 'true'
        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
        with:
          path: "constellation"
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Docker meta
        id: meta
        if: steps.needs-build.outputs.out == 'true'
        uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
        with:
          images: |
            ${{ env.REGISTRY }}/edgelesssys/gcp-guest-agent
          flavor: |
            latest=false
          tags: |
            type=raw,value=${{ steps.latest-release-semver.outputs.latest }}
            type=raw,value=${{ github.ref_name }},enable=${{ github.ref_name != 'main' }}
            type=sha,value=${{ github.sha }}
            type=raw,value=latest,enable=${{ github.ref_name == 'main' }}

      - name: Log in to the Container registry
        id: docker-login
        if: steps.needs-build.outputs.out == 'true'
        uses: ./constellation/.github/actions/container_registry_login
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Prepare hardcoded configuration file
        if: steps.needs-build.outputs.out == 'true'
        run: |
          cp "${GITHUB_WORKSPACE}/constellation/3rdparty/gcp-guest-agent/instance_configs.cfg" "${GITHUB_WORKSPACE}/guest-agent/"

      - name: Build and push container image
        if: steps.needs-build.outputs.out == 'true'
        id: build
        uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
        with:
          context: ./guest-agent
          file: ./constellation/3rdparty/gcp-guest-agent/Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
