feat(client): add RetryTransport for automatic retry with exponential backoff #119
Workflow file for this run
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-pr-approvals | |
| # Requires N approvals from users with write access before a release-please PR | |
| # can be merged. Posts a commit status (context "release-pr-approvals") so it can | |
| # be added as a required status check on the protected branch; the job itself | |
| # stays green. Normal PRs pass immediately. | |
| # | |
| # A PR counts as a release PR based on the branch name and author. | |
| on: | |
| pull_request_target: | |
| types: [opened, reopened, synchronize] | |
| pull_request_review: | |
| types: [submitted, dismissed, edited] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| statuses: write | |
| concurrency: | |
| group: release-pr-approvals-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| approvals: | |
| runs-on: ubuntu-latest | |
| env: | |
| REQUIRED_APPROVALS: "2" | |
| RELEASE_BRANCH_PREFIX: "release-please--" | |
| RELEASE_AUTHOR: "a2a-bot" | |
| steps: | |
| - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const CONTEXT = 'release-pr-approvals'; | |
| const required = Number(process.env.REQUIRED_APPROVALS); | |
| const pr = context.payload.pull_request; | |
| const { owner, repo } = context.repo; | |
| // pull_request_review runs on a fork PR get a read-only GITHUB_TOKEN, | |
| // so createCommitStatus would 403. Release PRs are always created in | |
| // this repo (release-please pushes release-please--* to the base repo, | |
| // never a fork), so their review events keep a write token. Every other | |
| // PR already gets its status from the pull_request_target run, which | |
| // has a write token even for forks. So skip fork review events. | |
| const isReviewEvent = context.eventName === 'pull_request_review'; | |
| const isFork = pr.head.repo?.full_name !== `${owner}/${repo}`; | |
| if (isReviewEvent && isFork) { | |
| core.info('Fork review event has a read-only token; status handled by pull_request_target.'); | |
| return; | |
| } | |
| const setStatus = (state, description) => | |
| github.rest.repos.createCommitStatus({ | |
| owner, repo, sha: pr.head.sha, context: CONTEXT, state, description, | |
| }); | |
| const isRelease = | |
| pr.head.ref.startsWith(process.env.RELEASE_BRANCH_PREFIX) && | |
| pr.user?.login === process.env.RELEASE_AUTHOR; | |
| if (!isRelease) { | |
| await setStatus('success', 'Not a release PR'); | |
| return; | |
| } | |
| const reviews = await github.paginate(github.rest.pulls.listReviews, { | |
| owner, repo, pull_number: pr.number, per_page: 100, | |
| }); | |
| // Latest decisive review per user; COMMENTED does not change approval state. | |
| const latest = new Map(); | |
| for (const r of reviews) { | |
| if (!r.user || r.state === 'COMMENTED') continue; | |
| latest.set(r.user.login, r.state); | |
| } | |
| let approvals = 0; | |
| for (const [login, state] of latest) { | |
| if (state !== 'APPROVED') continue; | |
| const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner, repo, username: login, | |
| }); | |
| if (perm.permission === 'admin' || perm.permission === 'write') approvals++; | |
| } | |
| const description = `${approvals}/${required} approvals`; | |
| await setStatus(approvals >= required ? 'success' : 'failure', description); | |
| core.info(description); |