diff --git a/doc/MILESTONE-MOVE-QUICK-REF.md b/doc/MILESTONE-MOVE-QUICK-REF.md new file mode 100644 index 0000000000..31c757ee64 --- /dev/null +++ b/doc/MILESTONE-MOVE-QUICK-REF.md @@ -0,0 +1,15 @@ +# Quick Reference: Move Items Between Milestones + +## The One-Liner (Copy-Paste Ready) + +```bash +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 --json number | jq -r '.[].number' | xargs -I {} gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4" +``` + +## Alternative: Using the Script + +```bash +./tools/move-milestone-items.sh "7.0.0-preview5" "7.0.0-preview4" +``` + +For detailed documentation, see [milestone-move-one-liner.md](./milestone-move-one-liner.md) diff --git a/doc/milestone-move-one-liner.md b/doc/milestone-move-one-liner.md new file mode 100644 index 0000000000..af87d8ed3a --- /dev/null +++ b/doc/milestone-move-one-liner.md @@ -0,0 +1,95 @@ +# Move Milestone Items - Bash One-Liner + +## The One-Liner + +To move all items (issues and PRs) from milestone `7.0.0-preview5` to `7.0.0-preview4`: + +```bash +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 --json number | jq -r '.[].number' | xargs -I {} gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4" +``` + +## Explanation + +This one-liner performs the following steps: + +1. **`gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 --json number`** + - Lists all issues and PRs in the `7.0.0-preview5` milestone + - `--state all` includes both open and closed items + - `--limit 1000` ensures we get all items (adjust if needed) + - `--json number` outputs only the issue/PR numbers in JSON format + +2. **`jq -r '.[].number'`** + - Extracts the issue/PR numbers from the JSON output + - `-r` flag outputs raw strings (without quotes) + - Each number is output on a separate line + +3. **`xargs -I {} gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4"`** + - Takes each issue/PR number from the previous command + - Executes `gh issue edit` for each number + - Updates the milestone to `7.0.0-preview4` + +## Prerequisites + +- GitHub CLI (`gh`) must be installed and authenticated +- Appropriate permissions on the dotnet/SqlClient repository +- `jq` command-line JSON processor must be installed + +## Alternative: With Progress Indication + +If you want to see progress as items are moved: + +```bash +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 --json number | jq -r '.[].number' | xargs -I {} sh -c 'echo "Moving issue #{}..." && gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4"' +``` + +## Alternative: Move Only Open Items + +To move only open issues/PRs: + +```bash +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state open --limit 1000 --json number | jq -r '.[].number' | xargs -I {} gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4" +``` + +## Alternative: Without jq (using grep/awk) + +If `jq` is not available: + +```bash +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 | awk '{print $1}' | xargs -I {} gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4" +``` + +## Verification + +To verify the move was successful: + +```bash +# Check items remaining in source milestone +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all + +# Check items in destination milestone +gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview4" --state all +``` + +## Safety Considerations + +1. **Dry Run**: First list the items to see what will be moved: + ```bash + gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 + ``` + +2. **Backup**: Consider documenting the current state before moving: + ```bash + gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 > backup-preview5-items.txt + ``` + +3. **Rate Limiting**: The GitHub API has rate limits. If you have many items, add a small delay: + ```bash + gh issue list --repo dotnet/SqlClient --milestone "7.0.0-preview5" --state all --limit 1000 --json number | jq -r '.[].number' | xargs -I {} sh -c 'gh issue edit {} --repo dotnet/SqlClient --milestone "7.0.0-preview4" && sleep 1' + ``` + +## Notes + +- The `gh issue list` command returns both issues and pull requests (PRs are treated as issues in the GitHub API) +- The `gh issue edit` command works for both issues and pull requests +- Milestone names are case-sensitive and must match exactly +- If a milestone doesn't exist, the command will fail with an error diff --git a/tools/move-milestone-items.sh b/tools/move-milestone-items.sh new file mode 100755 index 0000000000..229a3d030f --- /dev/null +++ b/tools/move-milestone-items.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Script to move all items from one milestone to another in the dotnet/SqlClient repository +# Usage: ./move-milestone-items.sh +# +# Example: +# ./move-milestone-items.sh "7.0.0-preview5" "7.0.0-preview4" + +set -e + +REPO="dotnet/SqlClient" + +if [ $# -ne 2 ]; then + echo "Usage: $0 " + echo "Example: $0 '7.0.0-preview5' '7.0.0-preview4'" + exit 1 +fi + +SOURCE_MILESTONE="$1" +TARGET_MILESTONE="$2" + +echo "Moving all items from milestone '$SOURCE_MILESTONE' to '$TARGET_MILESTONE' in repo $REPO" +echo "" + +# Check if gh is installed +if ! command -v gh &> /dev/null; then + echo "Error: gh CLI is not installed. Please install it first." + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed. Please install it first." + exit 1 +fi + +# List items to be moved +echo "Fetching items from milestone '$SOURCE_MILESTONE'..." +ITEMS=$(gh issue list --repo "$REPO" --milestone "$SOURCE_MILESTONE" --state all --limit 1000 --json number | jq -r '.[].number') + +if [ -z "$ITEMS" ]; then + echo "No items found in milestone '$SOURCE_MILESTONE'" + exit 0 +fi + +ITEM_COUNT=$(echo "$ITEMS" | wc -l) +echo "Found $ITEM_COUNT item(s) to move" +echo "" + +# Confirm before proceeding +read -p "Do you want to proceed with moving these items? (y/N) " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 +fi + +# Move items +echo "Moving items..." +COUNTER=0 +for ITEM_NUM in $ITEMS; do + COUNTER=$((COUNTER + 1)) + echo "[$COUNTER/$ITEM_COUNT] Moving issue/PR #$ITEM_NUM..." + gh issue edit "$ITEM_NUM" --repo "$REPO" --milestone "$TARGET_MILESTONE" + # Small delay to avoid rate limiting + sleep 0.5 +done + +echo "" +echo "Successfully moved $ITEM_COUNT item(s) from '$SOURCE_MILESTONE' to '$TARGET_MILESTONE'" +echo "" +echo "Verification:" +echo " Source milestone: gh issue list --repo $REPO --milestone \"$SOURCE_MILESTONE\" --state all" +echo " Target milestone: gh issue list --repo $REPO --milestone \"$TARGET_MILESTONE\" --state all"