Repository navigation
119 lines (104 loc) · 5.13 KB
/
Copy pathsync-main-to-develop.yml
File metadata and controls
119 lines (104 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Keep develop from drifting behind main.
#
# The normal direction is develop -> main: work lands on develop, gets tested,
# and the owner promotes it. main only moves ahead of develop when something
# skipped that path - a hotfix applied directly, or the merge commit a release
# creates. Left alone, develop then silently lacks a fix that is already live,
# and the next contributor branches from a tree that is missing it.
#
# This opens a pull request rather than pushing. Both branches are restricted to
# the owner on purpose, and a workflow that force-pushed past that would make
# the protection a decoration. The owner stays the only thing that merges;
# this only notices and asks.
name: Sync main to develop
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: sync-main-to-develop
cancel-in-progress: true
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Is develop actually behind?
id: check
run: |
git fetch origin main develop
# Commits on main that develop does not have. Zero is the normal
# case - after a release develop already contains everything.
BEHIND=$(git rev-list --count origin/develop..origin/main)
echo "behind=$BEHIND" >> "$GITHUB_OUTPUT"
echo "develop is $BEHIND commit(s) behind main"
- name: Open or update the sync pull request
if: steps.check.outputs.behind != '0'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH="sync/main-to-develop"
# A real merge, not a reset: develop may carry work main has never
# seen, and resetting it to main would delete that silently.
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -B "$BRANCH" origin/develop
if git merge --no-edit origin/main; then
CONFLICT=""
else
# Conflicts are left in the branch deliberately. A person has to
# resolve them, and hiding that by aborting would leave develop
# quietly behind with nothing to show for it.
git merge --abort || true
git checkout -B "$BRANCH" origin/main
CONFLICT=" (main had conflicts with develop - this branch is main, so review carefully)"
fi
git push -f origin "$BRANCH"
BODY="main has moved ahead of develop by ${{ steps.check.outputs.behind }} commit(s)${CONFLICT}.
That normally means a hotfix went straight to main, or this is the merge a release created. Either way develop should pick it up, or the next contributor branches from a tree that is missing a fix which is already live.
Nothing here is new work - it is main's own commits."
# ------------------------------------------------------------------
# THIS CANNOT OPEN THE PULL REQUEST, AND THAT IS A REPOSITORY SETTING.
#
# "GitHub Actions is not permitted to create or approve pull requests"
# is off here, so `gh pr create` fails on every run that gets this
# far. It has failed on every release this workflow has ever seen -
# #644, #651, #665 - and each failure read as though the sync itself
# had broken. It had not: the branch pushed above is correct and
# ready every time.
#
# The cost was never the red mark. It was that develop stayed behind
# main after each release, so the NEXT release pull request opened
# "out-of-date with the base branch" and somebody had to work that out
# from a workflow log nobody reads. release-promote.yml is blocked by
# the same setting.
#
# So this stops asking for a permission it will never be given. It
# still tries, in case the setting is turned on one day, but a refusal
# no longer fails the run. What the owner actually needs is a link,
# and it goes in the run summary where they are already looking while
# a release is in progress.
# ------------------------------------------------------------------
OPEN=$(gh pr list --head "$BRANCH" --state open --json number --jq 'length' || echo 1)
if [ "$OPEN" = "0" ]; then
gh pr create --base develop --head "$BRANCH" \
--title "Sync main into develop" --body "$BODY" \
--label "area: contributor" || echo "could not open it here; see the summary"
else
echo "a sync pull request is already open"
fi
# Said plainly whether the above worked or not.
{
echo "### develop is ${{ steps.check.outputs.behind }} commit(s) behind main"
echo
echo "$BODY"
echo
echo "Branch **$BRANCH** is pushed and ready."
echo
echo "[Open the sync pull request](https://github.com/$GITHUB_REPOSITORY/compare/develop...$BRANCH?expand=1)"
} >> "$GITHUB_STEP_SUMMARY"