Skip to content

Commit b4462db

Browse files
babblebeytravi
andauthored
feat: ES Module (#411)
* refactor: Convert require statements to ES6 imports * refactor: use `lodash-es` instead of `lodash` * refactor: remove `#readme` from `"package.json".homepage` * refactor: update "package.json" exports field for `esm` * refactor: use `createRequire` to get `homepage` from `package.json` * refactor: update `lib` functions to use named exports * refactor: update debug import in index.js * refactor: add "type" field to package.json * refactor: update import paths to `../index.js` in test files * refactor: replace `xo` with `prettier` * fix: `npm audit fix` package in lockfile * refactor: bump `semantic-release` peer-dependencies version * refactor: update Node.js versions in test workflow Update the Node.js versions in the test workflow to include 20.8.1, 20, and 21. This ensures compatibility with different versions of Node.js during testing. Also, replace the deprecated "npm ci" command with "npm clean-install" to install dependencies. Additionally, add a step to run "npm audit signatures" to check for any security issues in the dependencies. Finally, include a step to scan the lockfile for security issues using "lockfile-lint". * refactor: Update Node.js versions in test workflow * refactor: temporarily Remove `npm audit signatures` step in test workflow * fix(lint): initial prettier lint * refactor: update `semantic-release` peer-dependencies version BREAKING CHANGE: the minimum required version of semantic-release to use `@semantic-release/exec` is now v24.1.0; the warn logger method/function is now available to use in plugin * refactor: replace `nyc` with `c8` as package for code coverage * refactor: update Node.js versions in package-lock.json and package.json * refactor: update `semantic-release` peer-dependencies version * Update .github/workflows/test.yml Co-authored-by: Matt Travi <[email protected]> * refactor: update package.json to use fixed versions for `prettier` and `semantic-release` * refactor: add main entry point to package.json BREAKING CHANGE: `@semantic-release/exec` is now a native ES Module. It has named exports for each plugin hook (verifyConditions, analyzeCommits, verifyRelease, generateNotes, prepare, publish, addChannel, success, fail) --------- Co-authored-by: Matt Travi <[email protected]>
1 parent 488500b commit b4462db

21 files changed

+6707
-26022
lines changed

Diff for: .github/workflows/test.yml

+9-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ jobs:
1313
strategy:
1414
matrix:
1515
node-version:
16-
- '14.17'
17-
- 16
16+
- 20.8.1
17+
- 20
18+
- 22
1819
os:
1920
- ubuntu-latest
2021
- macos-latest
@@ -26,10 +27,10 @@ jobs:
2627
with:
2728
node-version: "${{ matrix.node-version }}"
2829
cache: npm
29-
- run: npm ci
30+
- run: npm clean-install
3031
- name: Ensure dependencies are compatible with the version of node
3132
run: npx ls-engines
32-
- run: "npm run test:ci"
33+
- run: "npm run test"
3334
test:
3435
runs-on: ubuntu-latest
3536
needs: test_matrix
@@ -40,5 +41,8 @@ jobs:
4041
with:
4142
node-version: "${{ matrix.node-version }}"
4243
cache: npm
43-
- run: npm ci
44+
- run: npm clean-install
4445
- run: npm run lint
46+
# https://github.com/lirantal/lockfile-lint#readme
47+
- name: Scan lockfile for security issues
48+
run: npx lockfile-lint --path package-lock.json

Diff for: README.md

+19-15
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![npm beta version](https://img.shields.io/npm/v/@semantic-release/exec/beta.svg)](https://www.npmjs.com/package/@semantic-release/exec)
88

99
| Step | Description |
10-
|--------------------|---------------------------------------------------------------------------------------------------------|
10+
| ------------------ | ------------------------------------------------------------------------------------------------------- |
1111
| `verifyConditions` | Execute a shell command to verify if the release should happen. |
1212
| `analyzeCommits` | Execute a shell command to determine the type of release. |
1313
| `verifyRelease` | Execute a shell command to verifying a release that was determined before and is about to be published. |
@@ -32,15 +32,19 @@ The plugin can be configured in the [**semantic-release** configuration file](ht
3232
"plugins": [
3333
"@semantic-release/commit-analyzer",
3434
"@semantic-release/release-notes-generator",
35-
["@semantic-release/exec", {
36-
"verifyConditionsCmd": "./verify.sh",
37-
"publishCmd": "./publish.sh ${nextRelease.version} ${branch.name} ${commits.length} ${Date.now()}"
38-
}],
35+
[
36+
"@semantic-release/exec",
37+
{
38+
"verifyConditionsCmd": "./verify.sh",
39+
"publishCmd": "./publish.sh ${nextRelease.version} ${branch.name} ${commits.length} ${Date.now()}"
40+
}
41+
]
3942
]
4043
}
4144
```
4245

4346
With this example:
47+
4448
- the shell command `./verify.sh` will be executed on the [verify conditions step](https://github.com/semantic-release/semantic-release#release-steps)
4549
- the shell command `./publish.sh 1.0.0 master 3 870668040000` (for the release of version `1.0.0` from branch `master` with `3` commits on `August 4th, 1997 at 2:14 AM`) will be executed on the [publish step](https://github.com/semantic-release/semantic-release#release-steps)
4650

@@ -51,7 +55,7 @@ With this example:
5155
### Options
5256

5357
| Options | Description |
54-
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
58+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
5559
| `verifyConditionsCmd` | The shell command to execute during the verify condition step. See [verifyConditionsCmd](#verifyconditionscmd). |
5660
| `analyzeCommitsCmd` | The shell command to execute during the analyze commits step. See [analyzeCommitsCmd](#analyzecommitscmd). |
5761
| `verifyReleaseCmd` | The shell command to execute during the verify release step. See [verifyReleaseCmd](#verifyreleasecmd). |
@@ -71,71 +75,71 @@ Each shell command is generated with [Lodash template](https://lodash.com/docs#t
7175
Execute a shell command to verify if the release should happen.
7276

7377
| Command property | Description |
74-
|------------------|--------------------------------------------------------------------------|
78+
| ---------------- | ------------------------------------------------------------------------ |
7579
| `exit code` | `0` if the verification is successful, or any other exit code otherwise. |
7680
| `stdout` | Write only the reason for the verification to fail. |
7781
| `stderr` | Can be used for logging. |
7882

7983
## analyzeCommitsCmd
8084

8185
| Command property | Description |
82-
|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
86+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
8387
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
8488
| `stdout` | Only the release type (`major`, `minor` or `patch` etc..) can be written to `stdout`. If no release has to be done the command must not write to `stdout`. |
8589
| `stderr` | Can be used for logging. |
8690

8791
## verifyReleaseCmd
8892

8993
| Command property | Description |
90-
|------------------|--------------------------------------------------------------------------|
94+
| ---------------- | ------------------------------------------------------------------------ |
9195
| `exit code` | `0` if the verification is successful, or any other exit code otherwise. |
9296
| `stdout` | Only the reason for the verification to fail can be written to `stdout`. |
9397
| `stderr` | Can be used for logging. |
9498

9599
## generateNotesCmd
96100

97101
| Command property | Description |
98-
|------------------|---------------------------------------------------------------------------------------------------------------------|
102+
| ---------------- | ------------------------------------------------------------------------------------------------------------------- |
99103
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
100104
| `stdout` | Only the release note must be written to `stdout`. |
101105
| `stderr` | Can be used for logging. |
102106

103107
## prepareCmd
104108

105109
| Command property | Description |
106-
|------------------|---------------------------------------------------------------------------------------------------------------------|
110+
| ---------------- | ------------------------------------------------------------------------------------------------------------------- |
107111
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
108112
| `stdout` | Can be used for logging. |
109113
| `stderr` | Can be used for logging. |
110114

111115
## addChannelCmd
112116

113117
| Command property | Description |
114-
|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
118+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115119
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
116120
| `stdout` | The `release` information can be written to `stdout` as parseable JSON (for example `{"name": "Release name", "url": "http://url/release/1.0.0"}`). If the command write non parseable JSON to `stdout` no `release` information will be returned. |
117121
| `stderr` | Can be used for logging. |
118122

119123
## publishCmd
120124

121125
| Command property | Description |
122-
|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
126+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
123127
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
124128
| `stdout` | The `release` information can be written to `stdout` as parseable JSON (for example `{"name": "Release name", "url": "http://url/release/1.0.0"}`). If the command write non parseable JSON to `stdout` no `release` information will be returned. |
125129
| `stderr` | Can be used for logging. |
126130

127131
## successCmd
128132

129133
| Command property | Description |
130-
|------------------|---------------------------------------------------------------------------------------------------------------------|
134+
| ---------------- | ------------------------------------------------------------------------------------------------------------------- |
131135
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
132136
| `stdout` | Can be used for logging. |
133137
| `stderr` | Can be used for logging. |
134138

135139
## failCmd
136140

137141
| Command property | Description |
138-
|------------------|---------------------------------------------------------------------------------------------------------------------|
142+
| ---------------- | ------------------------------------------------------------------------------------------------------------------- |
139143
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
140144
| `stdout` | Can be used for logging. |
141145
| `stderr` | Can be used for logging. |

Diff for: index.js

+42-50
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,67 @@
1-
const {isNil} = require('lodash');
2-
const parseJson = require('parse-json');
3-
const debug = require('debug')('semantic-release:exec');
4-
const SemanticReleaseError = require('@semantic-release/error');
5-
const exec = require('./lib/exec.js');
6-
const verifyConfig = require('./lib/verify-config.js');
7-
8-
async function verifyConditions(pluginConfig, context) {
1+
import { isNil } from "lodash-es";
2+
import parseJson from "parse-json";
3+
import debugFactory from "debug";
4+
import SemanticReleaseError from "@semantic-release/error";
5+
import exec from "./lib/exec.js";
6+
import verifyConfig from "./lib/verify-config.js";
7+
8+
const debug = debugFactory("semantic-release:exec");
9+
10+
export async function verifyConditions(pluginConfig, context) {
911
if (!isNil(pluginConfig.verifyConditionsCmd) || !isNil(pluginConfig.cmd)) {
10-
verifyConfig('verifyConditionsCmd', pluginConfig);
12+
verifyConfig("verifyConditionsCmd", pluginConfig);
1113

1214
try {
13-
await exec('verifyConditionsCmd', pluginConfig, context);
15+
await exec("verifyConditionsCmd", pluginConfig, context);
1416
} catch (error) {
15-
throw new SemanticReleaseError(error.stdout, 'EVERIFYCONDITIONS');
17+
throw new SemanticReleaseError(error.stdout, "EVERIFYCONDITIONS");
1618
}
1719
}
1820
}
1921

20-
async function analyzeCommits(pluginConfig, context) {
22+
export async function analyzeCommits(pluginConfig, context) {
2123
if (!isNil(pluginConfig.analyzeCommitsCmd) || !isNil(pluginConfig.cmd)) {
22-
verifyConfig('analyzeCommitsCmd', pluginConfig);
24+
verifyConfig("analyzeCommitsCmd", pluginConfig);
2325

24-
const stdout = await exec('analyzeCommitsCmd', pluginConfig, context);
26+
const stdout = await exec("analyzeCommitsCmd", pluginConfig, context);
2527
return stdout || undefined;
2628
}
2729
}
2830

29-
async function verifyRelease(pluginConfig, context) {
31+
export async function verifyRelease(pluginConfig, context) {
3032
if (!isNil(pluginConfig.verifyReleaseCmd) || !isNil(pluginConfig.cmd)) {
31-
verifyConfig('verifyReleaseCmd', pluginConfig);
33+
verifyConfig("verifyReleaseCmd", pluginConfig);
3234

3335
try {
34-
await exec('verifyReleaseCmd', pluginConfig, context);
36+
await exec("verifyReleaseCmd", pluginConfig, context);
3537
} catch (error) {
36-
throw new SemanticReleaseError(error.stdout, 'EVERIFYRELEASE');
38+
throw new SemanticReleaseError(error.stdout, "EVERIFYRELEASE");
3739
}
3840
}
3941
}
4042

41-
async function generateNotes(pluginConfig, context) {
43+
export async function generateNotes(pluginConfig, context) {
4244
if (!isNil(pluginConfig.generateNotesCmd) || !isNil(pluginConfig.cmd)) {
43-
verifyConfig('generateNotesCmd', pluginConfig);
45+
verifyConfig("generateNotesCmd", pluginConfig);
4446

45-
const stdout = await exec('generateNotesCmd', pluginConfig, context);
47+
const stdout = await exec("generateNotesCmd", pluginConfig, context);
4648
return stdout;
4749
}
4850
}
4951

50-
async function prepare(pluginConfig, context) {
52+
export async function prepare(pluginConfig, context) {
5153
if (!isNil(pluginConfig.prepareCmd) || !isNil(pluginConfig.cmd)) {
52-
verifyConfig('prepareCmd', pluginConfig);
54+
verifyConfig("prepareCmd", pluginConfig);
5355

54-
await exec('prepareCmd', pluginConfig, context);
56+
await exec("prepareCmd", pluginConfig, context);
5557
}
5658
}
5759

58-
async function publish(pluginConfig, context) {
60+
export async function publish(pluginConfig, context) {
5961
if (!isNil(pluginConfig.publishCmd) || !isNil(pluginConfig.cmd)) {
60-
verifyConfig('publishCmd', pluginConfig);
62+
verifyConfig("publishCmd", pluginConfig);
6163

62-
const stdout = await exec('publishCmd', pluginConfig, context);
64+
const stdout = await exec("publishCmd", pluginConfig, context);
6365

6466
try {
6567
return stdout ? parseJson(stdout) : undefined;
@@ -70,7 +72,7 @@ async function publish(pluginConfig, context) {
7072
debug(
7173
`The command ${
7274
pluginConfig.publishCmd || pluginConfig.cmd
73-
} wrote invalid JSON to stdout. The stdout content will be ignored.`
75+
} wrote invalid JSON to stdout. The stdout content will be ignored.`,
7476
);
7577
}
7678

