Automatic compilation
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// SlackAPI JavaScript style
|
||||
// ---
|
||||
// This style helps maintainers enforce safe and consistent programming practices in this project. It is not meant to be
|
||||
// comprehensive on its own or vastly different from existing styles. The goal is to inherit and aggregate as many of
|
||||
// the communities' recommended styles for the technologies used as we can. When, and only when, we have a stated need
|
||||
// to differentiate, we add more rules (or modify options). Therefore, the fewer rules directly defined in this file,
|
||||
// the better.
|
||||
|
||||
module.exports = {
|
||||
// This is a root of the project, ESLint should not look through parent directories to find more config
|
||||
root: true,
|
||||
|
||||
ignorePatterns: [
|
||||
// Ignore all build outputs and artifacts (node_modules, dotfiles, and dot directories are implicitly ignored)
|
||||
'/dist',
|
||||
'/coverage',
|
||||
],
|
||||
|
||||
// These environments contain lists of global variables which are allowed to be accessed
|
||||
env: {
|
||||
// According to https://node.green, the target node version (v10) supports all important ES2018 features. But es2018
|
||||
// is not an option since it presumably doesn't introduce any new globals over ES2017.
|
||||
es2017: true,
|
||||
node: true,
|
||||
},
|
||||
|
||||
extends: [
|
||||
// ESLint's recommended built-in rules: https://eslint.org/docs/rules/
|
||||
'eslint:recommended',
|
||||
|
||||
// Node plugin's recommended rules: https://github.com/mysticatea/eslint-plugin-node
|
||||
'plugin:node/recommended',
|
||||
|
||||
// AirBnB style guide (without React) rules: https://github.com/airbnb/javascript.
|
||||
'airbnb-base',
|
||||
|
||||
// JSDoc plugin's recommended rules
|
||||
'plugin:jsdoc/recommended',
|
||||
],
|
||||
|
||||
rules: {
|
||||
// JavaScript rules
|
||||
// ---
|
||||
// The top level of this configuration contains rules which apply to JavaScript (and will also be inherited for
|
||||
// TypeScript). This section does not contain rules meant to override options or disable rules in the base
|
||||
// configurations (ESLint, Node, AirBnb). Those rules are added in the final override.
|
||||
|
||||
// Eliminate tabs to standardize on spaces for indentation. If you want to use tabs for something other than
|
||||
// indentation, you may need to turn this rule off using an inline config comments.
|
||||
'no-tabs': 'error',
|
||||
|
||||
// Bans use of comma as an operator because it can obscure side effects and is often an accident.
|
||||
'no-sequences': 'error',
|
||||
|
||||
// This repo uses console.log, which is fine to do in GitHub actions
|
||||
'no-console': 'off',
|
||||
|
||||
// Disallow the use of process.exit()
|
||||
'node/no-process-exit': 'error',
|
||||
|
||||
// Allow safe references to functions before the declaration. Overrides AirBnB config. Not located in the override
|
||||
// section below because a distinct override is necessary in TypeScript files.
|
||||
'no-use-before-define': ['error', 'nofunc'],
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.js'],
|
||||
rules: {
|
||||
// Override rules
|
||||
// ---
|
||||
// This level of this configuration contains rules which override options or disable rules in the base
|
||||
// configurations in JavaScript.
|
||||
|
||||
// Increase the max line length to 120. The rest of this setting is copied from the AirBnB config.
|
||||
'max-len': ['error', 120, 2, {
|
||||
ignoreUrls: true,
|
||||
ignoreComments: false,
|
||||
ignoreRegExpLiterals: true,
|
||||
ignoreStrings: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
}],
|
||||
|
||||
// Restrict the use of backticks to declare a normal string. Template literals should only be used when the
|
||||
// template string contains placeholders. The rest of this setting is copied from the AirBnb config.
|
||||
quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
|
||||
|
||||
// the server side Slack API uses snake_case for parameters often
|
||||
// for mocking and override support, we need to allow snake_case
|
||||
// Allow leading underscores for parameter names, which is used to acknowledge unused variables in TypeScript.
|
||||
// Also, enforce camelCase naming for variables. Ideally, the leading underscore could be restricted to only
|
||||
// unused parameter names, but this rule isn't capable of knowing when a variable is unused. The camelcase and
|
||||
// no-underscore-dangle rules are replaced with the naming-convention rule because this single rule can serve
|
||||
// both purposes, and it works fine on non-TypeScript code.
|
||||
camelcase: 'off',
|
||||
'no-underscore-dangle': 'off',
|
||||
|
||||
// Remove the minProperties option for enforcing line breaks between braces. The AirBnB config sets this to 4,
|
||||
// which is arbitrary and not backed by anything specific in the style guide. If we just remove it, we can
|
||||
// rely on the max-len rule to determine if the line is too long and then enforce line breaks. Overrides AirBnB
|
||||
// styles.
|
||||
'object-curly-newline': ['error', { multiline: true, consistent: true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['src/test/*.js'],
|
||||
rules: {
|
||||
// Test-specific rules
|
||||
// ---
|
||||
// Rules that only apply to JavaScript _test_ source files
|
||||
|
||||
// With Mocha as a test framework, it is sometimes helpful to assign
|
||||
// shared state to Mocha's Context object, for example in setup and
|
||||
// teardown test methods. Assigning stub/mock objects to the Context
|
||||
// object via `this` is a common pattern in Mocha. As such, using
|
||||
// `function` over the the arrow notation binds `this` appropriately and
|
||||
// should be used in tests. So: we turn off the prefer-arrow-callback
|
||||
// rule.
|
||||
// See https://github.com/slackapi/bolt-js/pull/1012#pullrequestreview-711232738
|
||||
// for a case of arrow-vs-function syntax coming up for the team
|
||||
'prefer-arrow-callback': 'off',
|
||||
|
||||
// Using ununamed functions (e.g., null logger) in tests is fine
|
||||
'func-names': 'off',
|
||||
// In tests, don't force constructing a Symbol with a descriptor, as
|
||||
// it's probably just for tests
|
||||
'symbol-description': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
# Contributors Guide
|
||||
|
||||
Interested in contributing? Awesome! Before you do though, please read our
|
||||
[Code of Conduct](https://slackhq.github.io/code-of-conduct). We take it very seriously, and expect that you will as
|
||||
well.
|
||||
|
||||
There are many ways you can contribute! :heart:
|
||||
|
||||
### Bug Reports and Fixes :bug:
|
||||
- If you find a bug, please [create a new issue](https://github.com/slackapi/slack-github-action/issues/new). Fill out the "Bug Report" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still
|
||||
be reviewed.
|
||||
- Issues that have already been identified as a bug (note: able to reproduce) will be labelled `bug`.
|
||||
- If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number.
|
||||
- Include tests that isolate the bug and verifies that it was fixed.
|
||||
|
||||
### New Features :bulb:
|
||||
- If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/slackapi/slack-github-action/issues/new).
|
||||
- Issues that have been identified as a feature request will be labelled `enhancement`.
|
||||
- If you'd like to implement the new feature, please wait for feedback from the project
|
||||
maintainers before spending too much time writing the code. In some cases, `enhancement`s may
|
||||
not align well with the project objectives at the time.
|
||||
|
||||
### Tests :mag:, Documentation :books:, Miscellaneous :sparkles:
|
||||
- If you'd like to improve the tests, you want to make the documentation clearer, you have an
|
||||
alternative implementation of something that may have advantages over the way its currently
|
||||
done, or you have any other change, we would be happy to hear about it!
|
||||
- If its a trivial change, go ahead and [send a Pull Request](#creating_a_pull_request) with the changes you have in mind.
|
||||
- If not, [open an Issue](https://github.com/slackapi/slack-github-actiondcjtfkgitihftbgeungvnhgbvkhjtdbiilknucucrfek/issues/new) to discuss the idea first.
|
||||
|
||||
If you're new to our project and looking for some way to make your first contribution, look for
|
||||
Issues labelled `good first contribution`.
|
||||
|
||||
## Requirements
|
||||
|
||||
For your contribution to be accepted:
|
||||
|
||||
- [x] You must have signed the [Contributor License Agreement (CLA)](https://cla-assistant.io/slackapi/slack-github-action).
|
||||
- [x] The test suite must be complete and pass.
|
||||
- [x] The changes must be approved by code review.
|
||||
- [x] Commits should be atomic and messages must be descriptive. Related issues should be mentioned by Issue number.
|
||||
|
||||
If the contribution doesn't meet the above criteria, you may fail our automated checks or a maintainer will discuss it with you. You can continue to improve a Pull Request by adding commits to the branch from which the PR was created.
|
||||
|
||||
[Interested in knowing more about about pull requests at Slack?](https://slack.engineering/on-empathy-pull-requests-979e4257d158#.awxtvmb2z)
|
||||
|
||||
## Creating a Pull Request
|
||||
|
||||
1. :fork_and_knife: Fork the repository on GitHub.
|
||||
2. :runner: Clone/fetch your fork to your local development machine. It's a good idea to run the tests just
|
||||
to make sure everything is in order.
|
||||
3. :herb: Create a new branch and check it out.
|
||||
4. :crystal_ball: Make your changes and commit them locally. Magic happens here!
|
||||
5. :arrow_heading_up: Push your new branch to your fork. (e.g. `git push username fix-issue-16`).
|
||||
6. :inbox_tray: Open a Pull Request on github.com from your new branch on your fork to `master` in this
|
||||
repository.
|
||||
|
||||
## Maintainers
|
||||
|
||||
There are more details about processes and workflow in the [Maintainer's Guide](./maintainers_guide.md).
|
||||
@@ -1,11 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'monthly'
|
||||
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'monthly'
|
||||
@@ -1,49 +0,0 @@
|
||||
### Description
|
||||
|
||||
Describe your issue here.
|
||||
|
||||
### What type of issue is this? (place an `x` in one of the `[ ]`)
|
||||
- [ ] bug
|
||||
- [ ] enhancement (feature request)
|
||||
- [ ] question
|
||||
- [ ] documentation related
|
||||
- [ ] example code related
|
||||
- [ ] testing related
|
||||
- [ ] discussion
|
||||
|
||||
### Requirements (place an `x` in each of the `[ ]`)
|
||||
* [ ] I've read and understood the [Contributing guidelines](https://github.com/slackapi/slack-github-action/blob/main/.github/contributing.md) and have done my best effort to follow them.
|
||||
* [ ] I've read and agree to the [Code of Conduct](https://slackhq.github.io/code-of-conduct).
|
||||
* [ ] I've searched for any related issues and avoided creating a duplicate issue.
|
||||
|
||||
---
|
||||
|
||||
### Bug Report
|
||||
|
||||
Filling out the following details about bugs will help us solve your issue sooner.
|
||||
|
||||
#### Reproducible in:
|
||||
|
||||
package version:
|
||||
|
||||
node version:
|
||||
|
||||
OS version(s):
|
||||
|
||||
#### Steps to reproduce:
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
#### Expected result:
|
||||
|
||||
What you expected to happen
|
||||
|
||||
#### Actual result:
|
||||
|
||||
What actually happened
|
||||
|
||||
#### Attachments:
|
||||
|
||||
Logs, screenshots, screencast, sample project, funny gif, etc.
|
||||
@@ -1,76 +0,0 @@
|
||||
# Maintainers Guide
|
||||
|
||||
This document describes tools, tasks and workflow that one needs to be familiar with in order to effectively maintain
|
||||
this project. If you use this package within your own software as is but don't plan on modifying it, this guide is
|
||||
**not** for you.
|
||||
|
||||
## Tools
|
||||
|
||||
All you need to work with this project is a supported version of [Node.js](https://nodejs.org/en/)
|
||||
(see `package.json` field "engines") and npm (which is distributed with Node.js).
|
||||
|
||||
## Tasks
|
||||
|
||||
### Testing
|
||||
|
||||
When testing locally, ensure at least linting and unit tests pass by running `npm test`.
|
||||
Additionally, sending a PR is highly recommended with every change as there are several GitHub
|
||||
Actions jobs that execute what are effectively integration tests for this GitHub Action.
|
||||
|
||||
### Releasing
|
||||
|
||||
* Update the version in `package.json`
|
||||
* Update all references to versions in the README and in the workflow files under `example-workflows/` to refer to the latest release
|
||||
* Commit the changes
|
||||
* Create a git tag for the new version. Should be in the format `v1.4.0`. `git tag v1.4.0`
|
||||
* Push changes up to GitHub `git push origin main --tags`
|
||||
* Create a GitHub Release based on the tag you just pushed up - this will trigger the publishing
|
||||
GitHub workflow
|
||||
|
||||
## Workflow
|
||||
|
||||
### Versioning and Tags
|
||||
|
||||
This project is versioned using [Semantic Versioning](http://semver.org/), particularly in the
|
||||
[npm flavor](https://docs.npmjs.com/getting-started/semantic-versioning). Each release is tagged
|
||||
using git.
|
||||
|
||||
### Fork
|
||||
|
||||
As a maintainer, the development you do will be almost entirely off of your forked version of this repository. The exception to this rule pertains to multiple collaborators working on the same feature, which is detailed in the **Branches** section below.
|
||||
|
||||
### Branches
|
||||
|
||||
`main` is where active development occurs.
|
||||
|
||||
When developing, branches should be created off of your fork and not directly off of this repository. If working on a long-running feature and in collaboration with others, a corresponding branch of the same name is permitted. This makes collaboration on a single branch possible, as contributors working on the same feature cannot push commits to others' open Pull Requests.
|
||||
|
||||
After a major version increment, there also may be maintenance branches created specifically for supporting older major versions.
|
||||
|
||||
### Issue Management
|
||||
|
||||
Labels are used to run issues through an organized workflow. Here are the basic definitions:
|
||||
|
||||
* `bug`: A confirmed bug report. A bug is considered confirmed when reproduction steps have been
|
||||
documented and the issue has been reproduced.
|
||||
* `enhancement`: A feature request for something this package might not already do.
|
||||
* `docs`: An issue that is purely about documentation work.
|
||||
* `tests`: An issue that is purely about testing work.
|
||||
* `needs feedback`: An issue that may have claimed to be a bug but was not reproducible, or was otherwise missing some information.
|
||||
* `discussion`: An issue that is purely meant to hold a discussion. Typically the maintainers are looking for feedback in this issues.
|
||||
* `question`: An issue that is like a support request because the user's usage was not correct.
|
||||
* `semver:major|minor|patch`: Metadata about how resolving this issue would affect the version number.
|
||||
* `security`: An issue that has special consideration for security reasons.
|
||||
* `good first contribution`: An issue that has a well-defined relatively-small scope, with clear expectations. It helps when the testing approach is also known.
|
||||
* `duplicate`: An issue that is functionally the same as another issue. Apply this only if you've linked the other issue by number.
|
||||
|
||||
**Triage** is the process of taking new issues that aren't yet "seen" and marking them with a basic
|
||||
level of information with labels. An issue should have **one** of the following labels applied:
|
||||
`bug`, `enhancement`, `question`, `needs feedback`, `docs`, `tests`, or `discussion`.
|
||||
|
||||
Issues are closed when a resolution has been reached. If for any reason a closed issue seems
|
||||
relevant once again, reopening is great and better than creating a duplicate issue.
|
||||
|
||||
## Everything else
|
||||
|
||||
When in doubt, find the other maintainers and ask.
|
||||
@@ -1,8 +0,0 @@
|
||||
### Summary
|
||||
|
||||
Describe the goal of this PR. Mention any related Issue numbers.
|
||||
|
||||
### Requirements (place an `x` in each `[ ]`)
|
||||
|
||||
* [ ] I've read and understood the [Contributing Guidelines](https://github.com/slackapi/slack-github-action/blob/main/.github/contributing.md) and have done my best effort to follow them.
|
||||
* [ ] I've read and agree to the [Code of Conduct](https://slackhq.github.io/code-of-conduct).
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"text": "Incoming Webhook test for slack send",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Content of the event name: {{ github.event_name }}",
|
||||
"emoji": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
name: Tests
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
unit_tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci && npm run build
|
||||
- run: npm test
|
||||
|
||||
integration_test_botToken:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci && npm run build
|
||||
- name: Post message to Slack via botToken
|
||||
id: slackToken
|
||||
uses: ./
|
||||
with:
|
||||
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
slack-message: 'CI Post from slack-send GitHub Action! Succeeded!!'
|
||||
# payload: "{\"key\":\"value\",\"foo\":\"bar\"}"
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
|
||||
# Use the output from the `slackToken` step
|
||||
- name: Check Action output is not empty
|
||||
run: test -n "${{ steps.slackToken.outputs.time }}"
|
||||
|
||||
integration_test_webhook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci && npm run build
|
||||
- run: echo "${{ github.event_name }}"
|
||||
- name: push trigger
|
||||
# Save commit url from GitHub Trigger event payload to URL env
|
||||
if: "contains(github.event_name, 'push')"
|
||||
run: |
|
||||
url=${{ github.event.head_commit.url }}
|
||||
echo "URL=$url" >> "$GITHUB_ENV"
|
||||
- name: pull request trigger
|
||||
# Save pull request url from GitHub Trigger event payload to URL env
|
||||
if: "contains(github.event_name, 'pull_request')"
|
||||
run: |
|
||||
url=${{ github.event.pull_request.url }}
|
||||
echo "URL=$url" >> "$GITHUB_ENV"
|
||||
- name: Post message to Slack via webhook
|
||||
id: slackWorkflow
|
||||
uses: ./
|
||||
with:
|
||||
# Workflow builder webhooks need to know the name of the keys in the payload in advance. Without normalizing, the github context payload keys can differ based on the GitHub trigger event type
|
||||
# Normalized payload with info pulled out from GitHub trigger event
|
||||
payload: "{\"author\":\"${{ github.event.sender.login }}\",\"url\":\"${{ env.URL}}\", \"repoName\":\"${{ github.event.repository.full_name }}\", \"status\":\"${{ job.status }}\"}"
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
|
||||
# Use the output from the `slackWorkflow` step
|
||||
- name: Check Action output is not empty
|
||||
run: test -n "${{ steps.slackWorkflow.outputs.time }}"
|
||||
|
||||
integration_test_incoming_webhook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci && npm run build
|
||||
- run: echo "${{ github.event_name }}"
|
||||
- name: Post message to Slack via incoming webhook
|
||||
id: slackIncoming
|
||||
uses: ./
|
||||
with:
|
||||
# block kit payload
|
||||
payload: "{\"text\":\"Incoming Webhook test for slack send\", \"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"plain_text\",\"text\":\"A post by Slack Send GitHub Action. Testing Incoming webhooks\",\"emoji\":true}}]}"
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_INCOMING_WEBHOOK_URL }}
|
||||
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||
|
||||
# Use the output from the `slackIncoming` step
|
||||
- name: Check Action output is not empty
|
||||
run: test -n "${{ steps.slackIncoming.outputs.time }}"
|
||||
|
||||
integration_test_file_payload:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci && npm run build
|
||||
- run: echo "${{ github.event_name }}"
|
||||
- name: Post message to Slack with Payload path
|
||||
id: slackPayloadFile
|
||||
uses: ./
|
||||
with:
|
||||
payload-file-path: ./.github/resources/payload-notification.json
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_INCOMING_WEBHOOK_URL }}
|
||||
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||
|
||||
# Use the output from the `slackIncoming` step
|
||||
- name: Check Action output is not empty
|
||||
run: test -n "${{ steps.slackPayloadFile.outputs.time }}"
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published, edited]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.release.tag_name }}
|
||||
- name: Install deps and build
|
||||
run: npm ci && npm run build
|
||||
- uses: JasonEtco/build-and-tag-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
@@ -1,4 +0,0 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
.nyc_output
|
||||
dist
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"timeout": 3000
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Slack Technologies, LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,178 +0,0 @@
|
||||
# Slack Send GitHub Action
|
||||
|
||||
Send data into Slack using this GitHub Action! This package has three different techniques to send data to Slack:
|
||||
|
||||
1) Send data to Slack's Workflow Builder (requires a paid Slack instance).
|
||||
2) Send data via a Slack app to post to a specific channel (use an existing custom app or create a new one).
|
||||
3) Send data via a Slack Incoming Webhook URL (use an existing custom app or create a new one).
|
||||
|
||||
The recommended way to use this action is with Slack's Workflow Builder (if you're on a paid Slack plan).
|
||||
|
||||
## Technique 1: Slack Workflow Builder
|
||||
|
||||
> ❗️ This approach requires a paid Slack plan
|
||||
|
||||
Sending data to [Slack's Workflow builder](https://slack.com/features/workflow-automation) is the recommended way to use this action. This action will send data into Slack via a webhook URL. Follow [these steps to create a Slack workflow using webhooks][create-webhook]. The Slack workflow webhook URL will be in the form `https://hooks.slack.com/workflows/....`. The payload sent by this GitHub action will be flattened (all nested keys moved to the top level) and stringified since Slack's workflow builder only supports top level string values in payloads.
|
||||
|
||||
As part of the [workflow setup](https://slack.com/help/articles/360041352714-Create-more-advanced-workflows-using-webhooks#workflow-setup),
|
||||
you will need to define expected variables in the payload the webhook will receive (described in the "Create custom variables" section of the docs). If these variables are missing in the payload, an error is returned.
|
||||
|
||||
### Setup
|
||||
|
||||
* [Create a Slack workflow webhook][create-webhook].
|
||||
* Copy the webhook URL (`https://hooks.slack.com/workflows/....`) and [add it as a secret in your repo settings][repo-secret] named `SLACK_WEBHOOK_URL`.
|
||||
* Add a step to your GitHub action to send data to your Webhook.
|
||||
* Configure your Slack workflow to use variables from the incoming payload from the GitHub Action. You can select where you want to post the data and how you want to format it in Slack's worflow builder interface.
|
||||
|
||||
### Usage
|
||||
|
||||
Add this Action as a [step][job-step] to your project's GitHub Action Workflow file:
|
||||
|
||||
```yaml
|
||||
- name: Send GitHub Action trigger data to Slack workflow
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```yaml
|
||||
- name: Send custom JSON data to Slack workflow
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
# This data can be any valid JSON from a previous step in the GitHub Action
|
||||
payload: |
|
||||
{
|
||||
"key": "value",
|
||||
"foo": "bar"
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
```
|
||||
or
|
||||
|
||||
> If the `payload` is provided it will take preference over `payload-file-path`
|
||||
|
||||
```yaml
|
||||
- name: Send custom JSON data to Slack workflow
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
payload-file-path: "./payload-slack-content.json"
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
```
|
||||
|
||||
## Technique 2: Slack App
|
||||
|
||||
By creating a new Slack app or using an existing one, this approach allows your GitHub Actions job to post a message in a Slack channel or direct message by utilizing the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) API method. Using this approach you can instantly post a message without setting up Slack workflows.
|
||||
|
||||
## Setup
|
||||
|
||||
* [Create a Slack App][apps] for your workspace (alternatively use an existing app you have already created and installed).
|
||||
* Add the [`chat.write`](https://api.slack.com/scopes/chat:write) bot scope under **OAuth & Permissions**.
|
||||
* Install the app to your workspace.
|
||||
* Copy the app's Bot Token from the **OAuth & Permissions** page and [add it as a secret in your repo settings][repo-secret] named `SLACK_BOT_TOKEN`.
|
||||
* Invite the bot user into the channel you wish to post messages to (`/invite @bot_user_name`).
|
||||
|
||||
### Usage
|
||||
|
||||
Add this Action as a [step][job-step] to your project's GitHub Action Workflow file:
|
||||
|
||||
```yaml
|
||||
- name: Post to a Slack channel
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
# Slack channel id, channel name, or user id to post message.
|
||||
# See also: https://api.slack.com/methods/chat.postMessage#channels
|
||||
channel-id: 'CHANNEL_ID'
|
||||
# For posting a simple plain text message
|
||||
slack-message: "GitHub build result: ${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
```
|
||||
|
||||
Using JSON payload for constructing a message is also available:
|
||||
|
||||
```yaml
|
||||
- name: Post to a Slack channel
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
# Slack channel id, channel name, or user id to post message.
|
||||
# See also: https://api.slack.com/methods/chat.postMessage#channels
|
||||
channel-id: 'CHANNEL_ID'
|
||||
# For posting a rich message using Block Kit
|
||||
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 }}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
```
|
||||
|
||||
## Technique 3: Slack Incoming Webhook
|
||||
|
||||
This approach allows your GitHub Actions job to post a message to a Slack channel or direct message by utilizing [Incoming Webhooks](https://api.slack.com/messaging/webhooks).
|
||||
|
||||
Incoming Webhooks conform to the same rules and functionality as any of Slack's other messaging APIs. You can make your posted messages as simple as a single line of text, or make them really useful with [interactive components](https://api.slack.com/messaging/interactivity). To make the message more expressive and useful use [Block Kit](https://api.slack.com/block-kit) to build and test visual components.
|
||||
|
||||
## Setup
|
||||
|
||||
* [Create a Slack App][apps] for your workspace (alternatively use an existing app you have already created and installed).
|
||||
* Add the [`incoming-webhook`](https://api.slack.com/scopes/incoming-webhook) bot scope under **OAuth & Permissions**.
|
||||
* Install the app to your workspace (you will select a channel to notify).
|
||||
* Activate and create a new webhook under **Incoming Webhooks**.
|
||||
* Copy the Webhook URL from the Webhook you just generated [add it as a secret in your repo settings][repo-secret] named `SLACK_WEBHOOK_URL`.
|
||||
|
||||
### Usage
|
||||
|
||||
```yaml
|
||||
- name: Send custom JSON data to Slack workflow
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
# For posting a rich message using Block Kit
|
||||
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 }}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING](.github/contributing.md).
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](LICENSE).
|
||||
|
||||
[create-webhook]: https://slack.com/intl/en-ca/help/articles/360041352714-Create-more-advanced-workflows-using-webhooks
|
||||
[job-step]: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idsteps
|
||||
[repo-secret]: https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository
|
||||
[apps]: https://api.slack.com/apps
|
||||
Vendored
+18034
File diff suppressed because one or more lines are too long
@@ -1,18 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
"key": "value",
|
||||
"foo": "bar"
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
@@ -1,14 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
payload-file-path: "./example-workflows/Technique_1_Slack_Workflow_Builder/payloads/example.json"
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"attachments": [
|
||||
{
|
||||
"color": "#d90000",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "${{ github.workflow }} workflow failed on ${{ env.DEFAULT_BRANCH }} branch in the ${{ github.event.repository.name }} repository!"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "actions",
|
||||
"elements": [
|
||||
{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Build",
|
||||
"emoji": true
|
||||
},
|
||||
"url": "${{ env.REPO_URL }}/actions/runs/${{ github.run_id }}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Commit",
|
||||
"emoji": true
|
||||
},
|
||||
"url": "${{ env.REPO_URL }}/commit/${{ github.sha }}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
channel-id: 'SLACK_CHANNEL_ID' # ID of Slack Channel you want to post to
|
||||
payload: |
|
||||
{
|
||||
"blocks": [
|
||||
{ "type": "divider" },
|
||||
{
|
||||
"type": "image",
|
||||
"title": {
|
||||
"type": "plain_text",
|
||||
"text": "Slack Slack Slack",
|
||||
"emoji": true
|
||||
},
|
||||
"image_url": "https://media.makeameme.org/created/a-slack-this.jpg",
|
||||
"alt_text": "marg"
|
||||
},
|
||||
{
|
||||
"type": "actions",
|
||||
"elements": [
|
||||
{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": $values.button_text
|
||||
},
|
||||
"url": $values.button_url
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"channel-id": "NEW_TARGET_CHANNEL_ID"
|
||||
}
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
values: |
|
||||
button_text: ${{ github.sha }}
|
||||
button_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
@@ -1,15 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
channel-id: 'SLACK_CHANNEL_ID' # ID of Slack Channel you want to post to
|
||||
payload: "{\"text\": \"posting from a github action\"}"
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
@@ -1,15 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Publish to slack channel via bot token
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
channel-id: 'SLACK_CHANNEL_ID' # ID of Slack Channel you want to post to
|
||||
slack-message: 'posting from a github action!' # The message you want to post
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
@@ -1,51 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
new_push_job:
|
||||
runs-on: ubuntu-latest
|
||||
name: New push to repo
|
||||
steps:
|
||||
- name: Send GitHub trigger payload to Slack Workflow Builder
|
||||
id: slack
|
||||
uses: slackapi/[email protected]
|
||||
with:
|
||||
payload: |
|
||||
{
|
||||
"text": "Danny Torrence left a 1 star review for your property.",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Danny Torrence left the following review for your property:"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"block_id": "section567",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "<https://example.com|Overlook Hotel> \\n :star: \\n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s."
|
||||
},
|
||||
"accessory": {
|
||||
"type": "image",
|
||||
"image_url": "https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg",
|
||||
"alt_text": "Haunted hotel image"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"block_id": "section789",
|
||||
"fields": [
|
||||
{
|
||||
"type": "mrkdwn",
|
||||
"text": "*Average Rating*\\n1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||
|
||||
Generated
-4363
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"name": "slack-github-action",
|
||||
"version": "1.18.0",
|
||||
"description": "The official slack github action. Use this to send data into your Slack workspace",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test:mocha": "nyc mocha --config .mocharc.json test/*-test.js",
|
||||
"test": "npm run lint && npm run test:mocha",
|
||||
"build": "npx @vercel/ncc build src/index.js --license licenses.txt"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/slackapi/slack-github-action.git"
|
||||
},
|
||||
"keywords": [
|
||||
"slack",
|
||||
"github",
|
||||
"action",
|
||||
"workflow"
|
||||
],
|
||||
"author": "Slack Technologies, LLC",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/slackapi/slack-github-action/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0",
|
||||
"npm": ">=6.4.1"
|
||||
},
|
||||
"homepage": "https://github.com/slackapi/slack-github-action#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.6.0",
|
||||
"@actions/github": "^5.0.0",
|
||||
"@slack/web-api": "^6.5.1",
|
||||
"axios": "^0.24.0",
|
||||
"flat": "^5.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "^0.33.1",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^8.6.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsdoc": "^37.5.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"mocha": "^9.1.3",
|
||||
"nyc": "^15.1.0",
|
||||
"rewiremock": "^3.14.3",
|
||||
"sinon": "^12.0.1"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
const core = require('@actions/core');
|
||||
const slackSend = require('./slack-send');
|
||||
|
||||
slackSend(core);
|
||||
@@ -1,115 +0,0 @@
|
||||
const github = require('@actions/github');
|
||||
const { WebClient } = require('@slack/web-api');
|
||||
const flatten = require('flat');
|
||||
const axios = require('axios');
|
||||
const { promises: fs } = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const SLACK_WEBHOOK_TYPES = {
|
||||
WORKFLOW_TRIGGER: 'WORKFLOW_TRIGGER',
|
||||
INCOMING_WEBHOOK: 'INCOMING_WEBHOOK',
|
||||
};
|
||||
|
||||
module.exports = async function slackSend(core) {
|
||||
try {
|
||||
const botToken = process.env.SLACK_BOT_TOKEN;
|
||||
const webhookUrl = process.env.SLACK_WEBHOOK_URL;
|
||||
let webhookType = SLACK_WEBHOOK_TYPES.WORKFLOW_TRIGGER;
|
||||
|
||||
if (process.env.SLACK_WEBHOOK_TYPE) {
|
||||
// The default type is for Workflow Builder triggers. If you want to use this action for Incoming Webhooks, use
|
||||
// the corresponding type instead.
|
||||
webhookType = process.env.SLACK_WEBHOOK_TYPE.toUpperCase();
|
||||
}
|
||||
|
||||
if (botToken === undefined && webhookUrl === undefined) {
|
||||
throw new Error('Need to provide at least one botToken or webhookUrl');
|
||||
}
|
||||
|
||||
let payload = core.getInput('payload');
|
||||
|
||||
const payloadFilePath = core.getInput('payload-file-path');
|
||||
|
||||
if (payloadFilePath && !payload) {
|
||||
try {
|
||||
payload = await fs.readFile(path.resolve(payloadFilePath), 'utf-8');
|
||||
} catch (error) {
|
||||
// passed in payload file path was invalid
|
||||
console.error(error);
|
||||
throw new Error(`The payload-file-path may be incorrect. Failed to load the file: ${payloadFilePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (payload) {
|
||||
try {
|
||||
// confirm it is valid json
|
||||
payload = JSON.parse(payload);
|
||||
} catch (e) {
|
||||
// passed in payload wasn't valid json
|
||||
console.error('passed in payload was invalid JSON');
|
||||
throw new Error('Need to provide valid JSON payload');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof botToken !== 'undefined' && botToken.length > 0) {
|
||||
const message = core.getInput('slack-message') || '';
|
||||
const channelId = core.getInput('channel-id') || '';
|
||||
const web = new WebClient(botToken);
|
||||
|
||||
if (channelId.length <= 0) {
|
||||
console.log('Channel ID is required to run this action. An empty one has been provided');
|
||||
throw new Error('Channel ID is required to run this action. An empty one has been provided');
|
||||
}
|
||||
|
||||
if (message.length > 0 || payload) {
|
||||
// post message
|
||||
await web.chat.postMessage({ channel: channelId, text: message, ...(payload || {}) });
|
||||
} else {
|
||||
console.log('Missing slack-message or payload! Did not send a message via chat.postMessage with botToken', { channel: channelId, text: message, ...(payload) });
|
||||
throw new Error('Missing message content, please input a valid payload or message to send. No Message has been send.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof webhookUrl !== 'undefined' && webhookUrl.length > 0) {
|
||||
if (!payload) {
|
||||
// No Payload was passed in
|
||||
console.log('no custom payload was passed in, using default payload that triggered the GitHub Action');
|
||||
// Get the JSON webhook payload for the event that triggered the workflow
|
||||
payload = github.context.payload;
|
||||
}
|
||||
|
||||
if (webhookType === SLACK_WEBHOOK_TYPES.WORKFLOW_TRIGGER) {
|
||||
// flatten JSON payload (no nested attributes)
|
||||
const flatPayload = flatten(payload);
|
||||
|
||||
// workflow builder requires values to be strings
|
||||
// iterate over every value and convert it to string
|
||||
Object.keys(flatPayload).forEach((key) => {
|
||||
flatPayload[key] = `${flatPayload[key]}`;
|
||||
});
|
||||
|
||||
payload = flatPayload;
|
||||
}
|
||||
|
||||
try {
|
||||
await axios.post(webhookUrl, payload);
|
||||
} catch (err) {
|
||||
console.log('axios post failed, double check the payload being sent includes the keys Slack expects');
|
||||
console.log(payload);
|
||||
// console.log(err);
|
||||
|
||||
if (err.response) {
|
||||
core.setFailed(err.response.data);
|
||||
}
|
||||
|
||||
core.setFailed(err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const time = (new Date()).toTimeString();
|
||||
core.setOutput('time', time);
|
||||
} catch (error) {
|
||||
core.setFailed(error);
|
||||
}
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
module.exports = {
|
||||
// These environments contain lists of global variables which are allowed to be accessed
|
||||
env: {
|
||||
// According to https://node.green, the target node version (v10) supports all important ES2018 features. But es2018
|
||||
// is not an option since it presumably doesn't introduce any new globals over ES2017.
|
||||
es2017: true,
|
||||
node: true,
|
||||
mocha: true,
|
||||
},
|
||||
rules: {
|
||||
// These rules dont like the use of devDependencies - which test code uses often.
|
||||
'node/no-unpublished-require': 0,
|
||||
'node/no-missing-require': 0,
|
||||
},
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
{not-valid-json
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"oliver": "benji",
|
||||
"bonny": "clyde"
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
const { assert } = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const core = require('@actions/core');
|
||||
const rewiremock = require('rewiremock/node');
|
||||
|
||||
const ChatStub = {
|
||||
postMessage: sinon.spy(),
|
||||
};
|
||||
/* eslint-disable-next-line global-require */
|
||||
rewiremock(() => require('@slack/web-api')).with({
|
||||
WebClient: class {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
this.chat = ChatStub;
|
||||
}
|
||||
},
|
||||
});
|
||||
const AxiosMock = {
|
||||
post: sinon.stub().resolves(),
|
||||
};
|
||||
/* eslint-disable-next-line global-require */
|
||||
rewiremock(() => require('axios')).with(AxiosMock);
|
||||
rewiremock.enable();
|
||||
const slackSend = require('../src/slack-send');
|
||||
|
||||
rewiremock.disable();
|
||||
|
||||
const ORIG_TOKEN_VAR = process.env.SLACK_BOT_TOKEN;
|
||||
const ORIG_WEBHOOK_VAR = process.env.SLACK_WEBHOOK_URL;
|
||||
|
||||
describe('slack-send', () => {
|
||||
const fakeCore = sinon.stub(core);
|
||||
beforeEach(() => {
|
||||
sinon.reset();
|
||||
});
|
||||
after(() => {
|
||||
process.env.SLACK_BOT_TOKEN = ORIG_TOKEN_VAR;
|
||||
process.env.SLACK_WEBHOOK_URL = ORIG_WEBHOOK_VAR;
|
||||
});
|
||||
|
||||
it('should set an error if no webhook URL or token is provided', async () => {
|
||||
delete process.env.SLACK_BOT_TOKEN;
|
||||
delete process.env.SLACK_WEBHOOK_URL;
|
||||
await slackSend(fakeCore);
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'Need to provide at least one botToken or webhook', 'Error set specifying what env vars need to be set.');
|
||||
});
|
||||
|
||||
describe('using a bot token', () => {
|
||||
beforeEach(() => {
|
||||
process.env.SLACK_BOT_TOKEN = 'xoxb-xxxxx';
|
||||
delete process.env.SLACK_WEBHOOK_URL;
|
||||
});
|
||||
describe('happy path', () => {
|
||||
it('should send a message using the postMessage API', async () => {
|
||||
fakeCore.getInput.withArgs('slack-message').returns('who let the dogs out?');
|
||||
fakeCore.getInput.withArgs('channel-id').returns('C123456');
|
||||
await slackSend(fakeCore);
|
||||
assert.equal(fakeCore.setOutput.lastCall.firstArg, 'time', 'Output name set to time');
|
||||
assert(fakeCore.setOutput.lastCall.lastArg.length > 0, 'Time output a non-zero-length string');
|
||||
const chatArgs = ChatStub.postMessage.lastCall.firstArg;
|
||||
assert.equal(chatArgs.channel, 'C123456', 'Correct channel provided to postMessage');
|
||||
assert.equal(chatArgs.text, 'who let the dogs out?', 'Correct message provided to postMessage');
|
||||
});
|
||||
|
||||
it('should accept a payload-file-path and use it\'s content in the message', async () => {
|
||||
// Prepare
|
||||
fakeCore.getInput.withArgs('channel-id').returns('C123456');
|
||||
fakeCore.getInput.withArgs('payload-file-path').returns('./test/resources/valid-payload.json');
|
||||
|
||||
// Run
|
||||
await slackSend(fakeCore);
|
||||
|
||||
// Assert
|
||||
assert.equal(fakeCore.setOutput.lastCall.firstArg, 'time', 'Output name set to time');
|
||||
assert(fakeCore.setOutput.lastCall.lastArg.length > 0, 'Time output a non-zero-length string');
|
||||
const chatArgs = ChatStub.postMessage.lastCall.firstArg;
|
||||
assert.equal(chatArgs.channel, 'C123456', 'Correct channel provided to postMessage');
|
||||
assert.equal(chatArgs.text, '', 'Correct message provided to postMessage');
|
||||
assert.equal(chatArgs.bonny, 'clyde', 'Correct message provided to postMessage');
|
||||
assert.equal(chatArgs.oliver, 'benji', 'Correct message provided to postMessage');
|
||||
});
|
||||
});
|
||||
describe('sad path', () => {
|
||||
it('should set an error if payload cannot be JSON parsed', async () => {
|
||||
fakeCore.getInput.withArgs('payload').returns('{not-valid-json');
|
||||
await slackSend(fakeCore);
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'Need to provide valid JSON', 'Error set specifying JSON was invalid.');
|
||||
});
|
||||
|
||||
it('should fail if an invalid payload-file-path is provided', async () => {
|
||||
// Prepare
|
||||
fakeCore.getInput.withArgs('channel-id').returns('C123456');
|
||||
fakeCore.getInput.withArgs('payload-file-path').returns('non-existing-path.json');
|
||||
|
||||
// Run
|
||||
await slackSend(fakeCore);
|
||||
|
||||
// Assert
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'The payload-file-path may be incorrect. Failed to load the file: non-existing-path.json', 'Error set specifying JSON was invalid.');
|
||||
});
|
||||
|
||||
it('should fail if a valid payload-file-path with an invalid JSON is provided', async () => {
|
||||
// Prepare
|
||||
fakeCore.getInput.withArgs('channel-id').returns('C123456');
|
||||
fakeCore.getInput.withArgs('payload-file-path').returns('./test/resources/invalid-payload.json');
|
||||
|
||||
// Run
|
||||
await slackSend(fakeCore);
|
||||
|
||||
// Assert
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'Need to provide valid JSON payload', 'Error set specifying JSON was invalid.');
|
||||
});
|
||||
|
||||
it('should fail if Channel ID is missing', async () => {
|
||||
// Run
|
||||
await slackSend(fakeCore);
|
||||
|
||||
// Assert
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'Channel ID is required to run this action. An empty one has been provided', 'Error set specifying JSON was invalid.');
|
||||
});
|
||||
|
||||
it('should fail if payload is missing or empty', async () => {
|
||||
// Prepare
|
||||
fakeCore.getInput.withArgs('channel-id').returns('C123456');
|
||||
|
||||
// Run
|
||||
await slackSend(fakeCore);
|
||||
|
||||
// Assert
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg.message, 'Missing message content, please input a valid payload or message to send. No Message has been send.', 'Error set specifying JSON was invalid.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('using a webhook URL', () => {
|
||||
beforeEach(() => {
|
||||
process.env.SLACK_WEBHOOK_URL = 'https://someurl';
|
||||
delete process.env.SLACK_BOT_TOKEN;
|
||||
});
|
||||
describe('happy path', () => {
|
||||
const payload = {
|
||||
batman: 'robin',
|
||||
thor: 'loki',
|
||||
};
|
||||
beforeEach(() => {
|
||||
fakeCore.getInput.withArgs('payload').returns(JSON.stringify(payload));
|
||||
});
|
||||
it('should post the payload to the webhook URL', async () => {
|
||||
await slackSend(fakeCore);
|
||||
assert(AxiosMock.post.calledWith('https://someurl', payload));
|
||||
});
|
||||
});
|
||||
describe('sad path', () => {
|
||||
it('should set an error if the POST to the webhook fails without a response', async () => {
|
||||
AxiosMock.post.rejects(new Error('boom'));
|
||||
await slackSend(fakeCore);
|
||||
assert.include(fakeCore.setFailed.lastCall.firstArg, 'boom', 'Error set to whatever axios reports as error.');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user