From 27a93265a8e06797b783883cfc082e9ccdf3c768 Mon Sep 17 00:00:00 2001 From: KillianHmyd Date: Thu, 28 Jan 2021 17:03:44 +0100 Subject: [PATCH 1/2] feat: allow to have a custom configuration per branches --- README.md | 21 +- lib/fail.js | 15 +- lib/getConfigToUse.js | 14 ++ lib/success.js | 16 +- lib/verifyConditions.js | 24 +++ package-lock.json | 358 ++++++++++++++++++++++++---------- package.json | 1 + test/getConfigToUse.test.js | 63 ++++++ test/testUtils.js | 7 +- test/verifyConditions.test.js | 56 ++++++ 10 files changed, 459 insertions(+), 116 deletions(-) create mode 100644 lib/getConfigToUse.js create mode 100644 test/getConfigToUse.test.js diff --git a/README.md b/README.md index abe93d0..01c1fba 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,19 @@ The plugin can be configured in the [**semantic-release** configuration file](ht "semantic-release-slack-bot", { "notifyOnSuccess": false, - "notifyOnFail": true + "notifyOnFail": false, + "slackWebhook": "https://my-webhook.com", + "branchesConfig": [ + { + "pattern": "lts/*", + "notifyOnFail": true + }, + { + "pattern": "master1", + "notifyOnSuccess": true, + "notifyOnFail": true + } + ] } ] ] @@ -45,8 +57,10 @@ The plugin can be configured in the [**semantic-release** configuration file](ht With this example: -- Slack notifications are skipped on a successful release -- Slack notifications are sent on a failed release +- Slack notification will always be sent using the "https://my-webhook.com" webhook url +- Slack notifications are sent on a failure release from branches matching "lts/\*" +- Slack notifications are sent on a failure or successful release from branch "master" +- Slack notifications are skipped on every other branches ## Screenshots @@ -93,6 +107,7 @@ Alternatively, you could pass the webhook as a configuration option. | `slackWebhook` | Slack webhook created when adding app to workspace. | value of the environment variable matching `slackWebhookEnVar` | | `packageName` | Override or add package name instead of npm package name | SEMANTIC_RELEASE_PACKAGE or npm package name | | `unsafeMaxLength` | Maximum character length for the release notes before truncation. If unsafeMaxLength is too high, messages can be dropped. [Read here](https://github.com/juliuscc/semantic-release-slack-bot/issues/26#issuecomment-569804359) for more information. Set to '0' to turn off truncation entirely. | 2900 | +| `branchesConfig` | Allow to specify a custom configuration for branches which match a given pattern. For every branches matching a branch config, the config will be merged with the one put at the root. A key "pattern" used to filter the branch using glob expression must be contained in every branchesConfig. | [] | ### Function diff --git a/lib/fail.js b/lib/fail.js index ca47fed..63d1380 100644 --- a/lib/fail.js +++ b/lib/fail.js @@ -1,4 +1,5 @@ /* eslint-disable camelcase */ +const getConfigToUse = require('./getConfigToUse') const postMessage = require('./postMessage') const template = require('./template') @@ -9,12 +10,14 @@ module.exports = async (pluginConfig, context) => { errors, env: { SEMANTIC_RELEASE_PACKAGE, npm_package_name } } = context - const { slackWebhook = process.env.SLACK_WEBHOOK, packageName } = pluginConfig + + const configToUse = getConfigToUse(pluginConfig, context) + const { slackWebhook = process.env.SLACK_WEBHOOK, packageName } = configToUse const package_name = SEMANTIC_RELEASE_PACKAGE || packageName || npm_package_name - if (!pluginConfig.notifyOnFail) { + if (!configToUse.notifyOnFail) { logger.log('Notifying on fail skipped') return } @@ -29,10 +32,10 @@ module.exports = async (pluginConfig, context) => { const repoURL = repoPath && `https://github.com/${repoPath}` // Override default fail message - if (pluginConfig.onFailFunction) { - slackMessage = pluginConfig.onFailFunction(pluginConfig, context) - } else if (pluginConfig.onFailTemplate) { - slackMessage = template(pluginConfig.onFailTemplate, { + if (configToUse.onFailFunction) { + slackMessage = configToUse.onFailFunction(configToUse, context) + } else if (configToUse.onFailTemplate) { + slackMessage = template(configToUse.onFailTemplate, { package_name, repo_path: repoPath, repo_url: repoURL diff --git a/lib/getConfigToUse.js b/lib/getConfigToUse.js new file mode 100644 index 0000000..69f79f9 --- /dev/null +++ b/lib/getConfigToUse.js @@ -0,0 +1,14 @@ +const micromatch = require('micromatch') + +module.exports = (pluginConfig, context) => { + const { + branch: { name } + } = context + + const { branchesConfig = [], ...globalPluginConfig } = pluginConfig + const { pattern, ...branchConfig } = + branchesConfig.find(({ pattern }) => micromatch.isMatch(name, pattern)) || + {} + + return { ...globalPluginConfig, ...branchConfig } +} diff --git a/lib/success.js b/lib/success.js index 53ea68f..0f7367f 100644 --- a/lib/success.js +++ b/lib/success.js @@ -4,6 +4,7 @@ const postMessage = require('./postMessage') const template = require('./template') const truncate = require('./truncate') const getRepoInfo = require('./getRepoInfo') +const getConfigToUse = require('./getConfigToUse') // 2900 is the limit for a message block of type 'section'. const MAX_LENGTH = 2900 @@ -16,17 +17,18 @@ module.exports = async (pluginConfig, context) => { env: { SEMANTIC_RELEASE_PACKAGE, npm_package_name } } = context + const configToUse = getConfigToUse(pluginConfig, context) const { slackWebhookEnVar = 'SLACK_WEBHOOK', slackWebhook = process.env[slackWebhookEnVar], unsafeMaxLength = MAX_LENGTH, packageName - } = pluginConfig + } = configToUse const package_name = SEMANTIC_RELEASE_PACKAGE || packageName || npm_package_name - if (!pluginConfig.notifyOnSuccess) { + if (!configToUse.notifyOnSuccess) { logger.log('Notifying on success skipped') return } @@ -37,7 +39,7 @@ module.exports = async (pluginConfig, context) => { let releaseNotes = nextRelease.notes - if (pluginConfig.markdownReleaseNotes) { + if (configToUse.markdownReleaseNotes) { // Creating slack format from the markdown notes. releaseNotes = slackifyMarkdown(releaseNotes) } @@ -49,10 +51,10 @@ module.exports = async (pluginConfig, context) => { let slackMessage = {} // Override default success message - if (pluginConfig.onSuccessFunction) { - slackMessage = pluginConfig.onSuccessFunction(pluginConfig, context) - } else if (pluginConfig.onSuccessTemplate) { - slackMessage = template(pluginConfig.onSuccessTemplate, { + if (configToUse.onSuccessFunction) { + slackMessage = configToUse.onSuccessFunction(configToUse, context) + } else if (configToUse.onSuccessTemplate) { + slackMessage = template(configToUse.onSuccessTemplate, { package_name, npm_package_version: nextRelease.version, repo_path: repo.path, diff --git a/lib/verifyConditions.js b/lib/verifyConditions.js index e858b2a..7b5f78a 100644 --- a/lib/verifyConditions.js +++ b/lib/verifyConditions.js @@ -30,4 +30,28 @@ module.exports = (pluginConfig, context) => { `A name for the package must be created. Run through npm (npm run to use npm package name or define packageName in the plugin config or \`SEMANTIC_RELEASE_PACKAGE\` in the environment` ) } + + if ( + pluginConfig.branchesConfig && + !Array.isArray(pluginConfig.branchesConfig) + ) { + logger.log('branchesConfig is defined and is not an array') + throw new SemanticReleaseError( + 'branchesConfig is not an array.', + 'EINVALIDBRANCHCONFIG', + `Provided branches configuration is not an array. Make "branchesConfig" is properly set in your configuration option.` + ) + } + + if ( + pluginConfig.branchesConfig && + pluginConfig.branchesConfig.some(({ pattern }) => !pattern) + ) { + logger.log('pattern is not defined in branchesConfig') + throw new SemanticReleaseError( + 'pattern is not defined in branchesConfig.', + 'ENOPATTERN', + `A pattern for the branch configuration must be added. Make "branchesConfig" is properly set in your configuration option.` + ) + } } diff --git a/package-lock.json b/package-lock.json index 4170853..dfbd8ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1971,32 +1971,11 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "fill-range": "^7.0.1" } }, "browser-stdout": { @@ -2537,9 +2516,9 @@ } }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -4043,26 +4022,11 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "find-node-modules": { @@ -4115,6 +4079,111 @@ "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "flat": { @@ -4594,6 +4663,26 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -5085,24 +5174,9 @@ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-obj": { "version": "1.0.1", @@ -5336,9 +5410,9 @@ "dev": true }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "levn": { @@ -5390,6 +5464,35 @@ "yup": "^0.26.10" }, "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -5399,6 +5502,70 @@ "ms": "^2.1.1" } }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -5410,6 +5577,16 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -5929,24 +6106,12 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "mime": { @@ -7870,7 +8035,7 @@ }, "https-proxy-agent": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "resolved": false, "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { @@ -10677,8 +10842,7 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pify": { "version": "2.3.0", @@ -11852,12 +12016,12 @@ "dev": true }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -12363,13 +12527,11 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "toposort": { diff --git a/package.json b/package.json index 519dbe2..3004fe2 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ }, "dependencies": { "@semantic-release/error": "^2.2.0", + "micromatch": "4.0.2", "node-fetch": "^2.3.0", "slackify-markdown": "^3.1.0" }, diff --git a/test/getConfigToUse.test.js b/test/getConfigToUse.test.js new file mode 100644 index 0000000..ed67178 --- /dev/null +++ b/test/getConfigToUse.test.js @@ -0,0 +1,63 @@ +const assert = require('assert') +const getConfigToUse = require('../lib/getConfigToUse') +const { getContext } = require('./testUtils') + +describe('test getConfigToUse', () => { + it('should return the global config when no branchesConfig', () => { + const context = getContext() + const pluginConfig = { + notifyOnSuccess: false, + notifyOnFail: true + } + const expectedConfig = pluginConfig + + const actual = getConfigToUse(pluginConfig, context) + assert.deepEqual(actual, expectedConfig) + }) + + it('should return the branche config merged with the global config when branchesConfig match the branch', () => { + const context = getContext('lts/1.x') + + const pluginConfig = { + slackWebhook: 'http://slack-webhook', + branchesConfig: [ + { + pattern: 'lts/*', + notifyOnSuccess: false, + notifyOnFail: true + } + ] + } + const expectedConfig = { + slackWebhook: 'http://slack-webhook', + notifyOnSuccess: false, + notifyOnFail: true + } + + const actual = getConfigToUse(pluginConfig, context) + assert.deepEqual(actual, expectedConfig) + }) + + it('should return the global config when no branchesConfig match the branch name', () => { + const context = getContext('beta') + const pluginConfig = { + notifyOnSuccess: false, + notifyOnFail: false, + branchesConfig: [ + { + pattern: 'lts/*', + notifyOnSuccess: true, + notifyOnFail: true + } + ] + } + + const expectedConfig = { + notifyOnSuccess: false, + notifyOnFail: false + } + + const actual = getConfigToUse(pluginConfig, context) + assert.deepEqual(actual, expectedConfig) + }) +}) diff --git a/test/testUtils.js b/test/testUtils.js index b217dda..21ac972 100644 --- a/test/testUtils.js +++ b/test/testUtils.js @@ -7,7 +7,7 @@ const getBaseConfig = packageName => { } } -const getContext = () => { +const getContext = (branchName = 'master') => { const version = '1.0.0' return { logger: console, @@ -23,7 +23,10 @@ const getContext = () => { env: { npm_package_name: 'internal test' }, - errors: ['Something went horribly wrong'] + errors: ['Something went horribly wrong'], + branch: { + name: branchName + } } } diff --git a/test/verifyConditions.test.js b/test/verifyConditions.test.js index afeb535..968b2c5 100644 --- a/test/verifyConditions.test.js +++ b/test/verifyConditions.test.js @@ -2,6 +2,7 @@ const SemanticReleaseError = require('@semantic-release/error') const assert = require('assert') const verifyConditions = require('../lib/verifyConditions') +const { getContext } = require('./testUtils') describe('test verifyConditions', () => { beforeEach(() => { @@ -61,4 +62,59 @@ describe('test verifyConditions', () => { ) }) }) + + describe('test branchesConfig options', () => { + const fakeContext = getContext() + const defaultPluginConfig = { + packageName: 'test', + slackWebhook: 'MY SLACK WEBHOOK' + } + + it('should throw if branchesConfig is not an array', () => { + assert.throws( + () => + verifyConditions( + { ...defaultPluginConfig, branchesConfig: {} }, + fakeContext + ), + new SemanticReleaseError( + 'branchesConfig is not an array.', + 'EINVALIDBRANCHCONFIG', + `Provided branches configuration is not an array. Make "branchesConfig" is properly set in your configuration option.` + ) + ) + }) + + it('should throw if branchesConfig do not contain a pattern', () => { + assert.throws( + () => + verifyConditions( + { + ...defaultPluginConfig, + branchesConfig: [{ pattern: 'master' }, {}] + }, + fakeContext + ), + new SemanticReleaseError( + 'pattern is not defined in branchesConfig.', + 'ENOPATTERN', + `A pattern for the branch configuration must be added. Make "branchesConfig" is properly set in your configuration option.` + ) + ) + }) + + it('should not throw if branchesConfig is not provided', () => { + verifyConditions(defaultPluginConfig, fakeContext) + }) + + it('should not throw if branchesConfig is properly set', () => { + verifyConditions( + { + ...defaultPluginConfig, + branchesConfig: [{ pattern: 'master' }, { pattern: 'lts/*' }] + }, + fakeContext + ) + }) + }) }) From 997c5b91d1daea74c15385945a446cf6cbb781dc Mon Sep 17 00:00:00 2001 From: Killian Hamayada Date: Mon, 1 Feb 2021 10:22:52 +0100 Subject: [PATCH 2/2] docs: fix spelling/grammar nitpicks Co-authored-by: Julius Recep Colliander Celik --- README.md | 2 +- lib/verifyConditions.js | 4 ++-- test/getConfigToUse.test.js | 2 +- test/verifyConditions.test.js | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 01c1fba..8bb926a 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ With this example: - Slack notification will always be sent using the "https://my-webhook.com" webhook url - Slack notifications are sent on a failure release from branches matching "lts/\*" - Slack notifications are sent on a failure or successful release from branch "master" -- Slack notifications are skipped on every other branches +- Slack notifications are skipped on all other branches ## Screenshots diff --git a/lib/verifyConditions.js b/lib/verifyConditions.js index 7b5f78a..e9c9cf9 100644 --- a/lib/verifyConditions.js +++ b/lib/verifyConditions.js @@ -39,7 +39,7 @@ module.exports = (pluginConfig, context) => { throw new SemanticReleaseError( 'branchesConfig is not an array.', 'EINVALIDBRANCHCONFIG', - `Provided branches configuration is not an array. Make "branchesConfig" is properly set in your configuration option.` + `Provided branches configuration is not an array. Ensure "branchesConfig" is properly set in your configuration option.` ) } @@ -51,7 +51,7 @@ module.exports = (pluginConfig, context) => { throw new SemanticReleaseError( 'pattern is not defined in branchesConfig.', 'ENOPATTERN', - `A pattern for the branch configuration must be added. Make "branchesConfig" is properly set in your configuration option.` + `A pattern for the branch configuration must be added. Ensure "branchesConfig" is properly set in your configuration option.` ) } } diff --git a/test/getConfigToUse.test.js b/test/getConfigToUse.test.js index ed67178..d26802a 100644 --- a/test/getConfigToUse.test.js +++ b/test/getConfigToUse.test.js @@ -15,7 +15,7 @@ describe('test getConfigToUse', () => { assert.deepEqual(actual, expectedConfig) }) - it('should return the branche config merged with the global config when branchesConfig match the branch', () => { + it('should return the branch config merged with the global config when branchesConfig match the branch', () => { const context = getContext('lts/1.x') const pluginConfig = { diff --git a/test/verifyConditions.test.js b/test/verifyConditions.test.js index 968b2c5..1ceb7a8 100644 --- a/test/verifyConditions.test.js +++ b/test/verifyConditions.test.js @@ -80,7 +80,7 @@ describe('test verifyConditions', () => { new SemanticReleaseError( 'branchesConfig is not an array.', 'EINVALIDBRANCHCONFIG', - `Provided branches configuration is not an array. Make "branchesConfig" is properly set in your configuration option.` + `Provided branches configuration is not an array. Ensure "branchesConfig" is properly set in your configuration option.` ) ) }) @@ -98,7 +98,7 @@ describe('test verifyConditions', () => { new SemanticReleaseError( 'pattern is not defined in branchesConfig.', 'ENOPATTERN', - `A pattern for the branch configuration must be added. Make "branchesConfig" is properly set in your configuration option.` + `A pattern for the branch configuration must be added. Ensure "branchesConfig" is properly set in your configuration option.` ) ) })