Skip to content

Commit eb4eb02

Browse files
committed
Enhance release process with beta version support
1 parent e1d60ea commit eb4eb02

File tree

3 files changed

+148
-36
lines changed

3 files changed

+148
-36
lines changed

.github/workflows/build-prebuilds-publish.yaml

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -160,65 +160,114 @@ jobs:
160160
VERSION="${{ github.ref_name }}"
161161
VERSION_NO_V="${VERSION#v}"
162162
163+
# Check if this is a beta release
164+
IS_BETA="false"
165+
if [[ "$VERSION_NO_V" == *"-beta."* ]]; then
166+
IS_BETA="true"
167+
# Extract base version (e.g., 5.2.0 from 5.2.0-beta.1)
168+
BASE_VERSION="${VERSION_NO_V%%-beta.*}"
169+
fi
170+
163171
# Start building the release body
164-
cat > release_notes.md << 'EOF'
165-
## node-av Release ${{ github.ref_name }}
166-
167-
### 📦 Updated Packages
168-
169-
The following platform packages have been updated to ${{ github.ref_name }}:
170-
- `@seydx/node-av-darwin-arm64@${{ github.ref_name }}`
171-
- `@seydx/node-av-darwin-x64@${{ github.ref_name }}`
172-
- `@seydx/node-av-linux-arm64@${{ github.ref_name }}`
173-
- `@seydx/node-av-linux-x64@${{ github.ref_name }}`
174-
- `@seydx/node-av-win32-arm64-mingw@${{ github.ref_name }}`
175-
- `@seydx/node-av-win32-x64-mingw@${{ github.ref_name }}`
176-
- `@seydx/node-av-win32-arm64-msvc@${{ github.ref_name }}`
177-
- `@seydx/node-av-win32-x64-msvc@${{ github.ref_name }}`
178-
EOF
172+
echo "" > release_notes.md
179173
180-
# Extract the specific version section from CHANGELOG.md
181-
if [ -f "CHANGELOG.md" ]; then
182-
# Extract content for this specific version
183-
VERSION_CONTENT=$(sed -n "/## \[${VERSION_NO_V}\]/,/## \[/p" CHANGELOG.md | sed '$d')
174+
# Beta warning at the top
175+
if [ "$IS_BETA" = "true" ]; then
176+
echo "> ⚠️ This is a pre-release version for testing. Install with: \`npm install node-av@beta\`" >> release_notes.md
177+
echo "" >> release_notes.md
178+
fi
184179
180+
# Extract the specific version section from CHANGELOG.md (only for stable releases)
181+
if [ "$IS_BETA" = "false" ] && [ -f "CHANGELOG.md" ]; then
182+
VERSION_CONTENT=$(sed -n "/## \[${VERSION_NO_V}\]/,/## \[/p" CHANGELOG.md | sed '$d')
185183
if [ -n "$VERSION_CONTENT" ]; then
186-
echo "" >> release_notes.md
187-
# Remove the version header line and add content
188184
echo "$VERSION_CONTENT" | tail -n +2 >> release_notes.md
185+
echo "" >> release_notes.md
189186
fi
190187
fi
191188
192-
# Always add commit history
193-
PREVIOUS_TAG=$(git describe --tags --abbrev=0 ${{ github.ref_name }}^ 2>/dev/null || echo "")
194-
if [ -n "$PREVIOUS_TAG" ]; then
189+
# Find the last stable tag (not a beta tag) for commit history
190+
LAST_STABLE_TAG=$(git tag -l 'v*' | grep -v '\-beta\.' | sort -V | tail -1)
191+
echo "Last stable tag: $LAST_STABLE_TAG"
192+
193+
if [ -n "$LAST_STABLE_TAG" ] && [ "$LAST_STABLE_TAG" != "${{ github.ref_name }}" ]; then
194+
echo "### 📋 All Changes since $LAST_STABLE_TAG" >> release_notes.md
195195
echo "" >> release_notes.md
196-
echo "### 📋 All Changes since $PREVIOUS_TAG" >> release_notes.md
196+
git log --pretty=format:"- %s (%h) - @%an" $LAST_STABLE_TAG..${{ github.ref_name }} >> release_notes.md
197197
echo "" >> release_notes.md
198-
git log --pretty=format:"- %s (%h) - @%an" $PREVIOUS_TAG..${{ github.ref_name }} >> release_notes.md
199198
fi
200199
200+
# Platform packages at the end
201+
cat >> release_notes.md << EOF
202+
203+
The following platform packages have been updated to v$VERSION_NO_V:
204+
- \`@seydx/node-av-darwin-arm64@$VERSION_NO_V\`
205+
- \`@seydx/node-av-darwin-x64@$VERSION_NO_V\`
206+
- \`@seydx/node-av-linux-arm64@$VERSION_NO_V\`
207+
- \`@seydx/node-av-linux-x64@$VERSION_NO_V\`
208+
- \`@seydx/node-av-win32-arm64-mingw@$VERSION_NO_V\`
209+
- \`@seydx/node-av-win32-x64-mingw@$VERSION_NO_V\`
210+
- \`@seydx/node-av-win32-arm64-msvc@$VERSION_NO_V\`
211+
- \`@seydx/node-av-win32-x64-msvc@$VERSION_NO_V\`
212+
EOF
213+
201214
# Output the release notes
202215
cat release_notes.md
203216
217+
- name: Determine NPM tag
218+
id: npm_tag
219+
run: |
220+
VERSION="${GITHUB_REF#refs/tags/v}"
221+
echo "Version: $VERSION"
222+
223+
# Determine NPM dist-tag based on version
224+
if [[ "$VERSION" == *"-beta."* ]]; then
225+
echo "tag=beta" >> $GITHUB_OUTPUT
226+
echo "NPM tag: beta"
227+
else
228+
echo "tag=latest" >> $GITHUB_OUTPUT
229+
echo "NPM tag: latest"
230+
fi
231+
204232
- name: Publish to NPM
205233
run: |
234+
NPM_TAG="${{ steps.npm_tag.outputs.tag }}"
235+
echo "Publishing with tag: $NPM_TAG"
236+
206237
# Publish platform packages
207238
for pkg_dir in packages/*/; do
208239
if [ -d "$pkg_dir" ]; then
209240
cd "$pkg_dir"
210-
npm publish --access public
241+
npm publish --access public --tag "$NPM_TAG"
211242
cd -
212243
fi
213244
done
214245
215246
# Publish main package
216-
npm publish --access public
247+
npm publish --access public --tag "$NPM_TAG"
217248
env:
218249
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
219250

251+
- name: Delete existing pre-release
252+
run: |
253+
VERSION="${GITHUB_REF#refs/tags/v}"
254+
255+
# Find and delete ALL existing pre-releases (we only keep one at a time)
256+
echo "Deleting all existing pre-releases..."
257+
RELEASES=$(gh release list --json tagName,isPrerelease -q ".[] | select(.isPrerelease == true) | .tagName" 2>/dev/null || echo "")
258+
259+
for TAG in $RELEASES; do
260+
if [ "$TAG" != "v$VERSION" ]; then
261+
echo "Deleting pre-release: $TAG"
262+
gh release delete "$TAG" --yes --cleanup-tag 2>/dev/null || true
263+
fi
264+
done
265+
env:
266+
GH_TOKEN: ${{ github.token }}
267+
220268
- name: Create GitHub Release
221269
uses: softprops/action-gh-release@v2
222270
with:
223271
files: "*.zip"
224272
body_path: release_notes.md
273+
prerelease: ${{ steps.npm_tag.outputs.tag == 'beta' }}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
"release:patch": "npm run build:tsc && node scripts/prepare-release.js patch",
6464
"release:minor": "npm run build:tsc && node scripts/prepare-release.js minor",
6565
"release:major": "npm run build:tsc && node scripts/prepare-release.js major",
66+
"release:beta:patch": "npm run build:tsc && node scripts/prepare-release.js beta-patch",
67+
"release:beta:minor": "npm run build:tsc && node scripts/prepare-release.js beta-minor",
68+
"release:beta:major": "npm run build:tsc && node scripts/prepare-release.js beta-major",
6669
"test": "tsx --test test/*.test.ts",
6770
"test:all": "npm run build:tests && npm run build:tsc && tsx --test test/*.test.ts",
6871
"update": "updates --update ./"

scripts/prepare-release.js

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,19 @@ import { fileURLToPath } from 'url';
88
const __dirname = dirname(fileURLToPath(import.meta.url));
99
const rootDir = join(__dirname, '..');
1010

11-
// Get version type from command line (patch, minor, major)
11+
// Get version type from command line
1212
const versionType = process.argv[2] || 'patch';
1313

14-
if (!['patch', 'minor', 'major'].includes(versionType)) {
15-
console.error('Usage: node prepare-release.js [patch|minor|major]');
14+
const validTypes = ['patch', 'minor', 'major', 'beta-patch', 'beta-minor', 'beta-major'];
15+
if (!validTypes.includes(versionType)) {
16+
console.error('Usage: node prepare-release.js [patch|minor|major|beta-patch|beta-minor|beta-major]');
17+
console.error('');
18+
console.error(' patch - Bump patch version (1.0.0 -> 1.0.1), or promote beta to stable');
19+
console.error(' minor - Bump minor version (1.0.0 -> 1.1.0), or promote beta to stable');
20+
console.error(' major - Bump major version (1.0.0 -> 2.0.0), or promote beta to stable');
21+
console.error(' beta-patch - Create/bump beta (1.0.0 -> 1.0.1-beta.1, or beta.1 -> beta.2)');
22+
console.error(' beta-minor - Create/bump beta (1.0.0 -> 1.1.0-beta.1, or beta.1 -> beta.2)');
23+
console.error(' beta-major - Create/bump beta (1.0.0 -> 2.0.0-beta.1, or beta.1 -> beta.2)');
1624
process.exit(1);
1725
}
1826

@@ -23,19 +31,71 @@ const packagePath = join(rootDir, 'package.json');
2331
const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
2432
const currentVersion = packageJson.version;
2533

26-
// Calculate new version
27-
const [major, minor, patch] = currentVersion.split('.').map(Number);
34+
// Parse current version (handles both regular and prerelease versions)
35+
const versionMatch = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)(?:-(alpha|beta|rc)\.(\d+))?$/);
36+
if (!versionMatch) {
37+
console.error(`Invalid current version format: ${currentVersion}`);
38+
process.exit(1);
39+
}
40+
41+
const [, majorStr, minorStr, patchStr, currentPreType, currentPreNum] = versionMatch;
42+
const major = Number(majorStr);
43+
const minor = Number(minorStr);
44+
const patch = Number(patchStr);
45+
2846
let newVersion;
2947

48+
// Check if we're currently on a prerelease version
49+
const isPrerelease = currentPreType !== undefined;
50+
3051
switch (versionType) {
3152
case 'major':
32-
newVersion = `${major + 1}.0.0`;
53+
// If on prerelease, promote to stable; otherwise bump major
54+
if (isPrerelease) {
55+
newVersion = `${major}.${minor}.${patch}`;
56+
} else {
57+
newVersion = `${major + 1}.0.0`;
58+
}
3359
break;
3460
case 'minor':
35-
newVersion = `${major}.${minor + 1}.0`;
61+
// If on prerelease, promote to stable; otherwise bump minor
62+
if (isPrerelease) {
63+
newVersion = `${major}.${minor}.${patch}`;
64+
} else {
65+
newVersion = `${major}.${minor + 1}.0`;
66+
}
3667
break;
3768
case 'patch':
38-
newVersion = `${major}.${minor}.${patch + 1}`;
69+
// If on prerelease, promote to stable; otherwise bump patch
70+
if (isPrerelease) {
71+
newVersion = `${major}.${minor}.${patch}`;
72+
} else {
73+
newVersion = `${major}.${minor}.${patch + 1}`;
74+
}
75+
break;
76+
case 'beta-patch':
77+
// If already on beta, increment beta number; otherwise create new beta
78+
if (isPrerelease && currentPreType === 'beta') {
79+
newVersion = `${major}.${minor}.${patch}-beta.${Number(currentPreNum) + 1}`;
80+
} else {
81+
newVersion = `${major}.${minor}.${patch + 1}-beta.1`;
82+
}
83+
break;
84+
case 'beta-minor':
85+
// If already on beta, increment beta number; otherwise create new beta
86+
if (isPrerelease && currentPreType === 'beta') {
87+
newVersion = `${major}.${minor}.${patch}-beta.${Number(currentPreNum) + 1}`;
88+
} else {
89+
newVersion = `${major}.${minor + 1}.0-beta.1`;
90+
}
91+
break;
92+
case 'beta-major':
93+
// If already on beta, increment beta number; otherwise create new beta
94+
if (isPrerelease && currentPreType === 'beta') {
95+
newVersion = `${major}.${minor}.${patch}-beta.${Number(currentPreNum) + 1}`;
96+
} else {
97+
newVersion = `${major + 1}.0.0-beta.1`;
98+
}
3999
break;
40100
}
41101

0 commit comments

Comments
 (0)