-
Notifications
You must be signed in to change notification settings - Fork 175
160 lines (129 loc) Β· 5.81 KB
/
pr-manage-stale.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Contributors: @wicksipedia @william-liebenberg @GordonBeeming
# < as per SSW.Rules: https://www.ssw.com.au/rules/standard-set-of-pull-request-workflows/ >
name: "PR - Manage Stale PRs"
on:
pull_request:
types: [opened, ready_for_review]
branches: [main]
schedule:
# run every 2nd hour
# https://crontab.guru/#0_0/2_*_*_*
- cron: "0 0/2 * * *"
workflow_dispatch:
permissions:
contents: read
issues: write
repository-projects: read
pull-requests: write
jobs:
new_pull_request:
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: add label
shell: pwsh
run: |
$thisPr = gh pr view ${{ github.event.pull_request.number }} --json number,isCrossRepository | ConvertFrom-Json
if ($thisPr.isCrossRepository) {
Write-Output "Skipping cross repository PR"
return
}
# ensure labels exist - create them if they don't
# https://docs.github.com/en/rest/reference/issues#create-a-label
$label = "Age: π₯ - New"
$description = "About 2 hours old"
Write-Output "Ensuring label exists: $label ($description))"
gh api repos/${{ github.repository }}/labels -f name="$label" -f color=000000 -f description="$description"
Write-Output "Adding label: $label"
gh pr edit $thisPr.number --add-label "$label"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
scheduled_run:
if: ${{ github.event_name != 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Find PRs
shell: pwsh
run: |
# labels for each age in hours (as an array)
$labels = @(
'Age: π₯ - New', # 2 hours
'Age: π£ - Young', # 4 hours
'Age: π₯ - Adolescent', # 8 hours
'Age: π€ - Mature', # 16 hours
'Age: π - Old', # 32 hours
'Age: π - Ancient', # 64 hours
'Age: π¦ - Extinct' # 128 hours
)
# ensure labels exist - create them if they don't
# https://docs.github.com/en/rest/reference/issues#create-a-label
$index = 0
$labels | ForEach-Object {
$label = $_
$description = "About $([math]::Pow(2, $index + 1)) hours old"
Write-Output "Ensuring label exists: $label ($description))"
gh api repos/${{ github.repository }}/labels -f name="$label" -f color=000000 -f description="$description"
$index++
}
$mergeDebtLabelText = "Merge Debt"
$mergeDebtLabel = "π₯ $mergeDebtLabelText"
$description = "This PR contains merge debt, see https://www.ssw.com.au/rules/merge-debt/"
Write-Output "Ensuring label exists: $mergeDebtLabel ($description))"
gh api repos/${{ github.repository }}/labels -f name="$mergeDebtLabel" -f color=000000 -f description="$description"
$now = Get-Date -AsUTC
# use github cli to get a list of open pull requests
$openPullRequests = gh pr list -s open --json title,number,createdAt,labels,author
Write-Output "Open pull requests:"
# for each pull request in the list calculate the age in hours
$openPullRequests | ConvertFrom-Json | ForEach-Object {
$title = $_.title
$number = $_.number
$createdAt = $_.createdAt
$prLabels = $_.labels
$author = $_.author
$ageInHours = [int]($now - $createdAt).TotalHours
if ($ageInHours -eq 0) {
Write-Output "$($number): $title ($ageInHours hours old) - skipping"
return
}
Write-Output "$($number): $title ($ageInHours hours old)"
# find age as nearest doubling number of 2
$ageAsPoints = [math]::Ceiling([math]::Log($ageInHours, 2))
Write-Output "ageAsPoints: $([math]::Pow(2,$ageAsPoints))"
# if the age is 0, then set it to 1
if ($ageAsPoints -eq 0) {
$ageAsPoints = 1
}
# if the age is greater than the length of the labels array
# then set it to the last label
if ($ageAsPoints -gt $labels.Length) {
$ageAsPoints = $labels.Length
}
$newLabel = $labels[$ageAsPoints - 1]
Write-Output "Adding label: $newLabel"
# all labels except the new label
$allLabels = ($labels | Where-Object { $_ -ne $newLabel }) -join ','
Write-Output "Removing labels: $allLabels"
gh pr edit $number --add-label "$newLabel" --remove-label "$allLabels"
$mergeLabelExists = $prLabels | Where-Object { $_.name.trim().EndsWith($mergeDebtLabelText) }
if ($ageInHours -ge 36 -and $mergeLabelExists -eq $null -and $author.is_bot -eq $false) { # after 36 hours old
Write-Output "Adding comment to PR: $number"
gh pr edit $number --add-label "$mergeDebtLabel"
$comment = @"
Howzit @$($author.login),
This PR has been here a while.
[Did you know you should avoid merge debt?](https://www.ssw.com.au/rules/merge-debt/)
1. Please action (e.g. get a review) and merge or close
Thanks!
"@
Set-Content -Path "comment.md" -Value $comment
gh pr comment $number --body-file comment.md
}
Write-Output ""
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}