diff --git a/.github/workflows/merge-from-milestone.yml b/.github/workflows/merge-from-milestone.yml index 44b4f81f4..fc7edf802 100644 --- a/.github/workflows/merge-from-milestone.yml +++ b/.github/workflows/merge-from-milestone.yml @@ -1,4 +1,4 @@ -name: Create Pre-Release PR from Milestone +name: Create Individual PRs from Milestone permissions: contents: write @@ -9,24 +9,24 @@ on: workflow_dispatch: inputs: milestone_name: - description: 'Milestone name to collect closed PRs from' + description: "Milestone name to collect closed PRs from" required: true - default: 'v3.8.2' + default: "v3.8.4" target_branch: - description: 'Target branch to merge the consolidated PR' + description: "Target branch to merge the consolidated PR" required: true - default: 'pre-release-v3.8.2' + default: "pre-release-v3.8.4" env: - MILESTONE_NAME: ${{ github.event.inputs.milestone_name || 'v3.8.2' }} - TARGET_BRANCH: ${{ github.event.inputs.target_branch || 'pre-release-v3.8.2' }} + MILESTONE_NAME: ${{ github.event.inputs.milestone_name || 'v3.8.4' }} + TARGET_BRANCH: ${{ github.event.inputs.target_branch || 'pre-release-v3.8.4' }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BOT_TOKEN: ${{ secrets.BOT_TOKEN }} LABEL_NAME: cherry-picked - TEMP_DIR: /tmp # Using /tmp as the temporary directory + TEMP_DIR: /tmp jobs: - cherry_pick_milestone_prs: + merge_milestone_prs: runs-on: ubuntu-latest steps: - name: Setup temp directory @@ -47,7 +47,6 @@ jobs: - name: Setup Git User for OpenIM-Robot run: | - # Set up Git credentials for the bot git config --global user.email "OpenIM-Robot@users.noreply.github.com" git config --global user.name "OpenIM-Robot" @@ -83,136 +82,66 @@ jobs: if ! echo "$labels" | grep -q "${LABEL_NAME}"; then echo "PR #$pr_number does not have the 'cherry-picked' label. Adding to the list." echo "$pr_number" >> ${{ env.TEMP_DIR }}/pr_numbers.txt - else - echo "PR #$pr_number already has the 'cherry-picked' label. Skipping." fi done - # Sort the filtered PR numbers sort -n ${{ env.TEMP_DIR }}/pr_numbers.txt -o ${{ env.TEMP_DIR }}/pr_numbers.txt - echo "Filtered and sorted PR numbers:" - cat ${{ env.TEMP_DIR }}/pr_numbers.txt || echo "No closed PR numbers found for milestone." - - - name: Fetch Merge Commits for PRs and Generate Title and Body + - name: Create Individual PRs run: | - # Ensure the files are initialized - > ${{ env.TEMP_DIR }}/commit_hashes.txt - > ${{ env.TEMP_DIR }}/pr_title.txt - > ${{ env.TEMP_DIR }}/pr_body.txt - - # Write description to the PR body - echo "### Description:" >> ${{ env.TEMP_DIR }}/pr_body.txt - echo "Merging PRs from milestone \`$MILESTONE_NAME\` into target branch \`$TARGET_BRANCH\`." >> ${{ env.TEMP_DIR }}/pr_body.txt - echo "" >> ${{ env.TEMP_DIR }}/pr_body.txt - echo "### Need Merge PRs:" >> ${{ env.TEMP_DIR }}/pr_body.txt - - pr_numbers_in_title="" - - # Process sorted PR numbers and generate commit hashes for pr_number in $(cat ${{ env.TEMP_DIR }}/pr_numbers.txt); do - echo "Processing PR #$pr_number" pr_details=$(curl -s -H "Authorization: token $BOT_TOKEN" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number") pr_title=$(echo "$pr_details" | jq -r '.title') + pr_body=$(echo "$pr_details" | jq -r '.body') + pr_creator=$(echo "$pr_details" | jq -r '.user.login') merge_commit=$(echo "$pr_details" | jq -r '.merge_commit_sha') short_commit_hash=$(echo "$merge_commit" | cut -c 1-7) - # Append PR details to the body - echo "- $pr_title: (#$pr_number) ($short_commit_hash)" >> ${{ env.TEMP_DIR }}/pr_body.txt - if [ "$merge_commit" != "null" ];then - echo "$merge_commit" >> ${{ env.TEMP_DIR }}/commit_hashes.txt - echo "#$pr_number" >> ${{ env.TEMP_DIR }}/pr_title.txt - pr_numbers_in_title="$pr_numbers_in_title #$pr_number" - fi - done + git fetch origin + + echo "Checking out target branch: $TARGET_BRANCH" + git checkout $TARGET_BRANCH + + echo "Pulling latest changes from target branch: $TARGET_BRANCH" + git pull origin $TARGET_BRANCH + + cherry_pick_branch="cherry-pick-${short_commit_hash}" + git checkout -b $cherry_pick_branch + + echo "Cherry-picking commit: $merge_commit" + if ! git cherry-pick "$merge_commit" --strategy=recursive -X theirs; then + echo "Cherry-pick encountered conflicts, attempting to continue..." + git cherry-pick --continue || { echo "Cherry-pick failed"; exit 1; } + fi + + git cherry-pick "$merge_commit" --strategy=recursive -X theirs || git cherry-pick --continue + git remote set-url origin "https://${BOT_TOKEN}@github.com/${{ github.repository }}.git" + + echo "Pushing branch: $cherry_pick_branch" + git push origin $cherry_pick_branch --force || { echo "Push failed"; exit 1; } + + new_pr_title="$pr_title [Created by @$pr_creator from #$pr_number]" + new_pr_body="$pr_body + > This PR cherry-picks commit from original PR #$pr_number." + + response=$(curl -s -X POST -H "Authorization: token $BOT_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/repos/${{ github.repository }}/pulls \ + -d "$(jq -n --arg title "$new_pr_title" \ + --arg head "$cherry_pick_branch" \ + --arg base "$TARGET_BRANCH" \ + --arg body "$new_pr_body" \ + '{title: $title, head: $head, base: $base, body: $body}')") - commit_hashes=$(cat ${{ env.TEMP_DIR }}/commit_hashes.txt | tr '\n' ' ') - first_commit_hash=$(head -n 1 ${{ env.TEMP_DIR }}/commit_hashes.txt) - cherry_pick_branch="cherry-pick-${first_commit_hash:0:7}" - echo "COMMIT_HASHES=$commit_hashes" >> $GITHUB_ENV - echo "CHERRY_PICK_BRANCH=$cherry_pick_branch" >> $GITHUB_ENV - echo "pr_numbers_in_title=$pr_numbers_in_title" >> $GITHUB_ENV + new_pr_number=$(echo "$response" | jq -r '.number') + echo "Created PR #$new_pr_number" - - name: Pull and Cherry-pick Commits, Then Push - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BOT_TOKEN: ${{ secrets.BOT_TOKEN }} - run: | - # Fetch and pull the latest changes from the target branch - git fetch origin - git checkout $TARGET_BRANCH - git pull origin $TARGET_BRANCH - - # Create a new branch for cherry-picking - git checkout -b $CHERRY_PICK_BRANCH - - # Cherry-pick the commits and handle conflicts - for commit_hash in $COMMIT_HASHES; do - echo "Attempting to cherry-pick commit $commit_hash" - if ! git cherry-pick "$commit_hash" --strategy=recursive -X theirs; then - echo "Conflict detected for $commit_hash. Resolving with incoming changes." - conflict_files=$(git diff --name-only --diff-filter=U) - echo "Conflicting files:" - echo "$conflict_files" - - for file in $conflict_files; do - if [ -f "$file" ]; then - echo "Resolving conflict for $file" - git add "$file" - else - echo "File $file has been deleted. Skipping." - git rm "$file" - fi - done - - echo "Conflicts resolved. Continuing cherry-pick." - git cherry-pick --continue - else - echo "Cherry-pick successful for commit $commit_hash." + curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"labels": ["milestone-merge"]}' \ + "https://api.github.com/repos/${{ github.repository }}/issues/$new_pr_number/labels" fi done - - # Push the cherry-pick branch to the repository - git remote set-url origin "https://${BOT_TOKEN}@github.com/${{ github.repository }}.git" - git push origin $CHERRY_PICK_BRANCH --force - - - name: Create Pull Request - run: | - # Prepare and create the PR - pr_title="deps: Merge ${{ env.pr_numbers_in_title }} PRs into $TARGET_BRANCH" - pr_body=$(cat ${{ env.TEMP_DIR }}/pr_body.txt) - - echo "Prepared PR title:" - echo "$pr_title" - echo "Prepared PR body:" - echo "$pr_body" - - # Create the PR using the GitHub API - response=$(curl -s -X POST -H "Authorization: token $BOT_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - https://api.github.com/repos/${{ github.repository }}/pulls \ - -d "$(jq -n --arg title "$pr_title" \ - --arg head "$CHERRY_PICK_BRANCH" \ - --arg base "$TARGET_BRANCH" \ - --arg body "$pr_body" \ - '{title: $title, head: $head, base: $base, body: $body}')") - - pr_number=$(echo "$response" | jq -r '.number') - echo "$pr_number" > ${{ env.TEMP_DIR }}/created_pr_number.txt - echo "Created PR #$pr_number" - - - name: Add Label to Created Pull Request - run: | - # Add 'milestone-merge' label to the created PR - pr_number=$(cat ${{ env.TEMP_DIR }}/created_pr_number.txt) - echo "Adding label to PR #$pr_number" - - curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"labels": ["milestone-merge"]}' \ - "https://api.github.com/repos/${{ github.repository }}/issues/$pr_number/labels" - - echo "Added 'milestone-merge' label to PR #$pr_number."