-
Notifications
You must be signed in to change notification settings - Fork 7
160 lines (142 loc) · 6.08 KB
/
release.yml
File metadata and controls
160 lines (142 loc) · 6.08 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
name: Release
on:
workflow_dispatch:
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
# Required for npm Trusted Publishers via GitHub OIDC
# See: https://docs.npmjs.com/trusted-publishers
id-token: write
steps:
- name: Generate Release Bot App Token
id: generate-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_APP_PRIVATE_KEY }}
- uses: actions/checkout@v6
with:
# Persist releasebot app credentials to ensure that the push
# below can bypass branch protection rules
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true
fetch-depth: 0
# Branch validation: main for stable, prerelease/* for beta
- name: Validate branch
run: |
BRANCH="${{ github.ref }}"
if [ "$BRANCH" == "refs/heads/main" ]; then
echo "RELEASE_TYPE=stable" >> $GITHUB_ENV
echo "Detected stable release from main branch"
elif [[ "$BRANCH" == refs/heads/prerelease/* ]]; then
echo "RELEASE_TYPE=beta" >> $GITHUB_ENV
echo "Detected beta release from ${BRANCH#refs/heads/}"
else
echo "::error::This workflow can only be run from 'main' (stable) or 'prerelease/*' (beta) branches."
exit 1
fi
- uses: actions/setup-node@v6
with:
node-version: 20
cache: "npm"
# registry-url is required for npm Trusted Publishers
registry-url: "https://registry.npmjs.org"
# Upgrade to npm >=11.5.1 for Trusted Publishers support
- run: npm install -g npm@latest
- run: npm ci
- run: npm run check
# Stable release: verify prerelease mode is not active
- name: Verify no active prerelease mode
if: env.RELEASE_TYPE == 'stable'
run: |
if [ -f .changeset/pre.json ]; then
mode=$(node -e "console.log(require('./.changeset/pre.json').mode)")
if [ "$mode" = "pre" ]; then
echo "::error::Active prerelease mode detected on main."
echo "Prerelease mode must be exited before publishing a stable release."
exit 1
fi
echo "Prerelease mode is not active (mode=$mode)"
else
echo "No prerelease mode detected"
fi
# Beta: verify prerelease mode is active
- name: Verify prerelease mode
if: env.RELEASE_TYPE == 'beta'
run: |
if [ ! -f .changeset/pre.json ]; then
echo "::error::Prerelease mode is not active."
echo "Run 'npx changeset pre enter beta' and commit before running this workflow."
exit 1
fi
mode=$(node -e "console.log(require('./.changeset/pre.json').mode)")
if [ "$mode" != "pre" ]; then
echo "::error::Prerelease mode has been exited (mode=$mode)."
echo "Re-enter with 'npx changeset pre enter beta' or merge to main for a stable release."
exit 1
fi
echo "Prerelease mode is active"
# No .npmrc creation needed - npm Trusted Publishers uses GitHub OIDC tokens
# automatically via the id-token: write permission and registry-url configuration
# Stable release: changesets/action creates a Release PR with version
# bumps and changelogs. When merged, the next run publishes to npm.
- name: Create Release Pull Request or Publish
if: env.RELEASE_TYPE == 'stable'
id: changesets
uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1.7.0
with:
publish: npm run release
version: npm run version-packages
title: "chore: release package"
commit: "chore: release package"
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
NPM_CONFIG_PROVENANCE: true
# Beta release: version, commit, publish, and push in one step.
# changesets/action is not used here because it requires two workflow
# runs (one to create a version PR, another to publish after merging).
# For beta releases we want to publish immediately.
- name: Version packages (beta)
if: env.RELEASE_TYPE == 'beta'
# GITHUB_TOKEN is required for @changesets/changelog-github to fetch
# PR/commit information from GitHub API when generating changelog entries
run: npm run version-packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit and push version changes (beta)
if: env.RELEASE_TYPE == 'beta'
run: |
VERSION=$(node -p "require('./package.json').version")
echo "Versioning to: $VERSION"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --staged --quiet || git commit -m "chore: version packages (beta) - $VERSION"
git push
- name: Publish beta packages
if: env.RELEASE_TYPE == 'beta'
# changeset publish automatically uses the beta tag when in
# prerelease mode and creates git tags for the release
run: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_CONFIG_PROVENANCE: true
- name: Push git tags (beta)
if: env.RELEASE_TYPE == 'beta'
run: git push origin --tags
# Log published packages
- name: Log published packages
if: |
(env.RELEASE_TYPE == 'stable' && steps.changesets.outputs.published == 'true') ||
env.RELEASE_TYPE == 'beta'
run: |
if [ "${{ env.RELEASE_TYPE }}" == "stable" ]; then
echo "Published - ${{ steps.changesets.outputs.publishedPackages }}"
else
VERSION=$(node -p "require('./package.json').version")
echo "Published beta release: $VERSION"
fi