From 83b469965dd52813b2f7f224b6bb8c33b1cedec8 Mon Sep 17 00:00:00 2001 From: Yoshi Takahashi <12172895+yoshitakahashi@users.noreply.github.com> Date: Mon, 27 Dec 2021 02:33:20 -0500 Subject: [PATCH] feat: allow to override slack channel when using webhook (#81) Currently, there is a logic to throw an error when only `SLACK_CHANNEL` is specified but not `SLACK_TOKEN`. When using incoming webhook, a developer can override the slack channel to send a notification to by specifying the `channel` param for the post request. This commit changes the logic so that a developer can use specify `SLACK_WEBHOOK` and `SLACK_CHANNEL` to override the default channel associated to the webhook. Co-authored-by: Yoshi --- README.md | 24 ++++++++++++++++++------ lib/postMessage.js | 3 +++ lib/verifyConditions.js | 14 ++------------ test/verifyConditions.test.js | 34 ---------------------------------- 4 files changed, 23 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 52da0fe..09cd4f0 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,17 @@ With this example: - Slack notifications are sent on a failure or successful release from branch "master" - Slack notifications are skipped on all other branches +#### Note + +[The official documentation](https://api.slack.com/messaging/webhooks) says that a developer cannot +override the default channel or icon that are associated with the webhook, but some users of this +library reported that they were able to. + +- use `slackIcon` (or `SLACK_ICON` env var) for overriding slack icon +- use `slackChannel` (or `SLACK_CHANNEL` env var) for overriding slack channel + +**WARNING: This is not mentioned in the official documentation, so use at your own risk.** + ## Slack Access Token/Channel Usage This configuration can be used with a [**bot**](https://api.slack.com/authentication/token-types#bot) Slack Access token with minimum permissions of `chat:write`. @@ -136,12 +147,13 @@ Options can be defined in the environment where you will run semantic release. T Alternatively, you can pass the webhook as a configuration option or use an Access Token. -| Variable | Description | -| -------------------------- | ------------------------------------------------------------------------------------ | -| `SLACK_WEBHOOK` | Slack webhook created when adding app to workspace. | -| `SLACK_TOKEN` | Slack bot Access token. | -| `SLACK_CHANNEL` | Slack channel name or id to send notifications to (must be used with `SLACK_TOKEN`). | -| `SEMANTIC_RELEASE_PACKAGE` | Override or add package name instead of npm package name | +| Variable | Description | +| -------------------------- | -------------------------------------------------------- | +| `SLACK_WEBHOOK` | Slack webhook created when adding app to workspace. | +| `SLACK_TOKEN` | Slack bot Access token. | +| `SLACK_CHANNEL` | Slack channel name or id to send notifications to. | +| `SLACK_ICON` | Slack bot app icon. | +| `SEMANTIC_RELEASE_PACKAGE` | Override or add package name instead of npm package name | ### Options diff --git a/lib/postMessage.js b/lib/postMessage.js index 4671dfd..b1e7d99 100644 --- a/lib/postMessage.js +++ b/lib/postMessage.js @@ -25,6 +25,9 @@ module.exports = async ( body: JSON.stringify(message) }) } else { + if (slackChannel) { + message.channel = slackChannel + } response = await fetch(slackWebhook, { method: 'post', headers: { diff --git a/lib/verifyConditions.js b/lib/verifyConditions.js index 6d7fae1..8e6cfbe 100644 --- a/lib/verifyConditions.js +++ b/lib/verifyConditions.js @@ -7,22 +7,12 @@ module.exports = (pluginConfig, context) => { slackWebhook, slackWebhookEnVar, slackToken, - slackTokenEnVar, slackChannel, slackChannelEnVar } = getSlackVars(pluginConfig) - if (slackChannel || slackToken) { - if (!slackToken) { - logger.log( - 'SLACK_CHANNEL must be used with SLACK_TOKEN which has not been defined.' - ) - throw new SemanticReleaseError( - 'No Slack token defined.', - 'ENOSLACKTOKEN', - `A Slack Token must be created and set in the \`${slackTokenEnVar}\` environment variable on your CI environment.\n\n\nPlease make sure to create a Slack Token and to set it in the \`${slackTokenEnVar}\` environment variable on your CI environment. Alternatively, provide \`slackToken\` as a configuration option.` - ) - } else if (!slackChannel) { + if (slackToken) { + if (!slackChannel) { logger.log( 'SLACK_TOKEN must be used with SLACK_CHANNEL which has not been defined.' ) diff --git a/test/verifyConditions.test.js b/test/verifyConditions.test.js index 47a3172..843b660 100644 --- a/test/verifyConditions.test.js +++ b/test/verifyConditions.test.js @@ -85,40 +85,6 @@ describe('test verifyConditions', () => { return `A Slack Channel must be created and set in the \`${slackChannelEnVar}\` environment variable on your CI environment.\n\n\nPlease make sure to set a Slack Channel in the \`${slackChannelEnVar}\` environment variable on your CI environment. Alternatively, provide \`slackChannel\` as a configuration option.` } - it('should throw if neither slackToken and environment variable SLACK_TOKEN are set but slackChannel is', () => { - assert.throws( - () => - verifyConditions( - { ...defaultPluginConfig, slackChannel: 'some channel' }, - fakeContext - ), - new SemanticReleaseError( - 'No Slack token defined.', - 'ENOSLACKTOKEN', - getMissingTokenError('SLACK_TOKEN') - ) - ) - }) - - it('should throw if slackChannel is set, slackToken is not set and slackTokenEnVar give an empty environment variable', () => { - assert.throws( - () => - verifyConditions( - { - ...defaultPluginConfig, - slackChannel: 'some channel', - slackTokenEnVar: 'CUSTOM_TOKEN' - }, - fakeContext - ), - new SemanticReleaseError( - 'No Slack token defined.', - 'ENOSLACKTOKEN', - getMissingTokenError('CUSTOM_TOKEN') - ) - ) - }) - it('should throw if neither slackChannel and environment variable SLACK_CHANNEL are set but slackToken is', () => { assert.throws( () =>