Skip to content

Commit 03f8143

Browse files
committed
chore: split release to version and release for easy run release branch
1 parent 68cc737 commit 03f8143

File tree

5 files changed

+99
-52
lines changed

5 files changed

+99
-52
lines changed

.github/workflows/release.yml

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,6 @@ name: Release Full
33
on:
44
workflow_dispatch:
55
inputs:
6-
version:
7-
type: choice
8-
description: "Release Version Type"
9-
required: true
10-
default: "patch"
11-
options:
12-
- major
13-
- premajor
14-
- minor
15-
- preminor
16-
- patch
17-
- prepatch
18-
- prerelease
19-
206
tag:
217
type: choice
228
description: "Release Npm Tag"
@@ -71,9 +57,10 @@ jobs:
7157
- name: Run Test
7258
run: pnpm run test
7359

74-
- name: Try release to npm
75-
run: pnpm run release
76-
env:
77-
DRY_RUN: ${{ inputs.dry_run }}
78-
TAG: ${{ inputs.tag }}
79-
VERSION: ${{ inputs.version }}
60+
- name: Dry run release to npm
61+
if: inputs.dry_run == 'true'
62+
run: node scripts/release.js --dry-run --tag ${{ github.event.inputs.tag }}
63+
64+
- name: Dry run release to npm
65+
if: inputs.dry_run == 'false'
66+
run: node scripts/release.js --tag ${{ github.event.inputs.tag }}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@rspack/core": "1.4.11",
4242
"@types/jest": "29.5.14",
4343
"@types/node": "^22.17.0",
44+
"cac": "^6.7.14",
4445
"cross-env": "^10.0.0",
4546
"execa": "9.6.0",
4647
"fs-extra": "11.3.0",

pnpm-lock.yaml

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

scripts/release.mjs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,62 @@
11
import path from 'path';
22
import * as url from 'url';
3+
import cac from 'cac';
34
import { $ } from 'execa';
45
import fs from 'fs-extra';
5-
import { inc } from 'semver';
66

7-
const RELEASE_TAG = process.env.TAG || 'beta';
8-
const RELEASE_DRY_RUN = process.env.DRY_RUN || 'true';
9-
const RELEASE_VERSION_TYPE = process.env.VERSION || 'prerelease';
7+
let cli = cac('release');
8+
cli.option(
9+
'--dry-run <run>',
10+
'Perform a dry run without publishing or pushing tags',
11+
{
12+
default: 'false',
13+
},
14+
);
15+
cli.option('--tag <tag>', 'The npm tag to publish under (default: canary)', {
16+
default: 'canary',
17+
});
1018

