-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add possibility to provide onSuccess function (#53)
- Loading branch information
1 parent
be18847
commit 1cb7fab
Showing
10 changed files
with
1,426 additions
and
448 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ Add the plugin to your npm-project: | |
$ npm install semantic-release-slack-bot -D | ||
``` | ||
|
||
The corresponding slack app has be installed in you slack workspace as well. Follow the instructions under [configuration](#configuration) for more information. | ||
The corresponding slack app has to be installed in your slack workspace as well. Follow the instructions under [configuration](#configuration) for more information. | ||
|
||
## Usage | ||
|
||
|
@@ -45,7 +45,7 @@ The plugin can be configured in the [**semantic-release** configuration file](ht | |
|
||
With this example: | ||
|
||
- Slack notifications are skipped on a succesfull release | ||
- Slack notifications are skipped on a successful release | ||
- Slack notifications are sent on a failed release | ||
|
||
## Screenshots | ||
|
@@ -61,15 +61,15 @@ The plugin uses a slack webhook which you get by adding the slack app to your sl | |
|
||
<a href="https://slack.com/oauth/authorize?client_id=605439709265.611687593109&scope=incoming-webhook"><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcset="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/[email protected] 2x"></a> | ||
|
||
For the security concerned, feel free to [create your own slack app](https://api.slack.com/apps) and create a web-hook or inspect the server code that does this creation for you at [create-webhook.js](lambda/create-webhook.js). The only required permission for the webhook is to publish to a single channel. | ||
For the security concerned, feel free to [create your own slack app](https://api.slack.com/apps) and create a webhook or inspect the server code that does this creation for you at [create-webhook.js](lambda/create-webhook.js). The only required permission for the webhook is to publish to a single channel. | ||
|
||
### Slack app authentication | ||
|
||
Installing the app will yield you with a webhook that the app uses to publish updates to your selected chanel. The Slack webhook authentication link is **required and needs to be kept a secret**. It should be defined in the [environment variables](#environment-variables). | ||
Installing the app will yield you with a webhook that the app uses to publish updates to your selected channel. The Slack webhook authentication link is **required and needs to be kept a secret**. It should be defined in the [environment variables](#environment-variables). | ||
|
||
### Environment variables | ||
|
||
The `SLACK_WEBHOOK` variable can be defined in the environment where you will be running semantic release. This can be done by exporting it in bash or in the user interface of your CI provider. Obtain this token by installing the slack app according to [slack app installation](#slack-app-installation). | ||
The `SLACK_WEBHOOK` variable can be defined in the environment where you will run semantic release. This can be done by exporting it in bash or in the user interface of your CI provider. Obtain this token by installing the slack app according to [slack app installation](#slack-app-installation). | ||
|
||
Alternatively, you could pass the webhook as a configuration option. | ||
|
||
|
@@ -80,17 +80,81 @@ Alternatively, you could pass the webhook as a configuration option. | |
|
||
### Options | ||
|
||
| Option | Description | Default | | ||
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------- | | ||
| `notifyOnSuccess` | Determines if a succesfull release should trigger a slack message to be sent. If `false` this plugin does nothing on success. | false | | ||
| `notifyOnFail` | Determines if a failed release should trigger a slack message to be sent. If `false` this plugin does nothing on fail. | false | | ||
| `onSuccessTemplate` | Provides a template for the slack message object on success when `notifyOnSuccess` is `true`. See [templating](#templating). | undefined | | ||
| `onFailTemplate` | Provides a template for the slack message object on fail when `notifyOnFail` is `true`. See [templating](#templating). | undefined | | ||
| `markdownReleaseNotes` | Pass release notes through markdown to slack formatter before rendering. | false | | ||
| `slackWebhookEnVar` | This decides what the environment variable for exporting the slack webhook is called. | SLACK_WEBHOOK | | ||
| `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 maxLength 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 | | ||
| Option | Description | Default | | ||
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------- | | ||
| `notifyOnSuccess` | Determines if a successful release should trigger a slack message to be sent. If `false` this plugin does nothing on success. | false | | ||
| `notifyOnFail` | Determines if a failed release should trigger a slack message to be sent. If `false` this plugin does nothing on fail. | false | | ||
| `onSuccessFunction` | Provides a function for the slack message object on success when `notifyOnSuccess` is `true`. See [function](#function). | undefined | | ||
| `onFailFunction` | Provides a function for the slack message object on fail when `notifyOnFail` is `true`. See [function](#function). | undefined | | ||
| `onSuccessTemplate` | Provides a template for the slack message object on success when `notifyOnSuccess` is `true`. See [templating](#templating). | undefined | | ||
| `onFailTemplate` | Provides a template for the slack message object on fail when `notifyOnFail` is `true`. See [templating](#templating). | undefined | | ||
| `markdownReleaseNotes` | Pass release notes through markdown to slack formatter before rendering. | false | | ||
| `slackWebhookEnVar` | This decides what the environment variable for exporting the slack webhook is called. | SLACK_WEBHOOK | | ||
| `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 | | ||
|
||
### Function | ||
|
||
If a function is provided with either the `onSuccessFunction` or `onFailFunction` options, it will be used for the respective slack message. The function should return an object that follows the [Slack API message structure](https://api.slack.com/docs/message-formatting). The function is passed two objects, `pluginConfig` and `context`, the same objects that are passed to [plugins](https://github.com/semantic-release/semantic-release/blob/master/docs/developer-guide/plugin.md#plugin-developer-guide). | ||
|
||
**Note**: This only works with a [configuration file](https://semantic-release.gitbook.io/semantic-release/usage/configuration#configuration-file) that exports an object (see below for an example). | ||
|
||
<details> | ||
|
||
<summary> Example config (some parts omitted) </summary> | ||
|
||
```js | ||
const slackifyMarkdown = require('slackify-markdown') | ||
const { chunkifyString } = require('semantic-release-slack-bot/lib/chunkifier') | ||
|
||
const onSuccessFunction = (pluginConfig, context) => { | ||
const releaseNotes = slackifyMarkdown(context.nextRelease.notes) | ||
const text = `Updates to ${ | ||
pluginConfig.packageName | ||
} has been released to *Stage!*` | ||
const headerBlock = { | ||
type: 'section', | ||
text: { | ||
type: 'mrkdwn', | ||
text | ||
} | ||
} | ||
|
||
return { | ||
text, | ||
blocks: [ | ||
headerBlock, | ||
...chunkifyString(releaseNotes, 2900).map(chunk => { | ||
return { | ||
type: 'section', | ||
text: { | ||
type: 'mrkdwn', | ||
text: chunk | ||
} | ||
} | ||
}) | ||
] | ||
} | ||
} | ||
|
||
module.exports = { | ||
branches: ['master'], | ||
preset: 'eslint', | ||
plugins: [ | ||
[ | ||
'semantic-release-slack-bot', | ||
{ | ||
notifyOnSuccess: true, | ||
onSuccessFunction, | ||
packageName: 'Testing Semantic Release' | ||
} | ||
] | ||
] | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
### Templating | ||
|
||
|
@@ -111,3 +175,13 @@ A sample configuration with template can look like this | |
"text": "A new version of $package_name with version $npm_package_version has been released at $repo_url!" | ||
} | ||
``` | ||
|
||
### Helper functions | ||
|
||
There are two helper functions exported by the [`chunkifier`](lib/chunkifier.js) module. | ||
|
||
`chunkifyArray` takes an array of strings and returns a new array based on `maxLength` and `delimiter`. `delimiter` is optional and defaults to newline. | ||
|
||
`chunkifyString` takes a string and returns an array based on `maxLength` and `delimiter`. `delimiter` is optional and defaults to newline. | ||
|
||
See respective implementation for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const chunkifyArray = (messageLines, maxLength, delimiter) => { | ||
delimiter = delimiter || '\n' | ||
|
||
let message = '' | ||
const resultLines = [] | ||
messageLines.forEach(line => { | ||
// the next chunk is made up of the (next) line and the delimiter | ||
let nextChunk = line + delimiter | ||
// if the message plus the next chunk puts us over the maxLength limit... | ||
if ((message + nextChunk).length > maxLength) { | ||
// ...we add the message to the result array... | ||
resultLines.push(message.trimEnd()) | ||
// ...and "reset" the message with the next chunk. | ||
message = nextChunk | ||
} else { | ||
// if not, we add the next chunk to the message | ||
message += nextChunk | ||
} | ||
}) | ||
|
||
// handle the case where we have a trailing message | ||
if (message.length > 0) { | ||
resultLines.push(message.trimEnd()) | ||
} | ||
|
||
return resultLines | ||
} | ||
|
||
const chunkifyString = (messageText, maxLength, delimiter) => { | ||
if (messageText.length <= maxLength) { | ||
return [messageText] | ||
} | ||
|
||
delimiter = delimiter || '\n' | ||
const messageLines = messageText.split(delimiter) | ||
|
||
return chunkifyArray(messageLines, maxLength, delimiter) | ||
} | ||
|
||
module.exports = { | ||
chunkifyArray, | ||
chunkifyString | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.