Repository navigation
204 lines (187 loc) · 9.11 KB
/
Copy pathrelease.yml
File metadata and controls
204 lines (187 loc) · 9.11 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
name: Release new version
on:
workflow_dispatch:
inputs:
tag_name:
description: 'Tag name to publish'
required: true
skip_pre_release_tests:
description: 'Skip the pre-release integration test gate. Use only when the gate is red for infra reasons unrelated to this release (e.g. staging/Core provisioning down) and the release carries unit-tested changes only.'
type: boolean
default: false
permissions: {}
jobs:
pre-release-testing:
if: ${{ !inputs.skip_pre_release_tests }}
permissions:
contents: write # Allure report is pushed to gh-pages.
pages: read # Allure report looks up the Pages URL.
statuses: write # Allure report posts a commit status.
packages: read # Firebolt Core image is pulled from ghcr.io.
actions: read # The smoke test downloads the jar artifact of this run.
uses: ./.github/workflows/pre-release-test.yml
secrets:
FIREBOLT_STG_USERNAME: ${{ secrets.FIREBOLT_STG_USERNAME }}
FIREBOLT_STG_PASSWORD: ${{ secrets.FIREBOLT_STG_PASSWORD }}
FIREBOLT_CLIENT_ID_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }}
FIREBOLT_CLIENT_SECRET_STG_NEW_IDN: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }}
ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_ID_STG }}
ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NO_USER_CLIENT_SECRET_STG }}
ECOSYSTEM_FIREBOLT_SA_NETWORK_POLICY_CLIENT_ID_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NETWORK_POLICY_CLIENT_ID_STG }}
ECOSYSTEM_FIREBOLT_SA_NETWORK_POLICY_CLIENT_SECRET_STG: ${{ secrets.ECOSYSTEM_FIREBOLT_SA_NETWORK_POLICY_CLIENT_SECRET_STG }}
bump-version:
needs: pre-release-testing
# Proceed when the gate passed, or when it was intentionally skipped via
# skip_pre_release_tests. A real failure/cancellation still halts the release.
if: ${{ always() && (needs.pre-release-testing.result == 'success' || needs.pre-release-testing.result == 'skipped') }}
runs-on: ubuntu-latest
permissions:
contents: read # Pushes use the GitHub App token.
env:
newVersion: ${{ github.event.inputs.tag_name }}
steps:
- name: Create GitHub App token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
client-id: ${{ secrets.GH_APP_FB_DB_CI_WRITER_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_FB_DB_CI_WRITER_APP_KEY_PEM }}
permission-contents: write
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
persist-credentials: true # The release step pushes the version bump and tag.
- name: Bump version in gradle.properties
run: |
newVersion="${newVersion#v}"
sed -i.bak "s/^version=.*/version=$newVersion/" gradle.properties
rm gradle.properties.bak
- name: Setup git config
run: |
git config user.name "GitHub Actions Bot"
git config user.email "<>"
- name: Commit version bump
run: |
git add gradle.properties
if git diff --cached --quiet; then
echo "gradle.properties already at $newVersion; nothing to commit"
else
git commit -m "chore: Bump version to $newVersion"
fi
- name: Tag version
run: |
git tag "$newVersion" || echo "tag $newVersion already exists"
# The build job checks out this tag and runs it in the default-branch context, which can
# write to the default-branch cache. Only release code that is part of master: refuse a
# release dispatched from another branch, or a pre-existing tag that points elsewhere.
- name: Verify the release tag is on master
run: |
# GITHUB_REF is the ref the run was dispatched on; the dispatcher can't change it.
if [ "$GITHUB_REF" != "refs/heads/master" ]; then
echo "::error::The release must be dispatched from master, not $GITHUB_REF."
exit 1
fi
# HEAD must be origin/master plus at most the version-bump commit made above.
if ! git merge-base --is-ancestor origin/master HEAD || [ "$(git rev-list --count origin/master..HEAD)" -gt 1 ]; then
echo "::error::HEAD is not master plus the version bump."
exit 1
fi
tag_commit=$(git rev-parse "refs/tags/$newVersion^{commit}")
if ! git merge-base --is-ancestor "$tag_commit" HEAD; then
echo "::error::Tag $newVersion points to $tag_commit, which is not part of master. Refusing to release it."
exit 1
fi
echo "Tag $newVersion ($tag_commit) is part of master."
- name: Push changes
run: |
git push origin master
# Push tag (already-present tag is a no-op)
git push origin "$newVersion" || echo "tag $newVersion already pushed"
build:
needs: bump-version
permissions:
contents: read
# bump-version runs under an always() gate; make the success dependency
# explicit so a skipped pre-release-testing upstream doesn't skip build.
if: ${{ always() && needs.bump-version.result == 'success' }}
uses: ./.github/workflows/build.yml
with:
branch: ${{ github.event.inputs.tag_name }}
publish:
runs-on: ubuntu-latest
needs: build
if: ${{ always() && needs.build.result == 'success' }}
permissions:
contents: write # Uploads the jar to the release and updates its notes.
steps:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.inputs.tag_name}}
persist-credentials: false
- name: Download uber-jar
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: ${{ needs.build.outputs.uber-jar }}
- name: Download sources-jar
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: ${{ needs.build.outputs.sources-jar }}
- uses: xresloader/upload-to-github-release@7c5757a90c0bcf0c0e1741da8f2abd7b85e675d0 # v1.6.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
file: ${{ needs.build.outputs.uber-jar }}
tags: true
draft: false
tag_name: ${{ github.event.inputs.tag_name }}
- name: Publish to Maven Central (Central Portal via OSSRH staging API)
# The legacy Nexus flow (publishToSonatype closeAndReleaseSonatypeStagingRepository)
# relies on the staging-profile API, which the Central Portal OSSRH shim does not
# expose -> "Failed to find staging profile for package group: io.firebolt". Instead
# deploy to the OSSRH staging deploy endpoint (auto-creates the namespace's default
# repository), then promote it into the Central Publisher Portal.
run: ./gradlew publishMavenPublicationToMavenRepository manualUploadToMavenCentral
env:
MAVEN_REPO_USERNAME: ${{ secrets.MAVEN_REPO_USERNAME }}
MAVEN_REPO_PASSWORD: ${{ secrets.MAVEN_REPO_PASSWORD }}
GRADLE_SIGNING_KEY: ${{ secrets.GRADLE_SIGNING_KEY }}
GRADLE_SIGNING_PASSWORD: ${{ secrets.GRADLE_SIGNING_PASSWORD }}
- name: Generate and update GitHub release notes
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
TAG_NAME: ${{ github.event.inputs.tag_name }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const tag = process.env.TAG_NAME;
const { owner, repo } = context.repo;
// Fetch existing release by tag (created earlier by upload step)
const release = await github.rest.repos.getReleaseByTag({ owner, repo, tag });
// Generate notes based on PRs/commits between last release and this tag
const notes = await github.rest.repos.generateReleaseNotes({ owner, repo, tag_name: tag });
// Sanitize internal JIRA links: [FIR-1234](...) -> `FIR-1234`, and wrap bare FIR-1234 in backticks
let body = notes.data.body || '';
body = body.replace(/\[(FIR-\d+)\]\([^)]*\)/g, '`$1`');
body = body.replace(/(?<!`)\bFIR-\d+\b(?!`)/g, (m) => `\`${m}\``);
// Update the release body with sanitized notes
await github.rest.repos.updateRelease({ owner, repo, release_id: release.data.id, body });
- name: Derive release version
id: release_version
env:
TAG_NAME: ${{ github.event.inputs.tag_name }}
run: |
ver="${TAG_NAME#v}"
echo "value=$ver" >> "$GITHUB_OUTPUT"
- name: Notify Slack of JDBC release
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
{
"channel": "ecosystem-team",
"text": "Firebolt JDBC driver ${{ steps.release_version.outputs.value }} has been released: <https://github.com/${{ github.repository }}/releases/tag/${{ github.event.inputs.tag_name }}|Release notes>"
}