Last active
May 20, 2026 21:07
-
-
Save stephenwaite/f1b3a5203f9d7be99a32c58d2aea2edb to your computer and use it in GitHub Desktop.
backport to rel-704
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Test first with dry-run | |
| # ./backport.sh --dry-run --branch rel-800 abc123def456 | |
| # Single commit | |
| # ./backport.sh --branch rel-800 abc123def456 | |
| # Multiple commits | |
| # ./backport.sh --branch rel-704 commit1 commit2 commit3 | |
| # Dry-run with multiple commits | |
| # ./backport.sh --dry-run --branch rel-800 commit1 commit2 commit3 | |
| # Parse flags | |
| DRY_RUN=false | |
| COMMITS=() | |
| TARGET_BRANCH="" | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --dry-run|-n) | |
| DRY_RUN=true | |
| shift | |
| ;; | |
| --branch|-b) | |
| TARGET_BRANCH="$2" | |
| shift 2 | |
| ;; | |
| *) | |
| COMMITS+=("$1") | |
| shift | |
| ;; | |
| esac | |
| done | |
| if [ -z "$TARGET_BRANCH" ]; then | |
| echo "Error: --branch <branch-name> is required (e.g. --branch rel-800)" | |
| echo "Usage: $0 [--dry-run] --branch <branch-name> <commit-hash> [<commit-hash>...]" | |
| exit 1 | |
| fi | |
| if [ ${#COMMITS[@]} -eq 0 ]; then | |
| echo "Usage: $0 [--dry-run] --branch <branch-name> <commit-hash> [<commit-hash>...]" | |
| exit 1 | |
| fi | |
| # Ensure upstream branch is available in origin | |
| echo "Syncing $TARGET_BRANCH from upstream to origin..." | |
| git fetch upstream "$TARGET_BRANCH" || { echo "✗ Failed to fetch upstream/$TARGET_BRANCH"; exit 1; } | |
| git push origin "upstream/$TARGET_BRANCH:refs/heads/$TARGET_BRANCH" 2>/dev/null || true | |
| git fetch origin "$TARGET_BRANCH" || { echo "✗ Failed to fetch origin/$TARGET_BRANCH"; exit 1; } | |
| # Build commit list | |
| COMMIT_LIST="" | |
| echo "Commits to backport:" | |
| for commit in "${COMMITS[@]}"; do | |
| COMMIT_MSG=$(git log -1 --pretty='%h - %s' $commit 2>/dev/null) | |
| if [ $? -ne 0 ]; then | |
| echo "Error: Commit $commit not found" | |
| exit 1 | |
| fi | |
| echo " $COMMIT_MSG" | |
| COMMIT_LIST="$COMMIT_LIST | |
| - $COMMIT_MSG" | |
| done | |
| # Determine title | |
| if [ ${#COMMITS[@]} -eq 1 ]; then | |
| TITLE="chore(backport): $TARGET_BRANCH: $(git log -1 --pretty=%s ${COMMITS[0]})" | |
| COMMIT_SHORT=$(echo ${COMMITS[0]} | cut -c1-7) | |
| else | |
| TITLE="Backport multiple commits to $TARGET_BRANCH" | |
| COMMIT_SHORT="multi" | |
| fi | |
| # Issue body | |
| ISSUE_BODY="Backport the following commits from master to $TARGET_BRANCH: | |
| $COMMIT_LIST" | |
| if [ "$DRY_RUN" = true ]; then | |
| echo "" | |
| echo "=== DRY RUN MODE ===" | |
| echo "" | |
| echo "Would create issue:" | |
| echo " Title: $TITLE" | |
| echo " Body: $ISSUE_BODY" | |
| echo " Label: backport" | |
| echo "" | |
| MOCK_ISSUE_NUM="123" | |
| BRANCH_NAME="backport-$MOCK_ISSUE_NUM-$COMMIT_SHORT" | |
| echo "Would execute:" | |
| echo " git fetch origin" | |
| echo " git checkout -b $BRANCH_NAME origin/$TARGET_BRANCH" | |
| echo " git cherry-pick ${COMMITS[@]}" | |
| echo " git push -u origin $BRANCH_NAME" | |
| echo "" | |
| echo "Would create PR:" | |
| echo " Base: $TARGET_BRANCH" | |
| echo " Title: $TITLE" | |
| echo " Body: Fixes #$MOCK_ISSUE_NUM" | |
| echo "" | |
| echo "Cherry-pick preview (use git log to see these commits):" | |
| for commit in "${COMMITS[@]}"; do | |
| git log -1 --pretty=full $commit | |
| echo "---" | |
| done | |
| exit 0 | |
| fi | |
| # Real execution | |
| echo "" | |
| echo "Creating issue..." | |
| ISSUE_NUM=$(gh issue create \ | |
| --title "$TITLE" \ | |
| --body "$ISSUE_BODY" \ | |
| --label "backport" \ | |
| | grep -o '[0-9]*$') | |
| echo "✓ Created issue #$ISSUE_NUM" | |
| # Create branch | |
| BRANCH_NAME="backport-$ISSUE_NUM-$COMMIT_SHORT" | |
| echo "Creating branch $BRANCH_NAME..." | |
| git checkout -b $BRANCH_NAME origin/$TARGET_BRANCH || exit 1 | |
| echo "Cherry-picking commits..." | |
| if git cherry-pick "${COMMITS[@]}"; then | |
| echo "✓ Cherry-pick successful" | |
| else | |
| echo "✗ Cherry-pick failed - resolve conflicts and run:" | |
| echo " git cherry-pick --continue" | |
| echo " git push -u origin $BRANCH_NAME" | |
| echo " gh pr create --base $TARGET_BRANCH --title \"$TITLE\" --body \"Fixes #$ISSUE_NUM\"" | |
| exit 1 | |
| fi | |
| echo "Pushing branch..." | |
| git push -u origin $BRANCH_NAME || exit 1 | |
| echo "Creating PR..." | |
| gh pr create \ | |
| --base "$TARGET_BRANCH" \ | |
| --title "$TITLE" \ | |
| --body "Fixes #$ISSUE_NUM | |
| Cherry-picked commits: | |
| $COMMIT_LIST" | |
| echo "" | |
| echo "✓ Done! Issue #$ISSUE_NUM and PR created." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment