name: Release

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to build (must match an existing draft release, e.g., v1.0.2)'
        required: true
        type: string

jobs:
  # Validate the release is a draft with a valid semver tag,
  # targeting an explicit commit SHA.
  validate:
    name: Validate Release
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.resolve.outputs.version }}
      ref: ${{ steps.resolve.outputs.ref }}

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: Resolve version and ref
        id: resolve
        env:
          INPUT_VERSION: ${{ inputs.version }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: .github/scripts/release/resolve-version-ref.sh

      - name: Validate semver
        env:
          VERSION: ${{ steps.resolve.outputs.version }}
        run: .github/scripts/release/validate-semver.sh "$VERSION"

      - name: Enforce commit SHA target
        env:
          REF: ${{ steps.resolve.outputs.ref }}
        run: .github/scripts/release/enforce-commit-sha.sh "$REF"

  # Build and sign all binaries (reuses build.yml workflow)
  build-and-sign:
    name: Build and Sign All Binaries
    needs: validate
    uses: ./.github/workflows/build.yml
    with:
      version: ${{ needs.validate.outputs.version }}
      is_release: true
      ref: ${{ needs.validate.outputs.ref }}
    permissions:
      contents: write
      id-token: write
      actions: read
    secrets: inherit

  # Upload binaries to the draft GitHub release
  upload-assets:
    name: Upload Release Assets
    needs: [validate, build-and-sign]
    runs-on: ubuntu-latest
    permissions:
      contents: write
      id-token: write
      actions: read

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          ref: ${{ needs.validate.outputs.ref }}

      - name: Check if release exists
        id: check_release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{ needs.validate.outputs.version }}
        run: .github/scripts/release/check-release-exists.sh

      - name: Download pre-built signed binaries
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: all-signed-binaries
          path: bin/

      - name: Verify binaries downloaded
        run: .github/scripts/release/verify-binaries-downloaded.sh bin 7

      - name: Set execution permissions on binaries
        run: .github/scripts/release/set-permissions.sh bin

      - name: Create ZIP and TAR.GZ archives
        run: .github/scripts/release/create-archives.sh bin

      - name: Generate SHA256SUMS
        run: .github/scripts/release/generate-checksums.sh bin

      - name: Import GPG key and export public key
        env:
          SIGNING_GPG_PRIVATE_KEY: ${{ secrets.SIGNING_GPG_PRIVATE_KEY }}
        run: .github/scripts/release/import-gpg-key.sh bin

      - name: Install Cosign
        uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4

      - name: Sign SHA256SUMS
        env:
          SIGNING_GPG_PASSPHRASE: ${{ secrets.SIGNING_GPG_PASSPHRASE }}
        run: .github/scripts/release/sign-checksums.sh bin

      - name: Verify signatures before upload
        run: .github/scripts/release/verify-files.sh bin

      - name: Upload assets to release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{ needs.validate.outputs.version }}
          CLOBBER: 'true'
        run: .github/scripts/release/upload-assets.sh bin

      - name: Verify all assets uploaded
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{ needs.validate.outputs.version }}
          CLOBBER: 'true'
        run: .github/scripts/release/verify-assets-uploaded.sh bin

      - name: Upload summary
        if: always()
        env:
          VERSION: ${{ needs.validate.outputs.version }}
          RELEASE_ID: ${{ steps.check_release.outputs.release_id }}
          IS_DRAFT: ${{ steps.check_release.outputs.is_draft }}
        run: .github/scripts/release/generate-upload-summary.sh
