Skip to content

Commit e1e417b

Browse files
authoredJul 23, 2020
Merge pull request #8 from Jskobos/add-dry-run
Add support for npm publish --dry-run
2 parents eba6c49 + 7ddae30 commit e1e417b

14 files changed

+186
-10
lines changed
 

‎README.md

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ You can set any or all of the following input parameters:
7878
|`registry` |string |no |https://registry.npmjs.org/ |The NPM registry URL to use
7979
|`package` |string |no |./package.json |The path of your package.json file
8080
|`check-version` |boolean |no |true |Only publish to NPM if the version number in `package.json` differs from the latest on NPM
81+
|`dry-run` |boolean |no |false |Run NPM publish with the `--dry-run` flag to prevent publication.
8182

8283

8384

@@ -194,6 +195,8 @@ options:
194195

195196
--help, -h Show help
196197

198+
--dry-run Pass the `--dry-run` flag to NPM
199+
197200
package_path The absolute or relative path of the NPM package to publish.
198201
Can be a directory path, or the path of a package.json file.
199202
Defaults to the current directory.

‎action.yml

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ inputs:
2929
required: false
3030
default: "true"
3131

32+
dry-run:
33+
description: If true, run with the --dry-run flag
34+
required: false
35+
default: "false"
36+
3237
outputs:
3338
type:
3439
description: The type of version change that occurred ("none", "major", "minor", "patch", etc.)

‎src/action/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,19 @@ async function main(): Promise<void> {
1818
registry: getInput("registry", { required: true }),
1919
package: getInput("package", { required: true }),
2020
checkVersion: getInput("check-version", { required: true }).toLowerCase() === "true",
21+
dryRun: getInput("dry-run").toLowerCase() === "true",
2122
debug: debugHandler,
2223
};
2324

24-
// Puglish to NPM
25+
// Publish to NPM
2526
let results = await npmPublish(options);
2627

2728
if (results.type === "none") {
2829
console.log(`\n📦 ${results.package} v${results.version} is already published to NPM`);
2930
}
31+
else if (results.dryRun) {
32+
console.log(`\n📦 ${results.package} v${results.version} successfully built but not published to NPM`);
33+
}
3034
else {
3135
console.log(`\n📦 Successfully published ${results.package} v${results.version} to NPM`);
3236
}

‎src/cli/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export async function main(args: string[]): Promise<void> {
3737
if (results.type === "none") {
3838
console.log(`\n📦 ${results.package} v${results.version} is already published to NPM`);
3939
}
40+
else if (results.dryRun) {
41+
console.log(`\n📦 ${results.package} v${results.version} successfully built but not published to NPM`);
42+
}
4043
else {
4144
console.log(`\n📦 Successfully published ${results.package} v${results.version} to NPM`);
4245
}

‎src/cli/parse-args.ts

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export function parseArgs(argv: string[]): ParsedArgs {
2828
{ name: "quiet", alias: "q", type: Boolean },
2929
{ name: "version", alias: "v", type: Boolean },
3030
{ name: "help", alias: "h", type: Boolean },
31+
{ name: "dry-run", type: Boolean, defaultOption: false }
3132
],
3233
{ argv }
3334
);
@@ -49,6 +50,7 @@ export function parseArgs(argv: string[]): ParsedArgs {
4950
package: args.package as string,
5051
debug: args.debug ? console.debug : undefined,
5152
quiet: args.quiet as boolean,
53+
dryRun: args["dry-run"] as boolean
5254
}
5355
};
5456

‎src/normalize-options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface NormalizedOptions {
1010
registry: URL;
1111
package: string;
1212
checkVersion: boolean;
13+
dryRun: boolean;
1314
quiet: boolean;
1415
debug: Debug;
1516
}
@@ -26,6 +27,7 @@ export function normalizeOptions(options: Options): NormalizedOptions {
2627
registry: registryURL || new URL("https://registry.npmjs.org/"),
2728
package: options.package || "package.json",
2829
checkVersion: options.checkVersion === undefined ? true : Boolean(options.checkVersion),
30+
dryRun: options.dryRun || false,
2931
quiet: options.quiet || false,
3032
debug: options.debug || (() => undefined),
3133
};

‎src/npm-publish.ts

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export async function npmPublish(opts: Options = {}): Promise<Results> {
2828
type: diff || "none",
2929
version: manifest.version.raw,
3030
oldVersion: publishedVersion.raw,
31+
dryRun: options.dryRun
3132
};
3233

3334
options.debug("OUTPUT:", results);

