diff --git a/README.md b/README.md index d3c0182..9f23f81 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Fast, easy publishing to NPM -============================================== +# Fast, easy publishing to NPM [](https://github.com/JS-DevTools/npm-publish/actions) [](https://github.com/JS-DevTools/npm-publish/actions) @@ -11,29 +10,25 @@ Fast, easy publishing to NPM [](LICENSE) [](https://plant.treeware.earth/JS-DevTools/npm-publish) +## Features - -Features --------------------------- - 🧠 **Smart**<br> -Only publishes if the version number in `package.json` differs from the latest on NPM + Only publishes if the version number in `package.json` differs from the latest on NPM - 🛠 **Configurable**<br> -Customize the version-checking behavior, the registry URL, and path of your package + Customize the version-checking behavior, the registry URL, and path of your package - 🔐 **Secure**<br> -Keeps your NPM access token secret. Doesn't write it to `~/.npmrc` + Keeps your NPM access token secret. Doesn't write it to `~/.npmrc` - ⚡ **Fast**<br> -100% JavaScript (which is faster than Docker) and bundled to optimize loading time + 100% JavaScript (which is faster than Docker) and bundled to optimize loading time - 📤 **Outputs**<br> -Exposes the old and new version numbers, and the type of change (major, minor, patch, etc.) as variables that you can use in your workflow. - + Exposes the old and new version numbers, and the type of change (major, minor, patch, etc.) as variables that you can use in your workflow. +## Usage -Usage --------------------------- This package can be used three different ways: - 🤖 A [**GitHub Action**](#github-action) as part of your CI/CD process @@ -42,10 +37,8 @@ This package can be used three different ways: - 🖥 A [**CLI**](#command-line-interface) that you run in your terminal +## GitHub Action - -GitHub Action ------------------------------ To use the GitHub Action, you'll need to add it as a step in your [Workflow file](https://help.github.com/en/actions/automating-your-workflow-with-github-actions). By default, the only thing you need to do is set the `token` parameter to your [NPM auth token](https://docs.npmjs.com/creating-and-viewing-authentication-tokens). ```yaml @@ -66,26 +59,24 @@ jobs: token: ${{ secrets.NPM_TOKEN }} ``` +## Input Parameters - -Input Parameters --------------------------- You can set any or all of the following input parameters: -|Name |Type |Default |Description -|----------------|-------- |----------------------------|------------------------------------ -|`token` |string |**required** |The NPM auth token to use for publishing -|`registry` |string |https://registry.npmjs.org/ |The NPM registry URL to use -|`package` |string |./package.json |The path of your package.json file -|`tag` |string |"latest" |The tag to publish to. This allows people to install the package using `npm install <package-name>@<tag>`. -|`access` |string |"public" for non-scoped packages. "restricted" for scoped packages.|Determines whether the published package should be publicly visible, or restricted to members of your NPM organization. -|`dry-run` |boolean |false |Run NPM publish with the `--dry-run` flag to prevent publication -|`check-version` |boolean |true |Only publish to NPM if the version number in `package.json` differs from the latest on NPM +|Name |Type |Default |Description +|----------------------|-------- |----------------------------|------------------------------------ +|`token` |string |**required** |The NPM auth token to use for publishing +|`registry` |string |https://registry.npmjs.org/ |The NPM registry URL to use +|`package` |string |./package.json |The path of your package.json file +|`tag` |string |"latest" |The tag to publish to. This allows people to install the package using `npm install <package-name>@<tag>`. +|`access` |string |"public" for non-scoped packages. "restricted" for scoped packages.|Determines whether the published package should be publicly visible, or restricted to members of your NPM organization. +|`dry-run` |boolean |false |Run NPM publish with the `--dry-run` flag to prevent publication +|`check-version` |boolean |true |Only publish to NPM if the version number in `package.json` differs from the latest on NPM +|`greater-version-only`|boolean |false |Only publish to NPM if the version number in `package.json` is greater than the latest on NPM | +## Output Variables -Output Variables --------------------------- npm-publish exposes some output variables, which you can use in later steps of your workflow. To access the output variables, you'll need to set an `id` for the npm-publish step. ```yaml @@ -100,20 +91,17 @@ steps: echo "Version changed: ${{ steps.publish.outputs.old-version }} => ${{ steps.publish.outputs.version }}" ``` +| Variable | Type | Description | +| ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | string | The type of version change that occurred ("major", "minor", "patch", etc.). If there was no version change, then type will be "none". If `greater-version-only` is set and the version is lower, then type will be "lower". | +| `version` | string | The version that was published | +| `old-version` | string | The version number that was previously published to NPM | +| `tag` | string | The tag that the package was published to. | +| `access` | string | Indicates whether the published package is publicly visible or restricted to members of your NPM organization. | +| `dry-run` | boolean | Indicates whether NPM was run in "dry run" mode | -|Variable |Type |Description -|--------------|--------|------------------------------------ -|`type` |string |The type of version change that occurred ("major", "minor", "patch", etc.). If there was no version change, then type will be "none". -|`version` |string |The version that was published -|`old-version` |string |The version number that was previously published to NPM -|`tag` |string |The tag that the package was published to. -|`access` |string |Indicates whether the published package is publicly visible or restricted to members of your NPM organization. -|`dry-run` |boolean |Indicates whether NPM was run in "dry run" mode +## JavaScript Function - - -JavaScript Function ------------------------------- To use npm-package in your JavaScript code, you'll need to install it using [NPM](https://docs.npmjs.com/about-npm/): ```bash @@ -131,42 +119,43 @@ await npmPublish(); // Run npm-publish with options await npmPublish({ package: "./path/to/package.json", - token: "YOUR_NPM_AUTH_TOKEN_HERE" + token: "YOUR_NPM_AUTH_TOKEN_HERE", }); ``` ### Options + As shown in the example above, you can pass options to the `npmPublish()` function. Here are the available options: -|Name |Type |Default |Description -|----------------|---------|----------------------------|------------------------------------ -|`token` |string |NPM's default credentials |The NPM auth token to use for publishing. If not set, then NPM will -|`registry` |string |https://registry.npmjs.org/ |The NPM registry URL to use -|`package` |string |./package.json |The path of your package.json file -|`tag` |string |"latest" |The tag to publish to. This allows people to install the package using `npm install <package-name>@<tag>`. -|`access` |string |"public" for non-scoped packages. "restricted" for scoped packages.|Determines whether the published package should be publicly visible, or restricted to members of your NPM organization. -|`dryRun` |boolean |false |Run NPM publish with the `--dry-run` flag to prevent publication -|`checkVersion` |boolean |true |Only publish to NPM if the version number in `package.json` differs from the latest on NPM -|`quiet` |boolean |false |Suppress console output from NPM and npm-publish -|`debug` |function |no-op |A function to log debug messages. You can set this to a custom function to receive debug messages, or just set it to `console.debug` to print debug messages to the console. +| Name | Type | Default | Description | +| -------------------- | -------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `token` | string | NPM's default credentials | The NPM auth token to use for publishing. If not set, then NPM will | +| `registry` | string | https://registry.npmjs.org/ | The NPM registry URL to use | +| `package` | string | ./package.json | The path of your package.json file | +| `tag` | string | "latest" | The tag to publish to. This allows people to install the package using `npm install <package-name>@<tag>`. | +| `access` | string | "public" for non-scoped packages. "restricted" for scoped packages. | Determines whether the published package should be publicly visible, or restricted to members of your NPM organization. | +| `dryRun` | boolean | false | Run NPM publish with the `--dry-run` flag to prevent publication | +| `checkVersion` | boolean | true | Only publish to NPM if the version number in `package.json` differs from the latest on NPM | +| `greaterVersionOnly` | boolean | false | Only publish to NPM if the version number in `package.json` is greater then the latest on NPM | +| `quiet` | boolean | false | Suppress console output from NPM and npm-publish | +| `debug` | function | no-op | A function to log debug messages. You can set this to a custom function to receive debug messages, or just set it to `console.debug` to print debug messages to the console. | ### Return Value -The `npmPublish()` function asynchronously returns an object with the following properties: -|Name |Type |Description -|----------------|---------|------------------------------------ -|`type` |string |The type of version change that occurred ("major", "minor", "patch", etc.) If there was no version change, then the the type is "none". -|`package` |string |The name of the NPM package that was published -|`version` |string |The version number that was published -|`oldVersion` |string |The version number that was previously published to NPM -|`tag` |string |The tag that the package was published to. -|`access` |string |Indicates whether the published package is publicly visible or restricted to members of your NPM organization. -|`dryRun` |boolean |Indicates whether NPM was run in "dry run" mode +The `npmPublish()` function asynchronously returns an object with the following properties: +| Name | Type | Description | +| ------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | string | The type of version change that occurred ("major", "minor", "patch", etc.) If there was no version change, then the the type is "none". If `greater-version-only` is set and the version is lower, then type will be "lower". | +| `package` | string | The name of the NPM package that was published | +| `version` | string | The version number that was published | +| `oldVersion` | string | The version number that was previously published to NPM | +| `tag` | string | The tag that the package was published to. | +| `access` | string | Indicates whether the published package is publicly visible or restricted to members of your NPM organization. | +| `dryRun` | boolean | Indicates whether NPM was run in "dry run" mode | +## Command Line Interface -Command Line Interface ------------------------------- To use npm-package from as a command-line tool in your terminal, you'll need to install it globally using [NPM](https://docs.npmjs.com/about-npm/): ```bash @@ -186,6 +175,7 @@ npm-publish --token=YOUR_NPM_AUTH_TOKEN_HERE ./path/to/package.json ``` ### Options + Run `npm-publish --help` to see the full list of options available. ``` @@ -221,39 +211,34 @@ package_path The absolute or relative path of the NPM package to publis Defaults to the current directory. ``` +## Contributing - -Contributing --------------------------- -Contributions, enhancements, and bug-fixes are welcome! [Open an issue](https://github.com/JS-DevTools/npm-publish/issues) on GitHub and [submit a pull request](https://github.com/JS-DevTools/npm-publish/pulls). +Contributions, enhancements, and bug-fixes are welcome! [Open an issue](https://github.com/JS-DevTools/npm-publish/issues) on GitHub and [submit a pull request](https://github.com/JS-DevTools/npm-publish/pulls). #### Building -To build the project locally on your computer: -1. __Clone this repo__<br> -`git clone https://github.com/JS-DevTools/npm-publish.git` +To build the project locally on your computer: -2. __Install dependencies__<br> -`npm install` +1. **Clone this repo**<br> + `git clone https://github.com/JS-DevTools/npm-publish.git` -3. __Build the code__<br> -`npm run build` +2. **Install dependencies**<br> + `npm install` -4. __Run the tests__<br> -`npm test` +3. **Build the code**<br> + `npm run build` +4. **Run the tests**<br> + `npm test` +## License -License --------------------------- npm-publish is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want. This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/JS-DevTools/npm-publish) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. +## Big Thanks To - -Big Thanks To --------------------------- Thanks to these awesome companies for their support of Open Source developers ❤ [](https://github.com/open-source) diff --git a/src/action/index.ts b/src/action/index.ts index e034bc5..357eded 100644 --- a/src/action/index.ts +++ b/src/action/index.ts @@ -4,6 +4,7 @@ import { Access, Options } from "../options"; /** * The main entry point of the GitHub Action + * * @internal */ async function main(): Promise<void> { @@ -17,10 +18,12 @@ async function main(): Promise<void> { token: getInput("token", { required: true }), registry: getInput("registry", { required: true }), package: getInput("package", { required: true }), - checkVersion: getInput("check-version", { required: true }).toLowerCase() === "true", + checkVersion: + getInput("check-version", { required: true }).toLowerCase() === "true", tag: getInput("tag"), access: getInput("access") as Access, dryRun: getInput("dry-run").toLowerCase() === "true", + greaterVersionOnly: getInput("greater-version-only").toLowerCase() === "true", debug: debugHandler, }; @@ -28,13 +31,24 @@ async function main(): Promise<void> { let results = await npmPublish(options); if (results.type === "none") { - console.log(`\n📦 ${results.package} v${results.version} is already published to ${options.registry}`); + console.log( + `\n📦 ${results.package} v${results.version} is already published to ${options.registry}` + ); + } + if (results.type === "lower") { + console.log( + `\n📦 ${results.package} v${results.version} is lower than the version published to ${options.registry}` + ); } else if (results.dryRun) { - console.log(`\n📦 ${results.package} v${results.version} was NOT actually published to ${options.registry} (dry run)`); + console.log( + `\n📦 ${results.package} v${results.version} was NOT actually published to ${options.registry} (dry run)` + ); } else { - console.log(`\n📦 Successfully published ${results.package} v${results.version} to ${options.registry}`); + console.log( + `\n📦 Successfully published ${results.package} v${results.version} to ${options.registry}` + ); } // Set the GitHub Actions output variables diff --git a/src/normalize-options.ts b/src/normalize-options.ts index bedd73e..23cffaa 100644 --- a/src/normalize-options.ts +++ b/src/normalize-options.ts @@ -13,6 +13,7 @@ export interface NormalizedOptions { access?: Access; dryRun: boolean; checkVersion: boolean; + greaterVersionOnly: boolean; quiet: boolean; debug: Debug; } @@ -22,7 +23,10 @@ export interface NormalizedOptions { * @internal */ export function normalizeOptions(options: Options): NormalizedOptions { - let registryURL = typeof options.registry === "string" ? new URL(options.registry) : options.registry; + let registryURL = + typeof options.registry === "string" + ? new URL(options.registry) + : options.registry; return { token: options.token || "", @@ -31,7 +35,12 @@ export function normalizeOptions(options: Options): NormalizedOptions { tag: options.tag || "latest", access: options.access, dryRun: options.dryRun || false, - checkVersion: options.checkVersion === undefined ? true : Boolean(options.checkVersion), + checkVersion: + options.checkVersion === undefined ? true : Boolean(options.checkVersion), + greaterVersionOnly: + options.greaterVersionOnly === undefined + ? false + : Boolean(options.greaterVersionOnly), quiet: options.quiet || false, debug: options.debug || (() => undefined), }; diff --git a/src/npm-publish.ts b/src/npm-publish.ts index 8d8bfb5..bedf07e 100644 --- a/src/npm-publish.ts +++ b/src/npm-publish.ts @@ -18,19 +18,33 @@ export async function npmPublish(opts: Options = {}): Promise<Results> { // Determine if/how the version has changed let diff = semver.diff(manifest.version, publishedVersion); - if (diff || !options.checkVersion) { + // Compare both versions to see if it's changed + let cmp = semver.compare(manifest.version, publishedVersion); + + let shouldPublish = + !options.checkVersion || + // compare returns 1 if manifest is higher than published + (options.greaterVersionOnly && cmp === 1) || + // compare returns 0 if the manifest is the same as published + cmp !== 0; + + if (shouldPublish) { // Publish the new version to NPM await npm.publish(manifest, options); } let results: Results = { package: manifest.name, - type: diff || "none", + // The version should be marked as lower if we disallow decrementing the version + type: + (options.greaterVersionOnly && cmp === -1 && "lower") || diff || "none", version: manifest.version.raw, oldVersion: publishedVersion.raw, tag: options.tag, - access: options.access || (manifest.name.startsWith("@") ? "restricted" : "public"), - dryRun: options.dryRun + access: + options.access || + (manifest.name.startsWith("@") ? "restricted" : "public"), + dryRun: options.dryRun, }; options.debug("OUTPUT:", results); diff --git a/src/options.ts b/src/options.ts index fee3190..1ed4ad8 100644 --- a/src/options.ts +++ b/src/options.ts @@ -64,6 +64,14 @@ export interface Options { */ quiet?: boolean; + /** + * Only publish the package if the version number in package.json + * is greater than the latest on NPM. + * + * Defaults to `false` + */ + greaterVersionOnly?: boolean; + /** * A function to call to log debug messages. * diff --git a/src/results.ts b/src/results.ts index 8f296df..fb9f7cb 100644 --- a/src/results.ts +++ b/src/results.ts @@ -10,7 +10,7 @@ export interface Results { /** * The type of version change that occurred */ - type: ReleaseType | "none"; + type: ReleaseType | "lower" | "none"; /** * The name of the NPM package that was published diff --git a/test/specs/action/success.spec.js b/test/specs/action/success.spec.js index 6c6e89f..9df0c81 100644 --- a/test/specs/action/success.spec.js +++ b/test/specs/action/success.spec.js @@ -9,10 +9,12 @@ const { EOL } = require("os"); const { join } = require("path"); describe("GitHub Action - success tests", () => { - it("should publish a new version to NPM", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "2.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "2.0.0" }, + }, ]); npm.mock({ @@ -39,12 +41,14 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 2.0.0"); - expect(cli).stdout.to.include("Successfully published my-lib v2.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published my-lib v2.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::2.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -53,9 +57,124 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", + `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + + `registry=https://registry.npmjs.org/${EOL}` + ); + + npm.assert.ran(4); + }); + + it("should publish a new version to NPM if the version is lower", () => { + files.create([ + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "0.1.0" }, + }, + ]); + + npm.mock({ + args: ["config", "get", "userconfig"], + stdout: `${paths.npmrc}${EOL}`, + }); + + npm.mock({ + args: ["view", "my-lib", "version"], + stdout: `1.0.0${EOL}`, + }); + + npm.mock({ + args: ["config", "get", "userconfig"], + stdout: `${paths.npmrc}${EOL}`, + }); + + npm.mock({ + args: ["publish"], + env: { INPUT_TOKEN: "my-secret-token" }, + stdout: `my-lib 0.1.0${EOL}`, + }); + + let cli = exec.action({ + env: { + INPUT_TOKEN: "my-secret-token", + }, + }); + + expect(cli).to.have.stderr(""); + expect(cli).stdout.to.include("my-lib 0.1.0"); + expect(cli).stdout.to.include( + "Successfully published my-lib v0.1.0 to NPM" + ); + expect(cli).stdout.to.include("::set-output name=type::major"); + expect(cli).stdout.to.include("::set-output name=version::0.1.0"); + expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); + expect(cli).stdout.to.include("::set-output name=tag::latest"); + expect(cli).stdout.to.include("::set-output name=access::public"); + expect(cli).stdout.to.include("::set-output name=dry-run::false"); + expect(cli).to.have.exitCode(0); + + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` + ); + + npm.assert.ran(4); + }); + + it("should not publish a new version to NPM if the version is lower and greaterVersion flag is set", () => { + files.create([ + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "0.1.0" }, + }, + ]); + + npm.mock({ + args: ["config", "get", "userconfig"], + stdout: `${paths.npmrc}${EOL}`, + }); + + npm.mock({ + args: ["view", "my-lib", "version"], + stdout: `1.0.0${EOL}`, + }); + + npm.mock({ + args: ["config", "get", "userconfig"], + stdout: `${paths.npmrc}${EOL}`, + }); + + npm.mock({ + args: ["publish"], + env: { INPUT_TOKEN: "my-secret-token" }, + stdout: `my-lib 0.1.0${EOL}`, + }); + + let cli = exec.action({ + env: { + INPUT_TOKEN: "my-secret-token", + "INPUT_GREATER-VERSION-ONLY": "true", + }, + }); + + expect(cli).to.have.stderr(""); + expect(cli).stdout.to.include( + "my-lib v0.1.0 is lower than the version published to NPM" + ); + expect(cli).stdout.to.include("::set-output name=type::lower"); + expect(cli).stdout.to.include("::set-output name=version::0.1.0"); + expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); + expect(cli).stdout.to.include("::set-output name=tag::latest"); + expect(cli).stdout.to.include("::set-output name=access::public"); + expect(cli).stdout.to.include("::set-output name=dry-run::false"); + expect(cli).to.have.exitCode(0); + + files.assert.contents( + "home/.npmrc", + `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -63,7 +182,10 @@ describe("GitHub Action - success tests", () => { it("should publish a new version to NPM if no package exists", async () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.0.0" }, + }, ]); npm.mock({ @@ -91,12 +213,14 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 1.0.0"); - expect(cli).stdout.to.include("Successfully published my-lib v1.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published my-lib v1.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::1.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::0.0.0"); @@ -105,9 +229,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -115,7 +240,10 @@ describe("GitHub Action - success tests", () => { it("should publish a new version to NPM if the tag does not exist", async () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.0.0" }, + }, ]); npm.mock({ @@ -142,12 +270,14 @@ describe("GitHub Action - success tests", () => { env: { INPUT_TOKEN: "my-secret-token", INPUT_TAG: "my-tag", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 1.0.0"); - expect(cli).stdout.to.include("Successfully published my-lib v1.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published my-lib v1.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::1.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::0.0.0"); @@ -156,9 +286,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -166,7 +297,10 @@ describe("GitHub Action - success tests", () => { it("should not publish a new version to NPM if the version number hasn't changed", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.0.0" }, + }, ]); npm.mock({ @@ -182,11 +316,13 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); - expect(cli).stdout.to.include("📦 my-lib v1.0.0 is already published to NPM"); + expect(cli).stdout.to.include( + "📦 my-lib v1.0.0 is already published to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::none"); expect(cli).stdout.to.include("::set-output name=version::1.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -195,9 +331,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(2); @@ -205,8 +342,15 @@ describe("GitHub Action - success tests", () => { it("should append to an existing .npmrc file", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.1.0" }}, - { path: "home/.npmrc", contents: "This is my NPM config.\nThere are many like it,\nbut this one is mine." }, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.1.0" }, + }, + { + path: "home/.npmrc", + contents: + "This is my NPM config.\nThere are many like it,\nbut this one is mine.", + }, ]); npm.mock({ @@ -233,12 +377,14 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 1.1.0"); - expect(cli).stdout.to.include("📦 Successfully published my-lib v1.1.0 to NPM"); + expect(cli).stdout.to.include( + "📦 Successfully published my-lib v1.1.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::minor"); expect(cli).stdout.to.include("::set-output name=version::1.1.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -247,13 +393,14 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `This is my NPM config.${EOL}` + - `There are many like it,${EOL}` + - `but this one is mine.${EOL}` + - `${EOL}` + - `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `There are many like it,${EOL}` + + `but this one is mine.${EOL}` + + `${EOL}` + + `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -261,7 +408,10 @@ describe("GitHub Action - success tests", () => { it("should update an existing .npmrc file's settings", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.0.1" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.0.1" }, + }, { path: "home/.npmrc", contents: @@ -273,7 +423,7 @@ describe("GitHub Action - success tests", () => { "registry=https://registry.npmjs.org/\n" + "\n" + "# Use some other package registry\n" + - "registry=https://registry.example.com/\n" + "registry=https://registry.example.com/\n", }, ]); @@ -301,12 +451,14 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 1.0.1"); - expect(cli).stdout.to.include("📦 Successfully published my-lib v1.0.1 to NPM"); + expect(cli).stdout.to.include( + "📦 Successfully published my-lib v1.0.1 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::patch"); expect(cli).stdout.to.include("::set-output name=version::1.0.1"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -315,16 +467,17 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `# Use the GitHub package registry${EOL}` + - `${EOL}` + - `# Use the NPM registry with no auth${EOL}` + - `${EOL}` + - `# Use some other package registry${EOL}` + - `${EOL}` + - `${EOL}` + - `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `${EOL}` + + `# Use the NPM registry with no auth${EOL}` + + `${EOL}` + + `# Use some other package registry${EOL}` + + `${EOL}` + + `${EOL}` + + `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -332,7 +485,10 @@ describe("GitHub Action - success tests", () => { it("should publish a package that's not in the root of the workspace directory", () => { files.create([ - { path: "workspace/subdir/my-lib/package.json", contents: { name: "my-lib", version: "1.0.0-beta" }}, + { + path: "workspace/subdir/my-lib/package.json", + contents: { name: "my-lib", version: "1.0.0-beta" }, + }, ]); npm.mock({ @@ -361,12 +517,14 @@ describe("GitHub Action - success tests", () => { env: { INPUT_TOKEN: "my-secret-token", INPUT_PACKAGE: "subdir/my-lib/package.json", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 1.0.0-beta"); - expect(cli).stdout.to.include("📦 Successfully published my-lib v1.0.0-beta to NPM"); + expect(cli).stdout.to.include( + "📦 Successfully published my-lib v1.0.0-beta to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::prerelease"); expect(cli).stdout.to.include("::set-output name=version::1.0.0-beta"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -375,9 +533,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -385,7 +544,10 @@ describe("GitHub Action - success tests", () => { it("should publish a scoped package", () => { files.create([ - { path: "workspace/package.json", contents: { name: "@my-scope/my-lib", version: "2.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "@my-scope/my-lib", version: "2.0.0" }, + }, ]); npm.mock({ @@ -412,12 +574,14 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("@my-scope/my-lib 2.0.0"); - expect(cli).stdout.to.include("Successfully published @my-scope/my-lib v2.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published @my-scope/my-lib v2.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::2.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -426,9 +590,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -436,7 +601,10 @@ describe("GitHub Action - success tests", () => { it("should publish to a specific tag", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "2.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "2.0.0" }, + }, ]); npm.mock({ @@ -464,12 +632,14 @@ describe("GitHub Action - success tests", () => { env: { INPUT_TOKEN: "my-secret-token", INPUT_TAG: "next", - } + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("my-lib 2.0.0"); - expect(cli).stdout.to.include("Successfully published my-lib v2.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published my-lib v2.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::2.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -478,9 +648,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -488,7 +659,10 @@ describe("GitHub Action - success tests", () => { it("should publish a scoped package with public access", () => { files.create([ - { path: "workspace/package.json", contents: { name: "@my-scope/my-lib", version: "2.0.0" }}, + { + path: "workspace/package.json", + contents: { name: "@my-scope/my-lib", version: "2.0.0" }, + }, ]); npm.mock({ @@ -515,13 +689,15 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - INPUT_ACCESS: "public" - } + INPUT_ACCESS: "public", + }, }); expect(cli).to.have.stderr(""); expect(cli).stdout.to.include("@my-scope/my-lib 2.0.0"); - expect(cli).stdout.to.include("Successfully published @my-scope/my-lib v2.0.0 to NPM"); + expect(cli).stdout.to.include( + "Successfully published @my-scope/my-lib v2.0.0 to NPM" + ); expect(cli).stdout.to.include("::set-output name=type::major"); expect(cli).stdout.to.include("::set-output name=version::2.0.0"); expect(cli).stdout.to.include("::set-output name=old-version::1.0.0"); @@ -530,9 +706,10 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=dry-run::false"); expect(cli).to.have.exitCode(0); - files.assert.contents("home/.npmrc", + files.assert.contents( + "home/.npmrc", `//registry.npmjs.org/:_authToken=\${INPUT_TOKEN}${EOL}` + - `registry=https://registry.npmjs.org/${EOL}` + `registry=https://registry.npmjs.org/${EOL}` ); npm.assert.ran(4); @@ -540,7 +717,10 @@ describe("GitHub Action - success tests", () => { it("should not publish a package if dryRun is true", () => { files.create([ - { path: "workspace/package.json", contents: { name: "my-lib", version: "1.1.0" }}, + { + path: "workspace/package.json", + contents: { name: "my-lib", version: "1.1.0" }, + }, ]); npm.mock({ @@ -567,8 +747,8 @@ describe("GitHub Action - success tests", () => { let cli = exec.action({ env: { INPUT_TOKEN: "my-secret-token", - "INPUT_DRY-RUN": "true" - } + "INPUT_DRY-RUN": "true", + }, }); expect(cli).to.have.stderr(""); @@ -579,10 +759,11 @@ describe("GitHub Action - success tests", () => { expect(cli).stdout.to.include("::set-output name=access::public"); expect(cli).stdout.to.include("::set-output name=dry-run::true"); expect(cli).stdout.to.include("my-lib 1.1.0"); - expect(cli).stdout.to.include("📦 my-lib v1.1.0 was NOT actually published to NPM (dry run)"); + expect(cli).stdout.to.include( + "📦 my-lib v1.1.0 was NOT actually published to NPM (dry run)" + ); expect(cli).to.have.exitCode(0); npm.assert.ran(4); }); - });