├── .dependabot └── config.yml ├── .eslintrc.json ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── check.yml │ ├── package.yml │ └── release.yml ├── .gitignore ├── .mergify.yml ├── .prettierrc ├── .vscode └── settings.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── THIRD-PARTY ├── __tests__ └── main.test.ts ├── action.yml ├── dist └── index.js ├── jest.config.js ├── package-lock.json ├── package.json ├── src └── main.ts └── tsconfig.json /.dependabot/config.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | update_configs: 3 | - package_manager: "javascript" 4 | directory: "/" 5 | update_schedule: "monthly" 6 | automerged_updates: 7 | - match: 8 | dependency_type: "all" 9 | update_type: "semver:minor" 10 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "env": { 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true, 7 | "jest": true 8 | }, 9 | "extends": [ 10 | "plugin:prettier/recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "globals": { 14 | "Atomics": "readonly", 15 | "SharedArrayBuffer": "readonly" 16 | }, 17 | "parserOptions": { 18 | "sourceType": "module", 19 | "ecmaVersion": 2018 20 | }, 21 | "rules": {} 22 | } -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 7 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | on: [pull_request] 2 | 3 | name: Check 4 | 5 | jobs: 6 | check: 7 | name: Run Unit Tests 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: Run tests 13 | run: | 14 | npm ci 15 | npm test 16 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | 6 | name: Package 7 | 8 | jobs: 9 | check: 10 | name: Package distribution file 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | with: 16 | ref: master 17 | - name: Package 18 | run: | 19 | npm ci 20 | npm test 21 | npm run all 22 | - name: Commit 23 | run: | 24 | git config --global user.name "GitHub Actions" 25 | git add dist/ 26 | git commit -m "(chore) updating dist" || echo "No changes to commit" 27 | git push origin HEAD:master 28 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 5 | 6 | name: Create Release 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@master 15 | - name: Create Release 16 | id: create_release 17 | uses: actions/create-release@latest 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 20 | with: 21 | tag_name: ${{ github.ref }} 22 | release_name: ${{ github.ref }} 23 | body: | 24 | See the CHANGELOG for more details on the release. 25 | draft: false 26 | prerelease: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directory 2 | node_modules 3 | 4 | # Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | jspm_packages/ 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | .env.test 71 | 72 | # parcel-bundler cache (https://parceljs.org/) 73 | .cache 74 | 75 | # next.js build output 76 | .next 77 | 78 | # nuxt.js build output 79 | .nuxt 80 | 81 | # vuepress build output 82 | .vuepress/dist 83 | 84 | # Serverless directories 85 | .serverless/ 86 | 87 | # FuseBox cache 88 | .fusebox/ 89 | 90 | # DynamoDB Local files 91 | .dynamodb/ 92 | 93 | # OS metadata 94 | .DS_Store 95 | Thumbs.db 96 | 97 | # Ignore built ts files 98 | __tests__/runner/* 99 | lib/**/* -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Automatically merge on CI success and review approval 3 | conditions: 4 | - base~=master|integ-tests 5 | - "#approved-reviews-by>=1" 6 | - approved-reviews-by=@aws-actions/aws-cfn-devx 7 | - -approved-reviews-by~=author 8 | - status-success=Run Unit Tests 9 | - status-success=Semantic Pull Request 10 | - label!=work-in-progress 11 | - -title~=(WIP|wip) 12 | - -merged 13 | - -closed 14 | - author!=dependabot[bot] 15 | - author!=dependabot-preview[bot] 16 | actions: 17 | merge: 18 | method: squash 19 | strict: smart 20 | strict_method: merge 21 | 22 | - name: Automatically approve Dependabot PRs 23 | conditions: 24 | - base=master 25 | - author~=^dependabot(|-preview)\[bot\]$ 26 | - -title~=(WIP|wip) 27 | - -label~=(blocked|do-not-merge) 28 | - -merged 29 | - -closed 30 | actions: 31 | review: 32 | type: APPROVE 33 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "singleQuote": true, 6 | "trailingComma": "none", 7 | "bracketSpacing": true, 8 | "arrowParens": "avoid", 9 | "parser": "typescript" 10 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "search.exclude": { 4 | "**/node_modules": true, 5 | "**/bower_components": true, 6 | "dist/**/*": true 7 | } 8 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## Features 6 | 7 | ## Bug Fixes 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | ## Reporting Bugs/Feature Requests 10 | 11 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 12 | 13 | When filing an issue, please check [existing open](https://github.com/aws-actions/amazon-chime-github-webhook/issues), or [recently closed](https://github.com/aws-actions/amazon-chime-github-webhook/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 14 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 15 | 16 | - A reproducible test case or series of steps 17 | - The version of our code being used 18 | - Any modifications you've made relevant to the bug 19 | - Anything unusual about your environment or deployment 20 | 21 | ## Contributing via Pull Requests 22 | 23 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 24 | 25 | 1. You are working against the latest source on the _master_ branch. 26 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 27 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 28 | 29 | To send us a pull request, please: 30 | 31 | 1. Fork the repository. 32 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 33 | 3. Ensure local tests pass. 34 | 4. Commit to your fork using clear commit messages. 35 | 5. Send us a pull request, answering any default questions in the pull request interface. 36 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 37 | 38 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 39 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 40 | 41 | ## Finding contributions to work on 42 | 43 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-actions/amazon-chime-github-webhook/labels/help%20wanted) issues is a great place to start. 44 | 45 | ## Code of Conduct 46 | 47 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 48 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 49 | opensource-codeofconduct@amazon.com with any additional questions or comments. 50 | 51 | ## Security issue notifications 52 | 53 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 54 | 55 | ## Licensing 56 | 57 | See the [LICENSE](https://github.com/aws-actions/amazon-chime-github-webhook/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 58 | 59 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2020 Amazon.com, Inc. or its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Amazon Chime "Chime Webhook" Action for GitHub Actions 2 | 3 | ![Package](https://github.com/aws-actions/amazon-chime-github-webhook/workflows/Package/badge.svg) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 5 | 6 | Send message to Amazon Chime chat rooms. 7 | 8 | ## Usage 9 | 10 | ```yaml 11 | - name: Send message to Amazon Chime chat room 12 | uses: aws-actions/amazon-chime-github-webhook@v1 13 | with: 14 | webhook: ${{ secrets.webhook }} 15 | message: "Whoohoo!" 16 | ``` 17 | 18 | The action can be passed a `webhook` URL and `message` to be send to a Amazon Chime chat room. `webook` should be defined as an [encrypted secret](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets) and not be exposed directly. 19 | 20 | See [action.yml](action.yml) for the full documentation for this action's inputs and outputs. 21 | 22 | > You can learn more about creating an [Amazon Chime Webhook](https://docs.aws.amazon.com/chime/latest/dg/webhooks.html) and about [Amazon Chime](https://aws.amazon.com/de/chime/) 23 | 24 | ## License 25 | 26 | [MIT](/LICENSE) 27 | -------------------------------------------------------------------------------- /THIRD-PARTY: -------------------------------------------------------------------------------- 1 | ** Axios; version 0.19.2 -- https://github.com/axios/axios 2 | Copyright (c) 2014-present Matt Zabriskie 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | ------ 23 | 24 | ** GitHub Actions Toolkit; version 1.2.0 -- https://github.com/actions/toolkit 25 | Copyright 2019 GitHub 26 | 27 | MIT License 28 | 29 | Copyright (c) 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy of 32 | this software and associated documentation files (the "Software"), to deal in 33 | the Software without restriction, including without limitation the rights to 34 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 35 | of the Software, and to permit persons to whom the Software is furnished to do 36 | so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in all 39 | copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 47 | SOFTWARE. 48 | -------------------------------------------------------------------------------- /__tests__/main.test.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import { run } from '../src/main'; 3 | import chime from 'chime'; 4 | 5 | jest.mock('@actions/core'); 6 | jest.mock('chime'); 7 | 8 | export type Inputs = { 9 | [key: string]: string; 10 | }; 11 | 12 | describe('Send Chime Webhook', () => { 13 | beforeEach(() => { 14 | jest.clearAllMocks(); 15 | 16 | const inputs: Inputs = { 17 | webhook: 'https://chime.test/12345', 18 | message: 'Wohooo!' 19 | }; 20 | 21 | jest.spyOn(core, 'getInput').mockImplementation((name: string) => { 22 | return inputs[name]; 23 | }); 24 | }); 25 | 26 | test('sends a message to the chat room', async () => { 27 | await run(); 28 | 29 | expect(core.setFailed).toHaveBeenCalledTimes(0); 30 | expect(chime.sendMessage).toHaveBeenCalledTimes(1); 31 | expect(chime.sendMessage).toHaveBeenNthCalledWith( 32 | 1, 33 | 'Wohooo!', 34 | 'https://chime.test/12345', 35 | { markdown: true } 36 | ); 37 | expect(core.setOutput).toHaveBeenNthCalledWith(1, 'message-id', undefined); 38 | }); 39 | 40 | test('sets failure upon failure of sending message', async () => { 41 | jest.spyOn(chime, 'sendMessage').mockImplementation(() => { 42 | return Promise.reject({ statusCode: 500, message: 'read ETIMEDOUT' }); 43 | }); 44 | 45 | await run(); 46 | 47 | expect(core.setFailed).toHaveBeenCalledTimes(1); 48 | expect(chime.sendMessage).toHaveBeenCalledTimes(1); 49 | expect(chime.sendMessage).toHaveBeenNthCalledWith( 50 | 1, 51 | 'Wohooo!', 52 | 'https://chime.test/12345', 53 | { markdown: true } 54 | ); 55 | expect(core.setOutput).toHaveBeenCalledTimes(0); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Amazon Chime "Chime Webhook" Action for GitHub Actions' 2 | description: "Send message to Amazon Chime chat rooms" 3 | branding: 4 | icon: "cloud" 5 | color: "orange" 6 | inputs: 7 | webhook: 8 | description: "The URL of the Amazon Chime Webhook" 9 | required: true 10 | message: 11 | description: "The message that is send to the Amazon Chime chat room" 12 | required: true 13 | no-markdown: 14 | description: "Do not send the message using markdown syntax" 15 | required: false 16 | default: "0" 17 | outputs: 18 | message-id: 19 | description: "Returns the id of the message in Amazon Chime" 20 | runs: 21 | using: "node12" 22 | main: "dist/index.js" 23 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | /******/ (function(modules, runtime) { // webpackBootstrap 3 | /******/ "use strict"; 4 | /******/ // The module cache 5 | /******/ var installedModules = {}; 6 | /******/ 7 | /******/ // The require function 8 | /******/ function __webpack_require__(moduleId) { 9 | /******/ 10 | /******/ // Check if module is in cache 11 | /******/ if(installedModules[moduleId]) { 12 | /******/ return installedModules[moduleId].exports; 13 | /******/ } 14 | /******/ // Create a new module (and put it into the cache) 15 | /******/ var module = installedModules[moduleId] = { 16 | /******/ i: moduleId, 17 | /******/ l: false, 18 | /******/ exports: {} 19 | /******/ }; 20 | /******/ 21 | /******/ // Execute the module function 22 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 23 | /******/ 24 | /******/ // Flag the module as loaded 25 | /******/ module.l = true; 26 | /******/ 27 | /******/ // Return the exports of the module 28 | /******/ return module.exports; 29 | /******/ } 30 | /******/ 31 | /******/ 32 | /******/ __webpack_require__.ab = __dirname + "/"; 33 | /******/ 34 | /******/ // the startup function 35 | /******/ function startup() { 36 | /******/ // Load entry module and return exports 37 | /******/ return __webpack_require__(198); 38 | /******/ }; 39 | /******/ 40 | /******/ // run startup 41 | /******/ return startup(); 42 | /******/ }) 43 | /************************************************************************/ 44 | /******/ ({ 45 | 46 | /***/ 87: 47 | /***/ (function(module) { 48 | 49 | module.exports = require("os"); 50 | 51 | /***/ }), 52 | 53 | /***/ 91: 54 | /***/ (function(module, __unusedexports, __webpack_require__) { 55 | 56 | "use strict"; 57 | 58 | 59 | const Chime = __webpack_require__(558); 60 | 61 | module.exports = Chime; 62 | 63 | 64 | /***/ }), 65 | 66 | /***/ 198: 67 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 68 | 69 | "use strict"; 70 | 71 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 72 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 73 | return new (P || (P = Promise))(function (resolve, reject) { 74 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 75 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 76 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 77 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 78 | }); 79 | }; 80 | var __importStar = (this && this.__importStar) || function (mod) { 81 | if (mod && mod.__esModule) return mod; 82 | var result = {}; 83 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 84 | result["default"] = mod; 85 | return result; 86 | }; 87 | var __importDefault = (this && this.__importDefault) || function (mod) { 88 | return (mod && mod.__esModule) ? mod : { "default": mod }; 89 | }; 90 | Object.defineProperty(exports, "__esModule", { value: true }); 91 | const core = __importStar(__webpack_require__(470)); 92 | const chime_1 = __importDefault(__webpack_require__(91)); 93 | function run() { 94 | return __awaiter(this, void 0, void 0, function* () { 95 | try { 96 | // Get inputs 97 | const webhook = core.getInput('webhook', { required: true }); 98 | const message = core.getInput('message', { required: true }); 99 | const noMarkdown = !!+core.getInput('no-markdown', { 100 | required: false 101 | }); 102 | // Post message to Chime Webhook 103 | core.debug('Post message to Amazon Chime Webhook'); 104 | // send the request 105 | const msg = yield chime_1.default.sendMessage(message, webhook, { 106 | markdown: !noMarkdown 107 | }); 108 | core.setOutput('message-id', msg === null || msg === void 0 ? void 0 : msg.messageId); 109 | } 110 | catch (err) { 111 | core.setFailed(err.message); 112 | core.debug(err.stack); 113 | } 114 | }); 115 | } 116 | exports.run = run; 117 | /* istanbul ignore next */ 118 | if (require.main === require.cache[eval('__filename')]) { 119 | run(); 120 | } 121 | 122 | 123 | /***/ }), 124 | 125 | /***/ 211: 126 | /***/ (function(module) { 127 | 128 | module.exports = require("https"); 129 | 130 | /***/ }), 131 | 132 | /***/ 431: 133 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 134 | 135 | "use strict"; 136 | 137 | var __importStar = (this && this.__importStar) || function (mod) { 138 | if (mod && mod.__esModule) return mod; 139 | var result = {}; 140 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 141 | result["default"] = mod; 142 | return result; 143 | }; 144 | Object.defineProperty(exports, "__esModule", { value: true }); 145 | const os = __importStar(__webpack_require__(87)); 146 | /** 147 | * Commands 148 | * 149 | * Command Format: 150 | * ::name key=value,key=value::message 151 | * 152 | * Examples: 153 | * ::warning::This is the message 154 | * ::set-env name=MY_VAR::some value 155 | */ 156 | function issueCommand(command, properties, message) { 157 | const cmd = new Command(command, properties, message); 158 | process.stdout.write(cmd.toString() + os.EOL); 159 | } 160 | exports.issueCommand = issueCommand; 161 | function issue(name, message = '') { 162 | issueCommand(name, {}, message); 163 | } 164 | exports.issue = issue; 165 | const CMD_STRING = '::'; 166 | class Command { 167 | constructor(command, properties, message) { 168 | if (!command) { 169 | command = 'missing.command'; 170 | } 171 | this.command = command; 172 | this.properties = properties; 173 | this.message = message; 174 | } 175 | toString() { 176 | let cmdStr = CMD_STRING + this.command; 177 | if (this.properties && Object.keys(this.properties).length > 0) { 178 | cmdStr += ' '; 179 | let first = true; 180 | for (const key in this.properties) { 181 | if (this.properties.hasOwnProperty(key)) { 182 | const val = this.properties[key]; 183 | if (val) { 184 | if (first) { 185 | first = false; 186 | } 187 | else { 188 | cmdStr += ','; 189 | } 190 | cmdStr += `${key}=${escapeProperty(val)}`; 191 | } 192 | } 193 | } 194 | } 195 | cmdStr += `${CMD_STRING}${escapeData(this.message)}`; 196 | return cmdStr; 197 | } 198 | } 199 | function escapeData(s) { 200 | return (s || '') 201 | .replace(/%/g, '%25') 202 | .replace(/\r/g, '%0D') 203 | .replace(/\n/g, '%0A'); 204 | } 205 | function escapeProperty(s) { 206 | return (s || '') 207 | .replace(/%/g, '%25') 208 | .replace(/\r/g, '%0D') 209 | .replace(/\n/g, '%0A') 210 | .replace(/:/g, '%3A') 211 | .replace(/,/g, '%2C'); 212 | } 213 | //# sourceMappingURL=command.js.map 214 | 215 | /***/ }), 216 | 217 | /***/ 470: 218 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 219 | 220 | "use strict"; 221 | 222 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 223 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 224 | return new (P || (P = Promise))(function (resolve, reject) { 225 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 226 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 227 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 228 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 229 | }); 230 | }; 231 | var __importStar = (this && this.__importStar) || function (mod) { 232 | if (mod && mod.__esModule) return mod; 233 | var result = {}; 234 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 235 | result["default"] = mod; 236 | return result; 237 | }; 238 | Object.defineProperty(exports, "__esModule", { value: true }); 239 | const command_1 = __webpack_require__(431); 240 | const os = __importStar(__webpack_require__(87)); 241 | const path = __importStar(__webpack_require__(622)); 242 | /** 243 | * The code to exit an action 244 | */ 245 | var ExitCode; 246 | (function (ExitCode) { 247 | /** 248 | * A code indicating that the action was successful 249 | */ 250 | ExitCode[ExitCode["Success"] = 0] = "Success"; 251 | /** 252 | * A code indicating that the action was a failure 253 | */ 254 | ExitCode[ExitCode["Failure"] = 1] = "Failure"; 255 | })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); 256 | //----------------------------------------------------------------------- 257 | // Variables 258 | //----------------------------------------------------------------------- 259 | /** 260 | * Sets env variable for this action and future actions in the job 261 | * @param name the name of the variable to set 262 | * @param val the value of the variable 263 | */ 264 | function exportVariable(name, val) { 265 | process.env[name] = val; 266 | command_1.issueCommand('set-env', { name }, val); 267 | } 268 | exports.exportVariable = exportVariable; 269 | /** 270 | * Registers a secret which will get masked from logs 271 | * @param secret value of the secret 272 | */ 273 | function setSecret(secret) { 274 | command_1.issueCommand('add-mask', {}, secret); 275 | } 276 | exports.setSecret = setSecret; 277 | /** 278 | * Prepends inputPath to the PATH (for this action and future actions) 279 | * @param inputPath 280 | */ 281 | function addPath(inputPath) { 282 | command_1.issueCommand('add-path', {}, inputPath); 283 | process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; 284 | } 285 | exports.addPath = addPath; 286 | /** 287 | * Gets the value of an input. The value is also trimmed. 288 | * 289 | * @param name name of the input to get 290 | * @param options optional. See InputOptions. 291 | * @returns string 292 | */ 293 | function getInput(name, options) { 294 | const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; 295 | if (options && options.required && !val) { 296 | throw new Error(`Input required and not supplied: ${name}`); 297 | } 298 | return val.trim(); 299 | } 300 | exports.getInput = getInput; 301 | /** 302 | * Sets the value of an output. 303 | * 304 | * @param name name of the output to set 305 | * @param value value to store 306 | */ 307 | function setOutput(name, value) { 308 | command_1.issueCommand('set-output', { name }, value); 309 | } 310 | exports.setOutput = setOutput; 311 | //----------------------------------------------------------------------- 312 | // Results 313 | //----------------------------------------------------------------------- 314 | /** 315 | * Sets the action status to failed. 316 | * When the action exits it will be with an exit code of 1 317 | * @param message add error issue message 318 | */ 319 | function setFailed(message) { 320 | process.exitCode = ExitCode.Failure; 321 | error(message); 322 | } 323 | exports.setFailed = setFailed; 324 | //----------------------------------------------------------------------- 325 | // Logging Commands 326 | //----------------------------------------------------------------------- 327 | /** 328 | * Gets whether Actions Step Debug is on or not 329 | */ 330 | function isDebug() { 331 | return process.env['RUNNER_DEBUG'] === '1'; 332 | } 333 | exports.isDebug = isDebug; 334 | /** 335 | * Writes debug message to user log 336 | * @param message debug message 337 | */ 338 | function debug(message) { 339 | command_1.issueCommand('debug', {}, message); 340 | } 341 | exports.debug = debug; 342 | /** 343 | * Adds an error issue 344 | * @param message error issue message 345 | */ 346 | function error(message) { 347 | command_1.issue('error', message); 348 | } 349 | exports.error = error; 350 | /** 351 | * Adds an warning issue 352 | * @param message warning issue message 353 | */ 354 | function warning(message) { 355 | command_1.issue('warning', message); 356 | } 357 | exports.warning = warning; 358 | /** 359 | * Writes info to log with console.log. 360 | * @param message info message 361 | */ 362 | function info(message) { 363 | process.stdout.write(message + os.EOL); 364 | } 365 | exports.info = info; 366 | /** 367 | * Begin an output group. 368 | * 369 | * Output until the next `groupEnd` will be foldable in this group 370 | * 371 | * @param name The name of the output group 372 | */ 373 | function startGroup(name) { 374 | command_1.issue('group', name); 375 | } 376 | exports.startGroup = startGroup; 377 | /** 378 | * End an output group. 379 | */ 380 | function endGroup() { 381 | command_1.issue('endgroup'); 382 | } 383 | exports.endGroup = endGroup; 384 | /** 385 | * Wrap an asynchronous function call in a group. 386 | * 387 | * Returns the same type as the function itself. 388 | * 389 | * @param name The name of the group 390 | * @param fn The function to wrap in the group 391 | */ 392 | function group(name, fn) { 393 | return __awaiter(this, void 0, void 0, function* () { 394 | startGroup(name); 395 | let result; 396 | try { 397 | result = yield fn(); 398 | } 399 | finally { 400 | endGroup(); 401 | } 402 | return result; 403 | }); 404 | } 405 | exports.group = group; 406 | //----------------------------------------------------------------------- 407 | // Wrapper action state 408 | //----------------------------------------------------------------------- 409 | /** 410 | * Saves state for current action, the state can only be retrieved by this action's post job execution. 411 | * 412 | * @param name name of the state to store 413 | * @param value value to store 414 | */ 415 | function saveState(name, value) { 416 | command_1.issueCommand('save-state', { name }, value); 417 | } 418 | exports.saveState = saveState; 419 | /** 420 | * Gets the value of an state set by this action's main execution. 421 | * 422 | * @param name name of the state to get 423 | * @returns string 424 | */ 425 | function getState(name) { 426 | return process.env[`STATE_${name}`] || ''; 427 | } 428 | exports.getState = getState; 429 | //# sourceMappingURL=core.js.map 430 | 431 | /***/ }), 432 | 433 | /***/ 558: 434 | /***/ (function(module, __unusedexports, __webpack_require__) { 435 | 436 | "use strict"; 437 | 438 | 439 | const https = __webpack_require__(211); 440 | 441 | const wm = new WeakMap(); 442 | 443 | const sendMessage = (message, url, { markdown = true }) => 444 | new Promise((resolve, reject) => { 445 | https 446 | .request(url, { method: 'POST' }, (res) => { 447 | let buf = ''; 448 | 449 | res 450 | .on('data', (chunk) => (buf += chunk)) 451 | .on('end', () => { 452 | buf = JSON.parse(buf); 453 | 454 | if (res.statusCode !== 200) { 455 | reject(new Error(buf.Message || buf.message)); 456 | } else { 457 | resolve({ messageId: buf.MessageId, roomId: buf.RoomId }); 458 | } 459 | }); 460 | }) 461 | .on('error', reject) 462 | .end(JSON.stringify({ Content: (markdown ? '/md ' : '') + message })); 463 | }); 464 | 465 | class Chime { 466 | constructor(url, options = {}) { 467 | wm.set(this, { ...options, url }); 468 | } 469 | 470 | static sendMessage(message, url, options = {}) { 471 | return sendMessage(message, url, options); 472 | } 473 | 474 | sendMessage(message, options = {}) { 475 | const { url, markdown } = wm.get(this); 476 | 477 | return sendMessage(message, url, { markdown, ...options }); 478 | } 479 | } 480 | 481 | module.exports = Chime; 482 | 483 | 484 | /***/ }), 485 | 486 | /***/ 622: 487 | /***/ (function(module) { 488 | 489 | module.exports = require("path"); 490 | 491 | /***/ }) 492 | 493 | /******/ }); -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | clearMocks: true, 3 | moduleFileExtensions: ["js", "ts"], 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | testRunner: "jest-circus/runner", 7 | transform: { 8 | "^.+\\.ts$": "ts-jest" 9 | }, 10 | verbose: true 11 | }; 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-actions-amazon-chime-github-webhook", 3 | "version": "1.0.0", 4 | "description": "Programmatically send message to Amazon Chime chat rooms", 5 | "main": "lib/main.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "format": "prettier --write **/*.ts", 9 | "format-check": "prettier --check **/*.ts", 10 | "lint": "eslint src/**/*.ts", 11 | "pack": "ncc build", 12 | "test": "DEBUG=jest eslint **/*.ts && jest --coverage --verbose", 13 | "all": "npm run build && npm run format && npm run lint && npm run pack && npm test" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/aws-actions/amazon-chime-github-webhook.git" 18 | }, 19 | "keywords": [ 20 | "AWS", 21 | "GitHub", 22 | "Actions", 23 | "JavaScript" 24 | ], 25 | "author": "AWS", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/aws-actions/amazon-chime-github-webhook/issues" 29 | }, 30 | "homepage": "https://github.com/aws-actions/amazon-chime-github-webhook#readme", 31 | "husky": { 32 | "hooks": { 33 | "pre-commit": "npm test && npm run format && npm run lint", 34 | "pre-push": "npm test && npm run format && npm run lint" 35 | } 36 | }, 37 | "dependencies": { 38 | "@actions/core": "^1.2.3", 39 | "chime": "^1.0.1" 40 | }, 41 | "devDependencies": { 42 | "@types/jest": "^25.1.4", 43 | "@types/node": "^13.9.2", 44 | "@typescript-eslint/eslint-plugin": "^2.24.0", 45 | "@typescript-eslint/parser": "^2.24.0", 46 | "@zeit/ncc": "^0.21.1", 47 | "eslint": "^6.8.0", 48 | "eslint-config-prettier": "^6.10.0", 49 | "eslint-plugin-github": "^3.4.1", 50 | "eslint-plugin-jest": "^23.8.2", 51 | "eslint-plugin-prettier": "^3.1.2", 52 | "husky": "^4.2.3", 53 | "jest": "^25.1.0", 54 | "jest-circus": "^25.1.0", 55 | "js-yaml": "^3.13.1", 56 | "prettier": "^1.19.1", 57 | "ts-jest": "^25.2.1", 58 | "typescript": "^3.6.4" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import chime from 'chime'; 3 | 4 | export async function run(): Promise { 5 | try { 6 | // Get inputs 7 | const webhook = core.getInput('webhook', { required: true }); 8 | const message = core.getInput('message', { required: true }); 9 | const noMarkdown = !!+core.getInput('no-markdown', { 10 | required: false 11 | }); 12 | 13 | // Post message to Chime Webhook 14 | core.debug('Post message to Amazon Chime Webhook'); 15 | 16 | // send the request 17 | const msg = await chime.sendMessage(message, webhook, { 18 | markdown: !noMarkdown 19 | }); 20 | 21 | core.setOutput('message-id', msg?.messageId); 22 | } catch (err) { 23 | core.setFailed(err.message); 24 | core.debug(err.stack); 25 | } 26 | } 27 | 28 | /* istanbul ignore next */ 29 | if (require.main === module) { 30 | run(); 31 | } 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 4 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 5 | "outDir": "./lib", /* Redirect output structure to the directory. */ 6 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 7 | "strict": true, /* Enable all strict type-checking options. */ 8 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 9 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | "**/*.test.ts" 14 | ] 15 | } --------------------------------------------------------------------------------