Skip to content

Commit 4a475e0

Browse files
Merge pull request #1982 from AxiomCodeAI/ci/close-issues-on-dev
ci: close the issues a pull request names once it reaches dev
2 parents b4473a2 + 10e0677 commit 4a475e0

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
# close-issues-on-dev.sh — close the issues named by pull requests that merged into a branch other than
3+
# dev, once their merge commit is part of dev (see .github/workflows/close-issues-on-dev.yml).
4+
#
5+
# DRY_RUN=1 .github/scripts/close-issues-on-dev.sh # list, close nothing
6+
#
7+
# Needs: gh (authenticated; GH_TOKEN in CI), a checkout with full history, and origin/dev or HEAD on dev.
8+
# LOOKBACK: how many recently merged pull requests to consider (default 300).
9+
set -euo pipefail
10+
11+
DRY_RUN="${DRY_RUN:-0}"
12+
LOOKBACK="${LOOKBACK:-300}"
13+
REPO="${GITHUB_REPOSITORY:-$(gh repo view --json nameWithOwner -q .nameWithOwner)}"
14+
DEV_REF="${DEV_REF:-HEAD}"
15+
[ "$DEV_REF" = HEAD ] && [ "$(git rev-parse --abbrev-ref HEAD)" != dev ] && DEV_REF=origin/dev
16+
17+
closed=0; pending=0
18+
while IFS=$'\t' read -r pr base merge body64; do
19+
[ -n "$merge" ] || continue
20+
[ "$base" = dev ] && continue # GitHub closes these itself
21+
if ! git merge-base --is-ancestor "$merge" "$DEV_REF" 2>/dev/null; then
22+
pending=$((pending + 1)); continue # merged, but not on dev yet
23+
fi
24+
body=$(printf '%s' "$body64" | base64 --decode)
25+
for n in $(printf '%s\n' "$body" | grep -oiE '\b(close[sd]?|fix(e[sd])?|resolve[sd]?)[[:space:]]*:?[[:space:]]+#[0-9]+' \
26+
| grep -oE '[0-9]+$' | sort -un); do
27+
state=$(gh issue view "$n" --repo "$REPO" --json state -q .state 2>/dev/null || echo MISSING)
28+
[ "$state" = OPEN ] || continue
29+
if [ "$DRY_RUN" = 1 ]; then
30+
echo "would close #$n (pull request #$pr into $base, ${merge:0:9} is on dev)"
31+
else
32+
gh issue close "$n" --repo "$REPO" \
33+
--comment "Closed by #$pr, which merged into \`$base\` and reached \`dev\` in ${merge:0:9}."
34+
echo "closed #$n (pull request #$pr into $base)"
35+
fi
36+
closed=$((closed + 1))
37+
done
38+
done < <(gh pr list --repo "$REPO" --state merged --limit "$LOOKBACK" \
39+
--json number,baseRefName,mergeCommit,body \
40+
-q '.[] | [.number, .baseRefName, (.mergeCommit.oid // ""), (.body // "" | @base64)] | @tsv')
41+
42+
verb=closed; [ "$DRY_RUN" = 1 ] && verb="to close"
43+
echo "issues $verb: $closed; merged pull requests not on dev yet: $pending"
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# ─────────────────────────────────────────────────────────────────────────────
2+
# A pull request that merges into a release or integration branch (0.2.1, a
3+
# perf branch) never closes the issues it names: GitHub acts on "Closes #N" only
4+
# when the merge lands on the default branch. This closes them when that work
5+
# reaches `dev`.
6+
#
7+
# On every push to dev it looks at pull requests merged into any other branch,
8+
# keeps those whose merge commit is now part of dev, and closes each open issue
9+
# their description closes ("Closes", "Fixes", "Resolves" #N), with a comment
10+
# naming the pull request. "Part of #N" and "Refs #N" are not closing words, so
11+
# umbrella issues stay open.
12+
# ─────────────────────────────────────────────────────────────────────────────
13+
name: close-issues-on-dev
14+
15+
on:
16+
push:
17+
branches: [dev]
18+
workflow_dispatch:
19+
inputs:
20+
dry_run:
21+
description: list what would be closed, close nothing
22+
type: boolean
23+
default: true
24+
25+
permissions:
26+
contents: read
27+
issues: write
28+
pull-requests: read
29+
30+
jobs:
31+
close:
32+
name: close issues whose pull request reached dev
33+
runs-on: ubuntu-24.04
34+
timeout-minutes: 10
35+
steps:
36+
- uses: actions/checkout@v4
37+
with:
38+
fetch-depth: 0
39+
40+
- name: close the issues
41+
env:
42+
GH_TOKEN: ${{ github.token }}
43+
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run && '1' || '0' }}
44+
run: .github/scripts/close-issues-on-dev.sh

0 commit comments

Comments
 (0)