diff --git a/.github/workflows/promote-main-to-release-candidate.yml b/.github/workflows/promote-main-to-release-candidate.yml
index 8658aa6..5d005bc 100644
--- a/.github/workflows/promote-main-to-release-candidate.yml
+++ b/.github/workflows/promote-main-to-release-candidate.yml
@@ -27,22 +27,37 @@ jobs:
github.event.pull_request.head.repo.full_name == github.repository)
runs-on: ubuntu-latest
steps:
- - name: Create or reuse promotion pull request
+ - name: Check out main
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Update the promotion branch and create or reuse its pull request
id: promotion
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
promotion_branch="automation/main-to-release-candidate"
- main_sha="$(gh api "repos/${GITHUB_REPOSITORY}/git/ref/heads/main" --jq '.object.sha')"
- if ! gh api --method POST "repos/${GITHUB_REPOSITORY}/git/refs" \
- -f "ref=refs/heads/${promotion_branch}" \
- -f "sha=${main_sha}"; then
- if ! gh api --method PATCH "repos/${GITHUB_REPOSITORY}/git/refs/heads/${promotion_branch}" \
- -f "sha=${main_sha}" \
- -F force=false; then
- echo "Promotion branch has diverged from main; leaving it unchanged for conflict resolution."
+ conflict=false
+ git fetch origin main
+
+ if git ls-remote --exit-code --heads origin "$promotion_branch" >/dev/null; then
+ git fetch origin "$promotion_branch"
+ git switch --force-create "$promotion_branch" "origin/$promotion_branch"
+
+ if ! git merge-base --is-ancestor origin/main HEAD; then
+ if git merge --no-edit origin/main; then
+ git push origin "HEAD:refs/heads/${promotion_branch}"
+ else
+ git merge --abort
+ conflict=true
+ echo "::warning::Merge conflict detected between main and the promotion branch."
+ fi
fi
+ else
+ git switch --create "$promotion_branch" origin/main
+ git push origin "HEAD:refs/heads/${promotion_branch}"
fi
pr_number="$(gh pr list \
@@ -52,19 +67,27 @@ jobs:
--json number \
--jq '.[0].number // empty')"
- if [[ -z "$pr_number" ]]; then
- pr_url="$(gh pr create \
- --base release-candidate \
- --head "$promotion_branch" \
- --title "Sync main into release-candidate" \
- --body $'Automated promotion of the latest main branch changes into release-candidate.\n\nThis pull request is maintained by the Promote main to release candidate workflow. Its dedicated branch allows Copilot to resolve conflicts without modifying the default branch.')"
- pr_number="${pr_url##*/}"
+ if [[ -z "$pr_number" && "$conflict" == false ]]; then
+ git fetch origin release-candidate
+ if [[ -z "$(git log --format=%H origin/release-candidate..HEAD)" ]]; then
+ echo "::notice::release-candidate already contains all commits from the promotion branch."
+ echo "no_changes=true" >> "$GITHUB_OUTPUT"
+ else
+ pr_url="$(gh pr create \
+ --base release-candidate \
+ --head "$promotion_branch" \
+ --title "Sync main into release-candidate" \
+ --body $'Automated promotion of the latest main branch changes into release-candidate.\n\nThis pull request is maintained by the Promote main to release candidate workflow. Its dedicated branch allows Copilot to resolve conflicts without modifying the default branch.')"
+ pr_number="${pr_url##*/}"
+ fi
fi
echo "number=$pr_number" >> "$GITHUB_OUTPUT"
+ echo "conflicting=$conflict" >> "$GITHUB_OUTPUT"
- name: Try to enable auto-merge
id: merge
+ if: steps.promotion.outputs.number != ''
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
@@ -86,7 +109,7 @@ jobs:
fi
- name: Ask Copilot to resolve merge conflicts
- if: steps.merge.outputs.conflicting == 'true' || failure()
+ if: steps.promotion.outputs.number != '' && (steps.promotion.outputs.conflicting == 'true' || steps.merge.outputs.conflicting == 'true')
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
diff --git a/DynamicsActivitiesPackage/DynamicsActivitiesPackage/DynamicsActivitiesPackage.csproj b/DynamicsActivitiesPackage/DynamicsActivitiesPackage/DynamicsActivitiesPackage.csproj
index 580fc98..7b30eae 100644
--- a/DynamicsActivitiesPackage/DynamicsActivitiesPackage/DynamicsActivitiesPackage.csproj
+++ b/DynamicsActivitiesPackage/DynamicsActivitiesPackage/DynamicsActivitiesPackage.csproj
@@ -8,8 +8,8 @@
True
10.3.0.0 - 12752
- 1.8.92
- Fix promote-main-to-rc workflow: handle conflicts gracefully without failing the job
+ 1.8.93
+ Fix main-to-release-candidate promotion branch synchronization
skyline:sdk:dataminertoken
skyline:sdk:dataminertoken
diff --git a/README.md b/README.md
index 0329a1f..8582504 100644
--- a/README.md
+++ b/README.md
@@ -219,7 +219,7 @@ and the frontend build base path is set to `/public/DynamicsActivitiesDev/` so s
| `.github/workflows/deploy-dma-on-pr-merge.yml` | Caller workflow for production-on-merge, manual `production` from `main` only, and manual `dev` deploys |
| `.github/workflows/deploy-dmapp-reusable.yml` | Reusable build/register/deploy workflow for DMAPP packaging and Catalog deployment |
| `.github/workflows/copilot-bug-triage.yml` | Auto-comments on `bug`-labeled issues to ask `@copilot` for investigation |
-| `.github/workflows/promote-main-to-release-candidate.yml` | Opens or updates the `main` → `release-candidate` promotion PR after changes reach `main`, using a dedicated branch so `@copilot` can resolve conflicts without modifying `main` |
+| `.github/workflows/promote-main-to-release-candidate.yml` | Merges `main` into its dedicated promotion branch before opening or updating the `main` → `release-candidate` PR, preserving conflict-resolution commits and skipping a PR when release-candidate already contains its changes |
### Release candidate deployment