@@ -80,19 +82,21 @@ async function publish(pluginConfig, context) {
8082
return false;
8183
}
8284

83-
async function addChannel(pluginConfig, context) {
85+
export async function addChannel(pluginConfig, context) {
8486
if (!isNil(pluginConfig.addChannelCmd) || !isNil(pluginConfig.cmd)) {
85-
verifyConfig('addChannelCmd', pluginConfig);
87+
verifyConfig("addChannelCmd", pluginConfig);
8688

87-
const stdout = await exec('addChannelCmd', pluginConfig, context);
89+
const stdout = await exec("addChannelCmd", pluginConfig, context);
8890

8991
try {
9092
return stdout ? parseJson(stdout) : undefined;
9193
} catch (error) {
9294
debug(stdout);
9395
debug(error);
9496

95-
debug(`The command ${pluginConfig.cmd} wrote invalid JSON to stdout. The stdout content will be ignored.`);
97+
debug(
98+
`The command ${pluginConfig.cmd} wrote invalid JSON to stdout. The stdout content will be ignored.`,
99+
);
96100

97101
return undefined;
98102
}
@@ -101,30 +105,18 @@ async function addChannel(pluginConfig, context) {
101105
return false;
102106
}
103107

104-
async function success(pluginConfig, context) {
108+
export async function success(pluginConfig, context) {
105109
if (!isNil(pluginConfig.successCmd) || !isNil(pluginConfig.cmd)) {
106-
verifyConfig('successCmd', pluginConfig);
110+
verifyConfig("successCmd", pluginConfig);
107111

108-
await exec('successCmd', pluginConfig, context);
112+
await exec("successCmd", pluginConfig, context);
109113
}
110114
}
111115

112-
async function fail(pluginConfig, context) {
116+
export async function fail(pluginConfig, context) {
113117
if (!isNil(pluginConfig.failCmd) || !isNil(pluginConfig.cmd)) {
114-
verifyConfig('failCmd', pluginConfig);
118+
verifyConfig("failCmd", pluginConfig);
115119

116-
await exec('failCmd', pluginConfig, context);
120+
await exec("failCmd", pluginConfig, context);
117121
}
118122
}
119-
120-
module.exports = {
121-
verifyConditions,
122-
analyzeCommits,
123-
verifyRelease,
124-
generateNotes,
125-
prepare,
126-
publish,
127-
addChannel,
128-
success,
129-
fail,
130-
};

0 commit comments

Comments
 (0)