Sync PR #126
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
name: Sync PR | |
on: | |
push: | |
branches: | |
- '8.*.x' | |
schedule: | |
- cron: '33 04 * * 1-5' # 04:33 UTC Mon-Fri | |
workflow_dispatch: | |
inputs: | |
head_branch: | |
description: Branch to merge into master | |
required: true | |
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 |