Repository navigation
104 lines (91 loc) · 4.34 KB
/
Copy pathforward-merge.yml
File metadata and controls
104 lines (91 loc) · 4.34 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
name: Forward Merge
# Keeps next containing dev (RFD #142): each push to dev is merged into next.
# It pushes with the DEV_NEXT_MERGE_KEY deploy key, the only non-admin allowed
# to bypass the next ruleset. When the merge conflicts it opens a
# "Merge dev into next" PR from dev-into-next instead, and conflicts are
# resolved on that branch, never on dev. Merge that PR with a merge commit
# only: a squash would drop dev's history from next.
on:
push:
branches:
- dev
workflow_dispatch:
permissions:
contents: read
pull-requests: write
actions: write
statuses: write
concurrency:
group: forward-merge
cancel-in-progress: false
env:
MERGE_BRANCH: dev-into-next
jobs:
forward-merge:
name: Merge dev into next
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ssh-key: ${{ secrets.DEV_NEXT_MERGE_KEY }}
- name: Merge dev into next, or open a PR on conflict
env:
GH_TOKEN: ${{ github.token }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git fetch origin dev next
git fetch origin "$MERGE_BRANCH" 2>/dev/null || true
lease=$(git rev-parse -q --verify "origin/$MERGE_BRANCH" || true)
if git merge-base --is-ancestor origin/dev origin/next; then
echo "next already contains dev."
exit 0
fi
pr=$(gh pr list --base next --head "$MERGE_BRANCH" --state open --json number --jq '.[0].number // empty')
# While a PR is open, keep going through it so work done on the
# branch is not bypassed. Any failure to merge directly opens one, so
# it shows up there instead of only as a failed run.
if [ -z "$pr" ]; then
git switch -C next origin/next
if git merge --no-edit origin/dev; then
if git push origin next; then
echo "Merged dev into next."
exit 0
fi
reason="Pushing the merge to \`next\` failed, most likely because a PR merged into \`next\` at the same time. Merge this PR if it is clean."
else
git merge --abort
reason="\`dev\` does not merge cleanly into \`next\`. Resolve the conflicts on \`$MERGE_BRANCH\` by merging \`origin/next\` into it, never on \`dev\`."
fi
echo "::warning::Could not merge dev into next directly, opening a PR. $reason"
fi
if [ -n "$pr" ] && [ -n "$lease" ] && \
! git merge-base --is-ancestor "origin/$MERGE_BRANCH" origin/dev; then
# Someone already resolved conflicts on the branch: build on that.
git switch -C "$MERGE_BRANCH" "origin/$MERGE_BRANCH"
if ! git merge --no-edit origin/dev; then
git merge --abort
gh pr comment "$pr" --body "dev moved to $(git rev-parse --short origin/dev) and does not merge cleanly into \`$MERGE_BRANCH\`. Merge \`dev\` into \`$MERGE_BRANCH\` by hand."
exit 0
fi
git push origin "$MERGE_BRANCH"
head=$(git rev-parse HEAD)
# testing.yml does not run on pushes to this branch.
gh workflow run testing.yml --ref "$MERGE_BRANCH"
else
# The branch is dev itself, so the checks already run on dev apply.
git push --force-with-lease="$MERGE_BRANCH:$lease" origin "origin/dev:refs/heads/$MERGE_BRANCH"
head=$(git rev-parse origin/dev)
fi
# Required on next, but the branch-policy job never runs for this PR
# because PRs opened with GITHUB_TOKEN do not trigger workflows.
gh api "repos/$GITHUB_REPOSITORY/statuses/$head" \
-f state=success -f context="Forward merge not conflicted" \
-f description="This is the forward merge PR" > /dev/null
if [ -z "$pr" ]; then
gh pr create --base next --head "$MERGE_BRANCH" \
--title "Merge dev into next" \
--body "Automatic forward merge of \`dev\` into \`next\` failed (RFD #142). $reason Merge with **Create a merge commit**, never squash. Until this PR is merged, other PRs into \`next\` are blocked and automatic forward merges pause."
fi