name: Manually Publish Images and Artifacts
on:
  workflow_dispatch:
    inputs:
      dry_run:
        default: true
        description: 'Skip publishing to DockerHub and Homebrew'
        required: false
        type: boolean
      dry-run-npm:
        default: true
        description: 'Skip publishing to npm'
        required: false
        type: boolean
      tag:
        description: 'Tag of an existing draft release to upload binary artifacts to.'
        required: true
        type: string
      publish_release:
        description: 'Publish (un-draft) the release after all artifacts are uploaded?'
        type: boolean
        required: false
        default: true

jobs:

  release-ldcli:
    permissions:
      id-token: write # Needed to obtain Docker tokens and to sign attestations
      contents: write # Needed to upload release artifacts
      packages: read # Needed to load goreleaser-cross image
      attestations: write # Needed for artifact attestations
    runs-on: ubuntu-latest
    outputs:
      images_and_digests: ${{ steps.publish.outputs.images_and_digests }}
    steps:
      - uses: actions/checkout@v4
        name: Checkout
        with:
          fetch-depth: 0

      - uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.0.1
        name: 'Get Docker token'
        with:
          aws_assume_role: ${{ vars.AWS_ROLE_ARN }}
          ssm_parameter_pairs: |
            /global/services/docker/public/username = DOCKER_HUB_USERNAME,
            /global/services/docker/public/token = DOCKER_HUB_TOKEN

      - uses: ./.github/actions/publish
        id: publish
        with:
          dry-run: ${{ inputs.dry_run }}
          token: ${{ secrets.GITHUB_TOKEN }}
          homebrew-gh-secret: ${{ secrets.HOMEBREW_DEPLOY_KEY }}
          tag: ${{ inputs.tag }}
          ghcr_token: "${{ secrets.GITHUB_TOKEN }}"

      - name: Attest binary artifacts
        if: ${{ !inputs.dry_run }}
        uses: actions/attest@v4
        with:
          subject-checksums: ${{ steps.publish.outputs.checksum_file }}

  attest-image-provenance:
    needs: [release-ldcli]
    if: ${{ !inputs.dry_run }}
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      attestations: write
    strategy:
      matrix:
        images_and_digests: ${{ fromJson(needs.release-ldcli.outputs.images_and_digests) }}
    steps:
      - name: Attest container image
        uses: actions/attest@v4
        with:
          subject-name: ${{ matrix.images_and_digests.image }}
          subject-digest: ${{ matrix.images_and_digests.digest }}

  release-ldcli-npm:
    runs-on: ubuntu-latest
    if: ${{ inputs.dry-run-npm == false }}
    needs: [release-ldcli]
    # id-token: write lets npm CLI exchange the GITHUB_TOKEN for an OIDC token
    # that the npm registry trusts via the trusted publisher config. The npm
    # trusted publisher must be configured with this workflow filename
    # (manual-publish.yml) for publishes from this path to succeed.
    permissions:
      actions: read
      id-token: write
      contents: write
    steps:
      - uses: actions/checkout@v4
        name: Checkout
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 20.x
          registry-url: 'https://registry.npmjs.org'
      - name: Update npm
        shell: bash
        # npm CLI requires >= 11.5.1 for trusted publishing (OIDC) support.
        run: npm install -g npm@11.6.2
      - id: publish-npm
        name: Publish NPM Package
        uses: ./.github/actions/publish-npm
        with:
          dry-run: ${{ inputs.dry_run }}
          prerelease: 'false'

  publish-release:
    needs: [release-ldcli, attest-image-provenance, release-ldcli-npm]
    # !cancelled() && !failure() lets this job run when release-ldcli-npm was
    # skipped (dry-run-npm: true) but still blocks if any needed job failed.
    if: ${{ !cancelled() && !failure() && !inputs.dry_run && inputs.publish_release }}
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Publish release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAG_NAME: ${{ inputs.tag }}
        run: >
          gh release edit "$TAG_NAME"
          --repo ${{ github.repository }}
          --draft=false
