-
Notifications
You must be signed in to change notification settings - Fork 146
297 lines (264 loc) · 13.7 KB
/
Copy pathcreate-release.yml
File metadata and controls
297 lines (264 loc) · 13.7 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
name: Create Release
on:
workflow_dispatch:
push:
branches:
- main
- tmp_hotfix_branch
env:
NODE_VERSION: '22.x'
# Package list for build, lint, pack, and publish operations
RELEASE_PACKAGES: 'i18n,cdk,core,platform,moment-adapter,datetime-adapter,cx,btp,ui5-webcomponents-base,ui5-webcomponents,ui5-webcomponents-fiori,ui5-webcomponents-ai,mcp-server'
IS_HOTFIX: ${{ github.ref == 'refs/heads/tmp_hotfix_branch' }}
IS_PRERELEASE: ${{ github.event_name == 'push' && github.ref != 'refs/heads/tmp_hotfix_branch' }}
IS_MANUAL: ${{ contains(github.event.head_commit.message, 'chore(release)') }}
NX_CLOUD_DISTRIBUTED_EXECUTION: true
NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 5
NX_BRANCH: ${{ github.event.number || github.ref_name }}
jobs:
nx_agents:
name: Nx Cloud Agent ${{ matrix.agent }}
runs-on: ubuntu-latest
environment: release
env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_AUTH_TOKEN }}
permissions:
contents: read
timeout-minutes: 60
strategy:
matrix:
agent: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4.2.2
with:
fetch-depth: 1 # Shallow clone for agents (they don't need git history)
- uses: ./.github/actions/nodejs
with:
node-version: ${{ env.NODE_VERSION }}
- name: Start Nx Cloud Agent
run: npx nx-cloud start-agent
env:
NX_AGENT_NAME: ${{ matrix.agent }}
create_release:
name: Create release
runs-on: ubuntu-latest
environment: release
env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_AUTH_TOKEN }}
permissions:
contents: write
id-token: write
outputs:
npmTag: ${{ steps.releaseTags.outputs.npm }}
ghTag: ${{ steps.releaseTags.outputs.gh }}
steps:
- name: Fetch from origin repo
uses: actions/checkout@v4.2.2
with:
ref: ${{ env.IS_HOTFIX == 'true' && 'tmp_hotfix_branch' || 'main' }}
fetch-depth: 0
token: ${{ secrets.GHACTIONS }}
- name: Setup Node.js, dependencies, and caching
uses: ./.github/actions/nodejs
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup git user
uses: ./.github/actions/set-up-git
with:
name: ${{ secrets.GH_NAME }}
email: ${{ secrets.GH_EMAIL }}
# npm 11.5.0+ auto-detects OIDC in GitHub Actions and handles trusted publishing.
# The bundled npm 10.x doesn't support this, so we upgrade.
# We cannot run `npm install -g npm@latest` directly because npm 10.9.7
# crashes with MODULE_NOT_FOUND when replacing its own files mid-execution.
# Instead, we use npx to run a fresh copy of npm@latest for the upgrade.
- name: Upgrade npm for OIDC trusted publishing
run: npx --yes npm@latest install -g npm@latest
# WORKAROUND: npm 11.x/12.x has missing sigstore dependency (npm/cli#9722)
# Install sigstore@^4.1.1 globally so npm can find it when generating provenance attestations
# Pinned to 4.1.1 for stability - npm 11.x was built against sigstore 4.x
- name: Install sigstore dependency for npm provenance
run: npm install -g sigstore@^4.1.1
- name: Initialize the Nx Cloud distributed CI run
run: npx nx-cloud start-ci-run
# Does conventional version bump and creates a tag
- name: Get next version
id: bumpVersion
uses: ./.github/actions/bump-version
with:
isManual: ${{ env.IS_MANUAL }}
isPrerelease: ${{ env.IS_PRERELEASE }}
isHotfix: ${{ env.IS_HOTFIX }}
# Takes bump tag and creates the release tags for both gh and npm.
# See implementation for more details
- name: Get Release Tags
uses: ./.github/actions/release-tags
id: releaseTags
with:
bumpTag: ${{ steps.bumpVersion.outputs.releaseTag }}
bumpedVersion: ${{ steps.bumpVersion.outputs.newVersion }}
# NX Release handles version updates, git commit, and git tag creation
# We disable git operations here and handle them manually after successful build
# to ensure we don't commit/tag if the build fails
- name: Update version using NX Release
if: env.IS_MANUAL != 'true'
run: |
npx nx release version ${{ steps.bumpVersion.outputs.newVersion }} --git-commit=false --git-tag=false
# Generate per-project CHANGELOG.md entries from conventional commits.
- name: Generate changelogs using NX Release
if: env.IS_MANUAL != 'true'
run: |
npx nx release changelog ${{ steps.bumpVersion.outputs.newVersion }} --git-commit=false --git-tag=false
# Reset dependency placeholders in source package.json files
# NX Release updates both version AND dependencies, but we want to keep placeholders in source
# Also run this for manual releases to ensure placeholders are always restored before building
- name: Reset dependency placeholders
run: node scripts/reset-placeholders.js
# Update lerna.json version for backward compatibility with hotfix releases on older versions
- name: Update lerna.json version
if: env.IS_MANUAL != 'true'
run: node scripts/update-lerna-version.js ${{ steps.bumpVersion.outputs.newVersion }}
# Regenerate the component metadata catalog with the new version
- name: Regenerate component metadata catalog
if: env.IS_MANUAL != 'true'
run: npx nx run mcp-server:extract-metadata
env:
NX_CLOUD_DISTRIBUTED_EXECUTION: false
- name: Lint and build
uses: ./.github/actions/parallel-commands
with:
parallel-commands: |
npx nx run-many --target=lint --skip-nx-cache --projects=${{ env.RELEASE_PACKAGES }} --parallel=3
npx nx run-many --target=build --projects=${{ env.RELEASE_PACKAGES }} --parallel=1
- name: Extract Angular version
id: angularVersion
run: |
ANGULAR_VERSION=$(node -e "console.log(require('./package.json').dependencies['@angular/core'].split('.')[0])")
echo "major=${ANGULAR_VERSION}" >> $GITHUB_OUTPUT
- name: Pack libraries
run: npx nx run-many --target=prepare --projects=${{ env.RELEASE_PACKAGES }} --parallel=3
env:
NX_CLOUD_DISTRIBUTED_EXECUTION: false
FD_ENV_VERSION_PLACEHOLDER: ${{ steps.bumpVersion.outputs.newVersion }}
FD_ENV_ANGULAR_VER_PLACEHOLDER: ^${{ steps.angularVersion.outputs.major }}.0.0
# Reset placeholders again after pack step
# The sync-versions generator writes actual versions back to source package.json files during build
# We need to restore placeholders before committing
- name: Reset dependency placeholders after pack
run: node scripts/reset-placeholders.js
# Use NX Release to publish all packages at once
# Authentication is handled via OIDC trusted publishing (id-token: write permission)
# setup-node with registry-url configures .npmrc for OIDC token exchange
# NPM_CONFIG_PROVENANCE generates signed provenance attestations
# NX Release publishes from dist/libs/{projectName} as configured in nx.json
# NPM tag is determined by release-tags action:
# - prerelease: for RC versions (e.g., 0.58.0-rc.19)
# - archive: for hotfix releases on older versions
# - latest: for stable releases
# IMPORTANT: Disable distributed execution for publishing (needs local dist/ files and npm auth)
- name: Publish packages to NPM using NX Release
run: |
echo "📦 Publishing all packages with npm tag: ${{ steps.releaseTags.outputs.npm }}"
npx nx release publish --tag="${{ steps.releaseTags.outputs.npm }}" --registry=https://registry.npmjs.org/
env:
NX_CLOUD_DISTRIBUTED_EXECUTION: false
NPM_CONFIG_PROVENANCE: true
# Create git commit and tag after successful build and publish
# We do this here instead of during 'nx release version' to ensure we only commit
# if build and publish succeed. The [ci skip] prevents triggering this workflow again.
- name: Commit version changes
if: env.IS_MANUAL != 'true'
run: |
git add .
git commit -m "chore(release): publish ${{ steps.bumpVersion.outputs.newVersion }} [ci skip]" || echo "No changes to commit"
# Create git tag for the release
# This tag is used by the GitHub release and for version resolution in future runs
- name: Create git tag
if: env.IS_MANUAL != 'true'
run: |
git tag -a "v${{ steps.bumpVersion.outputs.newVersion }}" -m "v${{ steps.bumpVersion.outputs.newVersion }}"
# Push both the commit and tags to the repository
# This will NOT trigger the workflow again due to [ci skip] in commit message
- name: Push changes and tags
if: env.IS_MANUAL != 'true'
run: |
if ! git push --follow-tags; then
echo "::error::Failed to push changes and tags"
exit 1
fi
# This will delete locally some tags to properly generate the release notes, so it should go after the push to upstream
- name: Generate Release Body
id: generate_body
uses: ./.github/actions/generate-conventional-release-notes
- name: Create Release
uses: ncipollo/release-action@v1.16.0
with:
prerelease: ${{ steps.bumpVersion.outputs.isPrerelease }}
tag: v${{ steps.bumpVersion.outputs.newVersion }}
body: ${{ steps.generate_body.outputs.generatedReleaseNotes }}
# This step is for pushing into the main only the version change, without anything else.
# This is useful when user created a Hotfix, and we need to sync the version on main
# if hotfix version is higher than latest stable and RC versions.
- name: Update version on main
if: env.IS_HOTFIX == 'true' && steps.releaseTags.outputs.mainNeedsSync == 'true'
run: |
git checkout -f main
npx nx release version ${{ steps.bumpVersion.outputs.newVersion }} --git-commit=false --git-tag=false
node scripts/reset-placeholders.js
node scripts/update-lerna-version.js ${{ steps.bumpVersion.outputs.newVersion }}
git add .
git commit -m "chore(release): sync version after hotfix v${{ steps.bumpVersion.outputs.newVersion }} [ci skip]"
git push origin main
# This step is responsible for cleaning up the temporary hotfix branch
- name: Delete Temporary hotfix branch
if: env.IS_HOTFIX == 'true'
run: git push origin --delete tmp_hotfix_branch
# Stop NX Cloud agents immediately if any step fails
# This prevents agents from running indefinitely when the main job fails
- name: Stop Nx Cloud agents on failure
if: failure()
run: npx --yes nx-cloud@latest stop-all-agents
env:
NX_CLOUD_AUTH_TOKEN: ${{ secrets.NX_CLOUD_AUTH_TOKEN }}
gh_pages:
name: Github Pages deploy
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
needs: create_release
if: ${{ needs.create_release.outputs.npmTag == 'latest' }}
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
with:
ref: main # always fetch from main branch
token: ${{ secrets.GHACTIONS }}
- name: Setup Node.js and Cache
uses: ./.github/actions/nodejs
with:
node-version: ${{ env.NODE_VERSION }}
- name: Run build prod
run: npx nx run docs:compile:production --skip-nx-cache
- name: Publish to gh-pages
uses: JamesIves/github-pages-deploy-action@v4.7.3
with:
folder: dist/apps/docs
token: ${{ secrets.GHACTIONS }}
repository-name: ${{ github.repository }}
stop_agents:
if: ${{ always() }}
needs: create_release
name: Nx Cloud - Stop Agents
runs-on: ubuntu-latest
environment: ci
permissions:
contents: read
steps:
- uses: actions/checkout@v4.2.2
with:
fetch-depth: 1
- name: Stop all running agents for this CI run
run: npx --yes nx-cloud@latest stop-all-agents
env:
NX_CLOUD_AUTH_TOKEN: ${{ secrets.NX_CLOUD_AUTH_TOKEN }}