# Copyright 2022 Google LLC
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

# A workflow to publish the official NPM package.
name: Publish to NPM

# Runs when called from another workflow.
# Can also be run manually for debugging purposes.
on:
  workflow_call:
    inputs:
      tag:
        required: true
        type: string
      latest:
        required: true
        type: boolean
    secrets:
      NPM_CI_TOKEN:
        required: true
      NPM_PACKAGE_NAME:
        required: true
  # For manual debugging:
  workflow_dispatch:
    inputs:
      tag:
        description: The tag to build from.
        required: true
        type: string
      latest:
        description: If true, push to the "latest" tag.
        required: true
        type: boolean

jobs:
  publish:
    name: Publish
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: ${{ inputs.tag }}
          persist-credentials: false

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: 'https://registry.npmjs.org'

      - name: Compute tags
        run: |
          # NPM publish always sets a tag.  If you don't provide an explicit
          # tag, you get the "latest" tag by default, but we want "latest" to
          # always point to the highest version number.  So we set an explicit
          # tag on every "publish" command, then follow up with a command to
          # set "latest" only if this release was the highest version yet.

          # The explicit tag is based on the branch.  If the git tag is v4.4.1,
          # the branch was v4.4.x, and the explicit NPM tag should be
          # v4.4-latest.
          GIT_TAG_NAME=${{ inputs.tag }}
          NPM_TAG=$(echo "$GIT_TAG_NAME" | cut -f 1-2 -d .)-latest
          echo "NPM_TAG=$NPM_TAG" >> $GITHUB_ENV

          # Since we also set the package version on-the-fly during publication,
          # compute that here.  It's the tag without the leading "v".
          NPM_VERSION=$(echo "$GIT_TAG_NAME" | sed -e 's/^v//')
          echo "NPM_VERSION=$NPM_VERSION" >> $GITHUB_ENV

          # Debug the decisions made here.
          echo "This release: $GIT_TAG_NAME"
          echo "NPM tag: $NPM_TAG"
          echo "NPM version: $NPM_VERSION"

      - name: Set package name and version
        run: |
          # These substitutions use | because the package name could contain
          # both / and @, but | should not appear in package names.
          sed npm/package.json -i \
              -e 's|"name": ""|"name": "${{ secrets.NPM_PACKAGE_NAME }}"|' \
              -e 's|"version": ""|"version": "${{ env.NPM_VERSION }}"|'

      - name: Publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_CI_TOKEN }}
        run: |
          cd npm

          # Publish with an explicit tag.
          # Also publish with explicit public access, to allow scoped packages.
          npm publish --tag "$NPM_TAG" --access=public

          # Add the "latest" tag if needed.
          if [[ "${{ inputs.latest }}" == "true" ]]; then
            npm dist-tag add "${{ secrets.NPM_PACKAGE_NAME }}@$NPM_VERSION" latest
          fi
