Skip to content

Commit b36c8dc

Browse files
build(next): Add release script (#114)
* tests(next): reuse existing tests but with different imports * build(next): Simplify test setup (#112) * Fix * Update jest.config.js * Update babel.config.js * chore: add default node version --------- Co-authored-by: David Dragovacz <[email protected]> * chore: apply changes based on review * build(next): add release script based on existing ones * build(next): add release:next scripts * chore: make changes based on review * build(next): adjust release script * Release next 1.0.0-alpha.1 * build(next): change release script - includes separate `dev` and `beta` versions - `dev` will work the same way as the main `dev` script that we have where we append the version with the timestamp - `beta` will increment the version in the `/next/package.json` file * build(next): add new scripts * build(next): do not update package.json with dev versions * build(next): adjust script to always use the current version * Release v1-beta 1.0.0-beta.1 * build(next): add `files` to package.json * build(next): correct main entry * Release v1-beta 1.0.0-beta.2 * build(next): release rules prevents the `dev` release when on `main` branch only allows a `beta` release when on `main` branch and local branch up to date * build(next): simplify `bumpVersion` * build(next): generate changelog for beta releases * fix: versioning bug * build(next): check dev version restriction - this checks the version in the `next` package before merging and fails if it is anything other than `beta` - this commit should make the build fail since I'm checking if it is `beta` (for testing purposes) * build(next): correcting version check * chore: reset version --------- Co-authored-by: thien-remote <[email protected]>
1 parent 9721c18 commit b36c8dc

File tree

6 files changed

+251
-4
lines changed

6 files changed

+251
-4
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ jobs:
6060
run: npm run lint
6161
- run: npm run prettier:check
6262
- run: npm run check:pr-version
63+
- run: npm run check:pr-next-version

next/package.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@remoteoss/json-schema-form",
3-
"version": "1.0.0-alpha.1",
3+
"version": "1.0.0-beta.0",
44
"packageManager": "[email protected]",
55
"description": "WIP V2 – Headless UI form powered by JSON Schemas",
66
"author": "Remote.com <[email protected]> (https://remote.com/)",
@@ -16,16 +16,23 @@
1616
"json-schema",
1717
"form"
1818
],
19-
"main": "index.js",
19+
"main": "dist/index.mjs",
20+
"module": "dist/index.mjs",
21+
"files": [
22+
"README.md",
23+
"dist"
24+
],
2025
"engines": {
21-
"node": "22.13.1"
26+
"node": ">=18.14.0"
2227
},
2328
"scripts": {
29+
"build": "tsup",
2430
"test": "jest",
2531
"test:watch": "jest --watchAll",
2632
"test:file": "jest --runTestsByPath",
2733
"lint": "eslint --max-warnings 0 .",
28-
"build": "tsup"
34+
"release:dev": "cd .. && npm run release:v1:dev",
35+
"release:beta": "cd .. && npm run release:v1:beta"
2936
},
3037
"devDependencies": {
3138
"@antfu/eslint-config": "^3.14.0",
@@ -35,6 +42,7 @@
3542
"@jest/globals": "^29.7.0",
3643
"babel-jest": "^29.7.0",
3744
"eslint": "^9.18.0",
45+
"generate-changelog": "^1.8.0",
3846
"jest": "^29.7.0",
3947
"json-schema-typed": "^8.0.1",
4048
"tsup": "^8.3.5",

next/pnpm-lock.yaml

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@
3232
"format:prettier": "prettier --write \"src/**/*.{js,ts}\"",
3333
"prettier:check": "prettier --check \"src/**/*.{js,ts}\"",
3434
"check:pr-version": "node scripts/pr_dev_version",
35+
"check:pr-next-version": "node scripts/pr_next_dev_version",
3536
"release:local": "node scripts/release_local",
3637
"release:dev:patch": "node scripts/release_dev patch",
3738
"release:dev:minor": "node scripts/release_dev minor",
3839
"release:main:patch": "node scripts/release_main patch",
3940
"release:main:minor": "node scripts/release_main minor",
41+
"release:v1:dev": "node scripts/release_v1 dev",
42+
"release:v1:beta": "node scripts/release_v1 beta",
4043
"version_as_main": "node scripts/version_as_main.js",
4144
"psrepublishOnly": "if [[ ! $PWD =~ scripts$ ]]; then npm run publish:nopublish; fi",
4245
"psublish:nopublish": "echo 'Use `npm release:*` script instead && exit 1"

scripts/pr_next_dev_version.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
function init() {
5+
const packageJson = fs.readFileSync(path.resolve(__dirname, '../next/package.json'), 'utf8');
6+
const { version } = JSON.parse(packageJson);
7+
8+
if (version.includes('-dev')) {
9+
console.log(
10+
`🟠 This PR cannot be merged because the next/package.json version ${version} contains "-dev".` +
11+
'\n The version in next/package.json should be a beta version (e.g., 1.0.0-beta.0).'
12+
);
13+
process.exit(1);
14+
}
15+
16+
if (!version.includes('-beta.')) {
17+
console.log(
18+
`🟠 This PR cannot be merged because the next/package.json version ${version} is not a beta version.` +
19+
'\n The version in next/package.json should be in format X.X.X-beta.Y (e.g., 1.0.0-beta.0).'
20+
);
21+
process.exit(1);
22+
}
23+
24+
console.log(
25+
`The package version in next/package.json is ${version} and seems valid. Continuing...`
26+
);
27+
}
28+
29+
init();

scripts/release_v1.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
const path = require('path');
2+
3+
const semver = require('semver');
4+
5+
const {
6+
askForConfirmation,
7+
askForText,
8+
checkGitStatus,
9+
checkNpmAuth,
10+
runExec,
11+
revertCommit,
12+
revertChanges,
13+
getDateYYYYMMDDHHMMSS,
14+
} = require('./release.helpers');
15+
16+
const packageJsonPath = path.resolve(__dirname, '../next/package.json');
17+
const packageJson = require(packageJsonPath);
18+
19+
async function checkGitBranchAndStatus() {
20+
const releaseType = process.argv[2];
21+
console.log(`Checking your branch for ${releaseType} release...`);
22+
23+
const resultBranch = await runExec('git branch --show-current', {
24+
silent: true,
25+
});
26+
const branchName = resultBranch.stdout.toString().trim();
27+
28+
if (releaseType === 'dev') {
29+
// For dev releases, cannot be on main branch
30+
if (branchName === 'main') {
31+
console.error(`🟠 You are at "main". Dev versions cannot be released from main branch.`);
32+
process.exit(1);
33+
}
34+
} else if (releaseType === 'beta') {
35+
// For beta releases, must be on main branch and up to date
36+
if (branchName !== 'main') {
37+
console.error(
38+
`🟠 You are at "${branchName}" instead of "main" branch. Beta versions must be released from main.`
39+
);
40+
process.exit(1);
41+
}
42+
43+
// Check if local main is up to date
44+
await runExec('git remote update', { silent: true });
45+
const resultStatus = await runExec('git status -uno', { silent: true });
46+
const mainStatus = resultStatus.stdout.toString().trim();
47+
48+
if (!mainStatus.includes("Your branch is up to date with 'origin/main'.")) {
49+
console.error(`🟠 Please make sure your branch is up to date with the git repo.`);
50+
process.exit(1);
51+
}
52+
}
53+
54+
await checkGitStatus();
55+
}
56+
57+
async function getNewVersion() {
58+
const releaseType = process.argv[2];
59+
if (!['dev', 'beta'].includes(releaseType)) {
60+
console.error('🟠 Invalid release type. Use dev or beta');
61+
process.exit(1);
62+
}
63+
64+
const currentVersion = packageJson.version;
65+
66+
if (releaseType === 'dev') {
67+
const timestamp = getDateYYYYMMDDHHMMSS();
68+
console.log('Creating new dev version...');
69+
return `1.0.0-dev.${timestamp}`;
70+
}
71+
72+
// For beta releases
73+
console.log('Creating new beta version...');
74+
if (currentVersion.includes('-beta.')) {
75+
return semver.inc(currentVersion, 'prerelease', 'beta');
76+
}
77+
78+
console.error(
79+
`🟠 Cannot create beta version: Current version "${currentVersion}" is not a beta version.\n` +
80+
' The package.json version should be in the format "1.0.0-beta.X"'
81+
);
82+
process.exit(1);
83+
}
84+
85+
async function bumpVersion({ newVersion }) {
86+
const cmd = `cd next && npm version --no-git-tag-version ${newVersion}`;
87+
await runExec(cmd);
88+
}
89+
90+
async function build() {
91+
console.log('Building next version...');
92+
const cmd = 'cd next && npm run build';
93+
await runExec(cmd);
94+
}
95+
96+
async function updateChangelog() {
97+
console.log('Updating changelog...');
98+
const cmd = 'cd next && npx generate-changelog';
99+
await runExec(cmd);
100+
}
101+
102+
async function gitCommit({ newVersion, releaseType }) {
103+
console.log('Committing published version...');
104+
const prefix = `v1-${releaseType}`;
105+
106+
let cmd;
107+
if (releaseType === 'beta') {
108+
// For beta, we commit package.json changes and changelog
109+
cmd = `git add next/package.json next/CHANGELOG.md && git commit -m "Release ${prefix} ${newVersion}" && git tag ${prefix}-${newVersion} && git push && git push origin --tags`;
110+
} else {
111+
// For dev, we only create a tag
112+
cmd = `git tag ${prefix}-${newVersion} && git push origin --tags`;
113+
}
114+
115+
await runExec(cmd);
116+
}
117+
118+
async function publish({ newVersion, releaseType, otp }) {
119+
console.log('Publishing new version...');
120+
const npmTag = `v1-${releaseType}`;
121+
const originalVersion = packageJson.version;
122+
123+
try {
124+
// Publish with the dev/beta version
125+
const cmd = `cd next && npm publish --access=public --tag=${npmTag} --otp=${otp}`;
126+
await runExec(cmd);
127+
128+
// For dev releases, revert package.json back to original version
129+
if (releaseType === 'dev') {
130+
const revertCmd = `cd next && npm version --no-git-tag-version ${originalVersion}`;
131+
await runExec(revertCmd);
132+
}
133+
134+
console.log(`🎉 ${npmTag} version ${newVersion} published!`);
135+
console.log(`Install with: npm i @remoteoss/json-schema-form@${npmTag}`);
136+
} catch {
137+
console.log('🚨 Publish failed! Perhaps the OTP is wrong.');
138+
await revertCommit({ newVersion });
139+
}
140+
}
141+
142+
async function init() {
143+
const releaseType = process.argv[2];
144+
await checkGitBranchAndStatus();
145+
const newVersion = await getNewVersion();
146+
147+
console.log(':: Current version:', packageJson.version);
148+
console.log(`:::::: New version (${releaseType}):`, newVersion);
149+
150+
const answer = await askForConfirmation('Ready to commit and publish it?');
151+
152+
if (answer === 'no') {
153+
process.exit(1);
154+
}
155+
156+
await checkNpmAuth();
157+
158+
await bumpVersion({ newVersion });
159+
160+
// Only update changelog for beta releases
161+
if (releaseType === 'beta') {
162+
await updateChangelog();
163+
const answerChangelog = await askForConfirmation(
164+
'Changelog is updated. You may tweak it as needed. Once ready, press Y to continue.'
165+
);
166+
if (answerChangelog === 'no') {
167+
await revertChanges();
168+
}
169+
}
170+
171+
await build();
172+
const otp = await askForText('🔐 What is the NPM Auth OTP? (Check 1PW) ');
173+
174+
await gitCommit({ newVersion, releaseType });
175+
await publish({ newVersion, releaseType, otp });
176+
}
177+
178+
init();

0 commit comments

Comments
 (0)