diff --git a/index.js b/index.js index f623e6d..b49b0d6 100755 --- a/index.js +++ b/index.js @@ -3,27 +3,37 @@ const chalk = require('chalk'); const prompt = require('prompt'); const getVersion = require('./utils/version'); -const getIssues = require('./utils/issues'); +const { getIssues, closeIssues } = require('./utils/issues'); const createChangelog = require('./utils/changelog'); const commitAndTag = require('./utils/commit-and-tag'); const release = require('./utils/release'); -const { error } = require('./utils/console-messages'); +const { success, error } = require('./utils/console-messages'); async function main(input) { const { - versionOverride, append, issues, closeIssues, publish, token, dryRun, + versionOverride, append, issueLabels, shouldCloseIssues, publish, token, dryRun, } = input; const version = await getVersion(versionOverride, append, dryRun); - const issuesToInclude = await getIssues({ - issues, closeIssues, version, token, - }); - const changelog = await createChangelog(version, issuesToInclude, dryRun); + const issues = await getIssues(issueLabels); + const changelog = await createChangelog(version, issues, dryRun); await commitAndTag(version, dryRun); if (publish) { - release(version, changelog, token, dryRun); + if (dryRun) { + success('Pushed to origin'); + success('Pushed tags to origin'); + success('Created Github release'); + } else { + release(version, changelog, token); + } } + + if (shouldCloseIssues && !dryRun) { + closeIssues(issues, version, token); + } + + success('Completed'); } console.log(chalk.magenta('Github Releaser') + chalk.yellow(' by ') + chalk.cyan('Tom Hewitt')); @@ -37,12 +47,12 @@ const schema = { type: 'string', description: 'Append to version (hit enter to skip)', }, - issues: { + issueLabels: { type: 'string', message: chalk.yellow('Issue labels are required!'), description: 'Issue labels (e.g. bug coded)', }, - closeIssues: { + shouldCloseIssues: { type: 'boolean', message: chalk.yellow('Must be one of \'true\', \'t\', \'false\', \'f\''), description: 'Close issues? (t/f)', @@ -77,9 +87,9 @@ prompt.get(schema, (err, input) => { process.exit(1); } - const { publish, closeIssues, token } = input; + const { publish, shouldCloseIssues, token } = input; - if ((publish || closeIssues) && (!token || token.length === 0)) { + if ((publish || shouldCloseIssues) && (!token || token.length === 0)) { error('No Github token has been specified'); process.exit(1); } diff --git a/utils/issues.js b/utils/issues.js index 733bed3..9ea6416 100644 --- a/utils/issues.js +++ b/utils/issues.js @@ -5,66 +5,61 @@ const figures = require('figures'); const { apiUrl } = require(`${process.cwd()}/package.json`).repository; const { success, error } = require('./console-messages'); -const getIssues = (data) => new Promise((resolve, reject) => { - const { - labels, closeIssues, version, token, - } = data; +module.exports = { + getIssues: (labels) => new Promise((resolve, reject) => { + if (!apiUrl) { + reject(new Error(`${chalk.red(figures.cross)} There is no "repository: { apiUrl : "" }" in your package.json!`)); + } - if (!apiUrl) { - reject(new Error(`${chalk.red(figures.cross)} There is no "repository: { apiUrl : "" }" in your package.json!`)); - } - - const filteredIssues = []; - fetch(`${apiUrl}/issues`) - .then((response) => response.json()) - .then((issues) => { - issues.forEach((issue) => { - issue.labels.forEach((label) => { - if (labels.includes(label.name)) { - filteredIssues.push(issue); - } + const filteredIssues = []; + fetch(`${apiUrl}/issues`) + .then((response) => response.json()) + .then((issues) => { + issues.forEach((issue) => { + issue.labels.forEach((label) => { + if (labels.includes(label.name)) { + filteredIssues.push(issue); + } + }); }); + success(`Adding ${filteredIssues.length} issues to the release`); + resolve(filteredIssues); }); - success(`Adding ${filteredIssues.length} issues to the release`); + }), - if (closeIssues) { - filteredIssues.forEach((issue) => { - // Add a comment - fetch(`${apiUrl}/issues/${issue.number}/comments`, { - method: 'POST', - body: JSON.stringify({ body: `Included in version ${version}` }), - headers: { - 'Content-Type': 'application/json', - Authorization: `token ${token}`, - }, - }) - .then((res) => { - if (!res.ok) { - error(`Could not add comment to issue #${issue.number}: ${res.status}`); - throw new Error(`Could not add comment to issue #${issue.number}: ${res.status}`); - } - }); + closeIssues: (issues, version, token) => { + issues.forEach((issue) => { + // Add a comment + fetch(`${apiUrl}/issues/${issue.number}/comments`, { + method: 'POST', + body: JSON.stringify({ body: `Included in version ${version}` }), + headers: { + 'Content-Type': 'application/json', + Authorization: `token ${token}`, + }, + }) + .then((res) => { + if (!res.ok) { + error(`Could not add comment to issue #${issue.number}: ${res.status}`); + throw new Error(`Could not add comment to issue #${issue.number}: ${res.status}`); + } + }); - // Update status - fetch(`${apiUrl}/issues/${issue.number}`, { - method: 'PATCH', - body: JSON.stringify({ state: 'closed' }), - headers: { - 'Content-Type': 'application/json', - Authorization: `token ${token}`, - }, - }) - .then((res) => { - if (!res.ok) { - error(`Could not close issue #${issue.number}: ${res.status}`); - throw new Error(`Could not close issue #${issue.number}: ${res.status}`); - } - }); + // Update status + fetch(`${apiUrl}/issues/${issue.number}`, { + method: 'PATCH', + body: JSON.stringify({ state: 'closed' }), + headers: { + 'Content-Type': 'application/json', + Authorization: `token ${token}`, + }, + }) + .then((res) => { + if (!res.ok) { + error(`Could not close issue #${issue.number}: ${res.status}`); + throw new Error(`Could not close issue #${issue.number}: ${res.status}`); + } }); - } }); - - resolve(filteredIssues); -}); - -module.exports = getIssues; + }, +}; diff --git a/utils/release.js b/utils/release.js index b1e16a1..f7b7216 100644 --- a/utils/release.js +++ b/utils/release.js @@ -8,44 +8,38 @@ const branch = branchName(cwd); const git = simpleGit(cwd); const { apiUrl } = require(`${cwd}/package.json`).repository; -async function release(version, changelog, token, dryRun) { - if (dryRun) { - success('Pushed to origin'); - success('Pushed tags to origin'); - success('Created Github release'); - } else { - await git.push('origin', branch) - .then(() => success('Pushed to origin')) - .catch((e) => error(`Could not push to branch '${branch}': ${e.message}`)); +async function release(version, changelog, token) { + await git.push('origin', branch) + .then(() => success('Pushed to origin')) + .catch((e) => error(`Could not push to branch '${branch}': ${e.message}`)); - await git.pushTags('origin') - .then(() => success('Pushed tags to origin')) - .catch((e) => error(`Could not push tags': ${e.message}`)); + await git.pushTags('origin') + .then(() => success('Pushed tags to origin')) + .catch((e) => error(`Could not push tags': ${e.message}`)); - const releaseBody = { - tag_name: version, - name: version, - body: changelog, - draft: false, - prerelease: false, - }; + const releaseBody = { + tag_name: version, + name: version, + body: changelog, + draft: false, + prerelease: false, + }; - fetch(`${apiUrl}/releases`, { - method: 'post', - body: JSON.stringify(releaseBody), - headers: { - 'Content-Type': 'application/json', - Authorization: `token ${token}`, - }, - }) - .then((res) => { - if (!res.ok) { - error(`Could not create Github release: ${res.status}`); - throw new Error(`Could not create Github release: ${res.status}`); - } - success('Created Github release'); - }); - } + fetch(`${apiUrl}/releases`, { + method: 'post', + body: JSON.stringify(releaseBody), + headers: { + 'Content-Type': 'application/json', + Authorization: `token ${token}`, + }, + }) + .then((res) => { + if (!res.ok) { + error(`Could not create Github release: ${res.status}`); + throw new Error(`Could not create Github release: ${res.status}`); + } + success('Created Github release'); + }); } module.exports = release;