chore: fix release workflow (#3366)

My original change to use the bazel-contrib BCR publishing workflow was
horribly broken.
This fixes a variety of issues.

* Fix the workflow call secrets variable name
* Allow getting the BCR publishing token from the workflow arg (the
release
  workflow calls it)
* Fix the overall syntax of the workflows. It was just entirely invalid
in
  several regards.
* Fix the yaml -> yml file name reference. NGL, it took me longer than
I'd
  like to admit to see that, eh.

Along the way, some cleanups and improvements

* Allow specifying a particular tag to release, while using workflow
state from
a different commit. This allows us to make fixes on main, and then use
it to
  manually re-trigger a tag to be released.
* Add descriptions for workflow inputs
* Allow bcr token to be passed to release. This will allow e.g.
automatically
  scheduled releases.
* Quote shell variables because its good practice.
diff --git a/.github/workflows/create_archive_and_notes.sh b/.github/workflows/create_archive_and_notes.sh
index b53c49a..a3cf828 100755
--- a/.github/workflows/create_archive_and_notes.sh
+++ b/.github/workflows/create_archive_and_notes.sh
@@ -18,6 +18,17 @@
 set -o errexit
 
 set -x
+
+TAG=$1
+if [ -z "$TAG" ]; then
+  echo "ERROR: TAG env var must be set"
+  exit 1
+fi
+# If the workflow checks out one commit, but is releasing another
+git fetch origin tag "$TAG"
+# Update our local state so the grep command below searches what we expect
+git checkout "$TAG"
+
 # Exclude dot directories, specifically, this file so that we don't
 # find the substring we're looking for in our own file.
 # Exclude CONTRIBUTING.md, RELEASING.md because they document how to use these strings.
@@ -34,14 +45,11 @@
   exit 1
 fi
 
-# Set by GH actions, see
-# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
-TAG=${GITHUB_REF_NAME}
 # A prefix is added to better match the GitHub generated archives.
 PREFIX="rules_python-${TAG}"
 ARCHIVE="rules_python-$TAG.tar.gz"
-git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE
-SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}')
+git archive --format=tar "--prefix=${PREFIX}/" "$TAG" | gzip > "$ARCHIVE"
+SHA=$(shasum -a 256 "$ARCHIVE" | awk '{print $1}')
 
 cat > release_notes.txt << EOF
 
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index f03e021..9ad5308 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,30 +1,28 @@
-# See https://github.com/bazel-contrib/publish-to-bcr
+# Publish new releases to Bazel Central Registry.
 name: Publish to BCR
-
 on:
   # Run the publish workflow after a successful release
-  # Can be triggered from the release.yaml workflow
+  # Will be triggered from the release.yaml workflow
   workflow_call:
     inputs:
       tag_name:
         required: true
         type: string
     secrets:
-      BCR_PUBLISH_TOKEN:
+      publish_token:
         required: true
   # In case of problems, let release engineers retry by manually dispatching
   # the workflow from the GitHub UI
   workflow_dispatch:
     inputs:
       tag_name:
+        description: git tag being released
         required: true
         type: string
-
 jobs:
   publish:
     uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v1.0.0
     with:
-      draft: false
       tag_name: ${{ inputs.tag_name }}
       # GitHub repository which is a fork of the upstream where the Pull Request will be opened.
       registry_fork: bazel-contrib/bazel-central-registry
@@ -32,4 +30,5 @@
     permissions:
       contents: write
     secrets:
-      publish_token: ${{ secrets.BCR_PUBLISH_TOKEN }}
+      # Necessary to push to the BCR fork, and to open a pull request against a registry
+      publish_token: ${{ secrets.publish_token || secrets.BCR_PUBLISH_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 0ed4992..0d24d79 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,51 +21,60 @@
       - "*.*.*"
   workflow_dispatch:
     inputs:
+      tag_name:
+        description: "release tag: tag that will be released"
+        required: true
+        type: string
       publish_to_pypi:
         description: 'Publish to PyPI'
         required: true
         type: boolean
         default: true
+    secrets:
+      publish_token:
+        required: false
 
 jobs:
-  build:
+  release:
+    name: Release
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
         uses: actions/checkout@v5
+        with:
+          ref: ${{ github.ref_name }}
       - name: Create release archive and notes
-        run: .github/workflows/create_archive_and_notes.sh
-
-  release:
-    name: Release
-    uses: softprops/action-gh-release@v2
-    with:
-      # Use GH feature to populate the changelog automatically
-      generate_release_notes: true
-      body_path: release_notes.txt
-      prerelease: ${{ contains(github.ref, '-rc') }}
-      fail_on_unmatched_files: true
-      files: rules_python-*.tar.gz
+        run: .github/workflows/create_archive_and_notes.sh ${{ inputs.tag_name || github.ref_name }}
+      - name: Release
+        uses: softprops/action-gh-release@v2
+        with:
+          # Use GH feature to populate the changelog automatically
+          generate_release_notes: true
+          body_path: release_notes.txt
+          prerelease: ${{ contains( (inputs.tag_name || github.ref), '-rc') }}
+          fail_on_unmatched_files: true
+          files: rules_python-*.tar.gz
+          tag_name: ${{ inputs.tag_name || github.ref_name }}
 
   publish_bcr:
-    name: Publish to BCR
     needs: release
-    uses: .github/workflows/publish.yaml
+    uses: ./.github/workflows/publish.yml
     with:
-      tag_name: ${{ github.ref_name }}
+      tag_name: ${{ inputs.tag_name || github.ref_name }}
     secrets:
-      BCR_PUBLISH_TOKEN: ${{ secrets.BCR_PUBLISH_TOKEN }}
+      publish_token: ${{ secrets.publish_token || secrets.BCR_PUBLISH_TOKEN }}
 
   publish_pypi:
     # We just want publish_pypi last, since once uploaded, it can't be changed.
     name: Publish runfiles to PyPI
     needs: publish_bcr
     runs-on: ubuntu-latest
-    if: github.event_name == 'push' || github.event.inputs.publish_to_pypi
-    env:
-      # This special value tells pypi that the user identity is supplied within the token
-      TWINE_USERNAME: __token__
-      # Note, the PYPI_API_TOKEN is for the rules-python pypi user, added by @rickylev on
-      # https://github.com/bazel-contrib/rules_python/settings/secrets/actions
-      TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
-    run: bazel run --stamp --embed_label=${{ github.ref_name }} //python/runfiles:wheel.publish
+    steps:
+      - if: github.event_name == 'push' || github.event.inputs.publish_to_pypi
+        env:
+          # This special value tells pypi that the user identity is supplied within the token
+          TWINE_USERNAME: __token__
+          # Note, the PYPI_API_TOKEN is for the rules-python pypi user, added by @rickylev on
+          # https://github.com/bazel-contrib/rules_python/settings/secrets/actions
+          TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
+        run: bazel run --stamp --embed_label=${{ inputs.tag_name || github.ref_name }} //python/runfiles:wheel.publish