@@ -46,54 +46,69 @@ jobs:
4646 julia <<'JL'
4747 using Dates, Base64
4848
49- sh(cmd) = chomp(read(cmd, String))
50- repo = ENV["REPO"]
51- pr = parse(Int, ENV["PR_NUMBER"])
52-
53- min_age = Minute(parse(Int, get(ENV,"MIN_AGE_MINUTES","10")))
54- allowed = filter(!isempty, strip.(split(get(ENV,"ALLOWED_AUTHORS",""), ',')))
55- head_prefix = get(ENV,"HEAD_PREFIX","")
56- title_re = Regex(get(ENV,"TITLE_REGEX","^New version:"))
57- commit_re = Regex(get(ENV,"COMMIT_REGEX","(?m)^Commit:"))
58- method = get(ENV,"MERGE_METHOD","squash")
59- del_branch = get(ENV,"DELETE_BRANCH","true") == "true"
60-
61- jq = "[.state, (.draft|tostring), .title, .user.login, .base.ref, .head.ref, .head.repo.full_name, .created_at, .head.sha, (.body // \"\" | @base64)] | @tsv"
62-
63- function meta()
64- f = split(sh(`gh api repos/$repo/pulls/$pr --jq $jq`), '\t'; keepempty=true)
65- state,draft,title,author,base,head,head_repo,created,sha,body64 = f
66- body = String(base64decode(body64))
67- return (; state,draft,title,author,base,head,head_repo,created,sha,body)
49+ function main()
50+ sh(cmd) = chomp(read(cmd, String))
51+ repo = ENV["REPO"]
52+ pr = parse(Int, ENV["PR_NUMBER"])
53+
54+ min_age = Minute(parse(Int, get(ENV,"MIN_AGE_MINUTES","10")))
55+ allowed = filter(!isempty, strip.(split(get(ENV,"ALLOWED_AUTHORS",""), ',')))
56+ head_prefix = get(ENV,"HEAD_PREFIX","")
57+ title_re = Regex(get(ENV,"TITLE_REGEX","^New version:"))
58+ commit_re = Regex(get(ENV,"COMMIT_REGEX","(?m)^Commit:"))
59+ method = get(ENV,"MERGE_METHOD","squash")
60+ del_branch = get(ENV,"DELETE_BRANCH","true") == "true"
61+
62+ jq = "[.state, (.draft|tostring), .title, .user.login, .base.ref, .head.ref, .head.repo.full_name, .created_at, .head.sha, (.body // \"\" | @base64)] | @tsv"
63+
64+ function meta(; retries=3, delay=5)
65+ for attempt in 1:retries
66+ try
67+ f = split(sh(`gh api repos/$repo/pulls/$pr --jq $jq`), '\t'; keepempty=true)
68+ state,draft,title,author,base,head,head_repo,created,sha,body64 = f
69+ body = String(base64decode(body64))
70+ return (; state,draft,title,author,base,head,head_repo,created,sha,body)
71+ catch e
72+ if attempt < retries
73+ @warn "Failed to fetch PR metadata (attempt $attempt/$retries), retrying in $(delay)s..." exception=e
74+ sleep(delay)
75+ else
76+ rethrow()
77+ end
78+ end
79+ end
80+ end
81+
82+ function eligible(m)
83+ m.state == "open" || return false
84+ m.draft == "false" || return false
85+ m.base == "main" || return false
86+ m.head_repo == repo || return false
87+ isempty(allowed) || (m.author in allowed) || return false
88+ isempty(head_prefix) || startswith(m.head, head_prefix) || return false
89+ occursin(title_re, m.title) || return false
90+ occursin(commit_re, m.body) || return false
91+ return true
92+ end
93+
94+ m = meta()
95+ eligible(m) || (println("PR #$pr not eligible; exiting."); return)
96+
97+ created = split(replace(m.created, "Z"=>""), ".")[1]
98+ created_dt = DateTime(created, dateformat"yyyy-mm-ddTHH:MM:SS")
99+ wait_ms = Dates.value((created_dt + min_age) - now())
100+ wait_ms > 0 && sleep(ceil(Int, wait_ms/1000))
101+
102+ m = meta()
103+ eligible(m) || (println("PR #$pr no longer eligible; exiting."); return)
104+
105+ run(`gh api -X PUT repos/$repo/pulls/$pr/merge -f merge_method=$method -f sha=$(m.sha)`)
106+
107+ if del_branch
108+ enc = replace(m.head, "/" => "%2F")
109+ try run(`gh api -X DELETE repos/$repo/git/refs/heads/$enc`) catch; end
110+ end
68111 end
69112
70- function eligible(m)
71- m.state == "open" || return false
72- m.draft == "false" || return false
73- m.base == "main" || return false
74- m.head_repo == repo || return false
75- isempty(allowed) || (m.author in allowed) || return false
76- isempty(head_prefix) || startswith(m.head, head_prefix) || return false
77- occursin(title_re, m.title) || return false
78- occursin(commit_re, m.body) || return false
79- return true
80- end
81-
82- m = meta()
83- eligible(m) || (println("PR #$pr not eligible; exiting."); exit(0))
84-
85- created = split(replace(m.created, "Z"=>""), ".")[1]
86- created_dt = DateTime(created, dateformat"yyyy-mm-ddTHH:MM:SS")
87- wait_ms = Dates.value((created_dt + min_age) - now())
88- wait_ms > 0 && sleep(ceil(Int, wait_ms/1000))
89-
90- m = meta()
91- eligible(m) || (println("PR #$pr no longer eligible; exiting."); exit(0))
92-
93- run(`gh api -X PUT repos/$repo/pulls/$pr/merge -f merge_method=$method -f sha=$(m.sha)`)
94-
95- if del_branch
96- enc = replace(m.head, "/" => "%2F")
97- try run(`gh api -X DELETE repos/$repo/git/refs/heads/$enc`) catch; end
98- end
113+ main()
99114 JL
0 commit comments