-
Notifications
You must be signed in to change notification settings - Fork 221
215 lines (189 loc) · 9.63 KB
/
forward-merge.yml
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
name: 'forward-merge'
on:
workflow_dispatch:
push:
branches:
- support
- master
- prerelease/minor
jobs:
get-branch-names:
# Only run if:
# - commit contains '[skip release]' (release commits or commits that skipped a release)
# - branch is prerelease/minor
#
# We don't want to run a forward merge on support/master on commits that will trigger a release.
# This would cause forward merge to run twice (once for normal commit, and one for the release)
# commit. `prerelease/minor` branch does not create release commits, so those branches are safe
# to forward-merge. A release commit looks like "chore: Release vx.x.x [skip release]" and all
# commits that skip the release action also contain "[skip release]". We will run forward merge
# on any commit that will not trigger another commit
if:
startsWith(github.ref_name, 'prerelease/') || contains(github.event.head_commit.message,
'[skip release]')
runs-on: ubuntu-latest
outputs: # Output branch names for the make-pull-request job
branch: ${{steps.extract-branch.outputs.branch}}
next-branch: ${{steps.extract-next-branch.outputs.branch}}
steps:
## `github.ref` is in the form of `refs/head/{name}`. This step extracts `{name}` and saves it
## as an output for later use
- name: Extract branch name
id: extract-branch
run: |
echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_OUTPUT"
- name: Extract next branch name
id: extract-next-branch
uses: Workday/canvas-kit-actions/get-next-branch@v1
with:
branch: ${{github.ref_name}}
- name: Current Branch
run: |
echo ${{steps.extract-branch.outputs.branch}}
- name: Next Branch
run: |
echo ${{steps.extract-next-branch.outputs.branch}}
test-ff-only:
needs: ['get-branch-names']
runs-on: ubuntu-latest
steps:
## First, we'll checkout the repository. We don't persist credentials because we need a
## Personal Access Token to push on a branch that is protected. See
## https://github.com/cycjimmy/semantic-release-action#basic-usage
- uses: actions/checkout@v3
with:
persist-credentials: false
ref: ${{needs.get-branch-names.outputs.next-branch}} # checkout the next branch
fetch-depth: 0 # Needed to do merges
## Attempt to do a fast-forward-only merge. If this succeeds, there is no divergence
## between the branches and we do not need to retest. The commit has already been
## verified. If this line fails, it will trigger `verify-merge`
- name: Test ff-only merge
run: git merge origin/${{ needs.get-branch-names.outputs.branch }} --ff-only
## If the previous step passed, push the verified commit directly to the next branch
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GH_RW_TOKEN }}
branch: refs/heads/${{ needs.get-branch-names.outputs.next-branch }}
## If the previous step failed, it means the fast-forward attempt failed. There is a
## divergence and we will need to merge the branches and verify everything works.
verify-merge:
runs-on: ubuntu-latest
if: failure()
needs: ['get-branch-names', 'test-ff-only']
steps:
## First, we'll checkout the repository. We don't persist credentials because we need a
## Personal Access Token to push on a branch that is protected. See
## https://github.com/cycjimmy/semantic-release-action#basic-usage
- uses: actions/checkout@v3
with:
persist-credentials: false
fetch-depth: 0 # Needed to do merges
- uses: Workday/canvas-kit-actions/install@v1
with:
node_version: 18.x
## A `yarn bump` will create a commit and a tag. We need to set up the git user to do this.
## We'll make that user be the github-actions user.
- name: Config git user
run: |
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
git config --global pull.rebase false
## Create a merge branch
- name: Forward merge
run: node utils/forward-merge.js
- name: Git Log
run: git log
# Keep steps separate for Github Actions annotation matching: https://github.com/actions/setup-node/blob/83c9f7a7df54d6b57455f7c57ac414f2ae5fb8de/src/setup-node.ts#L26-L33
- name: Lint
run: yarn lint
- name: Dependency Check
run: yarn depcheck
- name: Type Check
run: yarn typecheck
- name: Unit tests
run: yarn test
- name: Build Storybook
run: yarn build-storybook --quiet
- name: Cache Build
id: build-cache
uses: actions/cache/@v2
with:
path: docs
key: ${{ runner.os }}-build-${{ github.sha }}
# Not working for now...
# - name: Visual Tests
# uses: chromaui/action@main
# with:
# token: ${{ secrets.GITHUB_TOKEN }}
# appCode: dlpro96xybh
# storybookBuildDir: docs
# exitOnceUploaded: false
# exitZeroOnChanges: false
# ignoreLastBuildOnBranch: ${{ needs.get-branch-names.outputs.next-branch }}
# debug: true
- name: Integration tests
run: yarn cypress run --component --record --parallel
env:
# Github Actions doesn't support encryption on forks
# If these keys become compromised, we will rotate and disable these features
# on forked PRs until a suitable workaround is found
CYPRESS_RECORD_KEY: 3a9347b6-36ab-4a36-823d-709f4078b148
CYPRESS_CACHE_FOLDER: .cache/cypress
## Push both the commit and tag created by Lerna's version command using a PAT
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GH_RW_TOKEN }}
branch: refs/heads/${{ needs.get-branch-names.outputs.next-branch }}
## If we get here, it means the branches are not fast-forward mergeable, OR the merge commit
## failed verification. We will need manual intervention, so we'll create a pull request to
## be verified by a person.
make-pull-request:
runs-on: ubuntu-latest
# Run only if the verify-merge job failed. If the test-ff-only fails, but verify-merge passes, we should skip
if: failure() && needs.verify-merge.result == 'failure'
needs: ['get-branch-names', 'verify-merge']
steps:
## If we've failed any previous step, we'll need to create a PR instead
- uses: NicholasBoll/action-forward-merge-pr@main
with:
token: ${{secrets.GH_RW_TOKEN}} # use PAT to force GH Actions to run the PR verify. The regular token will not
branches: support+master,master+prerelease/minor,prerelease/minor+prerelease/major
prefix: 'chore: '
body: |
This pull request was automatically created by an automated [forward-merge job](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). The automated job failed automated checks and must be resolved manually.
Reasons for failure may include:
- Merge conflicts that cannot be automatically resolved
- A merge resulted in check failures
- Lint or type errors
- Test failures
- Unexpected visual changes
The pull request should inform you of merge conflicts before you start if any.
1. Run the following commands in your terminal. If this succeeds, skip step 2. The last command will run a script that tries to merge and resolve conflicts automatically.
```
git branch -D merge/${{needs.get-branch-names.outputs.branch}}-into-${{ needs.get-branch-names.outputs.next-branch }} || true
git fetch upstream
git checkout --track upstream/merge/${{needs.get-branch-names.outputs.branch}}-into-${{ needs.get-branch-names.outputs.next-branch }}
git pull upstream merge/${{needs.get-branch-names.outputs.branch}}-into-${{ needs.get-branch-names.outputs.next-branch }} -f
git pull upstream ${{needs.get-branch-names.outputs.branch}}
node utils/forward-merge.js
```
2. If the previous step succeeded, skip to step 4.
3. Resolve conflicts manually. Then run the following.
```
git add .
git commit -m "chore: Merge ${{needs.get-branch-names.outputs.branch}} into ${{ needs.get-branch-names.outputs.next-branch }}"
```
4. Push the merge commit back to the pull request
```
git push upstream merge/${{needs.get-branch-names.outputs.branch}}-into-${{ needs.get-branch-names.outputs.next-branch }}
```
If there were no merge conflicts, the forward-merge job failed because of a test failure. You can wait for the pull request to give errors, or you can check the logs for failures. You'll have to update code to fix errors.
This pull request will be merged using the `merge` strategy instead of the `squash` strategy. This means any commit in the log will show in the branch's history. Any commit you make should amend the merge commit. Use the following command:
```
git commit --amend --no-edit
```
You must then force-push the branch and the CI will rerun verification.
Use the `automerge` label like normal and the CI will pick the correct merge strategy.