Skip to content

Commit e2361ee

Browse files
committed
build: add a script for publishing to npm
Sets up a script that we can use to publish to npm so that we don't have to remember the steps.
1 parent 822dbbb commit e2361ee

File tree

5 files changed

+102
-11
lines changed

5 files changed

+102
-11
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ If you've cloned this repo and want to work on the tool, you have to install its
132132
running `pnpm install`.
133133
Once they're installed, you can run the following commands:
134134

135-
* `pnpm run release-build` - Builds the package in the `dist` directory for publishing to npm.
135+
* `pnpm run release-build` - Creates a release build of the package in `dist` directory.
136+
* `pnpm run npm-publish` - Builds the package and publishes it to npm.
136137
* `pnpm run eval` - Runs an eval from source.
137138
* `pnpm run report` - Runs the report app from source.
138139
* `pnpm run init` - Runs the init script from source.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "0.0.5",
44
"scripts": {
55
"build-runner": "tsc",
6-
"release-build": "tsx release-build.ts",
6+
"release-build": "tsx ./scripts/release-build.ts",
7+
"npm-publish": "tsx ./scripts/npm-publish.ts",
78
"web-codegen-scorer": "tsx ./runner/bin/cli.ts",
89
"wcs": "pnpm -s web-codegen-scorer",
910
"eval": "pnpm web-codegen-scorer eval",
@@ -92,4 +93,4 @@
9293
"prettier": "^3.5.3",
9394
"tsx": "^4.20.3"
9495
}
95-
}
96+
}

scripts/npm-publish.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { join } from 'path';
2+
import { spawn } from 'child_process';
3+
import { input } from '@inquirer/prompts';
4+
import { executeCommand } from '../runner/utils/exec.js';
5+
import { readFile, writeFile } from 'fs/promises';
6+
7+
const root = join(import.meta.dirname, '..');
8+
const distDirectory = join(root, 'dist');
9+
const packageJsonPath = join(root, 'package.json');
10+
const registry = 'https://wombat-dressing-room.appspot.com';
11+
12+
(async () => {
13+
try {
14+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8')) as {
15+
version: string;
16+
};
17+
18+
const version = await input({
19+
message: `Which version would you like to publish? Current version is ${packageJson.version}`,
20+
required: true,
21+
});
22+
23+
// Build the project.
24+
await executeCommand(
25+
`pnpm release-build --version=${version}`,
26+
root,
27+
undefined,
28+
{
29+
forwardStdoutToParent: true,
30+
forwardStderrToParent: true,
31+
}
32+
);
33+
34+
// Log into our registry.
35+
await spawnInteractive('npm', ['login', '--registry', registry]);
36+
37+
// Publish to npm.
38+
await executeCommand(
39+
`npm --registry ${registry} publish --access public --tag latest`,
40+
distDirectory,
41+
undefined,
42+
{
43+
forwardStderrToParent: true,
44+
forwardStdoutToParent: true,
45+
}
46+
);
47+
48+
// Write the package.json back to disk so the version is in sync.
49+
packageJson.version = version;
50+
await writeFile(packageJsonPath, JSON.stringify(packageJson, undefined, 2));
51+
52+
console.log('Done! 🎉');
53+
console.log('Remember to push the changed package.json!');
54+
} catch (e: unknown) {
55+
// If the user presses ctrl + c, Inquirer will throw `ExitPromptError`. Ignore it.
56+
if (!(e instanceof Error) || e.name !== 'ExitPromptError') {
57+
throw e;
58+
}
59+
}
60+
})();
61+
62+
function spawnInteractive(command: string, args: string[]) {
63+
return new Promise<void>((resolve, reject) => {
64+
const childProcess = spawn(command, args, {
65+
shell: true,
66+
stdio: 'inherit',
67+
});
68+
69+
childProcess.on('close', (status) =>
70+
status === 0 ? resolve() : reject(status)
71+
);
72+
});
73+
}

release-build.ts renamed to scripts/release-build.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
/// <reference types="node"/>
21
import { join } from 'path';
32
import { rm, cp, readFile, writeFile } from 'fs/promises';
43
import yargs from 'yargs';
54
import { hideBin } from 'yargs/helpers';
65
import { globSync as glob } from 'tinyglobby';
7-
import { executeCommand } from './runner/utils/exec.js';
6+
import { executeCommand } from '../runner/utils/exec.js';
87

9-
const root = import.meta.dirname;
8+
const root = join(import.meta.dirname, '..');
109
const runnerSource = join(root, 'runner');
1110
const targetDirectory = join(root, 'dist');
1211
const reportAppSource = join(root, 'report-app');
1312
const reportAppDist = join(reportAppSource, 'dist');
1413
const browserAgentRelativePath = 'runner/testing/browser-agent';
1514

1615
const args = yargs(hideBin(process.argv))
16+
.version(false)
1717
.option('runner-only', {
1818
type: 'boolean',
1919
default: false,
2020
})
21+
.option('version', {
22+
type: 'string',
23+
default: null,
24+
})
2125
.parseSync();
2226

2327
(async () => {
@@ -34,7 +38,7 @@ const args = yargs(hideBin(process.argv))
3438
// Generate the package.json.
3539
await writeFile(
3640
join(targetDirectory, 'package.json'),
37-
await getPackageJson(join(root, 'package.json'))
41+
await getPackageJson(join(root, 'package.json'), args.version)
3842
);
3943

4044
// Copy the readme and license.
@@ -86,17 +90,29 @@ const args = yargs(hideBin(process.argv))
8690
}
8791

8892
console.log(`Release output has been built in ${targetDirectory}`);
89-
90-
// TODO: also have `npm publish` here?
9193
})();
9294

93-
async function getPackageJson(path: string): Promise<string> {
95+
async function getPackageJson(
96+
path: string,
97+
version: string | null
98+
): Promise<string> {
9499
const content = await readFile(path, 'utf8');
95100
const parsed = JSON.parse(content) as {
101+
version: string;
96102
scripts?: unknown;
97103
devDependencies?: unknown;
98104
};
99105

106+
if (version) {
107+
if (version === parsed.version) {
108+
throw new Error(
109+
`Specified version is the same version as the current one.`
110+
);
111+
} else {
112+
parsed.version = version;
113+
}
114+
}
115+
100116
// Delete some fields that aren't relevant for end users.
101117
delete parsed.scripts;
102118
delete parsed.devDependencies;

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
"types": ["node"]
1414
},
1515
"include": ["runner/**/*.ts"],
16-
"exclude": ["node_modules", "examples"]
16+
"exclude": ["node_modules", "examples", "scripts"]
1717
}

0 commit comments

Comments
 (0)