Skip to content

Commit 508a2c1

Browse files
authored
Merge pull request #101 from django/add-pr-min-age-workflow
Add PR minimum age workflow
2 parents 6bbbfc7 + d9d922e commit 508a2c1

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

.github/workflows/pr-min-age.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: PR Minimum Age
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, labeled, unlabeled, synchronize]
6+
schedule:
7+
- cron: "0 0 * * *"
8+
9+
jobs:
10+
check-pr-age:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
pull-requests: read
14+
statuses: write
15+
steps:
16+
- name: Check PR age
17+
uses: actions/github-script@v7
18+
with:
19+
script: |
20+
const BYPASS_LABEL = 'expedited';
21+
const MIN_DAYS = 30;
22+
23+
let prs;
24+
25+
if (context.eventName === 'schedule') {
26+
const { data } = await github.rest.pulls.list({
27+
owner: context.repo.owner,
28+
repo: context.repo.repo,
29+
state: 'open',
30+
});
31+
prs = data;
32+
} else {
33+
const { data } = await github.rest.pulls.get({
34+
owner: context.repo.owner,
35+
repo: context.repo.repo,
36+
pull_number: context.payload.pull_request.number,
37+
});
38+
prs = [data];
39+
}
40+
41+
for (const pr of prs) {
42+
const hasBypass = pr.labels.some(l => l.name === BYPASS_LABEL);
43+
const ageMs = Date.now() - new Date(pr.created_at).getTime();
44+
const ageDays = ageMs / (1000 * 60 * 60 * 24);
45+
const state = hasBypass || ageDays >= MIN_DAYS ? 'success' : 'pending';
46+
const description = hasBypass
47+
? `Bypassed via "${BYPASS_LABEL}" label`
48+
: ageDays >= MIN_DAYS
49+
? `PR has been open for ${Math.floor(ageDays)} days`
50+
: `PR must be open for at least ${MIN_DAYS} days (${Math.floor(MIN_DAYS - ageDays)} days remaining)`;
51+
52+
await github.rest.repos.createCommitStatus({
53+
owner: context.repo.owner,
54+
repo: context.repo.repo,
55+
sha: pr.head.sha,
56+
state,
57+
description,
58+
context: 'PR Minimum Age',
59+
});
60+
}

0 commit comments

Comments
 (0)