@@ -3,14 +3,110 @@ name: Release
3
3
on :
4
4
workflow_dispatch :
5
5
6
+
6
7
jobs :
7
- gradle :
8
+ # 1. We look at the target branch and figure out whether this should be a BUILD
9
+ # release or a patch release
10
+ get-update-type :
11
+ # If the context.ref is refs/heads/main we want to do a standard release
12
+ # If the context.ref is refs/heads/* we want to do a patch release
13
+ # If the context.ref is some other ref, we want to fail
14
+ # Selecting a tag github.ref becomes e.g.: refs/tags/4.1.9.0
15
+ runs-on : ubuntu-latest
16
+ permissions :
17
+ contents : read
18
+ outputs : # This means this can later be referenced with needs.get-update-type.outputs.update-type
19
+ update-type : ${{ steps.update-type.outputs.result }}
20
+ steps :
21
+ - name : Calculate update type
22
+ uses : actions/github-script@v7
23
+ id : update-type
24
+ with :
25
+ script : |
26
+ if (context.ref == "refs/heads/main") {
27
+ return "BUILD";
28
+ } else if (context.ref.startsWith("refs/heads/")) {
29
+ return "PATCH";
30
+ } else {
31
+ throw new Error("Target must be a patch branch or main, but was: " + context.ref);
32
+ }
33
+ result-encoding : string
34
+ - name : Print update type
35
+ shell : bash
36
+ run : echo "${{steps.update-type.outputs.result}}"
37
+
38
+ # 2. In parallel, we run:
39
+ # a) all the tests
40
+ # b) the mixed-mode tests
41
+ test :
42
+ runs-on : ubuntu-latest
43
+ permissions :
44
+ contents : read
45
+ steps :
46
+ - name : Checkout sources
47
+
48
+ - name : Setup Base Environment
49
+ id : setup-base
50
+ uses : ./actions/setup-base-env
51
+ - name : Setup FDB
52
+ uses : ./actions/setup-fdb
53
+ - name : Run Gradle Test
54
+ uses : ./actions/gradle-test
55
+ with :
56
+ gradle_args : -PreleaseBuild=true -PpublishBuild=true
57
+
58
+ # 2. b) We run the mixed mode tests
59
+ mixed-mode-test :
60
+ needs : [get-update-type]
61
+ runs-on : ubuntu-latest
62
+ permissions :
63
+ contents : read
64
+ steps :
65
+ - name : Checkout sources
66
+
67
+ - name : Setup Base Environment
68
+ uses : ./actions/setup-base-env
69
+ - name : Setup FDB
70
+ uses : ./actions/setup-fdb
71
+ - name : Run Gradle Test
72
+ uses : ./actions/gradle-test
73
+ with :
74
+ gradle_command : mixedModeTest
75
+ gradle_args : -PreleaseBuild=false -PpublishBuild=false
76
+ # We don't commit the incremented version, but we use this to know the version when generating
77
+ # the resulting markdown
78
+ - name : Increment version
79
+ shell : bash
80
+ run : python build/versionutils.py gradle.properties --increment -u ${{ needs.get-update-type.outputs.update-type }}
81
+ - name : Get new version
82
+ id : get_new_version
83
+ shell : bash
84
+ run : |
85
+ echo "version=$(python build/versionutils.py gradle.properties)" >> "$GITHUB_OUTPUT"
86
+ - name : Create markdown
87
+ shell : bash
88
+ run : python build/publish-mixed-mode-results.py ${{ steps.get_new_version.outputs.version }} --run-link ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} --output mixed-mode-results.md
89
+ - name : Preview results
90
+ shell : bash
91
+ run : cat mixed-mode-results.md >> $GITHUB_STEP_SUMMARY
92
+ # I think this _needs_ to be done at this level, rather than in the action
93
+ # so that "mixed-mode-results" gets passed around correctly
94
+ - name : Upload mixed mode results
95
+ id : mixed_mode_results
96
+
97
+ with :
98
+ name : mixed-mode-results
99
+ path : mixed-mode-results.md
100
+
101
+ # 3. Update the version in the repo, update the release notes, tag the commit
102
+ # and publish the artifacts, and if this is a BUILD release generate the documentation
103
+ publish :
104
+ needs : [test, mixed-mode-test, get-update-type]
8
105
runs-on : ubuntu-latest
9
106
permissions :
10
- checks : write
11
107
contents : write
12
108
packages : write
13
- pull-requests : write
109
+ pull-requests : write # We create a pull request if committing the release notes updates fails
14
110
steps :
15
111
- name : Checkout sources
16
112
@@ -20,52 +116,154 @@ jobs:
20
116
# fetch all the history to make sure that we have the last release
21
117
# I tried fetching part of the history, but I just couldn't get it to work, and fetching all still takes like 5s
22
118
fetch-depth : 0
23
- - name : Setup Base Environment
24
- id : setup-base
25
- uses : ./actions/setup-base-env
26
- - name : Setup FDB
27
- uses : ./actions/setup-fdb
119
+
28
120
- name : Configure git
121
+ shell : bash
29
122
run : |
30
123
git config --global user.name 'FoundationDB CI'
31
124
git config --global user.email '[email protected] '
32
-
33
- - name : Build and publish
34
- uses : ./actions/release-build-publish
125
+
126
+ - name : Setup Base Environment
127
+ uses : ./actions/setup-base-env
128
+ - name : Get old version
129
+ id : get_old_version
130
+ shell : bash
131
+ run : |
132
+ echo "version=$(python build/versionutils.py gradle.properties)" >> "$GITHUB_OUTPUT"
133
+ # Push a version bump back to main. There are failure scenarios that can result
134
+ # in published artifacts but an erroneous build, so it's safer to bump the version
135
+ # at the beginning
136
+ - name : Increment version
137
+ shell : bash
138
+ run : python build/versionutils.py gradle.properties --increment --commit -u ${{ needs.get-update-type.outputs.update-type }}
139
+ - name : Get new version
140
+ id : get_new_version
141
+ shell : bash
142
+ run : |
143
+ echo "version=$(python build/versionutils.py gradle.properties)" >> "$GITHUB_OUTPUT"
144
+ # We also want to push the tag, because that will be used for the next release's release notes
145
+ - name : Create tag
146
+ shell : bash
147
+ run : git tag -m "Release ${{ steps.get_new_version.outputs.version }}" -f "${{ steps.get_new_version.outputs.version }}"
148
+
149
+ # We want to do this before anything else, because if the later steps fail, we want to make sure that the full
150
+ # change log includes all changes, even if they reference a release that was never actually published.
151
+ - name : Download mixed mode results
152
+ uses : actions/download-artifact@v4
153
+ with :
154
+ name : mixed-mode-results
155
+ - name : echo results
156
+ shell : bash
157
+ run : cat mixed-mode-results.md || ls
158
+ - name : Update release notes
159
+ shell : bash
160
+ run : |
161
+ python ./build/create_release_notes.py \
162
+ --config ./build/release-notes-config.json \
163
+ --release-notes-md docs/sphinx/source/ReleaseNotes.md \
164
+ --skip-commit $(git log -n 1 --format=%H HEAD) \
165
+ --repository ${{ github.repository }} \
166
+ --commit \
167
+ --mixed-mode-results mixed-mode-results.md \
168
+ ${{ steps.get_old_version.outputs.version }} ${{ steps.get_new_version.outputs.version }}
169
+ env :
170
+ GH_TOKEN : ${{ github.token }}
171
+ # We move the tag to after the release notes are updated so that later steps (i.e. sphinx) will pick up the udpated
172
+ # release notes
173
+ - name : Move tag to HEAD
174
+ shell : bash
175
+ run : git tag -m "Release ${{ steps.get_new_version.outputs.version }}" -f "${{ steps.get_new_version.outputs.version }}"
176
+
177
+ # push the changes to gradle.properties, the release notes, and the tag as one operation, so if it fails,
178
+ # it will be as if the release never did anything
179
+ - name : Push Version Update
180
+ shell : bash
181
+ run : git push origin HEAD "${{ steps.get_new_version.outputs.version }}"
182
+
183
+ - name : Publish Artifacts
184
+ uses : ./actions/run-gradle
35
185
with :
36
- gpg_private_key : ${{ secrets.GPG_PRIVATE_KEY }}
37
- gpg_passphrase : ${{ secrets.GPG_PASSPHRASE }}
38
- update_type : BUILD
186
+ gradle_command : publish closeAndReleaseStagingRepositories -PreleaseBuild=true -PpublishBuild=true -PgithubPublish=true -PcentralPublish=true
39
187
env :
188
+ ORG_GRADLE_PROJECT_signingKey : ${{ secrets.GPG_PRIVATE_KEY }}
189
+ ORG_GRADLE_PROJECT_signingPassword : ${{ secrets.GPG_PASSPHRASE }}
40
190
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
41
191
MAVEN_USER : ${{ secrets.MAVEN_USER }}
42
192
MAVEN_PASSWORD : ${{ secrets.MAVEN_PASSWORD }}
193
+
194
+ # Post release: Update various files which reference version
195
+ # Updating the yaml files has to be done after the tests complete, or it will mark tests as failing that aren't
196
+ # supported by the previous version.
197
+ - name : Update YAML test file versions
198
+ uses : ./actions/run-gradle
199
+ with :
200
+ gradle_command : updateYamsql -PreleaseBuild=true
201
+ - name : Commit YAML updates
202
+ shell : bash
203
+ run : python ./build/commit_yamsql_updates.py "${{ steps.get_new_version.outputs.version }}"
204
+ - name : Push Updates
205
+ id : push_updates
206
+ shell : bash
207
+ run : git push origin
208
+ # Continue the build (including downstream steps). If the push fails, we'll create a PR
209
+ continue-on-error : true
210
+ - name : Create Merge PR if conflict
211
+ # Only create the PR if we've otherwise been successful, but the push failed. Note that
212
+ # we're checking the .outcome of the push step, which is applied before continue-on-error.
213
+ if : success() && steps.push_updates.outcome == 'failure'
214
+ uses : peter-evans/create-pull-request@bb88e27d3f9cc69c8bc689eba126096c6fe3dded
215
+ id : pr_on_conflict
216
+ with :
217
+ branch : release-build
218
+ branch-suffix : timestamp
219
+ title : " Updates for ${{ steps.get_new_version.outputs.version }} release"
220
+ sign-commits : true
221
+ body : |
222
+ Updates from release for version ${{ steps.get_new_version.outputs.version }}. Conflicts during the build prevented automatic updating. Please resolve conflicts by checking out the current branch, merging, and then deleting this branch.
223
+
224
+ # Creating the PR can change the current branch. Explicitly check out the tag here for downstream builds
225
+ - name : Revert to tag
226
+ shell : bash
227
+ run : git checkout "${{ steps.get_new_version.outputs.version }}"
43
228
44
- # Build documentation.
229
+ # Build documentation (We don't do any of the remaining steps for patch releases)
230
+ - name : LOG update type
231
+ shell : bash
232
+ run : echo "${{ needs.get-update-type.outputs.update-type }}"
45
233
- name : Cache Python Environment
234
+ if : needs.get-update-type.outputs.update-type == 'BUILD'
46
235
uses : actions/cache@v4
47
236
with :
48
237
path : docs/sphinx/.venv
49
238
key : ${{ runner.os }}-sphinx-python-${{ steps.setup-base.outputs.python-version }}-${{ hashFiles('docs/sphinx/requirements.txt') }}
50
239
- name : Build Documentation Site
240
+ if : needs.get-update-type.outputs.update-type == 'BUILD'
51
241
uses : ./actions/run-gradle
52
242
with :
53
243
gradle_command : documentationSite -PreleaseBuild=true
54
244
- name : Upload Documentation
245
+ if : needs.get-update-type.outputs.update-type == 'BUILD'
55
246
id : doc_upload
56
247
uses : actions/upload-pages-artifact@v3
57
248
with :
58
249
path : docs/sphinx/.out/html/
59
250
251
+ # 4. We deploy the documentation from (3) to github pages, unless this is a patch release
252
+ # deploy_docs is a separate job so that it can run with different permissions from
253
+ # everything else, but it depends on publish so, it will always run last
60
254
deploy_docs :
61
255
runs-on : ubuntu-latest
62
- needs : gradle
256
+ needs : [publish]
257
+ if : needs.get-update-type.outputs.update-type == 'BUILD'
63
258
permissions :
64
259
pages : write
65
260
id-token : write
66
261
environment :
67
262
name : github-pages
68
263
url : ${{ steps.doc_upload.outputs.page_url }}
69
264
steps :
265
+ - name : LOG update type
266
+ shell : bash
267
+ run : echo "${{ needs.get-update-type.outputs.update-type }}"
70
268
- name : Deploy Documentation
71
269
uses : actions/deploy-pages@v4
0 commit comments