diff --git a/README.md b/README.md index 30c32bd..2313c50 100644 --- a/README.md +++ b/README.md @@ -4,529 +4,12 @@ [![codecov](https://codecov.io/gh/slackapi/slack-github-action/graph/badge.svg?token=OZNX7FHN78)](https://codecov.io/gh/slackapi/slack-github-action) -Table of contents: +Comprehensive documentation is available at [tools.slack.dev/slack-github-action](https://tools.slack.dev/slack-github-action). -- [**Example workflows**](#example-workflows): Find inspiration in steps. -- [**Sending variables**](#sending-variables): Provide inputs to be sent. -- [**Sending techniques**](#sending-techniques): Choose how to send inputs. -- [**Additional configurations**](#additional-configurations): Customize - options. -- [**Expected outputs**](#expected-outputs): Retrieve response values. -- [**Project details**](#project-details): Information on the codebase. - -## Example workflows - -For examples on how to leverage this Action in workflows, check out -[example workflows we have][examples] available. - -## Sending variables - -There are different [techniques to send data](#sending-techniques) into Slack -and whichever one is chosen will require a certain set of customized inputs, as -described later. - -You can provide data to send to Slack from this GitHub Action and either source: - -- The default event [context][event-context] with a [payload][event-payload] - matching the GitHub event. -- A custom payload with optional [variables][variables] provided in the GitHub - Action step. - -These input options are valid for all techniques, but some techniques require -specific constraints with certain requirements for valid inputs. - -Additional [configurations](#additional-configurations) and other details are -also available for more customizations to the provided payload. - -## Sending techniques - -This Action offers three different techniques to send data to Slack: - -1. [**Technique 1**](#technique-1-slack-workflow-builder): Send data with a - webhook to start a workflow in [Workflow Builder][wfb]. -2. [**Technique 2**](#technique-2-slack-api-method): Send data using - [a Slack API method][methods] and a secret token with required scopes. -3. [**Technique 3**](#technique-3-slack-incoming-webhook): Send data as a - message with a Slack [incoming webhook][incoming-webhook] URL. - -### Technique 1: Slack Workflow Builder - -> :memo: This technique requires [a Slack paid plan][plans] to use Workflow -> Builder. - -This technique sends data to Slack using a webhook to start a workflow created -using Slack [Workflow Builder][wfb]. - -#### Setup - -Start in Slack to create a Slack workflow: - -1. [Create a Slack workflow][wfb-create] that starts from a webhook. -2. Copy the webhook URL and [add it as a repository secret][repo-secret] called - `SLACK_WEBHOOK_URL`. -3. [Add this Action as a step][job-step] to your GitHub workflow and provide an - input payload to send to the webhook. -4. Configure your Slack workflow to use the payload variables sent from the - GitHub Action. You can then update the steps of the Slack workflow to use - these values in creative and clever ways. - -The webhook URL will resemble something like so: - -```txt -https://hooks.slack.com/triggers/T0123456789/3141592653589/c6e6c0d868b3054ca0f4611a5dbadaf -``` - -#### Usage - -Update the input payloads sent from this GitHub Action to your Slack workflow -using the following options: - -##### Sending values from the default GitHub event context - -In the example below, the default GitHub event [context][event-context] and -event [payload][event-payload] associated with the job that started the GitHub -workflow are sent to the provided webhook URL: - -```yaml -- name: Send GitHub Action data to a Slack workflow - uses: slackapi/slack-github-action@v2.0.0 - with: - payload-delimiter: "_" - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: webhook-trigger -``` - -Accessing variables sent to [Workflow Builder][wfb] with a webhook require that -the payload variables are flattened with stringified values. Nested variables in -the provided payload can be both flattened and also stringified with the -`payload-delimiter` option or changed with other -[configurations](#additional-configurations) to match this format expected from -Workflow Builder. - -##### Providing parsed payload information as strings - -Provided input values for payload information are sent to the webhook URL after -the job is started: - -```yaml -- name: Send custom event details to a Slack workflow - uses: slackapi/slack-github-action@v2.0.0 - with: - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: webhook-trigger - payload: | - status: "${{ job.status }}" - option: "false" -``` - -##### Gathering details of the payload from a saved file - -Input values for the payload to be sent can also be provided in a file, either -in JSON or YAML format: - -```yaml -- name: Send a saved artifact to a Slack workflow - uses: slackapi/slack-github-action@v2.0.0 - with: - payload-file-path: "./artifacts.json" - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: webhook-trigger -``` - -### Technique 2: Slack API method - -A bot token or user token or [token of some other kind][tokens] must be used to -call one of [the Slack API methods][methods] with this technique. - -#### Setup - -Different Slack API [methods][methods] require different [scopes][scopes], but -setup should be similar for all methods: - -1. [Create a Slack app][apps-new] for your workspace or use an existing app. -2. Depending on the Slack API [method][methods] you wish to call, add the - required **scopes** to your app under the **OAuth & Permissions** page on - [app settings][apps]. -3. Install the app to your workspace using the **Install App** page. -4. Once your app is installed to a workspace, a new [token][tokens] with your - app's specified scopes will be minted for that workspace. It is worth noting - that tokens are only valid for a single workspace! Find the token on the - **OAuth & Permissions** page. -5. Add the token as [a repository secret][repo-secret] called `SLACK_BOT_TOKEN` - or something similar and memorable. -6. [Add this Action as a step][job-step] to your GitHub workflow and provide an - input payload to send to the method. - -Methods that require an app configuration token should gather this token from -the [app configuration token][config-tokens] settings instead of from a specific -app since this token is associated with the workspace. - -#### Usage - -Choosing inputs for these steps is left as an exercise for the actioneer since -each of the Slack API methods requires certain values and specific parameters, -but these snippets might be helpful when starting. - -##### Posting a message with text - -Posting a message with the [`chat.postMessage`][chat.postMessage] method can be -achieved by adding this step to a job in your GitHub workflow and inviting the -bot associated with your app to the channel for posting: - -```yaml -- name: Post text to a Slack channel - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "howdy <@channel>!" -``` - -##### Posting a message with blocks - -More complex message layouts, such as messages made with [Block Kit][block-kit] -blocks, can also be sent with one of the Slack API methods: - -```yaml -- name: Post blocks to a Slack channel - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" - blocks: - - type: "section" - text: - type: "mrkdwn" - text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" -``` - -##### Updating a message - -Updating a message after it's posted can be done with the -[`chat.update`][chat.update] method and chaining multiple steps together using -outputs from past steps as inputs to current ones: - -```yaml -- name: Initiate the deployment launch sequence - id: launch_sequence - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "Deployment started :eyes:" - attachments: - - color: "dbab09" - fields: - - title: "Status" - short: true - value: "In Progress" -- name: Countdown until launch - run: sleep 10 -- name: Update the original message with success - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.update - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - ts: "${{ steps.launch_sequence.outputs.ts }}" - text: "Deployment finished! :rocket:" - attachments: - - color: "28a745" - fields: - - title: "Status" - short: true - value: "Completed" -``` - -##### Replying to a message - -Posting [threaded replies to a message][messaging-threads] from a past job can -be done by including the `thread_ts` attribute of the parent message in the -`payload`: - -```yaml -- name: Initiate a deployment - uses: slackapi/slack-github-action@v2.0.0 - id: deployment_message - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "Deployment started :eyes:" -- name: Conclude the deployment - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - thread_ts: "${{ steps.deployment_message.outputs.ts }}" - text: "Deployment finished! :rocket:" -``` - -##### Uploading a file - -Calling [a Slack API method][methods] with [`@slack/web-api`][slack-web-api] -makes [uploading a file][files.upload] just another API call with all of the -convenience of the [`files.uploadV2`][files.uploadV2] method: - -```yaml -- name: Share a file to that channel - uses: slackapi/slack-github-action@v2.0.0 - with: - method: files.uploadV2 - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel_id: ${{ secrets.SLACK_CHANNEL_ID }} - initial_comment: "the results are in!" - file: "./path/to/results.out" - filename: "results-${{ github.sha }}.out" -``` - -### Technique 3: Slack incoming webhook - -This technique uses this Action to post a message to a channel or direct message -with [incoming webhooks][incoming-webhook] and a Slack app. - -Incoming webhooks follow the same [formatting][formatting] patterns as other -Slack messaging APIs. Posted messages can be as short as a single line of text, -include additional interactivity with [interactive components][interactivity], -or be formatted with [Block Kit][block-kit] to build visual components. - -#### Setup - -Gather a Slack incoming webhook URL: - -1. [Create a Slack app][apps-new] for your workspace or use an existing app. -2. Add the [`incoming-webhook`][incoming-webhook-scope] bot scope under **OAuth - & Permissions** page on [app settings][apps]. -3. Install the app to your workspace and select a channel to notify from the - **Install App** page. -4. Create additional webhooks from the **Incoming Webhooks** page. -5. Add the generated incoming webhook URL as [a repository secret][repo-secret] - called `SLACK_WEBHOOK_URL`. -6. [Add this Action as a step][job-step] to your GitHub workflow and provide an - input payload to send as a message. - -The webhook URL will resemble something like so: - -```txt -https://hooks.slack.com/services/T0123456789/B1001010101/7IsoQTrixdUtE971O1xQTm4T -``` - -#### Usage - -Add the collected webhook from above to a GitHub workflow and configure the step -using [`mrkdwn`][mrkdwn] formatting values for a message or -[Block Kit][block-kit] blocks: - -```yaml -- name: Post a message in a channel - uses: slackapi/slack-github-action@v2.0.0 - with: - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: incoming-webhook - payload: | - text: "*GitHub Action build result*: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" - blocks: - - type: "section" - text: - type: "mrkdwn" - text: "GitHub Action build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" -``` - -## Additional configurations - -Not all of the above settings serve every customization of a workflow, so these -options might be useful. - -### Exiting with errors - -Invalid API requests or unexpected webhook payloads cause a failing response -that can be used to fail the GitHub Actions step with the `errors` option. - -The `errors` option defaults to `false` so failed requests do not cause the step -to fail. This result can still be gathered from the `ok` output. - -```yaml -- name: Attempt to call an unknown method - uses: slackapi/slack-github-action@v2.0.0 - with: - errors: true - method: chat.reverse - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - text: "palindrome" -``` - -Invalid inputs to the Action, such as not including a payload, will always cause -the GitHub step to fail. - -### Flattening nested payloads - -Variables and data provided in the payload might contain nested fields that need -to be flattened before being sent with a -[webhook trigger](#technique-1-slack-workflow-builder) to match the expected -input format of [Workflow Builder][wfb]. - -The `payload-delimiter` option will flatten the input payload using the provided -delimiter and will also make values stringified: - -```yaml -- name: Flatten the default GitHub payload - uses: slackapi/slack-github-action@v2.0.0 - with: - payload-delimiter: "_" - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: webhook-trigger -``` - -Reference to the flattening implementation is available for exploration from -within the [`flat`][flat] package. - -### Parsing templated variables - -Additional variables provided in the Github event [context][event-context] and -event [payload][event-payload] can be used to replace templated variables in the -input payload with the `payload-templated` option: - -```yaml -- name: Send custom JSON data to Slack workflow - uses: slackapi/slack-github-action@v2.0.0 - with: - payload-file-path: "./payload-slack-content.json" - payload-templated: true - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} - webhook-type: webhook-trigger -``` - -This replaces variables templated as `${{ github.payload.repository.html_url }}` -with the values found in the GitHub Action event [payload][event-payload]. - -### Proxying HTTPS requests - -If you need to use a proxy to connect to Slack, you can use the `proxy` option. -In this example we use the technique that calls a Slack API method, but -configuring a proxy is the same for all techniques: - -```yaml -- name: Post to a Slack channel via a proxy - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - proxy: "http://proxy.example.org:8080" # Change this to a custom value - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "This message was sent through a proxy" -``` - -The `proxy` option can also be provided with the `HTTPS_PROXY` or `https_proxy` -[environment variable][github-environment] from within the GitHub Actions step. - -### Retrying failed requests - -Sometimes outgoing requests fail due to [rate limits][rate-limits] or similar -[HTTP responses][retry-after] and can be retried later. - -The `retries` option can be configured to the needs of your workflow with one of -these values: - -- `0`: No retries, just hope that things go alright. -- `5`: Five retries in five minutes. **Default**. -- `10`: Ten retries in about thirty minutes. -- `RAPID`: A burst of retries to keep things running fast. - -```yaml -- name: Attempt a burst of requests - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - retries: RAPID - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "status: all things are going good" -``` - -Behind the scenes, [automatic retries][retries] are handled with the -[`@slack/web-api`][slack-web-api] package for Slack API methods, and -[`axios-retry`][axios-retry] when sending with a webhook. - -### Sending to a custom API URL - -In certain circumstances, such as testing the sent payload, a -[custom API URL][custom-api-url] can be used to change where `method` requests -are sent: - -```yaml -- name: Send to a custom API URL - uses: slackapi/slack-github-action@v2.0.0 - with: - api: http://localhost:8080 - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ secrets.SLACK_CHANNEL_ID }} - text: "What's happening on localhost?" -``` - -The default value of `api` is "https://slack.com/api/" for steps using `method`. - -## Expected outputs - -Each technique above [outputs values][github-outputs] that can be used as inputs -in following steps of a GitHub workflow. - -The following outputs are returned with each of the techniques: - -- `time`: `number`. The Unix [epoch time][epoch] that the step completed. -- `ok`: `boolean`. If the request completed with success. -- `response`: `string`. The [response][response] from the request as stringified - JSON. - -While these outputs are returned with certain Slack API methods: - -- `channel_id`: `string`. The [channel ID][conversation] included in the - response. -- `ts`: `string`. The [timestamp][messaging-timestamp] of the Slack event or - message. -- `thread_ts`: `string`. The [timestamp][messaging-timestamp] of a parent Slack - message with [threaded replies][messaging-parents]. - -### Example responses - -The following snippet shows how multiple steps can be chained together to create -a Slack channel before posting a message: - -```yaml -- name: Create a new Slack channel for recent changes - id: conversation - uses: slackapi/slack-github-action@v2.0.0 - with: - method: conversations.create - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - name: pull-request-review-${{ github.sha }} -- name: Send the pull request link into the Slack channel - if: ${{ steps.conversation.outputs.ok }} - uses: slackapi/slack-github-action@v2.0.0 - with: - method: chat.postMessage - token: ${{ secrets.SLACK_BOT_TOKEN }} - payload: | - channel: ${{ steps.conversation.outputs.channel_id }} - text: "A PR was created : ${{ github.event.pull_request.html_url }}" -``` +Use this GitHub Action to: +* [Send data with a webhook to start a workflow in Workflow Builder](https://tools.slack.dev/slack-github-action/sending-techniques/sending-data-webhook-slack-workflow). +* [Send data using a Slack API method and a secret token with required scopes](https://tools.slack.dev/slack-github-action/sending-techniques/sending-data-slack-api-method/). +* [Send data as a message with a Slack incoming webhook URL](https://tools.slack.dev/slack-github-action/sending-techniques/sending-data-slack-incoming-webhook/). ## Project details