Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The GitHub Actions workflow `Build, Register and Deploy DMAPP to DMA on PR Merge
- `Frequency` (`id=10`, string): `instant`, `daily`, `weekly`, `monthly`.
- `ClientSecret` (`id=11`, string): Dataverse client secret.
- The notify script does **not** enforce an internal cadence gate; every run processes subscriptions matching the passed `Frequency`.
- Activity detection includes both new and updated activities: a record is included if `createdon > since` OR `modifiedon > since` per subscription.
- New activity detection uses `createdon > LastSentAt` per subscription.
- Sender/from behavior is controlled by DataMiner mail/SMTP configuration.

---
Expand Down
6 changes: 2 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
## Target branch

- [ ] This PR targets `release-candidate` because the work is based on or must be validated in RC first.
- [ ] This PR targets `main` because the work can go directly to production.
- [ ] This PR creates, updates, or deletes Dataverse data and targets `release-candidate`.
- [ ] This PR is read-only and targets `main`.

Use the **base** selector on the pull request page before opening the PR. Promote the complete release candidate with a separate `release-candidate` to `main` pull request.

Keep the PR base aligned with the branch the work started from and its intended release path. Do not rebase RC-based work onto `main` merely to change the PR target.
109 changes: 109 additions & 0 deletions .github/workflows/promote-main-to-release-candidate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Promote main to release candidate

on:
push:
branches: [main]
pull_request_target:
types: [synchronize]
branches: [release-candidate]
workflow_dispatch:

permissions:
contents: write
issues: write
pull-requests: write

concurrency:
group: sync-main-to-release-candidate
cancel-in-progress: false

jobs:
sync:
if: >-
github.event_name == 'push' ||
(github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
(github.event_name == 'pull_request_target' &&
github.event.pull_request.head.ref == 'automation/main-to-release-candidate' &&
github.event.pull_request.head.repo.full_name == github.repository)
runs-on: ubuntu-latest
steps:
- name: Create or reuse promotion 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."
fi
fi

pr_number="$(gh pr list \
--base release-candidate \
--head "$promotion_branch" \
--state open \
--json number \
--jq '.[0].number // empty')"

if [[ -z "$pr_number" ]]; then
pr_number="$(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.')"
fi

echo "number=$pr_number" >> "$GITHUB_OUTPUT"

- name: Try to enable auto-merge
id: merge
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ steps.promotion.outputs.number }}
run: |
merge_state="$(gh pr view "$PR_NUMBER" --json mergeStateStatus --jq '.mergeStateStatus')"

if [[ "$merge_state" == "CONFLICTING" ]]; then
echo "conflicting=true" >> "$GITHUB_OUTPUT"
exit 0
fi

if ! gh pr merge "$PR_NUMBER" --auto --merge 2>/dev/null; then
# Auto-merge requires branch protection rules; fall back to direct merge
gh pr merge "$PR_NUMBER" --merge
fi

- name: Ask Copilot to resolve merge conflicts
if: steps.merge.outputs.conflicting == 'true' || failure()
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ steps.promotion.outputs.number }}
run: |
merge_state="$(gh pr view "$PR_NUMBER" --json mergeStateStatus --jq '.mergeStateStatus')"
if [[ "$merge_state" != "CONFLICTING" ]]; then
exit 1
fi

marker="<!-- automated-main-to-rc-conflict-request -->"
if ! gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \
--paginate \
--jq '.[].body' | grep -Fq "$marker"; then
gh pr comment "$PR_NUMBER" --body "$(cat <<'EOF'
<!-- automated-main-to-rc-conflict-request -->
@copilot Please resolve the merge conflicts in this pull request. The head branch contains the latest `main` changes and the base is `release-candidate`.

Preserve the intended changes from both branches, run the repository's relevant checks, and push the conflict resolution to this pull request's dedicated head branch. Do not merge the pull request yourself; leave it ready for this workflow to auto-merge once it is clean.
EOF
)"
fi

exit 0
82 changes: 0 additions & 82 deletions .github/workflows/sync-main-to-release-candidate.yml

This file was deleted.

Loading