Skip to content

Commit

Permalink
feat: use cwd and env options passed by core
Browse files Browse the repository at this point in the history
BREAKING CHANGE: require `semantic-release` >= `15.8.0`
  • Loading branch information
pvdlg committed Jul 17, 2018
1 parent 683cf3d commit 1f906b4
Show file tree
Hide file tree
Showing 15 changed files with 387 additions and 440 deletions.
10 changes: 8 additions & 2 deletions lib/fail.js
Expand Up @@ -7,9 +7,15 @@ const getClient = require('./get-client');
const findSRIssues = require('./find-sr-issues');
const getFailComment = require('./get-fail-comment');

module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, errors, logger}) => {
module.exports = async (pluginConfig, context) => {
const {
options: {branch, repositoryUrl},
errors,
logger,
} = context;
const {githubToken, githubUrl, githubApiPathPrefix, proxy, failComment, failTitle, labels, assignees} = resolveConfig(
pluginConfig
pluginConfig,
context
);
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
Expand Down
4 changes: 2 additions & 2 deletions lib/glob-assets.js
Expand Up @@ -3,7 +3,7 @@ const {isPlainObject, castArray, uniqWith} = require('lodash');
const globby = require('globby');
const debug = require('debug')('semantic-release:github');

module.exports = async assets =>
module.exports = async ({cwd}, assets) =>
uniqWith(
[]
.concat(
Expand All @@ -19,7 +19,7 @@ module.exports = async assets =>
);
return [];
}
const globbed = await globby(glob, {expandDirectories: true, gitignore: false, dot: true});
const globbed = await globby(glob, {cwd, expandDirectories: true, gitignore: false, dot: true});
if (isPlainObject(asset)) {
if (globbed.length > 1) {
// If asset is an Object with a glob the `path` property that resolve to multiple files,
Expand Down
18 changes: 12 additions & 6 deletions lib/publish.js
@@ -1,4 +1,4 @@
const {basename, extname} = require('path');
const {basename, extname, resolve} = require('path');
const {stat, readFile} = require('fs-extra');
const {isPlainObject} = require('lodash');
const parseGithubUrl = require('parse-github-url');
Expand All @@ -8,8 +8,14 @@ const globAssets = require('./glob-assets.js');
const resolveConfig = require('./resolve-config');
const getClient = require('./get-client');

module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, nextRelease: {gitTag, notes}, logger}) => {
const {githubToken, githubUrl, githubApiPathPrefix, proxy, assets} = resolveConfig(pluginConfig);
module.exports = async (pluginConfig, context) => {
const {
cwd,
options: {branch, repositoryUrl},
nextRelease: {gitTag, notes},
logger,
} = context;
const {githubToken, githubUrl, githubApiPathPrefix, proxy, assets} = resolveConfig(pluginConfig, context);
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
const release = {owner, repo, tag_name: gitTag, name: gitTag, target_commitish: branch, body: notes}; // eslint-disable-line camelcase
Expand All @@ -25,7 +31,7 @@ module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, nextRel
logger.log('Published GitHub release: %s', url);

if (assets && assets.length > 0) {
const globbedAssets = await globAssets(assets);
const globbedAssets = await globAssets(context, assets);
debug('globed assets: %o', globbedAssets);

await Promise.all(
Expand All @@ -34,7 +40,7 @@ module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, nextRel
let file;

try {
file = await stat(filePath);
file = await stat(resolve(cwd, filePath));
} catch (err) {
logger.error('The asset %s cannot be read, and will be ignored.', filePath);
return;
Expand All @@ -47,7 +53,7 @@ module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, nextRel
const fileName = asset.name || basename(filePath);
const upload = {
url: uploadUrl,
file: await readFile(filePath),
file: await readFile(resolve(cwd, filePath)),
contentType: mime.getType(extname(fileName)) || 'text/plain',
contentLength: file.size,
name: fileName,
Expand Down
23 changes: 8 additions & 15 deletions lib/resolve-config.js
@@ -1,20 +1,13 @@
const {isUndefined, castArray} = require('lodash');

module.exports = ({
githubUrl,
githubApiPathPrefix,
proxy,
assets,
successComment,
failTitle,
failComment,
labels,
assignees,
}) => ({
githubToken: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
githubUrl: githubUrl || process.env.GH_URL || process.env.GITHUB_URL,
githubApiPathPrefix: githubApiPathPrefix || process.env.GH_PREFIX || process.env.GITHUB_PREFIX || '',
proxy: proxy || process.env.HTTP_PROXY,
module.exports = (
{githubUrl, githubApiPathPrefix, proxy, assets, successComment, failTitle, failComment, labels, assignees},
{env}
) => ({
githubToken: env.GH_TOKEN || env.GITHUB_TOKEN,
githubUrl: githubUrl || env.GH_URL || env.GITHUB_URL,
githubApiPathPrefix: githubApiPathPrefix || env.GH_PREFIX || env.GITHUB_PREFIX || '',
proxy: proxy || env.HTTP_PROXY,
assets: assets ? castArray(assets) : assets,
successComment,
failTitle: isUndefined(failTitle) || failTitle === false ? 'The automated release is failing 🚨' : failTitle,
Expand Down
18 changes: 13 additions & 5 deletions lib/success.js
Expand Up @@ -10,11 +10,19 @@ const getSearchQueries = require('./get-search-queries');
const getSuccessComment = require('./get-success-comment');
const findSRIssues = require('./find-sr-issues');

module.exports = async (
pluginConfig,
{options: {branch, repositoryUrl}, lastRelease, commits, nextRelease, releases, logger}
) => {
const {githubToken, githubUrl, githubApiPathPrefix, proxy, successComment, failTitle} = resolveConfig(pluginConfig);
module.exports = async (pluginConfig, context) => {
const {
options: {branch, repositoryUrl},
lastRelease,
commits,
nextRelease,
releases,
logger,
} = context;
const {githubToken, githubUrl, githubApiPathPrefix, proxy, successComment, failTitle} = resolveConfig(
pluginConfig,
context
);
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
const parser = issueParser('github', githubUrl ? {hosts: [githubUrl]} : {});
Expand Down
8 changes: 6 additions & 2 deletions lib/verify.js
Expand Up @@ -23,8 +23,12 @@ const VALIDATORS = {
assignees: isArrayOf(isStringOrStringArray),
};

module.exports = async (pluginConfig, {options: {repositoryUrl}, logger}) => {
const {githubToken, githubUrl, githubApiPathPrefix, proxy, ...options} = resolveConfig(pluginConfig);
module.exports = async (pluginConfig, context) => {
const {
options: {repositoryUrl},
logger,
} = context;
const {githubToken, githubUrl, githubApiPathPrefix, proxy, ...options} = resolveConfig(pluginConfig, context);

const errors = Object.entries({...options, proxy}).reduce(
(errors, [option, value]) =>
Expand Down
3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -82,6 +82,9 @@
],
"all": true
},
"peerDependencies": {
"semantic-release": ">=15.8.0 <16.0.0"
},
"prettier": {
"printWidth": 120,
"trailingComma": "es5"
Expand Down
48 changes: 18 additions & 30 deletions test/fail.test.js
Expand Up @@ -14,34 +14,22 @@ const fail = proxyquire('../lib/fail', {
'./get-client': proxyquire('../lib/get-client', {'./definitions/rate-limit': rateLimit}),
});

// Save the current process.env
const envBackup = Object.assign({}, process.env);

test.beforeEach(t => {
// Delete env variables in case they are on the machine running the tests
delete process.env.GH_TOKEN;
delete process.env.GITHUB_TOKEN;
delete process.env.GH_URL;
delete process.env.GITHUB_URL;
delete process.env.GH_PREFIX;
delete process.env.GITHUB_PREFIX;
// Mock logger
t.context.log = stub();
t.context.error = stub();
t.context.logger = {log: t.context.log, error: t.context.error};
});

test.afterEach.always(() => {
// Restore process.env
process.env = envBackup;
// Clear nock
nock.cleanAll();
});

test.serial('Open a new issue with the list of errors', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'The automated release is failing 🚨';
const pluginConfig = {failTitle};
const options = {branch: 'master', repositoryUrl: `https://github.com/${owner}/${repo}.git`};
Expand All @@ -50,7 +38,7 @@ test.serial('Open a new issue with the list of errors', async t => {
new SemanticReleaseError('Error message 2', 'ERR2', 'Error 2 details'),
new SemanticReleaseError('Error message 3', 'ERR3', 'Error 3 details'),
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand All @@ -64,7 +52,7 @@ test.serial('Open a new issue with the list of errors', async t => {
})
.reply(200, {html_url: 'https://github.com/issues/1', number: 1});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Created issue #%d: %s.', 1, 'https://github.com/issues/1'));
t.true(github.isDone());
Expand All @@ -73,7 +61,7 @@ test.serial('Open a new issue with the list of errors', async t => {
test.serial('Open a new issue with the list of errors, retrying 4 times', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'The automated release is failing 🚨';
const pluginConfig = {failTitle};
const options = {branch: 'master', repositoryUrl: `https://github.com/${owner}/${repo}.git`};
Expand All @@ -82,7 +70,7 @@ test.serial('Open a new issue with the list of errors, retrying 4 times', async
new SemanticReleaseError('Error message 2', 'ERR2', 'Error 2 details'),
new SemanticReleaseError('Error message 3', 'ERR3', 'Error 3 details'),
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand Down Expand Up @@ -110,7 +98,7 @@ test.serial('Open a new issue with the list of errors, retrying 4 times', async
})
.reply(200, {html_url: 'https://github.com/issues/1', number: 1});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Created issue #%d: %s.', 1, 'https://github.com/issues/1'));
t.true(github.isDone());
Expand All @@ -119,7 +107,7 @@ test.serial('Open a new issue with the list of errors, retrying 4 times', async
test.serial('Open a new issue with the list of errors and custom title and comment', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'Custom title';
const failComment = `branch \${branch} \${errors[0].message} \${errors[1].message} \${errors[2].message}`;
const pluginConfig = {failTitle, failComment};
Expand All @@ -129,7 +117,7 @@ test.serial('Open a new issue with the list of errors and custom title and comme
new SemanticReleaseError('Error message 2', 'ERR2', 'Error 2 details'),
new SemanticReleaseError('Error message 3', 'ERR3', 'Error 3 details'),
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand All @@ -143,7 +131,7 @@ test.serial('Open a new issue with the list of errors and custom title and comme
})
.reply(200, {html_url: 'https://github.com/issues/1', number: 1});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Created issue #%d: %s.', 1, 'https://github.com/issues/1'));
t.true(github.isDone());
Expand All @@ -152,7 +140,7 @@ test.serial('Open a new issue with the list of errors and custom title and comme
test.serial('Open a new issue with assignees and the list of errors', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'The automated release is failing 🚨';
const assignees = ['user1', 'user2'];
const pluginConfig = {failTitle, assignees};
Expand All @@ -161,7 +149,7 @@ test.serial('Open a new issue with assignees and the list of errors', async t =>
new SemanticReleaseError('Error message 1', 'ERR1', 'Error 1 details'),
new SemanticReleaseError('Error message 2', 'ERR2', 'Error 2 details'),
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand All @@ -176,7 +164,7 @@ test.serial('Open a new issue with assignees and the list of errors', async t =>
})
.reply(200, {html_url: 'https://github.com/issues/1', number: 1});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Created issue #%d: %s.', 1, 'https://github.com/issues/1'));
t.true(github.isDone());
Expand All @@ -185,7 +173,7 @@ test.serial('Open a new issue with assignees and the list of errors', async t =>
test.serial('Open a new issue without labels and the list of errors', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'The automated release is failing 🚨';
const labels = false;
const pluginConfig = {failTitle, labels};
Expand All @@ -194,7 +182,7 @@ test.serial('Open a new issue without labels and the list of errors', async t =>
new SemanticReleaseError('Error message 1', 'ERR1', 'Error 1 details'),
new SemanticReleaseError('Error message 2', 'ERR2', 'Error 2 details'),
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand All @@ -208,7 +196,7 @@ test.serial('Open a new issue without labels and the list of errors', async t =>
})
.reply(200, {html_url: 'https://github.com/issues/1', number: 1});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Created issue #%d: %s.', 1, 'https://github.com/issues/1'));
t.true(github.isDone());
Expand All @@ -217,7 +205,7 @@ test.serial('Open a new issue without labels and the list of errors', async t =>
test.serial('Update the first existing issue with the list of errors', async t => {
const owner = 'test_user';
const repo = 'test_repo';
process.env.GITHUB_TOKEN = 'github_token';
const env = {GITHUB_TOKEN: 'github_token'};
const failTitle = 'The automated release is failing 🚨';
const pluginConfig = {failTitle};
const options = {branch: 'master', repositoryUrl: `https://github.com/${owner}/${repo}.git`};
Expand All @@ -231,7 +219,7 @@ test.serial('Update the first existing issue with the list of errors', async t =
{number: 2, body: `Issue 2 body\n\n${ISSUE_ID}`, title: failTitle},
{number: 3, body: `Issue 3 body\n\n${ISSUE_ID}`, title: failTitle},
];
const github = authenticate()
const github = authenticate(env)
.get(
`/search/issues?q=${escape('in:title')}+${escape(`repo:${owner}/${repo}`)}+${escape('type:issue')}+${escape(
'state:open'
Expand All @@ -243,7 +231,7 @@ test.serial('Update the first existing issue with the list of errors', async t =
})
.reply(200, {html_url: 'https://github.com/issues/2', number: 2});

await fail(pluginConfig, {options, errors, logger: t.context.logger});
await fail(pluginConfig, {env, options, errors, logger: t.context.logger});

t.true(t.context.log.calledWith('Found existing semantic-release issue #%d.', 2));
t.true(t.context.log.calledWith('Added comment to issue #%d: %s.', 2, 'https://github.com/issues/2'));
Expand Down

0 comments on commit 1f906b4

Please sign in to comment.