name: release
on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'image tag prefix'
        default: 'preview'
        required: true

permissions:
  contents: read

env:
  CONTROLLER: ${{ github.event.repository.name }}

jobs:
  release:
    outputs:
      hashes: ${{ steps.slsa.outputs.hashes }}
      image_url: ${{ steps.slsa.outputs.image_url }}
      image_digest: ${{ steps.slsa.outputs.image_digest }}
    runs-on: ubuntu-latest
    permissions:
      contents: write # for creating the GitHub release.
      id-token: write # for creating OIDC tokens for signing.
      packages: write # for pushing and signing container images.
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - name: Setup Kustomize
        uses: fluxcd/pkg/actions/kustomize@main
      - name: Prepare
        id: prep
        run: |
          VERSION="${{ github.event.inputs.tag }}-${GITHUB_SHA::8}"
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF/refs\/tags\//}
          fi
          echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
          echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
      - name: Setup QEMU
        uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0
      - name: Setup Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
      - name: Login to GitHub Container Registry
        uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
        with:
          registry: ghcr.io
          username: fluxcdbot
          password: ${{ secrets.GHCR_TOKEN }}
      - name: Login to Docker Hub
        uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
        with:
          username: fluxcdbot
          password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
      - name: Generate images meta
        id: meta
        uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
        with:
          images: |
            fluxcd/${{ env.CONTROLLER }}
            ghcr.io/fluxcd/${{ env.CONTROLLER }}
          tags: |
            type=raw,value=${{ steps.prep.outputs.VERSION }}
      - name: Publish images
        id: build-push
        uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
        with:
          sbom: true
          provenance: true
          push: true
          builder: ${{ steps.buildx.outputs.name }}
          context: .
          file: ./Dockerfile
          platforms: linux/amd64,linux/arm/v7,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
      - uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
      - name: Sign images
        env:
          COSIGN_EXPERIMENTAL: 1
        run: |
          cosign sign --yes fluxcd/${{ env.CONTROLLER }}@${{ steps.build-push.outputs.digest }}
          cosign sign --yes ghcr.io/fluxcd/${{ env.CONTROLLER }}@${{ steps.build-push.outputs.digest }}
      - name: Generate release artifacts
        if: startsWith(github.ref, 'refs/tags/v')
        run: |
          mkdir -p config/release
          kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
          kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
      - uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
      - name: Create release and SBOM
        id: run-goreleaser
        if: startsWith(github.ref, 'refs/tags/v')
        uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1
        with:
          version: latest
          args: release --clean --skip=validate
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Generate SLSA metadata
        id: slsa
        env:
          ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
        run: |
          hashes=$(echo -E $ARTIFACTS | jq --raw-output '.[] | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {digest} + {name} | join("  ") | sub("^sha256:";"")' | base64 -w0)
          echo "hashes=$hashes" >> $GITHUB_OUTPUT
          
          image_url=fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.version }}
          echo "image_url=$image_url" >> $GITHUB_OUTPUT
          
          image_digest=${{ steps.build-push.outputs.digest }}
          echo "image_digest=$image_digest" >> $GITHUB_OUTPUT

  release-provenance:
    needs: [release]
    permissions:
      actions: read # for detecting the Github Actions environment.
      id-token: write # for creating OIDC tokens for signing.
      contents: write # for uploading attestations to GitHub releases.
    if: startsWith(github.ref, 'refs/tags/v')
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
    with:
      provenance-name: "provenance.intoto.jsonl"
      base64-subjects: "${{ needs.release.outputs.hashes }}"
      upload-assets: true

  dockerhub-provenance:
    needs: [release]
    permissions:
      actions: read # for detecting the Github Actions environment.
      id-token: write # for creating OIDC tokens for signing.
      packages: write # for uploading attestations.
    if: startsWith(github.ref, 'refs/tags/v')
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
    with:
      image: ${{ needs.release.outputs.image_url }}
      digest: ${{ needs.release.outputs.image_digest }}
      registry-username: fluxcdbot
    secrets:
      registry-password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}

  ghcr-provenance:
    needs: [release]
    permissions:
      actions: read # for detecting the Github Actions environment.
      id-token: write # for creating OIDC tokens for signing.
      packages: write # for uploading attestations.
    if: startsWith(github.ref, 'refs/tags/v')
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
    with:
      image: ghcr.io/${{ needs.release.outputs.image_url }}
      digest: ${{ needs.release.outputs.image_digest }}
      registry-username: fluxcdbot
    secrets:
      registry-password: ${{ secrets.GHCR_TOKEN }}
