33# Cleanup script for GitHub Agentic Workflows test resources
44# This script cleans up test resources (issues, PRs, branches) created during e2e testing
55#
6- # Usage: ./clean.sh
6+ # Usage: ./clean.sh [--dry-run]
7+ #
8+ # Options:
9+ # --dry-run Preview what would be deleted without making changes
710#
811# This script will:
912# 1. Close all open issues with cleanup comment
@@ -23,6 +26,7 @@ NC='\033[0m' # No Color
2326
2427# Configuration
2528LOG_FILE=" cleanup-$( date +%Y%m%d-%H%M%S) .log"
29+ DRY_RUN=false
2630
2731# Utility functions
2832log () {
@@ -47,6 +51,9 @@ error() {
4751
4852cleanup_test_resources () {
4953 info " Cleaning up test resources..."
54+ if [[ " $DRY_RUN " == " true" ]]; then
55+ warning " DRY RUN MODE - No changes will be made"
56+ fi
5057 local issues_closed=0
5158 local prs_closed=0
5259 local discussions_closed=0
@@ -56,11 +63,16 @@ cleanup_test_resources() {
5663 info " Checking for open issues to close..."
5764 while read -r issue_num; do
5865 if [[ -n " $issue_num " ]]; then
59- if gh issue close " $issue_num " --comment " Closed by e2e test cleanup " & > /dev/null ; then
60- info " Closed issue #$issue_num "
66+ if [[ " $DRY_RUN " == " true " ]] ; then
67+ info " [DRY RUN] Would close issue #$issue_num "
6168 (( issues_closed++ ))
6269 else
63- warning " Failed to close issue #$issue_num "
70+ if gh issue close " $issue_num " --comment " Closed by e2e test cleanup" & > /dev/null; then
71+ info " Closed issue #$issue_num "
72+ (( issues_closed++ ))
73+ else
74+ warning " Failed to close issue #$issue_num "
75+ fi
6476 fi
6577 fi
6678 done < <( gh issue list --limit 20 --json number --jq ' .[].number' 2> /dev/null || true)
@@ -69,55 +81,130 @@ cleanup_test_resources() {
6981 info " Checking for open pull requests to close..."
7082 while read -r pr_num; do
7183 if [[ -n " $pr_num " ]]; then
72- if gh pr close " $pr_num " --comment " Closed by e2e test cleanup " & > /dev/null ; then
73- info " Closed pull request #$pr_num "
84+ if [[ " $DRY_RUN " == " true " ]] ; then
85+ info " [DRY RUN] Would close pull request #$pr_num "
7486 (( prs_closed++ ))
7587 else
76- warning " Failed to close pull request #$pr_num "
88+ if gh pr close " $pr_num " --comment " Closed by e2e test cleanup" & > /dev/null; then
89+ info " Closed pull request #$pr_num "
90+ (( prs_closed++ ))
91+ else
92+ warning " Failed to close pull request #$pr_num "
93+ fi
7794 fi
7895 fi
7996 done < <( gh pr list --limit 20 --json number --jq ' .[].number' 2> /dev/null || true)
8097
8198 # Close all discussions
8299 info " Checking for open discussions to close..."
83- while read -r discussion_id; do
84- if [[ -n " $discussion_id " ]]; then
85- # Close discussion using GraphQL mutation
86- local mutation=" mutation {
87- closeDiscussion(input: {discussionId: \" $discussion_id \" }) {
88- discussion {
89- number
90- }
91- }
92- }"
93- if gh api graphql -f query=" $mutation " & > /dev/null; then
94- info " Closed discussion with ID $discussion_id "
95- (( discussions_closed++ ))
96- else
97- warning " Failed to close discussion with ID $discussion_id "
100+ local discussion_count=0
101+
102+ # Debug: First check if discussions endpoint works
103+ info " Fetching discussions from API..."
104+ local api_response=$( gh api repos/:owner/:repo/discussions --paginate 2>&1 )
105+ local api_exit_code=$?
106+
107+ if [[ $api_exit_code -ne 0 ]]; then
108+ warning " API call failed with exit code $api_exit_code "
109+ echo " API response: $api_response " >> " $LOG_FILE "
110+ else
111+ info " API call succeeded, processing discussions..."
112+ echo " API response: $api_response " >> " $LOG_FILE "
113+ fi
114+
115+ # Process each discussion JSON object directly from the API
116+ # Note: GitHub API uses "state" field with values "open" or "closed", not a boolean "closed" field
117+ # Note: GraphQL mutations require node_id (global ID), not the numeric id
118+ while IFS= read -r discussion_line; do
119+ if [[ -n " $discussion_line " && " $discussion_line " != " null" ]]; then
120+ local discussion_node_id=$( echo " $discussion_line " | jq -r ' .node_id // empty' 2> /dev/null)
121+ local discussion_num=$( echo " $discussion_line " | jq -r ' .number // empty' 2> /dev/null)
122+ local discussion_title=$( echo " $discussion_line " | jq -r ' .title // empty' 2> /dev/null)
123+ local discussion_state=$( echo " $discussion_line " | jq -r ' .state // empty' 2> /dev/null)
124+
125+ info " Processing discussion: NODE_ID=$discussion_node_id , NUM=$discussion_num , STATE=$discussion_state , TITLE=$discussion_title "
126+
127+ if [[ -n " $discussion_node_id " && " $discussion_node_id " != " null" && " $discussion_state " == " open" ]]; then
128+ (( discussion_count++ ))
129+ info " Found open discussion #$discussion_num : $discussion_title (NODE_ID: $discussion_node_id )"
130+
131+ if [[ " $DRY_RUN " == " true" ]]; then
132+ info " [DRY RUN] Would close discussion #$discussion_num (NODE_ID: $discussion_node_id )"
133+ (( discussions_closed++ ))
134+ else
135+ # Close discussion using GraphQL mutation (requires node_id, not numeric id)
136+ local mutation=' mutation {
137+ closeDiscussion(input: {discussionId: "' $discussion_node_id ' "}) {
138+ discussion {
139+ number
140+ }
141+ }
142+ }'
143+ local result=$( gh api graphql -f query=" $mutation " 2>&1 )
144+ echo " $result " >> " $LOG_FILE "
145+
146+ if echo " $result " | grep -q ' "number"' ; then
147+ success " Closed discussion #$discussion_num (NODE_ID: $discussion_node_id )"
148+ (( discussions_closed++ ))
149+ else
150+ warning " Failed to close discussion #$discussion_num (NODE_ID: $discussion_node_id )"
151+ echo " $result " | tee -a " $LOG_FILE "
152+ fi
153+ fi
98154 fi
99155 fi
100- done < <( gh api repos/:owner/:repo/discussions --paginate --jq ' .[] | select(.closed == false) | .id' 2> /dev/null || true)
156+ done < <( echo " $api_response " | jq -c ' .[] | {node_id, number, title, state}' 2> /dev/null || true)
157+
158+ if [[ $discussion_count -eq 0 ]]; then
159+ info " No open discussions found to close"
160+ fi
101161
102162 # Delete test branches
103163 info " Checking for test branches to delete..."
104164 while read -r branch; do
105165 if [[ -n " $branch " ]]; then
106- if git push origin --delete " $branch " & > /dev/null ; then
107- info " Deleted branch: $branch "
166+ if [[ " $DRY_RUN " == " true " ]] ; then
167+ info " [DRY RUN] Would delete branch: $branch "
108168 (( branches_deleted++ ))
109169 else
110- warning " Failed to delete branch: $branch "
170+ if git push origin --delete " $branch " & > /dev/null; then
171+ info " Deleted branch: $branch "
172+ (( branches_deleted++ ))
173+ else
174+ warning " Failed to delete branch: $branch "
175+ fi
111176 fi
112177 fi
113178 done < <( git branch -r 2> /dev/null | grep ' origin/test-pr-\|origin/claude-test-branch\|origin/codex-test-branch' | sed ' s/origin\///' || true)
114179
115- success " Cleanup completed: $issues_closed issues closed, $prs_closed PRs closed, $discussions_closed discussions closed, $branches_deleted branches deleted"
180+ if [[ " $DRY_RUN " == " true" ]]; then
181+ success " [DRY RUN] Would cleanup: $issues_closed issues, $prs_closed PRs, $discussions_closed discussions, $branches_deleted branches"
182+ else
183+ success " Cleanup completed: $issues_closed issues closed, $prs_closed PRs closed, $discussions_closed discussions closed, $branches_deleted branches deleted"
184+ fi
116185}
117186
118187main () {
188+ # Parse arguments
189+ while [[ $# -gt 0 ]]; do
190+ case $1 in
191+ --dry-run)
192+ DRY_RUN=true
193+ shift
194+ ;;
195+ * )
196+ error " Unknown option: $1 "
197+ echo " Usage: $0 [--dry-run]"
198+ exit 1
199+ ;;
200+ esac
201+ done
202+
119203 echo -e " ${CYAN} 🧹 GitHub Agentic Workflows Test Resource Cleanup${NC} "
120204 echo -e " ${CYAN} ==================================================${NC} "
205+ if [[ " $DRY_RUN " == " true" ]]; then
206+ echo -e " ${YELLOW} 🔍 DRY RUN MODE - No changes will be made${NC} "
207+ fi
121208 echo
122209
123210 log " Starting cleanup at $( date) "
0 commit comments