11#! /usr/bin/env bash
22set -euo pipefail
3+ shopt -s nullglob
4+
5+ log () {
6+ echo " $@ " >&2
7+ }
8+
9+ trace () {
10+ log " Running:" " ${@@ Q} "
11+ " $@ "
12+ }
13+
14+ effect () {
15+ log -en " \e[33m"
16+ if [[ -z " ${PROD:- } " ]]; then
17+ log " Skipping effect:" " ${@@ Q} "
18+ # If there's stdin, show it
19+ if read -t 0 _; then
20+ sed " s/^/[stdin] /" >&2
21+ fi
22+ else
23+ trace " $@ "
24+ fi
25+ log -en " \e[0m"
26+ }
327
428usage () {
5- echo >&2 " Usage: $0 ORG ACTIVITY_REPO MEMBER_REPO DIR"
29+ log " Usage: $0 ORG ACTIVITY_REPO MEMBER_REPO DIR PR_CUTOFF_DATE "
630 exit 1
731}
832
933ORG=${1:- $(usage)}
1034ACTIVITY_REPO=${2:- $(usage)}
1135MEMBER_REPO=${3:- $(usage)}
1236DIR=${4:- $(usage)}
37+ CUTOFF_DATE=${5:- $(usage)}
1338
14- tmp=$( mktemp -d)
15-
16- shopt -s nullglob
17-
18- # One month plus a bit of leeway
19- epochOneMonthAgo=$(( $(date -- date= '1 month ago' +% s) - 60 * 60 * 12 ))
2039mainBranch=$( git branch --show-current)
40+ cutoffEpoch=$( date --date=" $CUTOFF_DATE " +%s)
41+
42+ if [[ -z " ${PROD:- } " ]]; then
43+ tmp=$( git rev-parse --show-toplevel) /.tmp
44+ rm -rf " $tmp "
45+ mkdir " $tmp "
46+ log -e " \e[33mPROD=1 is not set, skipping effects and keeping temporary files in $tmp until the next run\e[0m"
47+ else
48+ tmp=$( mktemp -d)
49+ trap ' rm -rf "$tmp"' exit
50+ fi
2151
2252mkdir -p " $DIR "
2353cd " $DIR "
2454for login in * ; do
25- gh api -X GET /repos/" $ORG " /" $ACTIVITY_REPO " /activity -f time_period=year -f actor=" $login " -f per_page=100 \
55+ trace gh api -X GET /repos/" $ORG " /" $ACTIVITY_REPO " /activity -f time_period=year -f actor=" $login " -f per_page=100 \
2656 --jq " .[] | \" - \(.timestamp) [\(.activity_type) on \(.ref | ltrimstr(\" refs/heads/\" ))](https://github.com/$ORG /$ACTIVITY_REPO /compare/\(.before)...\(.after))\" " \
2757 > " $tmp /$login "
2858 activityCount=$( wc -l < " $tmp /$login " )
2959
3060 branchName=retire-$login
31- prInfo=$( gh api -X GET /repos/" $ORG " /" $MEMBER_REPO " /pulls -f head=" $ORG " :" $branchName " --jq ' .[0]' )
61+ prInfo=$( trace gh api -X GET /repos/" $ORG " /" $MEMBER_REPO " /pulls -f head=" $ORG " :" $branchName " --jq ' .[0]' )
3262 if [[ -n " $prInfo " ]]; then
3363 # If there is a PR already
3464 prNumber=$( jq .number <<< " $prInfo" )
3565 epochCreatedAt=$( date --date=" $( jq -r .created_at <<< " $prInfo" ) " +%s)
36- if (( epochCreatedAt < epochOneMonthAgo )) ; then
37- echo " $login has a retirement PR due, comment with a reminder to merge "
66+ if (( epochCreatedAt < cutoffEpoch )) ; then
67+ log " $login has a retirement PR due, commenting with next steps "
3868 {
3969 if (( activityCount > 0 )) ; then
4070 echo " One month has passed, @$login has been active again:"
@@ -57,30 +87,33 @@ for login in *; do
5787 echo ' --method DELETE \'
5888 echo " '/orgs/NixOS/teams/nixpkgs-committers/memberships/$login '"
5989 echo ' ```'
60- } | gh api --method POST /repos/" $ORG " /" $MEMBER_REPO " /issues/" $prNumber " /comments -F " body=@-" > /dev/null
90+ } | effect gh api --method POST /repos/" $ORG " /" $MEMBER_REPO " /issues/" $prNumber " /comments -F " body=@-" > /dev/null
6191 else
62- echo " $login has a retirement PR pending"
92+ log " $login has a retirement PR pending"
6393 fi
6494 elif (( activityCount <= 0 )) ; then
65- echo " $login has become inactive, opening a PR"
95+ log " $login has become inactive, opening a PR"
6696 # If there is no PR yet, but they have become inactive
67- git switch -C " $branchName "
68- git rm " $login "
69- git commit -m " Automatic retirement of @$login "
70- git push -f origin " $branchName "
71- {
72- echo " This is an automated PR to retire @$login as a Nixpkgs committers due to not using their commit access for 1 year."
73- echo " "
74- echo " Make a comment with your motivation to keep commit access, otherwise this PR will be merged and implemented in 1 month."
75- } | gh api \
76- --method POST \
77- /repos/" $ORG " /" $MEMBER_REPO " /pulls \
78- -f " title=Automatic retirement of @$login " \
79- -F " body=@-" \
80- -f " head=$ORG :$branchName " \
81- -f " base=$mainBranch " > /dev/null
82- git checkout " $mainBranch "
97+ (
98+ trace git switch -C " $branchName "
99+ trap ' trace git checkout "$mainBranch" && trace git branch -D "$branchName"' exit
100+ trace git rm " $login "
101+ trace git commit -m " Automatic retirement of @$login "
102+ effect git push -f -u
[email protected] :
" $ORG " /
" $MEMBER_REPO " " $branchName " 103+ {
104+ echo " This is an automated PR to retire @$login as a Nixpkgs committers due to not using their commit access for 1 year."
105+ echo " "
106+ echo " Make a comment with your motivation to keep commit access, otherwise this PR will be merged and implemented in 1 month."
107+ } | effect gh api \
108+ --method POST \
109+ /repos/" $ORG " /" $MEMBER_REPO " /pulls \
110+ -f " title=Automatic retirement of @$login " \
111+ -F " body=@-" \
112+ -f " head=$ORG :$branchName " \
113+ -f " base=$mainBranch " > /dev/null
114+ )
83115 else
84- echo " $login is active with $activityCount activities"
116+ log " $login is active with $activityCount activities"
85117 fi
118+ log " "
86119done
0 commit comments