PR Minimum Age #7
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: PR Minimum Age | |
| on: | |
| pull_request: | |
| types: [opened, reopened, labeled, unlabeled, synchronize] | |
| schedule: | |
| - cron: "0 0 * * *" | |
| jobs: | |
| check-pr-age: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: read | |
| statuses: write | |
| steps: | |
| - name: Check PR age | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const BYPASS_LABEL = 'expedited'; | |
| const MIN_DAYS = 30; | |
| let prs; | |
| if (context.eventName === 'schedule') { | |
| const { data } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| }); | |
| prs = data; | |
| } else { | |
| const { data } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.pull_request.number, | |
| }); | |
| prs = [data]; | |
| } | |
| for (const pr of prs) { | |
| const hasBypass = pr.labels.some(l => l.name === BYPASS_LABEL); | |
| const ageMs = Date.now() - new Date(pr.created_at).getTime(); | |
| const ageDays = ageMs / (1000 * 60 * 60 * 24); | |
| const state = hasBypass || ageDays >= MIN_DAYS ? 'success' : 'pending'; | |
| const description = hasBypass | |
| ? `Bypassed via "${BYPASS_LABEL}" label` | |
| : ageDays >= MIN_DAYS | |
| ? `PR has been open for ${Math.floor(ageDays)} days` | |
| : `PR must be open for at least ${MIN_DAYS} days (${Math.floor(MIN_DAYS - ageDays)} days remaining)`; | |
| await github.rest.repos.createCommitStatus({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| sha: pr.head.sha, | |
| state, | |
| description, | |
| context: 'PR Minimum Age', | |
| }); | |
| } |