diff --git a/commands/publish/README.md b/commands/publish/README.md
index f86b27c781..b5c282c6e0 100644
--- a/commands/publish/README.md
+++ b/commands/publish/README.md
@@ -65,6 +65,7 @@ This is useful when a previous `lerna publish` failed to publish all packages to
- [`--tag-version-prefix`](#--tag-version-prefix)
- [`--temp-tag`](#--temp-tag)
- [`--yes`](#--yes)
+- [`--summary-file
`](#--summary-file)
### `--canary`
@@ -291,6 +292,27 @@ lerna publish --canary --yes
When run with this flag, `lerna publish` will skip all confirmation prompts.
Useful in [Continuous integration (CI)](https://en.wikipedia.org/wiki/Continuous_integration) to automatically answer the publish confirmation prompt.
+### `--summary-file`
+
+```sh
+lerna publish --canary --yes --summary-file ./output.json
+```
+
+When run with this flag, once a successfully publish it will create a json summary report(see below for an example).
+
+```json
+[
+ {
+ "packageName": "package1",
+ "version": "v1.0.1-alpha"
+ },
+ {
+ "packageName": "package2",
+ "version": "v2.0.1-alpha"
+ }
+]
+```
+
## Deprecated Options
### `--skip-npm`
diff --git a/commands/publish/__tests__/publish-command.test.js b/commands/publish/__tests__/publish-command.test.js
index 75a50df3e9..a50e79df5a 100644
--- a/commands/publish/__tests__/publish-command.test.js
+++ b/commands/publish/__tests__/publish-command.test.js
@@ -34,6 +34,8 @@ const initFixture = require("@lerna-test/init-fixture")(__dirname);
const path = require("path");
const fs = require("fs-extra");
+const fsmain = require("fs");
+
// file under test
const lernaPublish = require("@lerna-test/command-runner")(require("../command"));
@@ -306,6 +308,31 @@ Map {
});
});
+ describe("--summary-file", () => {
+ it("skips creating the summary file", async () => {
+ const cwd = await initFixture("normal");
+ const fsSpy = jest.spyOn(fs, "writeFileSync");
+ await lernaPublish(cwd);
+
+ expect(fsSpy).not.toHaveBeenCalled();
+ });
+
+ it("creates the summary file", async () => {
+ const cwd = await initFixture("normal");
+ const fsSpy = jest.spyOn(fsmain, "writeFileSync");
+ await lernaPublish(cwd)("--summary-file", "./output.json");
+
+ const expectedJsonResponse = [
+ { packageName: "package-1", version: "1.0.1" },
+ { packageName: "package-2", version: "1.0.1" },
+ { packageName: "package-3", version: "1.0.1" },
+ { packageName: "package-4", version: "1.0.1" },
+ ];
+ expect(fsSpy).toHaveBeenCalled();
+ expect(fsSpy).toHaveBeenCalledWith("./output.json", JSON.stringify(expectedJsonResponse));
+ });
+ });
+
describe("--no-verify-access", () => {
it("skips package access verification", async () => {
const cwd = await initFixture("normal");
diff --git a/commands/publish/command.js b/commands/publish/command.js
index ec2d3e9b0d..39f2b6a50b 100644
--- a/commands/publish/command.js
+++ b/commands/publish/command.js
@@ -110,6 +110,11 @@ exports.builder = (yargs) => {
hidden: true,
type: "boolean",
},
+ "summary-file": {
+ // Json output.
+ hidden: true,
+ type: "string",
+ },
// y: {
// describe: "Skip all confirmation prompts.",
// alias: "yes",
diff --git a/commands/publish/index.js b/commands/publish/index.js
index 16d12a2c88..dd5851838d 100644
--- a/commands/publish/index.js
+++ b/commands/publish/index.js
@@ -1,6 +1,7 @@
"use strict";
const os = require("os");
+const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const pMap = require("p-map");
@@ -237,10 +238,29 @@ class PublishCommand extends Command {
return chain.then(() => {
const count = this.packagesToPublish.length;
- const message = this.packagesToPublish.map((pkg) => ` - ${pkg.name}@${pkg.version}`);
output("Successfully published:");
- output(message.join(os.EOL));
+
+ if (this.options.summaryFile) {
+ // create a json object and output it to a file location.
+ const filePath = this.options.summaryFile || "./output.json";
+ const jsonObject = this.packagesToPublish.map((pkg) => {
+ return {
+ packageName: pkg.name,
+ version: pkg.version,
+ };
+ });
+ output(jsonObject);
+ try {
+ fs.writeFileSync(filePath, JSON.stringify(jsonObject));
+ output("Locate Summary Report Here: ", filePath);
+ } catch (error) {
+ output("Failed to create the summary report", error);
+ }
+ } else {
+ const message = this.packagesToPublish.map((pkg) => ` - ${pkg.name}@${pkg.version}`);
+ output(message.join(os.EOL));
+ }
this.logger.success("published", "%d %s", count, count === 1 ? "package" : "packages");
});