1+ ` ` ` yaml
12name: Create Hotfix PR
23
34on:
@@ -52,34 +53,35 @@ jobs:
5253 TARGET_BRANCHES=("main") # Always target main for hotfix
5354
5455 # Get all remote 'release-candidate' branches with version pattern as YY.I or YY.II
55- ALL_RELEASE_CANDIDATE_BRANCHES=$(git branch -r | grep 'origin/release-candidate/' | sed 's/.*origin\///' | grep -E '^release-candidate/[0-9]{2}\.[0-9]{1,2}$' | sort -V)
56+ ALL_RELEASE_CANDIDATE_BRANCHES=$(git branch -r \
57+ | grep 'origin/release-candidate/' \
58+ | sed 's/.*origin\/ //' \
59+ | grep -E '^release-candidate/[0-9]{2}\. [0-9]{1,2}$' \
60+ | sort -V)
5661 echo "Found release-candidate branches: $ALL_RELEASE_CANDIDATE_BRANCHES"
5762
5863 # Determine the version of the current PR's base branch
59- # Example: release-candidate/25.5 -> 25.05 (for proper numerical comparison)
60- PR_BASE_VERSION=$(echo "$PR_BASE_BRANCH" | sed -n 's/release-candidate\/\([0-9]\{2\}\)\.\([0-9]\{1,2\}\)/\1.\2/p')
61-
64+ PR_BASE_VERSION=$(echo "$PR_BASE_BRANCH" \
65+ | sed -n 's/release-candidate\/ \( [0-9]\{ 2\}\)\.\( [0-9]\{ 1,2\}\) /\1 .\2 /p')
66+
6267 # Handle cases like 25.5 vs 25.05 for comparison
6368 if [[ "$PR_BASE_VERSION" =~ ^[0-9]{2}\. [0-9]$ ]]; then
64- PR_BASE_VERSION=$(echo "$PR_BASE_VERSION" | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
69+ PR_BASE_VERSION=$(echo "$PR_BASE_VERSION" \
70+ | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
6571 fi
72+ echo "Base branch version: $PR_BASE_VERSION"
6673
6774 if [[ -n "$PR_BASE_VERSION" ]]; then
68- echo "Base branch version: $PR_BASE_VERSION"
6975 for branch in $ALL_RELEASE_CANDIDATE_BRANCHES; do
70- # Extract version for comparison
71- BRANCH_VERSION=$(echo "$branch" | sed -n 's/release-candidate\/\([0-9]\{2\}\)\.\([0-9]\{1,2\}\)/\1.\2/p')
72-
73- if [[ -n "$BRANCH_VERSION" ]]; then
74- if [[ "$BRANCH_VERSION" =~ ^[0-9]{2}\.[0-9]$ ]]; then
75- BRANCH_VERSION=$(echo "$BRANCH_VERSION" | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
76- fi
77-
78- # Compare versions
79- if (( $(echo "$BRANCH_VERSION > $PR_BASE_VERSION" | bc -l) )); then
80- TARGET_BRANCHES+=("$branch")
81- echo "Adding $branch (version $BRANCH_VERSION) as it's higher than $PR_BASE_BRANCH (version $PR_BASE_VERSION)"
82- fi
76+ BRANCH_VERSION=$(echo "$branch" \
77+ | sed -n 's/release-candidate\/ \( [0-9]\{ 2\}\)\.\( [0-9]\{ 1,2\}\) /\1 .\2 /p')
78+ if [[ "$BRANCH_VERSION" =~ ^[0-9]{2}\. [0-9]$ ]]; then
79+ BRANCH_VERSION=$(echo "$BRANCH_VERSION" \
80+ | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
81+ fi
82+ if (( $(echo "$BRANCH_VERSION > $PR_BASE_VERSION" | bc -l) )); then
83+ TARGET_BRANCHES+=("$branch")
84+ echo "Adding $branch (version $BRANCH_VERSION) as it's higher than $PR_BASE_BRANCH (version $PR_BASE_VERSION)"
8385 fi
8486 done
8587 fi
9092 echo "HOTFIX_BRANCHES<<$DELIMITER" >> $GITHUB_OUTPUT
9193 echo "$HOTFIX_BRANCHES_JSON" >> $GITHUB_OUTPUT
9294 echo "$DELIMITER" >> $GITHUB_OUTPUT
93- echo "Calculated hotfix target branches: ${TARGET_BRANCHES[@]}"
94-
9595
9696 - name: Define Branch Names
9797 id: define_branches
@@ -108,14 +108,19 @@ jobs:
108108 done
109109
110110 # Remove trailing space and store the list
111- branch_list="${branch_list% }"
112- echo "branch_pairs=${branch_list}" >> $GITHUB_OUTPUT
111+ echo "branch_pairs=${branch_list% }" >> $GITHUB_OUTPUT
113112
114113 - name: Create and Process Hotfix Branches
115114 env:
116115 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117116 run: |
118- # Read branch pairs and process each one
117+ # Prepare variables
118+ PR_NUMBER=${{ github.event.pull_request.number }}
119+ PR_URL=${{ github.event.pull_request.html_url }}
120+ PR_AUTHOR=${{ github.event.pull_request.user.login }}
121+ RAW_TITLE="${{ github.event.pull_request.title }}"
122+
123+ # Read branch pairs
119124 IFS=' ' read -r -a PAIRS <<< "${{ steps.define_branches.outputs.branch_pairs }}"
120125
121126 for pair in "${PAIRS[@]}"; do
@@ -153,6 +158,7 @@ jobs:
153158 had_conflicts="false"
154159 fi
155160
161+ # Skip if no changes after cherry-pick
156162 CHANGED_FILES=$(git diff-tree --no-commit-id --name-only -r HEAD)
157163 if [ -z "$CHANGED_FILES" ]; then
158164 echo "Cherry-pick resulted in no changes, skipping PR creation for $base_branch"
@@ -167,31 +173,35 @@ jobs:
167173 if git push origin "$new_branch"; then
168174 echo "Successfully pushed branch $new_branch"
169175
170- # Create PR
171- PR_NUMBER="${{ github.event.pull_request.number }}"
172- PR_URL="${{ github.event.pull_request.html_url }}"
173- PR_AUTHOR="${{ github.event.pull_request.user.login }}"
176+ # Build PR title & body using here-doc + placeholders (preserves backticks, emoji, etc.)
177+ read -r -d '' TEMPLATE <<'EOF'
178+ [Hotfix __BASE_BRANCH__]: __RAW_TITLE__
174179
175- # Adjust PR title based on the target branch
176- if [[ "$base_branch" == "main" ]]; then
177- PR_TITLE="[Hotfix Main]: ${{ github.event.pull_request.title }}"
178- else
179- base_branch_name=${base_branch#"release-candidate/"}
180- PR_TITLE="[Hotfix $base_branch_name]: ${{ github.event.pull_request.title }}"
181- fi
180+ Hotfix of PR #__PR_NUMBER__ (__PR_URL__) to the ` __BASE_BRANCH__` branch.
182181
183- PR_BODY="Hotfix of PR #${PR_NUMBER} (${PR_URL}) to the \`${base_branch}\` branch.
184- Hey @${PR_AUTHOR}, please review this hotfix PR created from your original PR."
182+ Hey @__PR_AUTHOR__, please review this hotfix PR.
183+ __CONFLICT_NOTICE__
184+ EOF
185185
186186 # Add conflict warning if needed
187187 if [[ "$had_conflicts" == "true" ]]; then
188- PR_BODY="${PR_BODY}
189-
190- ### ⚠️ **Note:** This PR had conflicts with the base branch and was resolved automatically. Please review the changes carefully. "
188+ CONFLICT_NOTICE=$'\n\n### ⚠️ **Note:** This PR had conflicts with the base branch and was resolved automatically. Please review the changes carefully.'
189+ else
190+ CONFLICT_NOTICE=" "
191191 fi
192-
192+
193+ # Replace placeholders
194+ PR_BODY="$TEMPLATE"
195+ PR_BODY=${PR_BODY//__BASE_BRANCH__/$base_branch}
196+ PR_BODY=${PR_BODY//__RAW_TITLE__/$RAW_TITLE}
197+ PR_BODY=${PR_BODY//__PR_NUMBER__/$PR_NUMBER}
198+ PR_BODY=${PR_BODY//__PR_URL__/$PR_URL}
199+ PR_BODY=${PR_BODY//__PR_AUTHOR__/$PR_AUTHOR}
200+ PR_BODY=${PR_BODY//__CONFLICT_NOTICE__/$CONFLICT_NOTICE}
201+
202+ # Create PR
193203 gh pr create \
194- --title "$PR_TITLE " \
204+ --title "[Hotfix ${base_branch#release-candidate/}]: $RAW_TITLE " \
195205 --body "$PR_BODY" \
196206 --head "$new_branch" \
197207 --base "$base_branch" \
@@ -201,4 +211,5 @@ jobs:
201211 else
202212 echo "Failed to push branch $new_branch"
203213 fi
204- done
214+ done
215+ ` ` `
0 commit comments