Skip to content

Commit 23ecced

Browse files
authored
chore(workflow): enable trusted publishing (#30)
1 parent 29e31fc commit 23ecced

3 files changed

Lines changed: 61 additions & 77 deletions

File tree

.github/workflows/release.yml

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,36 @@
1-
21
name: Release Full
32

43
on:
54
workflow_dispatch:
65
inputs:
7-
version:
8-
type: choice
9-
description: "Release Version Type"
10-
required: true
11-
default: "patch"
12-
options:
13-
- major
14-
- premajor
15-
- minor
16-
- preminor
17-
- patch
18-
- prepatch
19-
- prerelease
20-
216
tag:
227
type: choice
238
description: "Release Npm Tag"
249
required: true
25-
default: "latest"
10+
default: "nightly"
2611
options:
12+
- alpha
13+
- beta
2714
- canary
28-
- nightly
2915
- latest
30-
- beta
31-
- alpha
32-
16+
- nightly
17+
- rc
18+
3319
dry_run:
3420
type: boolean
3521
description: "DryRun release"
3622
required: true
3723
default: false
3824

3925
permissions:
26+
contents: write
4027
# To publish packages with provenance
4128
id-token: write
4229

4330
jobs:
4431
release:
4532
name: Release
46-
permissions:
47-
contents: write
48-
# To publish packages with provenance
49-
id-token: write
33+
environment: npm
5034
runs-on: ubuntu-latest
5135

5236
steps:
@@ -62,18 +46,22 @@ jobs:
6246
node-version: 20
6347
cache: "pnpm"
6448

49+
# Update npm to the latest version to enable OIDC
50+
- name: Update npm
51+
run: |
52+
npm install -g npm@latest
53+
npm --version
54+
6555
- name: Install Dependencies
6656
run: pnpm install
6757

6858
- name: Run Test
6959
run: pnpm run test
70-
71-
- name: Try release to npm
72-
run: pnpm run release
73-
env:
74-
DRY_RUN: ${{ inputs.dry_run }}
75-
TAG: ${{ inputs.tag }}
76-
VERSION: ${{ inputs.version }}
77-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
7860

79-
61+
- name: Dry run release to npm
62+
if: inputs.dry_run
63+
run: node scripts/release.mjs --dry-run --tag ${{ inputs.tag }}
64+
65+
- name: Release to npm
66+
if: ${{ !inputs.dry_run }}
67+
run: node scripts/release.mjs --tag ${{ inputs.tag }}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"prepare": "simple-git-hooks && npm run build",
2626
"test": "cross-env RSPACK_HOT_TEST=true jest --colors",
2727
"testu": "cross-env RSPACK_HOT_TEST=true jest --colors --updateSnapshot",
28-
"release": "node ./scripts/release.mjs"
28+
"release": "node ./scripts/release.mjs",
29+
"bump": "npx bumpp --no-push --no-tag --no-commit"
2930
},
3031
"files": [
3132
"client",
@@ -71,7 +72,6 @@
7172
"packageManager": "pnpm@10.17.1",
7273
"publishConfig": {
7374
"access": "public",
74-
"registry": "https://registry.npmjs.org/",
75-
"provenance": true
75+
"registry": "https://registry.npmjs.org/"
7676
}
7777
}

scripts/release.mjs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,64 @@
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';
10-
const RELEASE_NPM_TOKEN = process.env.NPM_TOKEN || '';
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+
});
1118

1219
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
1320
const PKG_PATH = path.resolve(__dirname, '../package.json');
1421
const pkg = fs.readJsonSync(PKG_PATH);
15-
const currentVersion = pkg.version;
16-
const nextVersion = inc(currentVersion, RELEASE_VERSION_TYPE);
17-
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 === 'true';
27+
28+
const allowedTags = ['latest', 'canary', 'alpha', 'beta', 'rc', 'nightly'];
29+
if (!allowedTags.includes(npmTag)) {
1830
throw new Error(
19-
`Failed to generate next version from "${currentVersion}" with type "${RELEASE_VERSION_TYPE}"`,
31+
`Invalid npm tag: ${npmTag}. Allowed tags: ${allowedTags.join(', ')}`,
2032
);
2133
}
2234

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

30-
// Write npmrc
31-
const npmrcPath = `${process.env.HOME}/.npmrc`;
32-
console.info(`Writing npmrc to ${npmrcPath}`);
33-
fs.writeFileSync(
34-
npmrcPath,
35-
`//registry.npmjs.org/:_authToken=${RELEASE_NPM_TOKEN}`,
43+
console.info(
44+
`Release ${npmTag} version ${publishVersion}${isDryRun ? '(dry-run)' : ''}`,
3645
);
3746

38-
// Publish to npm
39-
console.info(`Publishing to npm with tag ${RELEASE_TAG}`);
40-
const dryRun = RELEASE_DRY_RUN === 'true' ? ['--dry-run'] : [];
4147
try {
42-
await $`pnpm publish ${dryRun} --tag ${RELEASE_TAG} --no-git-checks --provenance`;
48+
const flags = isDryRun
49+
? ['--dry-run', `--tag`, npmTag, `--no-git-checks`]
50+
: [`--tag`, npmTag, `--no-git-checks`];
51+
await $`pnpm publish ${flags}`;
4352
console.info(`Published successfully`);
4453
} catch (e) {
4554
console.error(`Publish failed: ${e.message}`);
4655
process.exit(1);
47-
} finally {
48-
fs.removeSync(npmrcPath);
4956
}
5057

51-
// Push tag to github
52-
if (RELEASE_DRY_RUN !== 'true') {
58+
// Push tag to GitHub
59+
if (!isDryRun) {
5360
console.info(`Pushing tag to github`);
54-
const tagName = `v${nextVersion}`;
61+
const tagName = `v${publishVersion}`;
5562
try {
5663
await $`git config --global --add safe.directory /github/workspace`;
5764
await $`git config --global user.name "github-actions[bot]"`;
@@ -64,17 +71,6 @@ if (RELEASE_DRY_RUN !== 'true') {
6471
console.error(`Push tag failed: ${e.message}`);
6572
process.exit(1);
6673
}
67-
68-
try {
69-
await $`git add --all`;
70-
const commitMsg = `release ${tagName}`;
71-
await $`git commit -m ${commitMsg}`;
72-
await $`git push`;
73-
console.info(`Pushed branch successfully`);
74-
} catch (e) {
75-
console.error(`Update branch failed: ${e.message}`);
76-
process.exit(1);
77-
}
7874
}
7975

8076
console.info(`Release completed`);

0 commit comments

Comments
 (0)