‎src/npm.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const npm = {
2525

2626
options.debug(`Running command: npm view ${name} version`);
2727

28-
// Run NPM to get the latest published versiono of the package
28+
// Run NPM to get the latest published version of the package
2929
let { stdout } = await ezSpawn.async("npm", ["view", name, "version"], { env });
3030
let version = stdout.trim();
3131

@@ -60,8 +60,10 @@ export const npm = {
6060

6161
options.debug("Running command: npm publish", { stdio, cwd, env });
6262

63+
let command = options.dryRun ? ["publish", "--dry-run"] : ["publish"];
64+
6365
// Run NPM to publish the package
64-
await ezSpawn.async("npm", ["publish"], { cwd, stdio, env });
66+
await ezSpawn.async("npm", command, { cwd, stdio, env });
6567
}
6668
catch (error) {
6769
throw ono(error, `Unable to publish ${name} v${version} to NPM.`);

‎src/options.ts

+9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ export interface Options {
3131
*/
3232
checkVersion?: boolean;
3333

34+
/**
35+
* If true, run npm publish with the --dry-run flag
36+
* so that the package is not published. Used for
37+
* testing workflows.
38+
*
39+
* Defaults to `false`
40+
*/
41+
dryRun?: boolean;
42+
3443
/**
3544
* Suppress console output from NPM and npm-publish.
3645
*

‎src/results.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ReleaseType } from "semver";
33
export { ReleaseType };
44

55
/**
6-
* Results of the `publish
6+
* Results of the publish
77
*/
88
export interface Results {
99
/**
@@ -25,4 +25,9 @@ export interface Results {
2525
* The version number that was previously published to NPM
2626
*/
2727
oldVersion: string;
28+
29+
/**
30+
* Whether this was a dry run (not published to NPM)
31+
*/
32+
dryRun: boolean;
2833
}

‎test/specs/action/success.spec.js

+45
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,49 @@ describe("GitHub Action - success tests", () => {
265265
npm.assert.ran(4);
266266
});
267267

268+
it("should not publish a package if dryRun is true", () => {
269+
files.create([
270+
{ path: "workspace/package.json", contents: { name: "my-lib", version: "1.1.0" }},
271+
{ path: "home/.npmrc", contents: "This is my NPM config.\nThere are many like it,\nbut this one is mine." },
272+
]);
273+
274+
npm.mock({
275+
args: ["config", "get", "userconfig"],
276+
stdout: `${paths.npmrc}${EOL}`,
277+
});
278+
279+
npm.mock({
280+
args: ["view", "my-lib", "version"],
281+
stdout: `1.0.0${EOL}`,
282+
});
283+
284+
npm.mock({
285+
args: ["config", "get", "userconfig"],
286+
stdout: `${paths.npmrc}${EOL}`,
287+
});
288+
289+
npm.mock({
290+
args: ["publish", "--dry-run"],
291+
env: { INPUT_TOKEN: "my-secret-token" },
292+
stdout: `my-lib 1.1.0${EOL}`,
293+
});
294+
295+
let cli = exec.action({
296+
env: {
297+
INPUT_TOKEN: "my-secret-token",
298+
"INPUT_DRY-RUN": "true"
299+
}
300+
});
301+
302+
expect(cli).to.have.stderr("");
303+
expect(cli).stdout.to.include("::set-output name=type::minor");
304+
expect(cli).stdout.to.include("::set-output name=version::1.1.0");
305+
expect(cli).stdout.to.include("::set-output name=old-version::1.0.0");
306+
expect(cli).stdout.to.include("my-lib 1.1.0");
307+
expect(cli).stdout.to.include("📦 my-lib v1.1.0 successfully built but not published to NPM");
308+
expect(cli).to.have.exitCode(0);
309+
310+
npm.assert.ran(4);
311+
});
312+
268313
});

‎test/specs/cli/args.spec.js

+8
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,12 @@ describe("CLI - argument tests", () => {
139139
npm.assert.ran(0);
140140
});
141141
});
142+
143+
144+
describe("npm-publish --dry-run", () => {
145+
it("should call npm publish with the --dry-run flag", () => {
146+
let cli = exec.cli("--dry-run");
147+
expect(cli.args).to.include("--dry-run");
148+
});
149+
});
142150
});

‎test/specs/cli/success.spec.js

+34
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,38 @@ describe("CLI - success tests", () => {
266266
npm.assert.ran(4);
267267
});
268268

