Skip to content

Commit c0b9a50

Browse files
pvdlggr2m
authored andcommitted
feat: return release info in publish and add success and fail hooks (#11)
1 parent 0ffe41d commit c0b9a50

File tree

6 files changed

+119
-6
lines changed

6 files changed

+119
-6
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ Execute a shell command to generate the release note.
5353

5454
Execute a shell command to publish the release.
5555

56+
| Command property | Description |
57+
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
58+
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
59+
| `stdout` | Only the `release` information must be written to `stdout` as parseable JSON (for example `{"name": "Release name", "url": "http://url/release/1.0.0"}`). |
60+
| `stderr` | Can be used for logging. |
61+
62+
## success
63+
64+
Execute a shell command to notify of a successful release.
65+
66+
| Command property | Description |
67+
|------------------|---------------------------------------------------------------------------------------------------------------------|
68+
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
69+
| `stdout` | Can be used for logging. |
70+
| `stderr` | Can be used for logging. |
71+
72+
## fail
73+
74+
Execute a shell command to notify of a failed release.
75+
5676
| Command property | Description |
5777
|------------------|---------------------------------------------------------------------------------------------------------------------|
5878
| `exit code` | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |

index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const {castArray, isPlainObject} = require('lodash');
2+
const parseJson = require('parse-json');
23
const SemanticReleaseError = require('@semantic-release/error');
34
const execScript = require('./lib/exec-script');
45
const verifyConfig = require('./lib/verify-config');
@@ -46,7 +47,16 @@ async function generateNotes(pluginConfig, params) {
4647
}
4748

4849
async function publish(pluginConfig, params) {
50+
const stdout = await execScript(pluginConfig, params);
51+
return stdout.trim() ? parseJson(stdout) : undefined;
52+
}
53+
54+
async function success(pluginConfig, params) {
55+
await execScript(pluginConfig, params);
56+
}
57+
58+
async function fail(pluginConfig, params) {
4959
await execScript(pluginConfig, params);
5060
}
5161

52-
module.exports = {verifyConditions, analyzeCommits, verifyRelease, generateNotes, publish};
62+
module.exports = {verifyConditions, analyzeCommits, verifyRelease, generateNotes, publish, success, fail};

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"@semantic-release/error": "^2.1.0",
2020
"debug": "^3.1.0",
2121
"execa": "^0.9.0",
22-
"lodash": "^4.17.4"
22+
"lodash": "^4.17.4",
23+
"parse-json": "^4.0.0"
2324
},
2425
"devDependencies": {
2526
"ava": "^0.25.0",

test/fail.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import test from 'ava';
2+
import {stub} from 'sinon';
3+
import {fail} from '..';
4+
5+
stub(process.stdout, 'write');
6+
stub(process.stderr, 'write');
7+
8+
test.beforeEach(t => {
9+
// Mock logger
10+
t.context.log = stub();
11+
t.context.error = stub();
12+
t.context.logger = {log: t.context.log, error: t.context.error};
13+
});
14+
15+
test.serial('Return the value fail script wrote to stdout', async t => {
16+
const pluginConfig = {
17+
cmd: './test/fixtures/echo-args.sh',
18+
};
19+
const params = {logger: t.context.logger};
20+
21+
await t.notThrows(fail(pluginConfig, params));
22+
});
23+
24+
test.serial('Throw "Error" if the fail script does not returns 0', async t => {
25+
const pluginConfig = {cmd: 'exit 1'};
26+
const params = {logger: t.context.logger};
27+
28+
await t.throws(fail(pluginConfig, params), Error);
29+
});

test/publish.test.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,35 @@ test.beforeEach(t => {
1313
t.context.logger = {log: t.context.log, error: t.context.error};
1414
});
1515

16-
test.serial('Return if the publish script returns 0', async t => {
17-
const pluginConfig = {cmd: 'exit 0'};
18-
const params = {logger: t.context.logger, options: {}};
16+
test.serial('Parse JSON returned by publish script', async t => {
17+
const pluginConfig = {
18+
cmd:
19+
'./test/fixtures/echo-args.sh {\\"name\\": \\"Release name\\", \\"url\\": \\"https://host.com/release/1.0.0\\"}',
20+
};
21+
const params = {logger: t.context.logger};
22+
23+
const result = await publish(pluginConfig, params);
24+
t.deepEqual(result, {name: 'Release name', url: 'https://host.com/release/1.0.0'});
25+
});
26+
27+
test.serial('Return "undefined" if the publish script wrtite nothing to stdout', async t => {
28+
const pluginConfig = {
29+
cmd: './test/fixtures/echo-args.sh',
30+
};
31+
const params = {logger: t.context.logger};
32+
33+
const result = await publish(pluginConfig, params);
34+
t.is(result, undefined);
35+
});
36+
37+
test.serial('Throw JSONError if publish script write invalid JSON to stdout', async t => {
38+
const pluginConfig = {
39+
cmd: './test/fixtures/echo-args.sh invalid_json',
40+
};
41+
const params = {logger: t.context.logger};
1942

20-
await t.notThrows(publish(pluginConfig, params));
43+
const error = await t.throws(publish(pluginConfig, params));
44+
t.is(error.name, 'JSONError');
2145
});
2246

2347
test.serial('Throw "Error" if the publish script does not returns 0', async t => {

test/success.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import test from 'ava';
2+
import {stub} from 'sinon';
3+
import {success} from '..';
4+
5+
stub(process.stdout, 'write');
6+
stub(process.stderr, 'write');
7+
8+
test.beforeEach(t => {
9+
// Mock logger
10+
t.context.log = stub();
11+
t.context.error = stub();
12+
t.context.logger = {log: t.context.log, error: t.context.error};
13+
});
14+
15+
test.serial('Return the value success script wrote to stdout', async t => {
16+
const pluginConfig = {
17+
cmd: './test/fixtures/echo-args.sh',
18+
};
19+
const params = {logger: t.context.logger};
20+
21+
await t.notThrows(success(pluginConfig, params));
22+
});
23+
24+
test.serial('Throw "Error" if the success script does not returns 0', async t => {
25+
const pluginConfig = {cmd: 'exit 1'};
26+
const params = {logger: t.context.logger};
27+
28+
await t.throws(success(pluginConfig, params), Error);
29+
});

0 commit comments

Comments
 (0)