name: Release PR on: issue_comment: types: [created] permissions: {} jobs: release_check: if: github.repository == 'changesets/action' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/release-pr') timeout-minutes: 5 runs-on: ubuntu-latest permissions: contents: read issues: write pull-requests: read steps: - id: report_in_progress run: | echo "in_progress_reaction_id=$(gh api /repos/${{github.repository}}/issues/comments/${{github.event.comment.id}}/reactions -f content='eyes' --jq '.id')" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - id: parse_command run: | if [[ "$COMMENT_BODY" =~ ^/release-pr[[:space:]]+([0-9a-fA-F]{7,40})[[:space:]]*$ ]] then echo "requested_sha=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT" else echo "Expected '/release-pr ' where is a 7-40 character commit SHA." exit 1 fi env: COMMENT_BODY: ${{ github.event.comment.body }} - id: check_authorization run: | if [[ $AUTHOR_ASSOCIATION == 'MEMBER' || $AUTHOR_ASSOCIATION == 'OWNER' || $AUTHOR_ASSOCIATION == 'COLLABORATOR' ]] then echo "User is authorized to release" else echo "User is not authorized to release" exit 1 fi env: AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association }} - id: resolve_requested_sha run: | requested_sha=$(echo "$REQUESTED_SHA" | tr '[:upper:]' '[:lower:]') mapfile -t matches < <( gh api /repos/${{ github.repository }}/pulls/${{ github.event.issue.number }}/commits --paginate --jq '.[].sha' | awk -v sha="$requested_sha" 'index(tolower($0), sha) == 1 { print $0 }' ) if [[ ${#matches[@]} -eq 0 ]] then echo "Requested SHA $REQUESTED_SHA is not part of this pull request." exit 1 fi if [[ ${#matches[@]} -gt 1 ]] then echo "Requested SHA $REQUESTED_SHA is ambiguous for this pull request." exit 1 fi resolved_sha="${matches[0]}" pr_head_sha=$(gh pr view ${{ github.event.issue.number }} --json headRefOid --jq '.headRefOid') if [[ "$resolved_sha" != "$pr_head_sha" ]] then echo "Requested SHA $resolved_sha is not the current PR head $pr_head_sha." exit 1 fi echo "resolved_sha=$resolved_sha" >> "$GITHUB_OUTPUT" echo "pr_head_sha=$pr_head_sha" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REQUESTED_SHA: ${{ steps.parse_command.outputs.requested_sha }} - id: get_pr_head_repository run: | echo "head_repository=$(gh pr view ${{ github.event.issue.number }} --json headRepositoryOwner,headRepository --jq '.headRepositoryOwner.login + "/" + .headRepository.name')" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} outputs: in_progress_reaction_id: ${{ steps.report_in_progress.outputs.in_progress_reaction_id }} requested_sha: ${{ steps.parse_command.outputs.requested_sha }} resolved_sha: ${{ steps.resolve_requested_sha.outputs.resolved_sha }} pr_head_sha: ${{ steps.resolve_requested_sha.outputs.pr_head_sha }} head_repository: ${{ steps.get_pr_head_repository.outputs.head_repository }} release: if: github.repository == 'changesets/action' timeout-minutes: 20 runs-on: ubuntu-latest needs: release_check permissions: contents: write issues: write pull-requests: write steps: - name: Check out repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - uses: ./.github/actions/ci-setup - name: Fetch validated commit from pull request head repository run: | git remote add pr-head https://github.com/$HEAD_REPOSITORY.git git fetch --no-tags pr-head $RESOLVED_SHA env: HEAD_REPOSITORY: ${{ needs.release_check.outputs.head_repository }} RESOLVED_SHA: ${{ needs.release_check.outputs.resolved_sha }} - name: Checkout validated commit run: git checkout --detach $RESOLVED_SHA env: RESOLVED_SHA: ${{ needs.release_check.outputs.resolved_sha }} - name: Check if Version Packages PR id: check_version_packages run: | echo "version_packages=$(gh pr view ${{ github.event.issue.number }} --json headRefName --jq '.headRefName|startswith("changeset-release/")')" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Reset Version Packages PR if: steps.check_version_packages.outputs.version_packages == 'true' run: git reset --hard HEAD~1 - name: Create snapshot version run: pnpm changeset version --snapshot pr${{ github.event.issue.number }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build run: pnpm build - name: Setup Git user run: | git config --global user.name "github-actions[bot]" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Release snapshot version run: pnpm release:pr - name: Add success reaction run: gh api /repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions -f content='rocket' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Remove in-progress reaction run: gh api -X DELETE /repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions/${{ needs.release_check.outputs.in_progress_reaction_id }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Comment success run: | gh pr comment ${{ github.event.issue.number }} --body "The release for \`${{ needs.release_check.outputs.resolved_sha }}\` triggered by [this comment](${{ github.event.comment.url }}) has [succeeded](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}). Published commit: [${{ github.repository }}@$(git rev-parse HEAD)](https://github.com/${{ github.repository }}/commit/$(git rev-parse HEAD))." env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} report-failure-if-needed: needs: [release_check, release] timeout-minutes: 2 runs-on: ubuntu-latest if: failure() && github.repository == 'changesets/action' && (needs.release_check.result == 'failure' || needs.release.result == 'failure') permissions: issues: write pull-requests: write steps: - name: Add failure reaction run: gh api /repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions -f content='-1' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Remove in-progress reaction run: gh api -X DELETE /repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions/${{ needs.release_check.outputs.in_progress_reaction_id }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Comment failure run: | gh pr comment ${{ github.event.issue.number }} --body "The release for \`${{ needs.release_check.outputs.requested_sha }}\` triggered by [this comment](${{ github.event.comment.url }}) has [failed](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})." env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_REPO: ${{ github.repository }}