269+
it("should not publish the package if publish is called with --dry-run", () => {
270+
files.create([
271+
{ path: "workspace/package.json", contents: { name: "my-lib", version: "1.1.0" }},
272+
]);
273+
274+
npm.mock({
275+
args: ["config", "get", "userconfig"],
276+
stdout: `${paths.npmrc}${EOL}`,
277+
});
278+
279+
npm.mock({
280+
args: ["view", "my-lib", "version"],
281+
stdout: `1.0.0${EOL}`,
282+
});
283+
284+
npm.mock({
285+
args: ["config", "get", "userconfig"],
286+
stdout: `${paths.npmrc}${EOL}`,
287+
});
288+
289+
npm.mock({
290+
args: ["publish", "--dry-run"],
291+
stdout: `my-lib 1.1.0${EOL}`,
292+
});
293+
294+
let cli = exec.cli("--dry-run");
295+
296+
expect(cli).to.have.stderr("");
297+
expect(cli).stdout.to.include("my-lib 1.1.0");
298+
expect(cli).stdout.to.include("📦 my-lib v1.1.0 successfully built but not published to NPM");
299+
expect(cli).to.have.exitCode(0);
300+
301+
npm.assert.ran(4);
302+
});
269303
});

‎test/specs/lib/success.spec.js

+59-6
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ describe("NPM package - success tests", () => {
5151
type: "major",
5252
package: "my-lib",
5353
version: "2.0.0",
54-
oldVersion: "1.0.0"
54+
oldVersion: "1.0.0",
55+
dryRun: false
5556
});
5657

5758
files.assert.contents("home/.npmrc",
@@ -83,7 +84,8 @@ describe("NPM package - success tests", () => {
8384
type: "none",
8485
package: "my-lib",
8586
version: "1.0.0",
86-
oldVersion: "1.0.0"
87+
oldVersion: "1.0.0",
88+
dryRun: false
8789
});
8890

8991
files.assert.contents("home/.npmrc",
@@ -129,7 +131,8 @@ describe("NPM package - success tests", () => {
129131
type: "prerelease",
130132
package: "my-lib",
131133
version: "1.0.0-beta.1",
132-
oldVersion: "1.0.0"
134+
oldVersion: "1.0.0",
135+
dryRun: false
133136
});
134137

135138
files.assert.contents("home/.npmrc",
@@ -172,7 +175,8 @@ describe("NPM package - success tests", () => {
172175
type: "minor",
173176
package: "my-lib",
174177
version: "1.1.0",
175-
oldVersion: "1.0.0"
178+
oldVersion: "1.0.0",
179+
dryRun: false
176180
});
177181

178182
files.assert.contents("home/.npmrc",
@@ -231,7 +235,8 @@ describe("NPM package - success tests", () => {
231235
type: "patch",
232236
package: "my-lib",
233237
version: "1.0.1",
234-
oldVersion: "1.0.0"
238+
oldVersion: "1.0.0",
239+
dryRun: false
235240
});
236241

237242
files.assert.contents("home/.npmrc",
@@ -284,7 +289,55 @@ describe("NPM package - success tests", () => {
284289
type: "prerelease",
285290
package: "my-lib",
286291
version: "1.0.0-beta",
287-
oldVersion: "1.0.0"
292+
oldVersion: "1.0.0",
293+
dryRun: false
294+
});
295+
296+
files.assert.contents("home/.npmrc",
297+
`//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` +
298+
`registry=https://registry.npmjs.org/${EOL}`
299+
);
300+
301+
npm.assert.ran(4);
302+
});
303+
304+
it("results.dryRun should be true when called with --dry-run", async () => {
305+
files.create([
306+
{ path: "workspace/package.json", contents: { name: "my-lib", version: "1.1.0" }},
307+
]);
308+
309+
npm.mock({
310+
args: ["config", "get", "userconfig"],
311+
stdout: `${paths.npmrc}${EOL}`,
312+
});
313+
314+
npm.mock({
315+
args: ["view", "my-lib", "version"],
316+
stdout: `1.0.0${EOL}`,
317+
});
318+
319+
npm.mock({
320+
args: ["config", "get", "userconfig"],
321+
stdout: `${paths.npmrc}${EOL}`,
322+
});
323+
324+
npm.mock({
325+
args: ["publish", "--dry-run"],
326+
stdout: `my-lib 1.1.0${EOL}`,
327+
});
328+
329+
let results = await npmPublish({
330+
quiet: true,
331+
package: "package.json",
332+
dryRun: true
333+
});
334+
335+
expect(results).to.deep.equal({
336+
type: "minor",
337+
package: "my-lib",
338+
version: "1.1.0",
339+
oldVersion: "1.0.0",
340+
dryRun: true
288341
});
289342

290343
files.assert.contents("home/.npmrc",

0 commit comments

Comments
 (0)
Failed to load comments.