Skip to content

[Hotfix] [SCFD-5640] Separating the time averaged output from non time averaged ones in translated JSON (#1263) #118

[Hotfix] [SCFD-5640] Separating the time averaged output from non time averaged ones in translated JSON (#1263)

[Hotfix] [SCFD-5640] Separating the time averaged output from non time averaged ones in translated JSON (#1263) #118

name: Create Hotfix PR
on:
pull_request:
types:
- closed # Trigger when a PR is closed
branches:
- 'release-candidate/*' # Trigger for any branch starting with 'release-candidate/'
jobs:
create_hotfix_pr:
# Only run this job if the PR was actually merged
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write # To push branches and commit changes
pull-requests: write # To create the pull request
env:
BOT_NAME: "flow360-auto-hotfix-bot" # Name for the git committer
BOT_EMAIL: "[email protected]" # Email for the git committer
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
run: |
git config user.name "${{ env.BOT_NAME }}"
git config user.email "${{ env.BOT_EMAIL }}"
- name: Get Merged Commit SHA (Assuming Squash Merge)
id: get_commit
# This SHA reliably points to the single commit if squash-and-merge was used.
# If using merge commits, this SHA points to the merge commit itself,
# which might be harder to cherry-pick cleanly.
run: |
echo "sha=${{ github.event.pull_request.merge_commit_sha }}" >> $GITHUB_OUTPUT
echo "branch_name=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
echo "base_branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT
- name: Get Hotfix Target Branches
id: get_target_branches
run: |
PR_BASE_BRANCH="${{ steps.get_commit.outputs.base_branch }}"
echo "PR was merged into: $PR_BASE_BRANCH"
TARGET_BRANCHES=("main") # Always target main for hotfix
# Get all remote 'release-candidate' branches with version pattern as YY.I or YY.II
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)
echo "Found release-candidate branches: $ALL_RELEASE_CANDIDATE_BRANCHES"
# Determine the version of the current PR's base branch
# Example: release-candidate/25.5 -> 25.05 (for proper numerical comparison)
PR_BASE_VERSION=$(echo "$PR_BASE_BRANCH" | sed -n 's/release-candidate\/\([0-9]\{2\}\)\.\([0-9]\{1,2\}\)/\1.\2/p')
# Handle cases like 25.5 vs 25.05 for comparison
if [[ "$PR_BASE_VERSION" =~ ^[0-9]{2}\.[0-9]$ ]]; then
PR_BASE_VERSION=$(echo "$PR_BASE_VERSION" | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
fi
if [[ -n "$PR_BASE_VERSION" ]]; then
echo "Base branch version: $PR_BASE_VERSION"
for branch in $ALL_RELEASE_CANDIDATE_BRANCHES; do
# Extract version for comparison
BRANCH_VERSION=$(echo "$branch" | sed -n 's/release-candidate\/\([0-9]\{2\}\)\.\([0-9]\{1,2\}\)/\1.\2/p')
if [[ -n "$BRANCH_VERSION" ]]; then
if [[ "$BRANCH_VERSION" =~ ^[0-9]{2}\.[0-9]$ ]]; then
BRANCH_VERSION=$(echo "$BRANCH_VERSION" | awk '{printf "%s%02d", substr($1,1,3), substr($1,4)}')
fi
# Compare versions
if (( $(echo "$BRANCH_VERSION > $PR_BASE_VERSION" | bc -l) )); then
TARGET_BRANCHES+=("$branch")
echo "Adding $branch (version $BRANCH_VERSION) as it's higher than $PR_BASE_BRANCH (version $PR_BASE_VERSION)"
fi
fi
done
fi
# Prepare output for next step
HOTFIX_BRANCHES_JSON=$(printf '%s\n' "${TARGET_BRANCHES[@]}" | jq -R . | jq -s .)
DELIMITER=$(uuidgen) # Generate a unique delimiter
echo "HOTFIX_BRANCHES<<$DELIMITER" >> $GITHUB_OUTPUT
echo "$HOTFIX_BRANCHES_JSON" >> $GITHUB_OUTPUT
echo "$DELIMITER" >> $GITHUB_OUTPUT
echo "Calculated hotfix target branches: ${TARGET_BRANCHES[@]}"
- name: Define Branch Names
id: define_branches
run: |
ORIGINAL_PR_NUMBER=${{ github.event.pull_request.number }}
# Convert JSON array to space-separated list
BRANCHES=$(echo '${{ steps.get_target_branches.outputs.HOTFIX_BRANCHES }}' | jq -r '.[]')
# Create outputs for all branches
branch_list=""
for branch in $BRANCHES; do
new_branch="hotfix-${branch//\//-}-pr${ORIGINAL_PR_NUMBER}" # Replace '/' with '-' for new branch name
branch_list+="${branch}:${new_branch} "
done
# Remove trailing space and store the list
branch_list="${branch_list% }"
echo "branch_pairs=${branch_list}" >> $GITHUB_OUTPUT
- name: Create and Process Hotfix Branches
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
# Read branch pairs and process each one
IFS=' ' read -r -a PAIRS <<< "${{ steps.define_branches.outputs.branch_pairs }}"
for pair in "${PAIRS[@]}"; do
IFS=':' read -r base_branch new_branch <<< "$pair"
echo "Processing hotfix for branch: $base_branch"
# Create and switch to new branch
git checkout "$base_branch"
git pull origin "$base_branch"
git checkout -b "$new_branch"
# Attempt cherry-pick
if ! git cherry-pick ${{ steps.get_commit.outputs.sha }} --empty=keep; then
echo "Cherry-pick encountered conflicts for $base_branch, attempting to resolve..."
git add -A
# Check if there are actual changes staged after conflict resolution attempt
if git diff --cached --quiet; then
echo "Conflict resolution resulted in no changes. Aborting cherry-pick."
git cherry-pick --abort
continue # Skip PR creation if no changes after resolution
fi
git cherry-pick --continue
if [ $? -eq 0 ]; then
echo "Successfully resolved conflicts for $base_branch"
had_conflicts="true"
else
echo "Failed to resolve conflicts for $base_branch"
git cherry-pick --abort
continue
fi
else
echo "Cherry-pick successful for $base_branch"
had_conflicts="false"
fi
CHANGED_FILES=$(git diff-tree --no-commit-id --name-only -r HEAD)
if [ -z "$CHANGED_FILES" ]; then
echo "Cherry-pick resulted in no changes, skipping PR creation for $base_branch"
git reset --hard HEAD^ # Discard the empty commit if one was created by cherry-pick
continue
fi
echo "Changed files:"
echo "$CHANGED_FILES"
# Push branch
if git push origin "$new_branch"; then
echo "Successfully pushed branch $new_branch"
# Create PR
PR_NUMBER="${{ github.event.pull_request.number }}"
PR_URL="${{ github.event.pull_request.html_url }}"
PR_AUTHOR="${{ github.event.pull_request.user.login }}"
# Adjust PR title based on the target branch
if [[ "$base_branch" == "main" ]]; then
HOTFIX_PR_TITLE="[Hotfix Main]: $PR_TITLE"
else
base_branch_name=${base_branch#"release-candidate/"}
HOTFIX_PR_TITLE="[Hotfix $base_branch_name]: $PR_TITLE"
fi
PR_BODY="Hotfix of PR #${PR_NUMBER} (${PR_URL}) to the \`${base_branch}\` branch.
Hey @${PR_AUTHOR}, please review this hotfix PR created from your original PR."
# Add conflict warning if needed
if [[ "$had_conflicts" == "true" ]]; then
PR_BODY="${PR_BODY}
### ⚠️ **Note:** This PR had conflicts with the base branch and was resolved automatically. Please review the changes carefully."
fi
# Create PR using gh cli
gh pr create \
--title "$HOTFIX_PR_TITLE" \
--body "$PR_BODY" \
--head "$new_branch" \
--base "$base_branch" \
--label "auto-hotfix" \
--assignee "$PR_AUTHOR" \
--draft
else
echo "Failed to push branch $new_branch"
fi
done