fix: accept opaque GitHub tokens #66
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| # Trigger on push to main for Release PR creation/update | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - ".github/ISSUE_TEMPLATE/**" | |
| - ".github/PULL_REQUEST_TEMPLATE/**" | |
| # Trigger on PR events for dry-run checks | |
| pull_request: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| branches: | |
| - main | |
| # Manual trigger for emergency releases | |
| workflow_dispatch: | |
| inputs: | |
| mode: | |
| description: "Workflow mode to run" | |
| required: false | |
| type: choice | |
| default: release-pr | |
| options: | |
| - release-pr | |
| - dry-run | |
| force_release: | |
| description: "Force a release even if no changes" | |
| required: false | |
| type: boolean | |
| default: false | |
| head_ref: | |
| description: "Release PR head ref for dispatched dry-run validation" | |
| required: false | |
| type: string | |
| pr_number: | |
| description: "Release PR number for dispatched dry-run validation" | |
| required: false | |
| type: string | |
| concurrency: | |
| group: release-${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} | |
| cancel-in-progress: true | |
| env: | |
| GO_VERSION: "1.25.9" | |
| INITIAL_VERSION: "v0.0.10" | |
| NODE_VERSION: "22" | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| permissions: | |
| actions: write | |
| contents: write | |
| packages: write | |
| pull-requests: write | |
| id-token: write | |
| attestations: write | |
| jobs: | |
| # Job 1: Create or update Release PR | |
| release-pr: | |
| name: Create/Update Release PR | |
| if: | | |
| (github.event_name == 'push' && | |
| github.ref == 'refs/heads/main' && | |
| !startsWith(github.event.head_commit.message, 'release:') && | |
| !startsWith(github.event.head_commit.message, 'ci(release):') && | |
| !startsWith(github.event.head_commit.message, 'Merge pull request') && | |
| github.event.head_commit.author.name != 'github-actions[bot]') || | |
| (github.event_name == 'workflow_dispatch' && | |
| (inputs.mode == 'release-pr' || inputs.mode == '')) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: ./.github/actions/setup-go | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| install-tools: "false" | |
| - uses: ./.github/actions/setup-node | |
| - uses: ./.github/actions/setup-git-cliff | |
| - name: Build pr-release CLI | |
| run: go build -o bin/pr-release . | |
| - name: Run PR Release Orchestrator | |
| id: pr_release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }} | |
| INITIAL_VERSION: ${{ env.INITIAL_VERSION }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "${{ github.event.inputs.force_release }}" == "true" ]]; then | |
| ./bin/pr-release pr-release --force --enable-rollback --ci-output | |
| else | |
| ./bin/pr-release pr-release --enable-rollback --ci-output | |
| fi | |
| branch="$(git branch --show-current)" | |
| if [[ "$branch" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
| echo "has_release_pr=true" >> "$GITHUB_OUTPUT" | |
| echo "release_branch=$branch" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "No release PR branch produced; skipping release PR checks." | |
| echo "has_release_pr=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Dispatch Release PR Checks | |
| if: steps.pr_release.outputs.has_release_pr == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_BRANCH: ${{ steps.pr_release.outputs.release_branch }} | |
| run: | | |
| set -euo pipefail | |
| branch="$RELEASE_BRANCH" | |
| if [[ ! "$branch" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
| echo "::error::Expected to be on a release branch after orchestration, got '$branch'" | |
| exit 1 | |
| fi | |
| pr_number="$(gh pr view "$branch" --json number --jq '.number')" | |
| if [[ -z "$pr_number" ]]; then | |
| echo "::error::Could not resolve pull request for $branch" | |
| exit 1 | |
| fi | |
| echo "Dispatching CI workflow for $branch" | |
| gh workflow run ci.yml --ref "$branch" | |
| echo "Dispatching release dry-run workflow for $branch (PR #$pr_number)" | |
| gh workflow run release.yml \ | |
| --ref "$branch" \ | |
| -f mode=dry-run \ | |
| -f head_ref="$branch" \ | |
| -f pr_number="$pr_number" | |
| # Job 2: Dry-run checks on Release PR | |
| dry-run: | |
| name: Dry-Run Release Check | |
| if: | | |
| ( | |
| github.event_name == 'pull_request' && | |
| ( | |
| startsWith(github.event.pull_request.title, 'release: Release ') || | |
| startsWith(github.event.pull_request.title, 'ci(release): Release ') | |
| ) | |
| ) || | |
| ( | |
| github.event_name == 'workflow_dispatch' && | |
| inputs.mode == 'dry-run' | |
| ) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| ref: ${{ github.event_name == 'workflow_dispatch' && inputs.head_ref || github.ref }} | |
| - uses: ./.github/actions/setup-go | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| install-tools: false | |
| - uses: ./.github/actions/setup-node | |
| - name: Build pr-release CLI | |
| run: go build -o bin/pr-release . | |
| - name: Setup Release Tools | |
| uses: ./.github/actions/setup-release | |
| with: | |
| goreleaser-distribution: goreleaser-pro | |
| setup-docker: false | |
| setup-docker-login: false | |
| - name: Run Dry-Run Orchestrator | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }} | |
| GITHUB_HEAD_REF: ${{ github.event_name == 'workflow_dispatch' && inputs.head_ref || github.head_ref }} | |
| GITHUB_ISSUE_NUMBER: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_number || github.event.pull_request.number }} | |
| GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} | |
| run: ./bin/pr-release dry-run --ci-output | |
| # Job 3: Production release on merge | |
| release: | |
| name: Production Release | |
| if: | | |
| github.event_name == 'push' && | |
| github.ref == 'refs/heads/main' && | |
| ( | |
| startsWith(github.event.head_commit.message, 'release:') || | |
| startsWith(github.event.head_commit.message, 'ci(release):') | |
| ) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 | |
| env: | |
| DOCKER_CLI_EXPERIMENTAL: enabled | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - name: Set up Go with caching | |
| uses: ./.github/actions/setup-go | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| install-tools: "true" | |
| - uses: ./.github/actions/setup-node | |
| - name: Setup Release Tools | |
| uses: ./.github/actions/setup-release | |
| with: | |
| goreleaser-distribution: goreleaser-pro | |
| setup-docker: true | |
| setup-docker-login: true | |
| setup-qemu: true | |
| docker-registry: ghcr.io | |
| docker-username: ${{ github.actor }} | |
| docker-token: ${{ secrets.GITHUB_TOKEN }} | |
| cosign-version: "v2.2.4" | |
| - name: Create Git Tag | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| run: | | |
| # Use git-cliff to get the bumped version | |
| VERSION=$(git cliff --bumped-version 2>/dev/null | sed 's/^v//') | |
| if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag -a "v$VERSION" -m "Release v$VERSION" | |
| git push origin "v$VERSION" | |
| echo "Created and pushed tag v$VERSION" | |
| else | |
| echo "Could not get version from git-cliff. Got: $VERSION" | |
| echo "Fallback: Extract from commit message" | |
| VERSION=$(git log -1 --pretty=format:"%s" | sed -E 's/.*Release v([0-9]+\.[0-9]+\.[0-9]+).*/\1/') | |
| if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag -a "v$VERSION" -m "Release v$VERSION" | |
| git push origin "v$VERSION" | |
| echo "Created and pushed tag v$VERSION" | |
| else | |
| echo "Could not extract version from any source. Got: $VERSION" | |
| exit 1 | |
| fi | |
| fi | |
| - uses: goreleaser/goreleaser-action@v6 | |
| with: | |
| distribution: goreleaser-pro | |
| version: ~> v2 | |
| args: >- | |
| release --clean | |
| --release-notes=RELEASE_BODY.md | |
| --release-header-tmpl=.goreleaser.release-header.md.tmpl | |
| --release-footer-tmpl=.goreleaser.release-footer.md.tmpl | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
| AUR_KEY: ${{ secrets.AUR_KEY }} | |
| COSIGN_EXPERIMENTAL: 1 | |
| GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} |