Skip to content

Commit 0a48eee

Browse files
committed
Update update-from-template.yml
xdev-software/java-template#8
1 parent 117e21e commit 0a48eee

File tree

1 file changed

+193
-16
lines changed

1 file changed

+193
-16
lines changed

.github/workflows/update-from-template.yml

Lines changed: 193 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,15 @@ on:
1111
schedule:
1212
- cron: '55 2 * * 1'
1313
workflow_dispatch:
14+
inputs:
15+
no_automatic_merge:
16+
type: boolean
17+
description: 'No automatic merge'
18+
default: false
1419

1520
env:
1621
UPDATE_BRANCH: update-from-template
22+
UPDATE_BRANCH_MERGED: update-from-template-merged
1723
REMOTE_URL: https://github.com/xdev-software/java-template.git
1824
REMOTE_BRANCH: master
1925

@@ -36,31 +42,34 @@ jobs:
3642

3743
- name: Init Git
3844
run: |
39-
git config --global user.email "actions@github.com"
40-
git config --global user.name "GitHub Actions"
45+
git config --global user.email "[email protected].i.8713187.xyz"
46+
git config --global user.name "XDEV Bot"
4147
42-
- name: Main workflow
43-
id: main
48+
- name: Manage branches
49+
id: manage-branches
4450
run: |
4551
echo "Adding remote template-repo"
4652
git remote add template ${{ env.REMOTE_URL }}
4753
4854
echo "Fetching remote template repo"
4955
git fetch template
5056
51-
echo "Deleting local branch that will contain the updates - if present"
57+
echo "Deleting local branches that will contain the updates - if present"
5258
git branch -D ${{ env.UPDATE_BRANCH }} || true
59+
git branch -D ${{ env.UPDATE_BRANCH_MERGED }} || true
5360
5461
echo "Checking if the remote template repo has new commits"
5562
git rev-list ..template/${{ env.REMOTE_BRANCH }}
5663
5764
if [ $(git rev-list --count ..template/${{ env.REMOTE_BRANCH }}) -eq 0 ]; then
5865
echo "There are no commits new commits on the template repo"
5966
60-
echo "Deleting origin branch that contains the updates - if present"
67+
echo "Deleting origin branch(es) that contain the updates - if present"
6168
git push -f origin --delete ${{ env.UPDATE_BRANCH }} || true
69+
git push -f origin --delete ${{ env.UPDATE_BRANCH_MERGED }} || true
6270
63-
echo "abort=1" >> $GITHUB_OUTPUT
71+
echo "create_update_branch_pr=0" >> $GITHUB_OUTPUT
72+
echo "create_update_branch_merged_pr=0" >> $GITHUB_OUTPUT
6473
exit 0
6574
fi
6675
@@ -73,21 +82,189 @@ jobs:
7382
echo "Pushing update branch"
7483
git push -f -u origin ${{ env.UPDATE_BRANCH }}
7584
76-
echo "Getting current branch"
77-
current_branch=$(git branch --show-current)
78-
echo "Current branch is $current_branch"
79-
echo "current_branch=$current_branch" >> $GITHUB_OUTPUT
85+
echo "Getting base branch"
86+
base_branch=$(git branch --show-current)
87+
echo "Base branch is $base_branch"
88+
echo "base_branch=$base_branch" >> $GITHUB_OUTPUT
8089
81-
echo "abort=0" >> $GITHUB_OUTPUT
90+
echo "Trying to create auto-merged branch ${{ env.UPDATE_BRANCH_MERGED }}"
91+
git branch ${{ env.UPDATE_BRANCH_MERGED }} ${{ env.UPDATE_BRANCH }}
92+
git checkout ${{ env.UPDATE_BRANCH_MERGED }}
8293
83-
- name: pull-request
84-
if: steps.main.outputs.abort == 0
94+
echo "Merging branch $base_branch into ${{ env.UPDATE_BRANCH_MERGED }}"
95+
git merge $base_branch && merge_exit_code=$? || merge_exit_code=$?
96+
if [ $merge_exit_code -ne 0 ]; then
97+
echo "Auto merge failed! Manual merge required"
98+
echo "::notice ::Auto merge failed - Manual merge required"
99+
100+
echo "Cleaning up failed merge"
101+
git merge --abort
102+
git checkout $base_branch
103+
git branch -D ${{ env.UPDATE_BRANCH_MERGED }} || true
104+
105+
echo "Deleting auto-merge branch - if present"
106+
git push -f origin --delete ${{ env.UPDATE_BRANCH_MERGED }} || true
107+
108+
echo "create_update_branch_pr=1" >> $GITHUB_OUTPUT
109+
echo "create_update_branch_merged_pr=0" >> $GITHUB_OUTPUT
110+
exit 0
111+
fi
112+
113+
echo "Post processing: Trying to automatically fill in template variables"
114+
find . -type f \
115+
-not -path "./.git/**" \
116+
-not -path "./.github/workflows/update-from-template.yml" -print0 \
117+
| xargs -0 sed -i "s/template-placeholder/${GITHUB_REPOSITORY#*/}/g"
118+
119+
git status
120+
git add --all
121+
122+
if [[ "$(git status --porcelain)" != "" ]]; then
123+
echo "Filled in template; Committing"
124+
125+
git commit -m "Fill in template"
126+
fi
127+
128+
echo "Pushing auto-merged branch"
129+
git push -f -u origin ${{ env.UPDATE_BRANCH_MERGED }}
130+
131+
echo "update_branch_merged_commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
132+
133+
echo "Restoring base branch $base_branch"
134+
git checkout $base_branch
135+
136+
echo "create_update_branch_pr=0" >> $GITHUB_OUTPUT
137+
echo "create_update_branch_merged_pr=1" >> $GITHUB_OUTPUT
138+
139+
- name: PR update_branch
140+
if: steps.manage-branches.outputs.create_update_branch_pr == 1
85141
env:
86-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
142+
GH_TOKEN: ${{ secrets.UPDATE_FROM_TEMPLATE_PAT }}
87143
run: |
88144
gh_pr_up() {
89145
gh pr create -H "${{ env.UPDATE_BRANCH }}" "$@" || (git checkout "${{ env.UPDATE_BRANCH }}" && gh pr edit "$@")
90146
}
91-
gh_pr_up -B "${{ steps.main.outputs.current_branch }}" \
147+
gh_pr_up -B "${{ steps.manage-branches.outputs.base_branch }}" \
92148
--title "Update from template" \
93149
--body "An automated PR to sync changes from the template into this repo"
150+
151+
- name: PR update_branch_merged
152+
if: steps.manage-branches.outputs.create_update_branch_merged_pr == 1
153+
env:
154+
GH_TOKEN: ${{ secrets.UPDATE_FROM_TEMPLATE_PAT }}
155+
run: |
156+
gh_pr_up() {
157+
gh pr create -H "${{ env.UPDATE_BRANCH_MERGED }}" "$@" || (git checkout "${{ env.UPDATE_BRANCH_MERGED }}" && gh pr edit "$@")
158+
}
159+
gh_pr_up -B "${{ steps.manage-branches.outputs.base_branch }}" \
160+
--title "Update from template (auto-merged)" \
161+
--body "An automated PR to sync changes from the template into this repo"
162+
163+
- name: Checking if auto-merge for PR update_branch_merged can be done
164+
id: auto-merge-check
165+
if: steps.manage-branches.outputs.create_update_branch_merged_pr == 1
166+
env:
167+
GH_TOKEN: ${{ secrets.UPDATE_FROM_TEMPLATE_PAT }}
168+
run: |
169+
not_failed_conclusion="skipped|neutral|success"
170+
not_relevant_app_slug="dependabot"
171+
172+
echo "Waiting for workflows to start..."
173+
sleep 60s
174+
175+
for i in {1..15}; do
176+
echo "Checking if PR can be auto-merged. Try: $i"
177+
178+
echo "Fetching checks"
179+
cs_response=$(curl -sL \
180+
--fail-with-body \
181+
--connect-timeout 60 \
182+
--max-time 120 \
183+
-H "Accept: application/vnd.github+json" \
184+
-H "Authorization: Bearer $GH_TOKEN" \
185+
-H "X-GitHub-Api-Version: 2022-11-28" \
186+
https://api.github.com/repos/${{ github.repository }}/commits/${{ steps.manage-branches.outputs.update_branch_merged_commit }}/check-suites)
187+
188+
cs_data=$(echo $cs_response | jq '.check_suites[] | { conclusion: .conclusion, slug: .app.slug, check_runs_url: .check_runs_url }')
189+
echo $cs_data
190+
191+
if [[ -z "$cs_data" ]]; then
192+
echo "No check suite data - Assuming that there are no checks to run"
193+
194+
echo "perform=1" >> $GITHUB_OUTPUT
195+
exit 0
196+
fi
197+
198+
cs_failed=$(echo $cs_data | jq --arg x "$not_failed_conclusion" 'select ((.conclusion == null or (.conclusion | test($x))) | not)')
199+
if [[ -z "$cs_failed" ]]; then
200+
echo "No check failed so far; Checking if relevant checks are still running"
201+
202+
cs_relevant_still_running=$(echo $cs_data | jq --arg x "$not_relevant_app_slug" 'select (.conclusion == null and (.slug | test($x) | not))')
203+
if [[ -z $cs_relevant_still_running ]]; then
204+
echo "All relevant checks finished - PR can be merged"
205+
206+
echo "perform=1" >> $GITHUB_OUTPUT
207+
exit 0
208+
else
209+
echo "Relevant checks are still running"
210+
echo $cs_relevant_still_running
211+
fi
212+
else
213+
echo "Detected failed check"
214+
echo $cs_failed
215+
216+
echo "perform=0" >> $GITHUB_OUTPUT
217+
exit 0
218+
fi
219+
220+
echo "Waiting before next run..."
221+
sleep 60s
222+
done
223+
224+
echo "Timed out"
225+
echo "perform=0" >> $GITHUB_OUTPUT
226+
227+
- name: Auto-merge update_branch_merged
228+
if: steps.auto-merge-check.outputs.perform == 1
229+
run: |
230+
base_branch="${{ steps.manage-branches.outputs.base_branch }}"
231+
echo "Restoring base branch $base_branch"
232+
git checkout $base_branch
233+
234+
echo "Fetching..."
235+
git fetch
236+
237+
expected_commit="${{ steps.manage-branches.outputs.update_branch_merged_commit }}"
238+
actual_commit=$(git rev-parse origin/${{ env.UPDATE_BRANCH_MERGED }})
239+
if [[ "$expected_commit" != "$actual_commit" ]]; then
240+
echo "Branch ${{ env.UPDATE_BRANCH_MERGED }} contains unexpected commit $actual_commit"
241+
echo "Expected: $expected_commit"
242+
243+
exit 0
244+
fi
245+
246+
echo "Ensuring that current branch $base_branch is up-to-date"
247+
git pull
248+
249+
echo "Merging ${{ env.UPDATE_BRANCH_MERGED }} into $base_branch"
250+
git merge ${{ env.UPDATE_BRANCH_MERGED }} && merge_exit_code=$? || merge_exit_code=$?
251+
if [ $merge_exit_code -ne 0 ]; then
252+
echo "Unexpected merge failure $merge_exit_code - Requires manual resolution"
253+
254+
exit 0
255+
fi
256+
257+
if [[ "${{ inputs.no_automatic_merge }}" == "true" ]]; then
258+
echo "Exiting due no_automatic_merge"
259+
260+
exit 0
261+
fi
262+
263+
echo "Pushing"
264+
git push
265+
266+
echo "Cleaning up"
267+
git branch -D ${{ env.UPDATE_BRANCH }} || true
268+
git branch -D ${{ env.UPDATE_BRANCH_MERGED }} || true
269+
git push -f origin --delete ${{ env.UPDATE_BRANCH }} || true
270+
git push -f origin --delete ${{ env.UPDATE_BRANCH_MERGED }} || true

0 commit comments

Comments
 (0)