Repository navigation
534 lines (476 loc) · 21.2 KB
/
Copy pathrelease-codegen-3.yml
File metadata and controls
534 lines (476 loc) · 21.2 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
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
name: Release Codegen 3.0
# Manual release workflow for codegen 3.0.0, with optional generators release.
on:
workflow_dispatch:
inputs:
release_generators:
description: 'Release swagger-codegen-generators together with codegen'
required: true
default: 'false'
type: choice
options:
- 'false'
- 'true'
skip_maven_deploy:
description: 'Skip Maven deploy for recovery when artifacts are already published'
required: true
default: 'false'
type: choice
options:
- 'false'
- 'true'
skip_docker_push:
description: 'Skip Docker build and push'
required: true
default: 'false'
type: choice
options:
- 'false'
- 'true'
skip_rancher_deploy:
description: 'Skip Swagger online generator deployment'
required: true
default: 'false'
type: choice
options:
- 'false'
- 'true'
previous_generators_version:
description: 'Generator release or snapshot version used to bootstrap the first codegen build when releasing generators'
required: false
type: string
codegen_generators_bootstrap_version:
description: 'Codegen release or snapshot version used to build generators'
required: false
type: string
dry_run:
description: 'Run validation and builds without deploy, Docker push, or Rancher deploy (post-release PR is still created)'
required: true
default: 'true'
type: choice
options:
- 'true'
- 'false'
permissions:
contents: read
jobs:
validate-branch:
if: github.ref_name != '3.0.0'
runs-on: ubuntu-latest
steps:
- name: Require 3.0.0 branch
run: |
echo "This workflow can run only from branch 3.0.0 (current: ${GITHUB_REF_NAME})."
exit 1
validate:
# Single source of truth for resolved versions and release-mode decisions.
if: github.ref_name == '3.0.0'
runs-on: ubuntu-latest
outputs:
codegen_version: ${{ steps.resolve.outputs.codegen_version }}
generators_version: ${{ steps.resolve.outputs.generators_version }}
codegen_build_generators_version: ${{ steps.resolve.outputs.codegen_build_generators_version }}
bootstrap_generators_version: ${{ steps.resolve.outputs.bootstrap_generators_version }}
bootstrap_codegen_version: ${{ steps.resolve.outputs.bootstrap_codegen_version }}
next_codegen_snapshot_version: ${{ steps.resolve.outputs.next_codegen_snapshot_version }}
generators_deploy_needed: ${{ steps.resolve.outputs.generators_deploy_needed }}
steps:
- name: Checkout swagger-codegen 3.0.0
uses: actions/checkout@v6
with:
ref: 3.0.0
- name: Checkout swagger-codegen-generators
if: inputs.release_generators == 'true'
uses: actions/checkout@v6
with:
repository: swagger-api/swagger-codegen-generators
ref: master
path: generators-repo
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Java and Maven
uses: actions/setup-java@v5
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }}
with:
java-version: '17'
distribution: temurin
server-id: central
cache: maven
overwrite-settings: false
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Add Central Portal snapshot repository
uses: s4u/maven-settings-action@v4.0.0
with:
repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]'
servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]'
- name: Validate and resolve versions
id: resolve
# Computes build/deploy coordinates and enforces safe release preconditions.
env:
RELEASE_GENERATORS: ${{ inputs.release_generators }}
PREVIOUS_GENERATORS_VERSION: ${{ inputs.previous_generators_version }}
CODEGEN_GENERATORS_BOOTSTRAP_VERSION: ${{ inputs.codegen_generators_bootstrap_version }}
SKIP_MAVEN_DEPLOY: ${{ inputs.skip_maven_deploy }}
DRY_RUN: ${{ inputs.dry_run }}
run: bash CI/release/resolve-release-versions.sh
bootstrap_codegen:
# Break circular dependency: build codegen first with previous generators version.
runs-on: ubuntu-latest
needs: validate
if: inputs.release_generators == 'true' && needs.validate.outputs.generators_deploy_needed == 'true'
steps:
- name: Checkout swagger-codegen 3.0.0
uses: actions/checkout@v6
with:
ref: 3.0.0
- name: Set up Java and Maven
uses: actions/setup-java@v5
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
with:
java-version: '17'
distribution: temurin
server-id: central
cache: maven
overwrite-settings: false
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Add Central Portal snapshot repository
uses: s4u/maven-settings-action@v4.0.0
with:
repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]'
servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]'
- name: Build codegen with bootstrap generators
run: |
bash CI/release/build-codegen-with-generators.sh "${{ needs.validate.outputs.bootstrap_generators_version }}"
generators:
# Build/deploy generators only when this run is responsible for publishing them.
runs-on: ubuntu-latest
needs:
- validate
- bootstrap_codegen
if: inputs.release_generators == 'true' && needs.validate.outputs.generators_deploy_needed == 'true'
steps:
- name: Checkout swagger-codegen-generators
uses: actions/checkout@v6
with:
repository: swagger-api/swagger-codegen-generators
ref: master
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Java and Maven
uses: actions/setup-java@v5
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }}
with:
java-version: '17'
distribution: temurin
server-id: central
cache: maven
overwrite-settings: false
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Add Central Portal snapshot repository
uses: s4u/maven-settings-action@v4.0.0
with:
repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]'
servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]'
- name: Build swagger-codegen-generators
run: |
mvn -B -U clean install \
-Dswagger-codegen-version="${{ needs.validate.outputs.bootstrap_codegen_version }}"
- name: Deploy swagger-codegen-generators
# Recovery controls: deploy can be skipped with dry_run/skip_maven_deploy.
if: inputs.skip_maven_deploy != 'true' && inputs.dry_run != 'true'
run: mvn --no-transfer-progress -B -Prelease deploy
- name: Skip swagger-codegen-generators deploy
if: inputs.skip_maven_deploy == 'true' || inputs.dry_run == 'true'
run: |
echo "Generator deploy skipped."
echo "skip_maven_deploy=${{ inputs.skip_maven_deploy }}"
echo "dry_run=${{ inputs.dry_run }}"
codegen:
# Main codegen build and Maven release deploy.
runs-on: ubuntu-latest
permissions:
contents: write
needs:
- validate
- generators
if: always() && needs.validate.result == 'success' && (needs.generators.result == 'success' || needs.generators.result == 'skipped')
outputs:
codegen_version: ${{ steps.expose.outputs.codegen_version }}
generators_version: ${{ steps.expose.outputs.generators_version }}
next_codegen_snapshot_version: ${{ steps.expose.outputs.next_codegen_snapshot_version }}
steps:
- name: Checkout swagger-codegen 3.0.0
uses: actions/checkout@v6
with:
ref: 3.0.0
- name: Set up Java and Maven
uses: actions/setup-java@v5
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PRIVATE_PASSPHRASE }}
with:
java-version: '17'
distribution: temurin
server-id: central
cache: maven
overwrite-settings: false
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.OSSRH_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Add Central Portal snapshot repository
uses: s4u/maven-settings-action@v4.0.0
with:
repositories: '[{"id":"central-portal-snapshots","name":"Sonatype Central Portal snapshots","url":"https://central.sonatype.com/repository/maven-snapshots/","releases":{"enabled":false},"snapshots":{"enabled":true}}]'
servers: '[{"id":"central","username":"${{ secrets.MAVEN_CENTRAL_USERNAME }}","password":"${{ secrets.MAVEN_CENTRAL_PASSWORD }}"}]'
- name: Build swagger-codegen
run: |
bash CI/release/build-codegen-with-generators.sh "${{ needs.validate.outputs.codegen_build_generators_version }}"
- name: Deploy swagger-codegen
# Intended for final release run; disabled in dry_run/recovery skip mode.
if: inputs.skip_maven_deploy != 'true' && inputs.dry_run != 'true'
run: |
mvn --no-transfer-progress -B -Prelease deploy \
-Dswagger-codegen-generators-version="${{ needs.validate.outputs.codegen_build_generators_version }}"
- name: Skip swagger-codegen deploy
if: inputs.skip_maven_deploy == 'true' || inputs.dry_run == 'true'
run: |
echo "Codegen Maven deploy skipped."
echo "skip_maven_deploy=${{ inputs.skip_maven_deploy }}"
echo "dry_run=${{ inputs.dry_run }}"
- name: Expose release outputs
id: expose
run: |
echo "codegen_version=${{ needs.validate.outputs.codegen_version }}" >> "${GITHUB_OUTPUT}"
echo "generators_version=${{ needs.validate.outputs.generators_version }}" >> "${GITHUB_OUTPUT}"
echo "next_codegen_snapshot_version=${{ needs.validate.outputs.next_codegen_snapshot_version }}" >> "${GITHUB_OUTPUT}"
- name: Publish prepared draft release notes
# Publishes the draft release created in prepare-release workflow.
if: inputs.dry_run != 'true'
uses: actions/github-script@v8
with:
script: |
const tag = `v${{ needs.validate.outputs.codegen_version }}`;
const owner = context.repo.owner;
const repo = context.repo.repo;
let release;
try {
const { data } = await github.rest.repos.getReleaseByTag({ owner, repo, tag });
release = data;
} catch (error) {
core.setFailed(`Expected prepared draft release for tag ${tag}, but it was not found.`);
return;
}
if (!release.draft) {
core.info(`Release ${tag} is already published.`);
return;
}
await github.rest.repos.updateRelease({
owner,
repo,
release_id: release.id,
draft: false
});
core.info(`Published draft release ${tag}.`);
docker:
# Optional container publication stage; can be disabled independently.
runs-on: ubuntu-latest
needs: codegen
if: inputs.skip_docker_push != 'true' && inputs.dry_run != 'true'
steps:
- name: Checkout swagger-codegen 3.0.0
uses: actions/checkout@v6
with:
ref: 3.0.0
- name: Set up Java and Maven
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: temurin
cache: maven
- name: Build Docker inputs
run: |
mvn -B -U clean install -Pdocker \
-Dswagger-codegen-generators-version="${{ needs.codegen.outputs.generators_version }}" \
-DJETTY_TEST_HTTP_PORT=8090 \
-DJETTY_TEST_STOP_PORT=8089
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_SB_USERNAME }}
password: ${{ secrets.DOCKERHUB_SB_PASSWORD }}
- name: Build and push swagger-generator-v3
uses: docker/build-push-action@v5
with:
context: ./modules/swagger-generator
file: ./modules/swagger-generator/Dockerfile
push: true
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
provenance: false
build-args: |
HIDDEN_OPTIONS_DEFAULT_PATH=hiddenOptions.yaml
JAVA_MEM=1024m
HTTP_PORT=8080
tags: swaggerapi/swagger-generator-v3:${{ needs.codegen.outputs.codegen_version }},swaggerapi/swagger-generator-v3:latest
- name: Build and push swagger-generator-v3-root
uses: docker/build-push-action@v5
with:
context: ./modules/swagger-generator
file: ./modules/swagger-generator/Dockerfile_root
push: true
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
provenance: false
build-args: |
HIDDEN_OPTIONS_DEFAULT_PATH=hiddenOptions.yaml
JAVA_MEM=1024m
HTTP_PORT=8080
tags: swaggerapi/swagger-generator-v3-root:${{ needs.codegen.outputs.codegen_version }},swaggerapi/swagger-generator-v3-root:latest
- name: Build and push swagger-codegen-cli-v3
uses: docker/build-push-action@v5
with:
context: ./modules/swagger-codegen-cli
file: ./modules/swagger-codegen-cli/Dockerfile
push: true
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x
provenance: false
tags: swaggerapi/swagger-codegen-cli-v3:${{ needs.codegen.outputs.codegen_version }},swaggerapi/swagger-codegen-cli-v3:latest
- name: Build and push swagger-generator-v3-minimal
uses: docker/build-push-action@v5
with:
context: ./modules/swagger-generator
file: ./modules/swagger-generator/Dockerfile_minimal
push: true
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x
provenance: false
tags: swaggerapi/swagger-generator-v3-minimal:${{ needs.codegen.outputs.codegen_version }},swaggerapi/swagger-generator-v3-minimal:latest
online_deploy:
# Optional Swagger online deployment with rollback on readiness failure.
runs-on: ubuntu-latest
needs:
- codegen
- docker
if: inputs.skip_rancher_deploy != 'true' && inputs.skip_docker_push != 'true' && inputs.dry_run != 'true'
steps:
- name: Deploy Swagger online generator with rollback
env:
SC_VERSION: ${{ needs.codegen.outputs.codegen_version }}
TOKEN: ${{ secrets.RANCHER2_BEARER_TOKEN }}
RANCHER_HOST: rancher.tools.swagger.io
CLUSTER_ID: c-n8zp2
NAMESPACE_NAME: swagger-oss
K8S_OBJECT_TYPE: daemonsets
K8S_OBJECT_NAME: swagger-generator-v3
run: |
set -euo pipefail
DEPLOY_IMAGE="swaggerapi/swagger-generator-v3:${SC_VERSION}"
workloadStatus=""
getStatus() {
echo "Getting ${K8S_OBJECT_NAME} status..."
workloadStatus="$(curl --fail --silent --show-error -X GET \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
"https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}/status")"
}
updateObject() {
local image="${1}"
echo "Updating ${K8S_OBJECT_NAME} to ${image}"
curl --fail --silent --show-error -X PATCH \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json-patch+json' \
"https://${RANCHER_HOST}/k8s/clusters/${CLUSTER_ID}/apis/apps/v1/namespaces/${NAMESPACE_NAME}/${K8S_OBJECT_TYPE}/${K8S_OBJECT_NAME}" \
-d "[{\"op\":\"replace\",\"path\":\"/spec/template/spec/containers/0/image\",\"value\":\"${image}\"}]"
}
[[ "${SC_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
echo "::error::Invalid release version ${SC_VERSION}"
exit 1
}
getStatus
ROLLBACK_IMAGE="$(echo "${workloadStatus}" | jq -r '.spec.template.spec.containers[0].image')"
echo "Current image: ${ROLLBACK_IMAGE}"
updateObject "${DEPLOY_IMAGE}"
sleep 60s
getStatus
status="$(echo "${workloadStatus}" | jq '.status')"
numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')"
numberReady="$(echo "${status}" | jq -r '.numberReady')"
if (( numberReady == numberDesired )); then
echo "${K8S_OBJECT_NAME} upgraded to ${DEPLOY_IMAGE}"
exit 0
fi
echo "::error::Deployment did not become ready; rolling back to ${ROLLBACK_IMAGE}"
updateObject "${ROLLBACK_IMAGE}"
sleep 60s
getStatus
status="$(echo "${workloadStatus}" | jq '.status')"
numberDesired="$(echo "${status}" | jq -r '.desiredNumberScheduled')"
numberReady="$(echo "${status}" | jq -r '.numberReady')"
if (( numberReady == numberDesired )); then
echo "Rollback to ${ROLLBACK_IMAGE} completed."
else
echo "::error::Rollback to ${ROLLBACK_IMAGE} failed."
fi
exit 1
post_release_pr:
# Prepares and opens next snapshot PR after successful release pipeline.
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
needs:
- codegen
- docker
- online_deploy
if: always() && needs.codegen.result == 'success' && (needs.docker.result == 'success' || needs.docker.result == 'skipped') && (needs.online_deploy.result == 'success' || needs.online_deploy.result == 'skipped')
env:
NEXT_CODEGEN_SNAPSHOT_VERSION: ${{ needs.codegen.outputs.next_codegen_snapshot_version }}
GENERATORS_VERSION: ${{ needs.codegen.outputs.generators_version }}
steps:
- name: Checkout swagger-codegen 3.0.0
uses: actions/checkout@v6
with:
ref: 3.0.0
- uses: actions/create-github-app-token@v3
id: generate-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Set up Java and Maven
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: temurin
cache: maven
- name: Prepare next snapshot changes
id: next-snapshot
# Moves repo from release version to next -SNAPSHOT and updates docs/poms.
run: bash CI/release/post-codegen-snapshot.sh
- name: Create next snapshot pull request
uses: peter-evans/create-pull-request@v8
with:
token: ${{ steps.generate-token.outputs.token }}
commit-message: bump snapshot ${{ steps.next-snapshot.outputs.next_codegen_snapshot_version }}
title: bump snapshot ${{ steps.next-snapshot.outputs.next_codegen_snapshot_version }}
branch: bump-snap-${{ steps.next-snapshot.outputs.next_codegen_snapshot_version }}
base: 3.0.0
body: |
Bump Swagger Codegen to ${{ steps.next-snapshot.outputs.next_codegen_snapshot_version }} after release.
release_generators: ${{ inputs.release_generators }}
swagger-codegen-generators dependency retained as: ${{ needs.codegen.outputs.generators_version }}