diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml index cf29cba..e26c31a 100644 --- a/.github/workflows/label-pr.yml +++ b/.github/workflows/label-pr.yml @@ -13,11 +13,22 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 + # Prefer the maintainer-provided PAT (`LABELER_PAT`) when set, fall + # back to the workflow's auto-generated `GITHUB_TOKEN` otherwise. + # GitHub started rejecting the auto token on POST /labels with + # spurious 401 "Bad credentials" earlier in 2026; a fine-grained + # PAT scoped to this repo (issues: write + pull_requests: write) + # is the documented escape hatch. Empty secrets are falsy in this + # ternary, so unset → fallback works without extra plumbing. + env: + LABEL_TOKEN: ${{ secrets.LABELER_PAT || secrets.GITHUB_TOKEN }} + steps: # Scope labels based on changed files - name: Path-based labels uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0 with: + repo-token: ${{ env.LABEL_TOKEN }} sync-labels: true # Type labels based on PR title (conventional commits) @@ -26,6 +37,7 @@ jobs: - name: Type labels uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: + github-token: ${{ env.LABEL_TOKEN }} script: | const title = context.payload.pull_request.title; const prefixMap = { @@ -56,6 +68,7 @@ jobs: - name: Size labels uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: + github-token: ${{ env.LABEL_TOKEN }} script: | const { data: files } = await github.rest.pulls.listFiles({ owner: context.repo.owner, diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 4cc9c19..8dc762c 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -12,6 +12,17 @@ name: Release Please # (release-please-bump-lockfile.yml) that listens to the # release-please PR being opened / synchronized — release-please # can't bump Cargo.lock natively because it's regenerated by cargo. +# +# **Migrated 2026-05 from `googleapis/release-please-action@v5.0.0` +# (deprecated, bundling an older release-please library) to the +# CLI directly because the action started returning persistent +# 401 "Bad credentials" on its GitHub API calls. The CLI uses the +# same `GITHUB_TOKEN` cleanly. Behaviour is identical from the +# caller's perspective: same release PR branch +# (`release-please--branches--main--components--waveflow`), same +# `github-actions[bot]` author, so the lockfile-build companion +# workflow keeps gating correctly on `startsWith(head_ref, +# 'release-please--')`.** "on": push: @@ -28,9 +39,35 @@ concurrency: jobs: release-please: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - token: ${{ secrets.GITHUB_TOKEN }} - config-file: release-please-config.json - manifest-file: .release-please-manifest.json + node-version: 20 + + # Phase A — open / update the release PR. Idempotent: re-runs + # on every push, only mutates GitHub when something changed. + - name: Update release PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npx --yes release-please@17 release-pr \ + --token="${GITHUB_TOKEN}" \ + --repo-url="${GITHUB_REPOSITORY}" \ + --config-file=release-please-config.json \ + --manifest-file=.release-please-manifest.json + + # Phase B — when the head commit IS the release PR's merge + # commit, cut the GitHub release + tag. No-op on every other + # push, so we can run both phases unconditionally. + - name: Publish GitHub release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npx --yes release-please@17 github-release \ + --token="${GITHUB_TOKEN}" \ + --repo-url="${GITHUB_REPOSITORY}" \ + --config-file=release-please-config.json \ + --manifest-file=.release-please-manifest.json