Skip to content

Commit dd65b1a

Browse files
committed
ci: daily merge-train/spartan stale-PR notifier (proposal)
1 parent 7c5fa1c commit dd65b1a

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Merge-Train Stale Check
2+
3+
on:
4+
schedule:
5+
# Daily at 09:07 UTC — once per day, off the round-minute mark.
6+
- cron: "7 9 * * *"
7+
workflow_dispatch:
8+
9+
jobs:
10+
spartan:
11+
name: Check merge-train/spartan
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: read
15+
pull-requests: read
16+
steps:
17+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
18+
- name: Run stale check
19+
env:
20+
GH_TOKEN: ${{ secrets.AZTEC_BOT_GITHUB_TOKEN }}
21+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
22+
run: ./ci3/merge_train_stale_check merge-train/spartan '#team-alpha'

ci3/merge_train_stale_check

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env bash
2+
# Check whether the open PR for a merge-train branch has been open longer
3+
# than a threshold (default 24h). If so, post a one-line alert to a Slack
4+
# channel. Intended to be called from a daily scheduled GitHub Actions job.
5+
#
6+
# Usage: merge_train_stale_check <merge-train-branch> <slack-channel>
7+
#
8+
# Example:
9+
# merge_train_stale_check merge-train/spartan '#team-alpha'
10+
#
11+
# Required env vars:
12+
# GH_TOKEN — GitHub API token (used by `gh api`)
13+
# SLACK_BOT_TOKEN — Slack bot token (consumed by ci3/slack_notify)
14+
#
15+
# Optional env vars:
16+
# STALE_HOURS — alert threshold in hours (default 24)
17+
# BASE_BRANCH — PR base branch to filter on (default "next")
18+
19+
set -euo pipefail
20+
21+
REF_NAME="${1:?Usage: $0 <merge-train-branch> <slack-channel>}"
22+
CHANNEL="${2:?Usage: $0 <merge-train-branch> <slack-channel>}"
23+
STALE_HOURS="${STALE_HOURS:-24}"
24+
BASE_BRANCH="${BASE_BRANCH:-next}"
25+
26+
pr_json=$(gh api "repos/AztecProtocol/aztec-packages/pulls?head=AztecProtocol:${REF_NAME}&state=open&base=${BASE_BRANCH}" --jq '.[0] // empty')
27+
28+
if [[ -z "$pr_json" ]]; then
29+
echo "$REF_NAME: no open PR targeting $BASE_BRANCH — nothing to alert."
30+
exit 0
31+
fi
32+
33+
pr_number=$(jq -r '.number' <<<"$pr_json")
34+
pr_url=$(jq -r '.html_url' <<<"$pr_json")
35+
created_at=$(jq -r '.created_at' <<<"$pr_json")
36+
37+
now_s=$(date -u +%s)
38+
created_s=$(date -u -d "$created_at" +%s)
39+
age_hours=$(( (now_s - created_s) / 3600 ))
40+
41+
echo "$REF_NAME PR #$pr_number opened $age_hours hour(s) ago (created $created_at)"
42+
43+
if (( age_hours < STALE_HOURS )); then
44+
echo "Within ${STALE_HOURS}h window — no alert."
45+
exit 0
46+
fi
47+
48+
mergeable_state=$(gh api "repos/AztecProtocol/aztec-packages/pulls/$pr_number" --jq '.mergeable_state // "unknown"')
49+
days=$(( age_hours / 24 ))
50+
51+
message=$(printf ':warning: `%s` has not merged into `%s` in %d day(s) — <%s|PR #%d> is in state `%s`. Please investigate.' \
52+
"$REF_NAME" "$BASE_BRANCH" "$days" "$pr_url" "$pr_number" "$mergeable_state")
53+
54+
TOPDIR=$(git rev-parse --show-toplevel)
55+
"$TOPDIR/ci3/slack_notify" "$message" "$CHANNEL"
56+
57+
echo "Alert sent to $CHANNEL: $message"

0 commit comments

Comments
 (0)