├── .github ├── renovate.json └── workflows │ ├── release.yml │ ├── test.yml │ └── deploy.yml ├── app.yml ├── .gitignore ├── handler.js ├── app.js ├── package.json ├── LICENSE ├── serverless.yml ├── .vscode └── launch.json ├── test.js ├── README.md └── CODE_OF_CONDUCT.md /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>probot/.github" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /app.yml: -------------------------------------------------------------------------------- 1 | default_events: 2 | - issues 3 | 4 | default_permissions: 5 | issues: write 6 | metadata: read 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | 4 | # Serverless directories 5 | .serverless 6 | 7 | .env 8 | coverage 9 | .nyc_output -------------------------------------------------------------------------------- /handler.js: -------------------------------------------------------------------------------- 1 | const { 2 | createLambdaFunction, 3 | createProbot, 4 | } = require("@probot/adapter-aws-lambda-serverless"); 5 | 6 | const appFn = require("./"); 7 | 8 | module.exports.webhooks = createLambdaFunction(appFn, { 9 | probot: createProbot(), 10 | }); 11 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {import('probot').Probot} app 3 | */ 4 | module.exports = (app) => { 5 | app.log("Yay! The app was loaded!"); 6 | 7 | app.on("issues.opened", async (context) => { 8 | return context.octokit.issues.createComment( 9 | context.issue({ body: "Hello, World!" }) 10 | ); 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | "on": 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | release: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: lts/* 14 | cache: npm 15 | - run: npx semantic-release 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | "on": 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | types: 8 | - opened 9 | - synchronize 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | with: 17 | cache: npm 18 | node-version: 16 19 | - run: npm ci 20 | - run: npm test 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | "on": 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: {} 7 | jobs: 8 | deploy: 9 | name: deploy 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: 16 16 | cache: npm 17 | - run: npm ci 18 | - name: serverless deploy 19 | uses: serverless/github-action@master 20 | with: 21 | args: deploy 22 | env: 23 | SERVERLESS_ACCESS_KEY: ${{ secrets.SERVERLESS_ACCESS_KEY }} 24 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 25 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@probot/example-aws-lambda-serverless", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "Probot & AWS Lambda example", 6 | "main": "app.js", 7 | "scripts": { 8 | "start": "probot run ./app.js", 9 | "test": "node test.js" 10 | }, 11 | "dependencies": { 12 | "@probot/adapter-aws-lambda-serverless": "^3.0.0" 13 | }, 14 | "repository": "github:probot/example-aws-lambda-serverless", 15 | "keywords": [], 16 | "author": "Gregor Martynus (https://twitter.com/gr2m)", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "nock": "^13.0.7", 20 | "smee-client": "^1.2.2", 21 | "uvu": "^0.5.1" 22 | }, 23 | "release": { 24 | "branches": [ 25 | "main" 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2020 Probot Contributors 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Serverless! 2 | # 3 | # This file is the main config file for your service. 4 | # It's very minimal at this point and uses default values. 5 | # You can always add more config options for more control. 6 | # We've included some commented out config examples here. 7 | # Just uncomment any of them to get that config option. 8 | # 9 | # For full config options, check the docs: 10 | # docs.serverless.com 11 | # 12 | # Happy Coding! 13 | 14 | service: example-aws-lambda-serverless 15 | 16 | # app and org for use with dashboard.serverless.com 17 | app: probot-hello-world-example 18 | org: probot 19 | 20 | frameworkVersion: "2" 21 | useDotenv: true 22 | 23 | provider: 24 | name: aws 25 | runtime: nodejs12.x 26 | lambdaHashingVersion: 20201221 27 | environment: 28 | APP_ID: ${param:APP_ID} 29 | PRIVATE_KEY: ${param:PRIVATE_KEY} 30 | WEBHOOK_SECRET: ${param:WEBHOOK_SECRET} 31 | NODE_ENV: production 32 | LOG_LEVEL: debug 33 | 34 | functions: 35 | webhooks: 36 | handler: handler.webhooks 37 | events: 38 | - httpApi: 39 | path: /api/github/webhooks 40 | method: post 41 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Mocha", 11 | "runtimeExecutable": "nyc", 12 | "runtimeArgs": [ 13 | "--reporter=lcov", 14 | "--reporter=cobertura", 15 | "--reporter=text-summary", 16 | "mocha", 17 | "--timeout", 18 | "999999", 19 | "--colors", 20 | "${workspaceFolder}" 21 | ], 22 | "console": "integratedTerminal", 23 | "cwd": "${workspaceRoot}/", 24 | }, 25 | { 26 | "type": "node", 27 | "request": "launch", 28 | "name": "Launch Probot", 29 | "runtimeExecutable": "probot", 30 | "runtimeArgs": ["run", "./app.js"], 31 | "console": "integratedTerminal", 32 | "cwd": "${workspaceRoot}/", 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const { suite } = require("uvu"); 2 | const assert = require("uvu/assert"); 3 | 4 | const nock = require("nock"); 5 | nock.disableNetConnect(); 6 | 7 | const { 8 | Probot, 9 | ProbotOctokit, 10 | } = require("@probot/adapter-aws-lambda-serverless"); 11 | 12 | const app = require("./app"); 13 | 14 | /** @type {import('probot').Probot */ 15 | let probot; 16 | const test = suite("app"); 17 | test.before.each(() => { 18 | probot = new Probot({ 19 | // simple authentication as alternative to appId/privateKey 20 | githubToken: "test", 21 | // disable logs 22 | logLevel: "warn", 23 | // disable request throttling and retries 24 | Octokit: ProbotOctokit.defaults({ 25 | throttle: { enabled: false }, 26 | retry: { enabled: false }, 27 | }), 28 | }); 29 | probot.load(app); 30 | }); 31 | 32 | test("recieves issues.opened event", async function () { 33 | const mock = nock("https://api.github.com") 34 | // create new check run 35 | .post( 36 | "/repos/probot/example-aws-lambda-serverless/issues/1/comments", 37 | (requestBody) => { 38 | assert.equal(requestBody, { body: "Hello, World!" }); 39 | 40 | return true; 41 | } 42 | ) 43 | .reply(201, {}); 44 | 45 | await probot.receive({ 46 | name: "issues", 47 | id: "1", 48 | payload: { 49 | action: "opened", 50 | repository: { 51 | owner: { 52 | login: "probot", 53 | }, 54 | name: "example-aws-lambda-serverless", 55 | }, 56 | issue: { 57 | number: 1, 58 | }, 59 | }, 60 | }); 61 | 62 | assert.equal(mock.activeMocks(), []); 63 | }); 64 | 65 | test.run(); 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Probot & AWS Lambda example 2 | 3 | This repository is an example of how to deploy the "Hello, World" of probot apps to [AWS Lambda](https://aws.amazon.com/lambda/) using [serverless](https://www.serverless.com/). 4 | 5 | ## Local setup 6 | 7 | Install dependencies 8 | 9 | ``` 10 | npm install 11 | ``` 12 | 13 | Start the server 14 | 15 | ``` 16 | npm start 17 | ``` 18 | 19 | Follow the instructions to register a new GitHub app. 20 | 21 | ## Deployment 22 | 23 | In order to deploy the app from you local environment, follow the [Serverless user guide for AWS](https://www.serverless.com/framework/docs/providers/aws/guide/quick-start/). 24 | 25 | If you use this example as a template, make sure to update [`serverless.yml`](serverless.yml) and set new values for 26 | 27 | - `service` 28 | - `app` 29 | - `org` 30 | 31 | Make sure to create the following parameters on [https://app.serverless.com](https://app.serverless.com): 32 | 33 | - `APP_ID` 34 | - `PRIVATE_KEY` 35 | - `WEBHOOK_SECRET` 36 | 37 | For continuous deployment via GitHub action, copy [this repository's deploy workflow](.github/workflows/deploy.yml) and create the following secrets: 38 | 39 | 1. `SERVERLESS_ACCESS_KEY` - You can create a Serverless access key at `https://app.serverless.com//settings/accessKeys` 40 | 2. `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` - you will likely find your AWS credentials in `~/.aws/credentials` 41 | 42 | ### Debug via unit tests 43 | 1. Intall nyc and mocha: `npm install -g nyc mocha` 44 | 1. From the VSCode `RUN AND DEBUG` menu select `Mocha` and click the green arrow to start debugging. 45 | 46 | ### Debug by launching probot locally and sending it a payload 47 | 48 | 1. Point your GitHub app to your local using something like smee.io 49 | 1. Copy .env-sample to .env and populate with values specific for your GitHub app. For the `PRIVATE_KEY` replace newlines with `\\n` to make the string value a single line. 50 | 1. From the VSCode `RUN AND DEBUG` menu select `Launch Probot` and click the green arrow to start debugging. 51 | 52 | ## License 53 | 54 | [ISC](LICENSE) 55 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at opensource+probot@github.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | --------------------------------------------------------------------------------