name: goreleaser

on:
  push:
    tags:
      - "v*"

permissions:
  contents: read

jobs:
  goreleaser:
    outputs:
      hashes: ${{ steps.hash.outputs.hashes }}
    permissions:
      contents: write  # for goreleaser/goreleaser-action to create a GitHub release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
        with:
          go-version: "1.21"
          check-latest: true

      - name: Install Syft
        uses: anchore/sbom-action/download-syft@b6a39da80722a2cb0ef5d197531764a89b5d48c3 # v0.15.8

      - name: Setup Node
        uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
        with:
          node-version: latest
          registry-url: 'https://registry.npmjs.org'

      - run: npm ci
      - run: npm run build
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Run GoReleaser
        id: run-goreleaser
        uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
        with:
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION_LDFLAGS: ${{ steps.ldflags.outputs.version }}

      - name: Generate subject
        id: hash
        env:
          ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
        run: |
          set -euo pipefail

          checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
          echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"

  provenance:
    needs: [goreleaser]
    permissions:
      actions: read # To read the workflow path.
      id-token: write # To sign the provenance.
      contents: write # To add assets to a release.
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@07e64b653f10a80b6510f4568f685f8b7b9ea830 # v1.9.0
    with:
      base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
      upload-assets: true # upload to a new release
  verification:
    needs: [goreleaser, provenance]
    runs-on: ubuntu-latest
    permissions: read-all
    steps:
      - name: Install the verifier
        uses: slsa-framework/slsa-verifier/actions/installer@7e1e47d7d793930ab0082c15c2b971fdb53a3c95 # v2.4.1

      - name: Download assets
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
        run: |
          set -euo pipefail
          gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.tar.gz"
          gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.sbom"
          gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "$PROVENANCE"
      - name: Verify assets
        env:
          CHECKSUMS: ${{ needs.goreleaser.outputs.hashes }}
          PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}"
        run: |
          set -euo pipefail
          checksums=$(echo "$CHECKSUMS" | base64 -d)
          while read -r line; do
              fn=$(echo $line | cut -d ' ' -f2)
              echo "Verifying $fn"
              slsa-verifier verify-artifact --provenance-path "$PROVENANCE" \
                                            --source-uri "github.com/$GITHUB_REPOSITORY" \
                                            --source-tag "$GITHUB_REF_NAME" \
                                            "$fn"
          done <<<"$checksums"
