Skip to content

Commit d33a0e6

Browse files
committed
Manual mirror of syncbot yaml file.
1 parent 100505a commit d33a0e6

1 file changed

Lines changed: 148 additions & 0 deletions

File tree

.github/workflows/syncbot.yml

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
name: Branch sync
2+
3+
on:
4+
pull_request_target:
5+
branches:
6+
- main
7+
- ootb
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
mirror-changes:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v6
18+
19+
- name: Get target branch
20+
id: target-branch
21+
run: |
22+
if [ "${{ github.base_ref }}" == "main" ]; then
23+
echo "branch=ootb" >> $GITHUB_OUTPUT
24+
else
25+
echo "branch=main" >> $GITHUB_OUTPUT
26+
fi
27+
echo "Target branch for sync: $(cat $GITHUB_OUTPUT | grep branch | cut -d= -f2)"
28+
29+
- name: Cherry-pick commits to target branch
30+
id: cherry-pick
31+
env:
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
run: |
35+
git config user.name syncbot
36+
git config user.email github-actions@github.com
37+
38+
# Fetch all branches and the PR head (which may be from a fork)
39+
git fetch origin
40+
git fetch origin pull/${{ github.event.pull_request.number }}/head
41+
42+
# Get the source branch name and target branch
43+
SOURCE_BRANCH="${{ github.head_ref }}"
44+
TARGET_BRANCH="${{ steps.target-branch.outputs.branch }}"
45+
SYNC_BRANCH="sync-${SOURCE_BRANCH}-to-${TARGET_BRANCH}"
46+
47+
echo "Source branch: $SOURCE_BRANCH"
48+
echo "Target branch: $TARGET_BRANCH"
49+
echo "Sync branch: $SYNC_BRANCH"
50+
51+
# Store branch names for next step
52+
echo "source_branch=$SOURCE_BRANCH" >> $GITHUB_OUTPUT
53+
echo "target_branch=$TARGET_BRANCH" >> $GITHUB_OUTPUT
54+
echo "sync_branch=$SYNC_BRANCH" >> $GITHUB_OUTPUT
55+
56+
# Delete local sync branch if it exists
57+
git branch -D $SYNC_BRANCH 2>/dev/null || true
58+
59+
# Create sync branch from target branch (will reset if remote exists)
60+
git checkout -b $SYNC_BRANCH origin/$TARGET_BRANCH
61+
62+
# Get only the commits that are part of the PR
63+
COMMITS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits --jq '.[].sha')
64+
65+
# Cherry-pick each commit
66+
echo "Cherry-picking commits..."
67+
SKIPPED_COMMITS=""
68+
for commit in $COMMITS; do
69+
echo "Cherry-picking $commit"
70+
git cherry-pick $commit || {
71+
# If the cherry-pick is empty (change already exists on target), skip it
72+
if git diff --cached --quiet; then
73+
echo "Cherry-pick of $commit is empty (already applied), skipping"
74+
git cherry-pick --skip
75+
else
76+
echo "Cherry-pick of $commit conflicted, skipping"
77+
git cherry-pick --abort
78+
SKIPPED_COMMITS="$SKIPPED_COMMITS $commit"
79+
fi
80+
}
81+
done
82+
83+
if [ -n "$SKIPPED_COMMITS" ]; then
84+
echo "skipped_commits=$SKIPPED_COMMITS" >> $GITHUB_OUTPUT
85+
echo "Some commits were skipped due to conflicts:$SKIPPED_COMMITS"
86+
fi
87+
88+
echo "Cherry-pick complete"
89+
90+
- name: Push sync branch and create PR
91+
env:
92+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
94+
run: |
95+
SOURCE_BRANCH="${{ steps.cherry-pick.outputs.source_branch }}"
96+
TARGET_BRANCH="${{ steps.cherry-pick.outputs.target_branch }}"
97+
SYNC_BRANCH="${{ steps.cherry-pick.outputs.sync_branch }}"
98+
SKIPPED="${{ steps.cherry-pick.outputs.skipped_commits }}"
99+
100+
# Push the sync branch
101+
git push origin $SYNC_BRANCH --force
102+
echo "Successfully pushed sync branch"
103+
104+
# Create PR using GitHub CLI
105+
PR_TITLE="[Sync] $(gh pr view ${{ github.event.pull_request.number }} --json title --jq .title)"
106+
PR_BODY="Automated sync of PR #${{ github.event.pull_request.number }} from \`$SOURCE_BRANCH\` to \`$TARGET_BRANCH\`
107+
108+
Syncbot will not be offended if the sync isn't appropriate and you close this PR.
109+
110+
Original PR: #${{ github.event.pull_request.number }}"
111+
112+
if [ -n "$SKIPPED" ]; then
113+
PR_BODY="$PR_BODY
114+
115+
**Note:** The following commits were skipped due to conflicts and may need manual syncing:
116+
$(for sha in $SKIPPED; do echo "- \`$sha\`"; done)"
117+
fi
118+
119+
# Check if PR already exists
120+
EXISTING_PR=$(gh pr list --head $SYNC_BRANCH --base $TARGET_BRANCH --json number --jq '.[0].number' || echo "")
121+
122+
if [ -n "$EXISTING_PR" ]; then
123+
echo "PR already exists: #$EXISTING_PR"
124+
gh pr edit $EXISTING_PR --body "$PR_BODY"
125+
else
126+
NEW_PR=$(gh pr create --base $TARGET_BRANCH --head $SYNC_BRANCH --title "$PR_TITLE" --body "$PR_BODY" --label "sync")
127+
echo "Created new PR: $NEW_PR"
128+
fi
129+
130+
- name: Update PR comment on success
131+
if: steps.cherry-pick.outputs.skipped_commits == ''
132+
uses: quarkusio/action-helpers@main
133+
with:
134+
action: maintain-one-comment
135+
github-token: ${{ secrets.GITHUB_TOKEN }}
136+
body: |
137+
🤖 This PR has been synchronized to the `${{ steps.cherry-pick.outputs.target_branch }}` branch. 🔄
138+
pr-number: ${{ github.event.pull_request.number }}
139+
140+
- name: Update PR comment on partial sync
141+
if: steps.cherry-pick.outputs.skipped_commits != ''
142+
uses: quarkusio/action-helpers@main
143+
with:
144+
action: maintain-one-comment
145+
github-token: ${{ secrets.GITHUB_TOKEN }}
146+
body: |
147+
🤖 This PR has been partially synchronized to the `${{ steps.cherry-pick.outputs.target_branch }}` branch. Some commits were skipped due to conflicts and may need manual syncing. 🔄
148+
pr-number: ${{ github.event.pull_request.number }}

0 commit comments

Comments
 (0)