refactor: don't use sub-package to allow reuse #64
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
| name: Cherry-pick via Comment | |
| on: | |
| issue_comment: | |
| types: [created] | |
| jobs: | |
| cherry-pick: | |
| # Only process comments on merged PRs that start with /cherry-pick | |
| if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/cherry-pick') }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - name: Comment on PR with results | |
| if: always() | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| PR_LIST: ${{ steps.cherry-pick.outputs.pr_list }} | |
| run: | | |
| # Build the URL to the current workflow run | |
| workflow_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" | |
| comment="✅ Cherry-pick operation is running! Check the progress in this action:\n\n- [Workflow Run]($workflow_url)" | |
| curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/comments" \ | |
| -d "{\"body\": \"$comment\"}" | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 # Get complete history for cherry-pick | |
| - name: Setup Git | |
| run: | | |
| git config --global user.name 'github-actions[bot]' | |
| git config --global user.email 'github-actions[bot]@users.noreply.github.com' | |
| - name: Get PR and Comment info | |
| env: | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "Comment: $COMMENT_BODY" | |
| echo "PR Number: $PR_NUMBER" | |
| - name: Extract target branches | |
| id: extract-branches | |
| env: | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| # Use regex to extract branch names | |
| if [[ "$COMMENT_BODY" =~ /cherry-pick[[:space:]]+([^,]+(,[[:space:]]*[^,]+)*) ]]; then | |
| branches="${BASH_REMATCH[1]}" | |
| # Convert comma-separated to space-separated | |
| branches="${branches//,/ }" | |
| echo "Extracted branches: $branches" | |
| echo 2 | |
| # Remove any carriage return characters to ensure valid output format | |
| echo "branches=$(echo "$branches" | tr -d '\r')" >> $GITHUB_OUTPUT | |
| echo 3 | |
| else | |
| echo "No target branches found" | |
| echo "branches=" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Get merged commit SHA | |
| id: get-commit | |
| env: | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| # Build correct API URL | |
| API_URL="https://api.github.com/repos/$REPO/pulls/$PR_NUMBER" | |
| echo "API URL: $API_URL" | |
| # Use GitHub API to get merged PR info | |
| response=$(curl -s "$API_URL") | |
| # echo "Raw response: $response" | |
| merge_commit_sha=$(echo "$response" | python3 -c "import sys, json; print(json.load(sys.stdin)['merge_commit_sha'])") | |
| is_merged=$(echo "$response" | python3 -c "import sys, json; print(json.load(sys.stdin)['merged'])") | |
| echo "Merge commit SHA: $merge_commit_sha" | |
| echo "Is merged: $is_merged" | |
| if [ -z "$merge_commit_sha" ] || [[ "$is_merged" != "True" && "$is_merged" != "true" ]]; then | |
| echo "Error: PR is not merged or cannot get merge commit SHA" | |
| exit 1 | |
| fi | |
| echo "Merge commit SHA: $merge_commit_sha" | |
| echo "commit_sha=$merge_commit_sha" >> $GITHUB_OUTPUT | |
| - name: Cherry-pick to target branches | |
| id: cherry-pick | |
| env: | |
| TARGET_BRANCHES: ${{ steps.extract-branches.outputs.branches }} | |
| MERGE_COMMIT_SHA: ${{ steps.get-commit.outputs.commit_sha }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| created_prs="" | |
| for branch in $TARGET_BRANCHES; do | |
| echo "Processing branch: $branch" | |
| # Check if target branch exists | |
| if ! git show-ref --verify --quiet refs/remotes/origin/$branch; then | |
| echo "Warning: Branch $branch does not exist, skipping" | |
| continue | |
| fi | |
| # Create new branch name with timestamp to avoid duplicates | |
| timestamp=$(date +%s) | |
| new_branch="cherry-pick-$branch-pr-$PR_NUMBER-$timestamp" | |
| # Create and switch to new branch | |
| git checkout -b "$new_branch" "origin/$branch" | |
| # Execute cherry-pick | |
| if git cherry-pick -x "$MERGE_COMMIT_SHA"; then | |
| echo "Successfully cherry-picked to $branch" | |
| # Push new branch | |
| git push origin "$new_branch" | |
| # Create PR | |
| pr_response=$(curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls" \ | |
| -d "{ | |
| \"title\": \"Cherry-pick PR #$PR_NUMBER to $branch\", | |
| \"body\": \"Automatically generated PR to cherry-pick #$PR_NUMBER to $branch branch.\n\nSource PR: #$PR_NUMBER\nSource Commit: $MERGE_COMMIT_SHA\", | |
| \"head\": \"$new_branch\", | |
| \"base\": \"$branch\" | |
| }") | |
| pr_url=$(echo "$pr_response" | grep -o '"html_url":"[^"]*' | cut -d'"' -f4) | |
| echo "Created PR: $pr_url" | |
| created_prs="$created_prs\n- $pr_url" | |
| else | |
| echo "Failed to cherry-pick to $branch, conflicts may exist" | |
| git cherry-pick --abort | |
| fi | |
| # Return to initial state | |
| git checkout - | |
| done | |
| # Output created PR list | |
| if [ -n "$created_prs" ]; then | |
| echo "pr_list=$created_prs" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Comment on PR with results | |
| if: always() | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| PR_LIST: ${{ steps.cherry-pick.outputs.pr_list }} | |
| run: | | |
| sleep 2 # wait 2 seconds to ensure the PR is updated | |
| if [ -n "$PR_LIST" ]; then | |
| comment="✅ Cherry-pick operation completed!" | |
| else | |
| comment="❌ Cherry-pick operation did not create any PRs, please check if the target branches exist or if there are conflicts." | |
| fi | |
| curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/issues/$PR_NUMBER/comments" \ | |
| -d "{\"body\": \"$comment\"}" |