Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert the plugin to esm along with other breaking changes #581

Merged
merged 25 commits into from Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2d8ff15
refactor(esm): converted the package to esm
travi Nov 24, 2021
f1992a5
fix(tempy): upgraded to the latest version of tempy
travi Jan 6, 2023
23a0de7
test(resolve): used as a named import from path
travi Jan 6, 2023
fd490b2
test(tempy): handled global caching issue with globby in the npm auth…
travi Jan 6, 2023
aff3574
feat(node-versions): dropped support for node versions below v18
travi Jan 6, 2023
0d198e8
style: replace `xo` with `prettier`
gr2m Jan 13, 2023
61deec7
style: prettier
gr2m Jan 13, 2023
c5036aa
build(git-blame-ignore-revs): a54c56cdc437d5a1bf4a2888a3d4dd03f58fbbf5
gr2m Jan 13, 2023
51ab3c8
fix: remove support for legacy auth
gr2m Jan 13, 2023
697f16b
Merge pull request #437 from semantic-release/esm
gr2m Jan 13, 2023
7c74660
fix(execa): upgraded to the latest version
travi Jan 16, 2023
1bce937
chore(dev-dependencies): upgraded packages that were at least one maj…
travi Jan 16, 2023
7285e05
fix(aggregate-error): upgraded to the latest version
travi Jan 17, 2023
b55bb01
fix(normalize-url): upgraded to the latest version
travi Jan 17, 2023
6c5d581
Merge pull request #566 from semantic-release/dependencies
travi Jan 17, 2023
22e70ad
feat(semantic-release-peer): raised the minimum peer requirement to t…
travi Jan 18, 2023
2b8ac2e
Merge pull request #567 from semantic-release/sr-peer
travi Jan 25, 2023
2a79f80
fix(deps): upgraded npm to v9
travi Feb 16, 2023
31bc1f3
Merge pull request #579 from semantic-release/npm-9
travi Feb 17, 2023
725f044
chore(deps): updated semantic-release to the latest stable version
travi Feb 17, 2023
3266f40
ci(release): configured the release job to use the latest lts version…
travi Feb 17, 2023
ed0b20f
Merge branch 'master' of github.com:semantic-release/npm into beta
travi Feb 24, 2023
a6aad6f
ci(provenance): enabled provenance for publishing
travi Feb 24, 2023
c434c47
Merge pull request #582 from semantic-release/provenance
travi Mar 3, 2023
fc6fd18
Merge branch 'master' of github.com:semantic-release/npm into beta
travi Mar 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
@@ -0,0 +1,2 @@
# style: prettier (#437)
a54c56cdc437d5a1bf4a2888a3d4dd03f58fbbf5
8 changes: 3 additions & 5 deletions .github/workflows/test.yml
Expand Up @@ -13,10 +13,8 @@ jobs:
strategy:
matrix:
node-version:
- 14.17
- 16.0.0
- 17.0.0
- 18.0.0
- 19
os:
- ubuntu-latest
runs-on: "${{ matrix.os }}"
Expand All @@ -27,7 +25,7 @@ jobs:
with:
node-version: "${{ matrix.node-version }}"
cache: npm
- run: npm ci
- run: npm clean-install
- run: "npm run test:ci"
test:
runs-on: ubuntu-latest
Expand All @@ -36,7 +34,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 'lts/*'
node-version: "lts/*"
cache: npm
- run: npm ci
- name: Ensure dependencies are compatible with the version of node
Expand Down
74 changes: 40 additions & 34 deletions README.md
Expand Up @@ -6,12 +6,12 @@
[![npm next version](https://img.shields.io/npm/v/@semantic-release/npm/next.svg)](https://www.npmjs.com/package/@semantic-release/npm)
[![npm beta version](https://img.shields.io/npm/v/@semantic-release/npm/beta.svg)](https://www.npmjs.com/package/@semantic-release/npm)

| Step | Description |
|--------------------|-------------|
| Step | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `verifyConditions` | Verify the presence of the `NPM_TOKEN` environment variable, or an `.npmrc` file, and verify the authentication method is valid. |
| `prepare` | Update the `package.json` version and [create](https://docs.npmjs.com/cli/pack) the npm package tarball. |
| `addChannel` | [Add a release to a dist-tag](https://docs.npmjs.com/cli/dist-tag). |
| `publish` | [Publish the npm package](https://docs.npmjs.com/cli/publish) to the registry. |
| `prepare` | Update the `package.json` version and [create](https://docs.npmjs.com/cli/pack) the npm package tarball. |
| `addChannel` | [Add a release to a dist-tag](https://docs.npmjs.com/cli/dist-tag). |
| `publish` | [Publish the npm package](https://docs.npmjs.com/cli/publish) to the registry. |

## Install

Expand All @@ -25,11 +25,7 @@ The plugin can be configured in the [**semantic-release** configuration file](ht

```json
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
]
"plugins": ["@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/npm"]
}
```

Expand All @@ -42,6 +38,7 @@ The npm authentication configuration is **required** and can be set via [environ
Both the [token](https://docs.npmjs.com/getting-started/working_with_tokens) and the legacy (`username`, `password` and `email`) authentication are supported. It is recommended to use the [token](https://docs.npmjs.com/getting-started/working_with_tokens) authentication. The legacy authentication is supported as the alternative npm registries [Artifactory](https://www.jfrog.com/open-source/#os-arti) and [npm-registry-couchapp](https://github.com/npm/npm-registry-couchapp) only supports that form of authentication.

**Notes**:

- Only the `auth-only` [level of npm two-factor authentication](https://docs.npmjs.com/getting-started/using-two-factor-authentication#levels-of-authentication) is supported, **semantic-release** will not work with the default `auth-and-writes` level.
- The presence of an `.npmrc` file will override any specified environment variables.

Expand All @@ -50,20 +47,15 @@ Both the [token](https://docs.npmjs.com/getting-started/working_with_tokens) and
| Variable | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `NPM_TOKEN` | Npm token created via [npm token create](https://docs.npmjs.com/getting-started/working_with_tokens#how-to-create-new-tokens) |
| `NPM_USERNAME` | Npm username created via [npm adduser](https://docs.npmjs.com/cli/adduser) or on [npmjs.com](https://www.npmjs.com) |
| `NPM_PASSWORD` | Password of the npm user. |
| `NPM_EMAIL` | Email address associated with the npm user |
| `NPM_CONFIG_USERCONFIG` | Path to non-default .npmrc file |

Use either `NPM_TOKEN` for token authentication or `NPM_USERNAME`, `NPM_PASSWORD` and `NPM_EMAIL` for legacy authentication
| `NPM_CONFIG_USERCONFIG` | Path to non-default .npmrc file |

### Options

| Options | Description | Default |
|--------------|---------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|
| `npmPublish` | Whether to publish the `npm` package to the registry. If `false` the `package.json` version will still be updated. | `false` if the `package.json` [private](https://docs.npmjs.com/files/package.json#private) property is `true`, `true` otherwise. |
| `pkgRoot` | Directory path to publish. | `.` |
| `tarballDir` | Directory path in which to write the package tarball. If `false` the tarball is not be kept on the file system. | `false` |
| Options | Description | Default |
| ------------ | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `npmPublish` | Whether to publish the `npm` package to the registry. If `false` the `package.json` version will still be updated. | `false` if the `package.json` [private](https://docs.npmjs.com/files/package.json#private) property is `true`, `true` otherwise. |
| `pkgRoot` | Directory path to publish. | `.` |
| `tarballDir` | Directory path in which to write the package tarball. If `false` the tarball is not be kept on the file system. | `false` |

**Note**: The `pkgRoot` directory must contain a `package.json`. The version will be updated only in the `package.json` and `npm-shrinkwrap.json` within the `pkgRoot` directory.

Expand All @@ -76,6 +68,7 @@ The plugin uses the [`npm` CLI](https://github.com/npm/cli) which will read the
The [`registry`](https://docs.npmjs.com/misc/registry) can be configured via the npm environment variable `NPM_CONFIG_REGISTRY` and will take precedence over the configuration in `.npmrc`.

The [`registry`](https://docs.npmjs.com/misc/registry) and [`dist-tag`](https://docs.npmjs.com/cli/dist-tag) can be configured in the `package.json` and will take precedence over the configuration in `.npmrc` and `NPM_CONFIG_REGISTRY`:

```json
{
"publishConfig": {
Expand All @@ -94,13 +87,19 @@ The `npmPublish` and `tarballDir` option can be used to skip the publishing to t
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/npm", {
"npmPublish": false,
"tarballDir": "dist",
}],
["@semantic-release/github", {
"assets": "dist/*.tgz"
}]
[
"@semantic-release/npm",
{
"npmPublish": false,
"tarballDir": "dist"
}
],
[
"@semantic-release/github",
{
"assets": "dist/*.tgz"
}
]
]
}
```
Expand All @@ -112,15 +111,22 @@ When publishing from a sub-directory with the `pkgRoot` option, the `package.jso
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/npm", {
"pkgRoot": "dist",
}],
["@semantic-release/git", {
"assets": ["package.json", "npm-shrinkwrap.json"]
}]
[
"@semantic-release/npm",
{
"pkgRoot": "dist"
}
],
[
"@semantic-release/git",
{
"assets": ["package.json", "npm-shrinkwrap.json"]
}
]
]
}
```

```json
{
"scripts": {
Expand Down
49 changes: 19 additions & 30 deletions index.js
@@ -1,23 +1,22 @@
const {defaultTo, castArray} = require('lodash');
const AggregateError = require('aggregate-error');
const tempy = require('tempy');
const setLegacyToken = require('./lib/set-legacy-token');
const getPkg = require('./lib/get-pkg');
const verifyNpmConfig = require('./lib/verify-config');
const verifyNpmAuth = require('./lib/verify-auth');
const addChannelNpm = require('./lib/add-channel');
const prepareNpm = require('./lib/prepare');
const publishNpm = require('./lib/publish');
import { castArray, defaultTo } from "lodash-es";
import AggregateError from "aggregate-error";
import { temporaryFile } from "tempy";
import getPkg from "./lib/get-pkg.js";
import verifyNpmConfig from "./lib/verify-config.js";
import verifyNpmAuth from "./lib/verify-auth.js";
import addChannelNpm from "./lib/add-channel.js";
import prepareNpm from "./lib/prepare.js";
import publishNpm from "./lib/publish.js";

let verified;
let prepared;
const npmrc = tempy.file({name: '.npmrc'});
const npmrc = temporaryFile({ name: ".npmrc" });

async function verifyConditions(pluginConfig, context) {
export async function verifyConditions(pluginConfig, context) {
// If the npm publish plugin is used and has `npmPublish`, `tarballDir` or `pkgRoot` configured, validate them now in order to prevent any release if the configuration is wrong
if (context.options.publish) {
const publishPlugin =
castArray(context.options.publish).find((config) => config.path && config.path === '@semantic-release/npm') || {};
castArray(context.options.publish).find((config) => config.path && config.path === "@semantic-release/npm") || {};

pluginConfig.npmPublish = defaultTo(pluginConfig.npmPublish, publishPlugin.npmPublish);
pluginConfig.tarballDir = defaultTo(pluginConfig.tarballDir, publishPlugin.tarballDir);
Expand All @@ -26,8 +25,6 @@ async function verifyConditions(pluginConfig, context) {

const errors = verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
const pkg = await getPkg(pluginConfig, context);

Expand All @@ -36,7 +33,7 @@ async function verifyConditions(pluginConfig, context) {
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
errors.push(...error);
errors.push(...error.errors);
}

if (errors.length > 0) {
Expand All @@ -46,19 +43,17 @@ async function verifyConditions(pluginConfig, context) {
verified = true;
}

async function prepare(pluginConfig, context) {
export async function prepare(pluginConfig, context) {
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
const pkg = await getPkg(pluginConfig, context);
if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
errors.push(...error);
errors.push(...error.errors);
}

if (errors.length > 0) {
Expand All @@ -69,20 +64,18 @@ async function prepare(pluginConfig, context) {
prepared = true;
}

async function publish(pluginConfig, context) {
export async function publish(pluginConfig, context) {
let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
pkg = await getPkg(pluginConfig, context);
if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
errors.push(...error);
errors.push(...error.errors);
}

if (errors.length > 0) {
Expand All @@ -96,20 +89,18 @@ async function publish(pluginConfig, context) {
return publishNpm(npmrc, pluginConfig, pkg, context);
}

async function addChannel(pluginConfig, context) {
export async function addChannel(pluginConfig, context) {
let pkg;
const errors = verified ? [] : verifyNpmConfig(pluginConfig);

setLegacyToken(context);

try {
// Reload package.json in case a previous external step updated it
pkg = await getPkg(pluginConfig, context);
if (!verified && pluginConfig.npmPublish !== false && pkg.private !== true) {
await verifyNpmAuth(npmrc, pkg, context);
}
} catch (error) {
errors.push(...error);
errors.push(...error.errors);
}

if (errors.length > 0) {
Expand All @@ -118,5 +109,3 @@ async function addChannel(pluginConfig, context) {

return addChannelNpm(npmrc, pluginConfig, pkg, context);
}

module.exports = {verifyConditions, prepare, publish, addChannel};
24 changes: 12 additions & 12 deletions lib/add-channel.js
@@ -1,15 +1,15 @@
const execa = require('execa');
const getRegistry = require('./get-registry');
const getChannel = require('./get-channel');
const getReleaseInfo = require('./get-release-info');
import { execa } from "execa";
import getRegistry from "./get-registry.js";
import getChannel from "./get-channel.js";
import getReleaseInfo from "./get-release-info.js";

module.exports = async (npmrc, {npmPublish}, pkg, context) => {
export default async function (npmrc, { npmPublish }, pkg, context) {
const {
cwd,
env,
stdout,
stderr,
nextRelease: {version, channel},
nextRelease: { version, channel },
logger,
} = context;

Expand All @@ -19,16 +19,16 @@ module.exports = async (npmrc, {npmPublish}, pkg, context) => {

logger.log(`Adding version ${version} to npm registry on dist-tag ${distTag}`);
const result = execa(
'npm',
['dist-tag', 'add', `${pkg.name}@${version}`, distTag, '--userconfig', npmrc, '--registry', registry],
"npm",
["dist-tag", "add", `${pkg.name}@${version}`, distTag, "--userconfig", npmrc, "--registry", registry],
{
cwd,
env,
preferLocal: true,
}
);
result.stdout.pipe(stdout, {end: false});
result.stderr.pipe(stderr, {end: false});
result.stdout.pipe(stdout, { end: false });
result.stderr.pipe(stderr, { end: false });
await result;

logger.log(`Added ${pkg.name}@${version} to dist-tag @${distTag} on ${registry}`);
Expand All @@ -37,10 +37,10 @@ module.exports = async (npmrc, {npmPublish}, pkg, context) => {
}

logger.log(
`Skip adding to npm channel as ${npmPublish === false ? 'npmPublish' : "package.json's private property"} is ${
`Skip adding to npm channel as ${npmPublish === false ? "npmPublish" : "package.json's private property"} is ${
npmPublish !== false
}`
);

return false;
};
}