Skip to content

Commit 0b89370

Browse files
committed
feat: add script to transfer issues
1 parent 61f4130 commit 0b89370

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# migrate_issues.sh - Transfer open GitHub issues from one repo to another using gh CLI.
17+
18+
set -e
19+
20+
usage() {
21+
echo "Usage: $0 <source-repo> <target-repo> [--label <label>] [--dry-run]"
22+
echo "Example: $0 googleapis/python-storage googleapis/google-cloud-python --label 'api: storage'"
23+
exit 1
24+
}
25+
26+
if [[ $# -lt 2 ]]; then
27+
usage
28+
fi
29+
30+
SOURCE_REPO=$1
31+
TARGET_REPO=$2
32+
shift 2
33+
34+
DRY_RUN=false
35+
REQUIRED_LABEL=""
36+
37+
while [[ "$#" -gt 0 ]]; do
38+
case $1 in
39+
--dry-run) DRY_RUN=true; shift ;;
40+
--label) REQUIRED_LABEL="$2"; shift 2 ;;
41+
*) echo "Unknown parameter passed: $1"; usage ;;
42+
esac
43+
done
44+
45+
# Check if gh is installed
46+
if ! command -v gh &> /dev/null; then
47+
echo "Error: gh (GitHub CLI) is not installed."
48+
exit 1
49+
fi
50+
51+
# Check if authenticated
52+
if ! gh auth status &> /dev/null; then
53+
echo "Error: gh is not authenticated. Run 'gh auth login' first."
54+
exit 1
55+
fi
56+
57+
echo "Transferring open issues from $SOURCE_REPO to $TARGET_REPO..."
58+
if [ "$DRY_RUN" = true ]; then
59+
echo "--- DRY RUN MODE ---"
60+
fi
61+
62+
# Ensure label exists in target repo
63+
if [[ -n "$REQUIRED_LABEL" ]]; then
64+
echo "Ensuring label '$REQUIRED_LABEL' exists in $TARGET_REPO..."
65+
if ! gh label list --repo "$TARGET_REPO" --json name --jq '.[].name' | grep -fxq "$REQUIRED_LABEL"; then
66+
if [ "$DRY_RUN" = true ]; then
67+
echo " [DRY RUN] Would create label '$REQUIRED_LABEL' in $TARGET_REPO"
68+
else
69+
echo " Creating label '$REQUIRED_LABEL' in $TARGET_REPO..."
70+
gh label create "$REQUIRED_LABEL" --repo "$TARGET_REPO" --color "ededed"
71+
fi
72+
else
73+
echo " Label '$REQUIRED_LABEL' already exists."
74+
fi
75+
fi
76+
77+
# Fetch all open issues from source repo
78+
# We use --limit 1000 to get a reasonable amount of issues. Adjust if needed.
79+
ISSUE_NUMBERS=$(gh issue list --repo "$SOURCE_REPO" --state open --limit 1000 --json number --jq '.[].number')
80+
81+
if [[ -z "$ISSUE_NUMBERS" ]]; then
82+
echo "No open issues found in $SOURCE_REPO."
83+
exit 0
84+
fi
85+
86+
# Extract short name from SOURCE_REPO (e.g., java-bigquery from googleapis/java-bigquery)
87+
REPO_SHORT_NAME=$(echo "$SOURCE_REPO" | cut -d'/' -f2)
88+
89+
# Process each issue
90+
for ISSUE_NUMBER in $ISSUE_NUMBERS; do
91+
echo "Processing Issue #$ISSUE_NUMBER..."
92+
93+
# Get the current title
94+
TITLE=$(gh issue view "$ISSUE_NUMBER" --repo "$SOURCE_REPO" --json title --jq '.title')
95+
NEW_TITLE="[$REPO_SHORT_NAME] $TITLE"
96+
97+
if [ "$DRY_RUN" = true ]; then
98+
echo " [DRY RUN] Would transfer #$ISSUE_NUMBER to $TARGET_REPO"
99+
echo " [DRY RUN] Would update title to: $NEW_TITLE"
100+
if [[ -n "$REQUIRED_LABEL" ]]; then
101+
echo " [DRY RUN] Would add label '$REQUIRED_LABEL' to transferred issue"
102+
fi
103+
else
104+
echo " Transferring #$ISSUE_NUMBER..."
105+
# Capture the output of transfer to get the new issue URL
106+
TRANSFER_OUTPUT=$(gh issue transfer "$ISSUE_NUMBER" "$TARGET_REPO" --repo "$SOURCE_REPO")
107+
108+
# The output is typically something like: https://github.com/googleapis/google-cloud-java/issues/1234
109+
NEW_ISSUE_URL=$(echo "$TRANSFER_OUTPUT" | grep -o 'https://github.com/[^ ]*')
110+
NEW_ISSUE_NUMBER=$(echo "$NEW_ISSUE_URL" | awk -F'/' '{print $NF}')
111+
112+
if [[ -n "$NEW_ISSUE_NUMBER" ]]; then
113+
echo " Transferred to $TARGET_REPO as #$NEW_ISSUE_NUMBER. Updating issue..."
114+
115+
# Prepare edit command arguments
116+
EDIT_ARGS=("--title" "$NEW_TITLE")
117+
if [[ -n "$REQUIRED_LABEL" ]]; then
118+
EDIT_ARGS+=("--add-label" "$REQUIRED_LABEL")
119+
fi
120+
121+
gh issue edit "$NEW_ISSUE_NUMBER" --repo "$TARGET_REPO" "${EDIT_ARGS[@]}"
122+
echo " Issue updated."
123+
else
124+
echo " Warning: Could not determine new issue number from output: $TRANSFER_OUTPUT"
125+
fi
126+
fi
127+
done
128+
129+
echo "Transfer completed."

0 commit comments

Comments
 (0)