1119
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
1220
const PKG_PATH = path.resolve(__dirname, '../package.json');
1321
const pkg = fs.readJsonSync(PKG_PATH);
14-
const currentVersion = pkg.version;
15-
const nextVersion = inc(currentVersion, RELEASE_VERSION_TYPE);
16-
if (!nextVersion) {
22+
const publishVersion = pkg.version;
23+
24+
const parsed = cli.parse();
25+
const npmTag = parsed.options.tag;
26+
const isDryRun = parsed.options.dryRun;
27+
28+
const allowedTags = ['latest', 'canary', 'alpha', 'beta', 'rc'];
29+
if (!allowedTags.includes(npmTag)) {
1730
throw new Error(
18-
`Failed to generate next version from "${currentVersion}" with type "${RELEASE_VERSION_TYPE}"`,
31+
`Invalid npm tag: ${npmTag}. Allowed tags: ${allowedTags.join(', ')}`,
1932
);
2033
}
2134

22-
console.info(`Release ${RELEASE_TAG} version ${nextVersion}`);
23-
24-
// Update pkg version
25-
console.info(`Updating version from ${currentVersion} to ${nextVersion}`);
26-
pkg.version = nextVersion;
27-
fs.writeJsonSync(PKG_PATH, pkg, { spaces: 2 });
35+
const prereleaseTags = ['alpha', 'beta', 'rc', 'canary'];
36+
if (
37+
npmTag === 'latest' &&
38+
prereleaseTags.some((tag) => publishVersion.includes(tag))
39+
) {
40+
throw Error(`Can't release ${publishVersion} to latest tag`);
41+
}
2842

29-
// Publish to npm
30-
console.info(`Publishing to npm with tag ${RELEASE_TAG}`);
31-
const dryRun = RELEASE_DRY_RUN === 'true' ? ['--dry-run'] : [];
43+
console.info(`Release ${npmTag} version ${publishVersion}`);
3244

3345
try {
34-
await $`pnpm publish ${dryRun} --tag ${RELEASE_TAG} --no-git-checks`;
46+
const flags = isDryRun
47+
? ['--dry-run', `--tag`, npmTag, `--no-git-checks`]
48+
: [`--tag`, npmTag, `--no-git-checks`];
49+
await $`pnpm publish ${flags}`;
3550
console.info(`Published successfully`);
3651
} catch (e) {
3752
console.error(`Publish failed: ${e.message}`);
3853
process.exit(1);
3954
}
4055

41-
// Push tag to github
42-
if (RELEASE_DRY_RUN !== 'true') {
56+
// Push tag to GitHub
57+
if (!isDryRun) {
4358
console.info(`Pushing tag to github`);
44-
const tagName = `v${nextVersion}`;
59+
const tagName = `v${publishVersion}`;
4560
try {
4661
await $`git config --global --add safe.directory /github/workspace`;
4762
await $`git config --global user.name "github-actions[bot]"`;
@@ -54,17 +69,6 @@ if (RELEASE_DRY_RUN !== 'true') {
5469
console.error(`Push tag failed: ${e.message}`);
5570
process.exit(1);
5671
}
57-
58-
try {
59-
await $`git add --all`;
60-
const commitMsg = `release ${tagName}`;
61-
await $`git commit -m ${commitMsg}`;
62-
await $`git push`;
63-
console.info(`Pushed branch successfully`);
64-
} catch (e) {
65-
console.error(`Update branch failed: ${e.message}`);
66-
process.exit(1);
67-
}
6872
}
6973

7074
console.info(`Release completed`);

scripts/version.mjs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { readFileSync, writeFileSync } from 'fs';
2+
import { dirname, join } from 'path';
3+
import { fileURLToPath } from 'url';
4+
import { cac } from 'cac';
5+
import semver from 'semver';
6+
7+
const cli = cac('version');
8+
cli.option('--pre [prerelease]', 'Set the version to a pre-release version');
9+
cli.command('version <bump_version>');
10+
const parsed = cli.parse();
11+
12+
const __dirname = dirname(fileURLToPath(import.meta.url));
13+
const pkgPath = join(__dirname, '../package.json');
14+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
15+
const currentVersion = pkg.version;
16+
17+
const allowedVersion = ['major', 'minor', 'patch'];
18+
const allowPretags = ['alpha', 'beta', 'rc'];
19+
20+
const version = parsed.args[0];
21+
22+
if (!allowedVersion.includes(version)) {
23+
throw new Error(
24+
`version must be one of ${allowedVersion}, but you passed ${version}`,
25+
);
26+
}
27+
28+
const hasPre = !!parsed.options.pre;
29+
const pre = parsed.options.pre;
30+
31+
if (hasPre && !allowPretags.includes(pre)) {
32+
throw new Error(
33+
`pre tag must be one of ${allowPretags}, but you passed ${pre}`,
34+
);
35+
}
36+
37+
let newVersion;
38+
if (hasPre) {
39+
newVersion = semver.inc(currentVersion, `prerelease`, pre);
40+
} else {
41+
newVersion = semver.inc(currentVersion, version);
42+
}
43+
44+
pkg.version = newVersion;
45+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
46+
console.log('package.json updated with new version.');

0 commit comments

Comments
 (0)