-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from MetRonnie/branch-sync
Add branch sync reusable workflow
- Loading branch information
Showing
1 changed file
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# This is a reusable workflow, rather than an action | ||
|
||
name: Sync PR | ||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
head_branch: | ||
type: string | ||
required: false | ||
|
||
jobs: | ||
sync: | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 5 | ||
env: | ||
BASE_BRANCH: master | ||
HEAD_BRANCH: ${{ inputs.head_branch || github.ref_name }} | ||
STATUS_JSON: https://raw.githubusercontent.com/cylc/cylc-admin/master/docs/status/branches.json | ||
FORCE_COLOR: 2 | ||
steps: | ||
- name: Check branch name | ||
shell: python | ||
run: | | ||
import os | ||
import json | ||
import sys | ||
from urllib.request import urlopen | ||
if os.environ['GITHUB_EVENT_NAME'] == 'schedule': | ||
# Get branch from status page | ||
meta = json.loads( | ||
urlopen(os.environ['STATUS_JSON']).read() | ||
)['meta_releases'] | ||
version = min(meta) | ||
branch = meta[version][os.environ['GITHUB_REPOSITORY']] | ||
else: | ||
branch = os.environ['HEAD_BRANCH'].strip() | ||
if branch.endswith('-sync'): | ||
sys.exit("::error::Do not run this workflow for already-created sync branches") | ||
with open(os.environ['GITHUB_ENV'], 'a') as F: | ||
print(f'HEAD_BRANCH={branch}', file=F) | ||
print(f'SYNC_BRANCH={branch}-sync', file=F) | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
ref: master | ||
|
||
- name: Configure git | ||
uses: cylc/release-actions/configure-git@v1 | ||
|
||
- name: Checkout sync branch if it exists | ||
continue-on-error: true | ||
run: | | ||
git switch -c "$SYNC_BRANCH" "origin/${SYNC_BRANCH}" | ||
echo "BASE_BRANCH=$SYNC_BRANCH" >> "$GITHUB_ENV" | ||
- name: Attempt fast-forward | ||
id: ff | ||
run: | | ||
if git merge "origin/${HEAD_BRANCH}" --ff-only; then | ||
if [[ "$(git rev-parse HEAD)" == "$(git rev-parse "origin/${BASE_BRANCH}")" ]]; then | ||
echo "::notice::$BASE_BRANCH is up to date with $HEAD_BRANCH" | ||
exit 0 | ||
fi | ||
git push origin "$BASE_BRANCH" | ||
elif [[ "$BASE_BRANCH" == "$SYNC_BRANCH" ]]; then | ||
echo "::notice::Cannot fast-forward $BASE_BRANCH to $HEAD_BRANCH; merge existing PR first" | ||
else | ||
echo "continue=true" >> "$GITHUB_OUTPUT" | ||
fi | ||
- name: Attempt merge into master | ||
id: merge | ||
if: steps.ff.outputs.continue | ||
run: | | ||
git switch master | ||
if git merge "origin/${HEAD_BRANCH}"; then | ||
if git diff HEAD^ --exit-code --stat; then | ||
echo "::notice::No diff between master and $HEAD_BRANCH" | ||
exit 0 | ||
fi | ||
else | ||
git merge --abort | ||
fi | ||
echo "continue=true" >> $GITHUB_OUTPUT | ||
- name: Push sync branch | ||
id: push | ||
if: steps.merge.outputs.continue | ||
run: | | ||
git switch -c "$SYNC_BRANCH" "origin/${HEAD_BRANCH}" | ||
git push origin "$SYNC_BRANCH" | ||
echo "continue=true" >> $GITHUB_OUTPUT | ||
- name: Open PR | ||
if: steps.push.outputs.continue | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
BODY: | | ||
Please do a **normal merge**, not squash merge. | ||
Please fix conflicts if necessary. | ||
--- | ||
Triggered by `${{ github.event_name }}` | ||
run: | | ||
url="$( | ||
gh pr create --head "$SYNC_BRANCH" \ | ||
--title "🤖 Merge ${SYNC_BRANCH} into master" \ | ||
--body "$BODY" | ||
)" | ||
echo "::notice::PR created at ${url}" | ||
gh pr edit "$SYNC_BRANCH" --add-label "sync" || true |