├── _config.yml ├── .github ├── FUNDING.yml ├── dependabot.yml ├── workflows │ ├── npm-test.yaml │ └── codeql-analysis.yaml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── assets ├── screenshot.png └── issuelabeler-logo.png ├── .gitignore ├── src ├── handler.js ├── static.js └── app.js ├── .editorconfig ├── test ├── fixtures │ ├── custom_config.yml │ ├── payload.json │ ├── event_opened.json │ ├── event_opened_custom.json │ └── event_edited.json └── index.test.js ├── Makefile ├── docs └── deploy.md ├── .devcontainer └── devcontainer.json ├── LICENSE ├── package.json ├── CONTRIBUTING.md ├── README.md ├── serverless.yml ├── CODE_OF_CONDUCT.md └── CHANGELOG.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://www.paypal.me/riyadhalnur 2 | -------------------------------------------------------------------------------- /assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riyadhalnur/issuelabeler/HEAD/assets/screenshot.png -------------------------------------------------------------------------------- /assets/issuelabeler-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riyadhalnur/issuelabeler/HEAD/assets/issuelabeler-logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless 7 | 8 | # Env files 9 | .env 10 | .envrc 11 | env.yml 12 | 13 | # Private key files 14 | *.pem 15 | 16 | # Zip files 17 | *.zip 18 | -------------------------------------------------------------------------------- /src/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | createLambdaFunction, 5 | createProbot, 6 | } = require('@probot/adapter-aws-lambda-serverless'); 7 | const app = require('./app'); 8 | 9 | module.exports = { 10 | bot: createLambdaFunction(app, { probot: createProbot() }), 11 | }; 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [{Makefile,**.mk}] 15 | indent_style = tab 16 | -------------------------------------------------------------------------------- /src/static.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.catch = async (event, context) => { 4 | try { 5 | context.callbackWaitsForEmptyEventLoop = false; 6 | return { 7 | statusCode: 200, 8 | body: 'PONG', 9 | }; 10 | } catch (error) { 11 | return { 12 | statusCode: 500, 13 | body: error, 14 | }; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/fixtures/custom_config.yml: -------------------------------------------------------------------------------- 1 | custom: 2 | - location: title 3 | keywords: 4 | - "hi" 5 | labels: 6 | - hey 7 | - h 8 | - location: body 9 | keywords: 10 | - "hey" 11 | labels: 12 | - feature:new 13 | - hey 14 | - location: body 15 | keywords: 16 | - "hi" 17 | labels: 18 | - h 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default modules clean key 2 | 3 | default: modules key 4 | 5 | modules: 6 | mkdir -p nodejs 7 | cp -r node_modules nodejs/ 8 | cp package.json nodejs/ 9 | cp package-lock.json nodejs/ 10 | zip -r modules.zip nodejs 11 | rm -rf nodejs/ 12 | 13 | key: 14 | zip key.zip issuelabeler-private-key.pem 15 | 16 | clean: 17 | rm -rf modules.zip 18 | rm -rf key.zip 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | -------------------------------------------------------------------------------- /.github/workflows/npm-test.yaml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | push: 8 | branches: 9 | - master 10 | release: 11 | types: [created] 12 | 13 | jobs: 14 | test: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | node_version: ['18', '20', '22'] 19 | os: [ubuntu-latest, macOS-latest] 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: actions/setup-node@v3 23 | with: 24 | node-version: ${{ matrix.node_version }} 25 | - run: npm i 26 | - run: npm test 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /docs/deploy.md: -------------------------------------------------------------------------------- 1 | # Deploying 2 | 3 | ## Requirements: 4 | 1. [NodeJS >= 10.x](https://nodejs.org) 5 | 2. [Serverless](https://serverless.com) 6 | 7 | ## Developing: 8 | 1. Run `npm install` to install dependencies 9 | 2. Create a `env.yml` file in the root 10 | 3. In your `env.yml` file, 11 | ```bash 12 | secrets: 13 | APP_ID: 14 | WEBHOOK_SECRET: 15 | PRIVATE_KEY: "/opt/.pem" 16 | ``` 17 | 4. Deploy using `sls deploy -v` 18 | 19 | If you would like to run your own instance of this app, see the [docs for deployment](https://probot.github.io/docs/serverless-deployment/). 20 | 21 | This app requires these **Permissions & events** for the GitHub App: 22 | 23 | - Issues - **Read & Write** 24 | - [x] Check the box for **Issue comment** events 25 | - [x] Check the box for **Issues** events 26 | - Single File - **Read-only** 27 | - Path: `.github/labeler.yml` 28 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node 3 | { 4 | "name": "Node.js", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/javascript-node:1-22-bookworm", 7 | 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | // "features": {}, 10 | 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [], 13 | 14 | // Use 'postCreateCommand' to run commands after the container is created. 15 | "postCreateCommand": "npm install", 16 | 17 | // Configure tool-specific properties. 18 | // "customizations": {}, 19 | 20 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 21 | // "remoteUser": "root" 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Riyadh Al Nur 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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "issuelabeler", 3 | "version": "2.2.0", 4 | "description": "A GitHub bot to label issues automatically based on title and body against list of defined labels", 5 | "author": "Riyadh Al Nur ", 6 | "license": "MIT", 7 | "repository": "https://github.com/riyadhalnur/issuelabeler.git", 8 | "main": "handler.js", 9 | "directories": { 10 | "doc": "docs", 11 | "test": "test" 12 | }, 13 | "scripts": { 14 | "lint": "prettier --single-quote --check '*.{js,md,json}' 'src/**/*.js' 'test/**/*.{js,json}' '.github/**/*.yml'", 15 | "lint:fix": "prettier --single-quote --write '*.{js,md,json}' 'src/**/*.js' 'test/**/*.{js,json}' '.github/**/*.yml'", 16 | "test": "jest" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/riyadhalnur/issuelabeler/issues" 20 | }, 21 | "homepage": "https://riyadhalnur.github.io/issuelabeler/", 22 | "dependencies": { 23 | "@probot/adapter-aws-lambda-serverless": "^4.0.3", 24 | "serverless-plugin-scripts": "1.0.2" 25 | }, 26 | "devDependencies": { 27 | "jest": "^29.7.0", 28 | "nock": "^14.0.1", 29 | "prettier": "^3.5.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | [fork]: /fork 4 | [pr]: /compare 5 | [style]: https://standardjs.com/ 6 | [code-of-conduct]: CODE_OF_CONDUCT.md 7 | 8 | Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. 9 | 10 | Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. 11 | 12 | ## Submitting a pull request 13 | 14 | 1. [Fork][fork] and clone the repository 15 | 1. Configure and install the dependencies: `npm install` 16 | 1. Make sure the tests pass on your machine: `npm test`, note: these tests also apply the linter, so no need to lint seperately 17 | 1. Create a new branch: `git checkout -b my-branch-name` 18 | 1. Make your change, add tests, and make sure the tests still pass 19 | 1. Push to your fork and [submit a pull request][pr] 20 | 1. Pat your self on the back and wait for your pull request to be reviewed and merged. 21 | 22 | Here are a few things you can do that will increase the likelihood of your pull request being accepted: 23 | 24 | - Follow the [style guide][style] which is using standard. Any linting errors should be shown when running `npm test` 25 | - Write and update tests. 26 | - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. 27 | - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 28 | 29 | Work in Progress pull request are also welcome to get feedback early on, or if there is something blocked you. 30 | 31 | ## Resources 32 | 33 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) 34 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) 35 | - [GitHub Help](https://help.github.com) 36 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const eventTypes = ['issues.opened', 'issues.edited']; 4 | const loc_body = 'body'; 5 | const loc_title = 'title'; 6 | 7 | const addCustomLabels = (issue, config) => { 8 | let labels = []; 9 | 10 | config.forEach((custCfg) => { 11 | if ( 12 | custCfg.location === loc_body && 13 | issue.body.toLowerCase().includes(custCfg.keywords.join(',')) 14 | ) { 15 | labels.push(...custCfg.labels); 16 | } 17 | 18 | if ( 19 | custCfg.location === loc_title && 20 | issue.title.toLowerCase().includes(custCfg.keywords.join(',')) 21 | ) { 22 | labels.push(...custCfg.labels); 23 | } 24 | }); 25 | 26 | return labels; 27 | }; 28 | 29 | module.exports = async (app) => { 30 | app.on(eventTypes, async (context) => { 31 | const config = await context.config('labeler.yml', { 32 | numLabels: 100, 33 | excludeLabels: [], 34 | }); 35 | const labels = await context.octokit.issues.listLabelsForRepo( 36 | context.issue({ per_page: config.numLabels }) 37 | ); 38 | const issue = await context.octokit.issues.get( 39 | context.issue({ issue_number: context.payload.issue.number }) 40 | ); 41 | 42 | let labelList = []; 43 | let labelsToAdd = []; 44 | 45 | if (config.custom) { 46 | labelsToAdd = addCustomLabels(issue.data, config.custom); 47 | } else { 48 | labels.data.map((label) => labelList.push(label.name)); 49 | labelList 50 | .filter((label) => !config.excludeLabels.includes(label)) 51 | .map((label) => 52 | issue.data.title.toLowerCase().includes(label.toLowerCase()) || 53 | issue.data.body.toLowerCase().includes(label.toLowerCase()) 54 | ? labelsToAdd.push(label) 55 | : null 56 | ); 57 | } 58 | 59 | return context.octokit.issues.addLabels( 60 | context.issue({ 61 | issue_number: context.payload.issue.number, 62 | labels: labelsToAdd, 63 | }) 64 | ); 65 | }); 66 | }; 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # issuelabeler 2 | 3 | 4 | 5 | ![Node.js Package](https://github.com/riyadhalnur/issuelabeler/workflows/Node.js%20Package/badge.svg) [![Known Vulnerabilities](https://snyk.io/test/github/riyadhalnur/issuelabeler/badge.svg?targetFile=package.json)](https://snyk.io/test/github/riyadhalnur/issuelabeler?targetFile=package.json) 6 | 7 | > A GitHub bot to label issues automatically based on title and body against list of defined labels. Built with [probot](https://github.com/probot/probot). 8 | 9 | ![Screenshot](assets/screenshot.png) 10 | 11 | ### Installation 12 | 13 | After installation, create `.github/labeler.yml` in the default branch to enable it: 14 | 15 | ```yml 16 | # Number of labels to fetch (optional). Defaults to 100 17 | numLabels: 40 18 | # These labels will not be used even if the issue contains them (optional). 19 | # Pass a blank array if no labels are to be excluded. 20 | # excludeLabels: [] 21 | excludeLabels: 22 | - pinned 23 | # custom configuration to override default behaviour 24 | # control explicitly what gets added and when 25 | custom: 26 | - location: title 27 | keywords: 28 | - 'hi' 29 | labels: 30 | - hey 31 | - h 32 | - location: body 33 | keywords: 34 | - 'hey' 35 | labels: 36 | - feature:new 37 | - hey 38 | - location: body 39 | keywords: 40 | - 'hi' 41 | labels: 42 | - h 43 | ``` 44 | 45 | ### Contributing 46 | 47 | Read the [CONTRIBUTING](CONTRIBUTING.md) guide for information. 48 | 49 | ### License 50 | 51 | Licensed under MIT. See [LICENSE](LICENSE) for more information. 52 | 53 | Logo built using [Streamline Emoji](http://emoji.streamlineicons.com) by [@webalys](https://twitter.com/webalys) under the Creative Common Attribution licence. 54 | 55 | ### Issues 56 | 57 | Report a bug in [issues](https://github.com/riyadhalnur/issuelabeler/issues). 58 | 59 | Made with love in Kuala Lumpur, Malaysia by [Riyadh Al Nur](https://verticalaxisbd.com) 60 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | service: issuelabler-bot 2 | 3 | frameworkVersion: "2" 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs22.x 8 | lambdaHashingVersion: 20201221 9 | httpApi: 10 | cors: 11 | allowedOrigins: 12 | - '*' 13 | allowedHeaders: 14 | - '*' 15 | allowedMethods: 16 | - get 17 | - options 18 | - post 19 | allowCredentials: false 20 | 21 | stage: ${opt:stage, 'development'} 22 | region: ${opt:region, 'ap-southeast-1'} 23 | 24 | environment: 25 | NODE_ENV: ${opt.stage, 'development'} 26 | APP_ID: ${file(env.yml):secrets.APP_ID, ''} 27 | WEBHOOK_SECRET: ${file(env.yml):secrets.WEBHOOK_SECRET, ''} 28 | PRIVATE_KEY_PATH: ${file(env.yml):secrets.PRIVATE_KEY_PATH, ''} 29 | DISABLE_STATS: true 30 | LOG_LEVEL: error 31 | 32 | plugins: 33 | - serverless-plugin-scripts 34 | 35 | custom: 36 | scripts: 37 | hooks: 38 | 'package:initialize': make 39 | 'deploy:finalize': make clean 40 | 41 | package: 42 | individually: true 43 | include: 44 | - 'src/**' 45 | - 'package.json' 46 | - 'package-lock.json' 47 | exclude: 48 | - '**/*' 49 | 50 | layers: 51 | modulesLib: 52 | package: 53 | artifact: modules.zip 54 | compatibleRuntimes: 55 | - nodejs22.x 56 | privateKey: 57 | package: 58 | artifact: key.zip 59 | 60 | functions: 61 | labelerbot: 62 | handler: 'src/handler.bot' 63 | name: issuelabeler-bot-${self:provider.stage} 64 | memorySize: 256 65 | timeout: 15 66 | layers: 67 | - { Ref: ModulesLibLambdaLayer } 68 | - { Ref: PrivateKeyLambdaLayer } 69 | events: 70 | - httpApi: 71 | path: /api/webhooks/github 72 | method: post 73 | catch: 74 | handler: 'src/static.catch' 75 | name: issuelabeler-bot-catch-${self:provider.stage} 76 | memorySize: 128 77 | timeout: 5 78 | layers: 79 | - { Ref: ModulesLibLambdaLayer } 80 | events: 81 | - httpApi: 82 | path: /ping 83 | method: get 84 | -------------------------------------------------------------------------------- /test/fixtures/payload.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://api.github.com/repos/issuebot/test/issues/2", 3 | "repository_url": "https://api.github.com/repos/issuebot/test", 4 | "labels_url": "https://api.github.com/repos/issuebot/test/issues/2/labels{/name}", 5 | "comments_url": "https://api.github.com/repos/issuebot/test/issues/2/comments", 6 | "events_url": "https://api.github.com/repos/issuebot/test/issues/2/events", 7 | "html_url": "https://github.com/issuebot/test/issues/2", 8 | "id": 3114, 9 | "number": 2, 10 | "title": "Test", 11 | "user": { 12 | "login": "issuebot", 13 | "id": 3457, 14 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 15 | "gravatar_id": "", 16 | "url": "https://api.github.com/users/issuebot", 17 | "html_url": "https://github.com/issuebot", 18 | "followers_url": "https://api.github.com/users/issuebot/followers", 19 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 20 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 21 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 22 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 23 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 24 | "repos_url": "https://api.github.com/users/issuebot/repos", 25 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 26 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 27 | "type": "User", 28 | "site_admin": false 29 | }, 30 | "labels": [], 31 | "state": "open", 32 | "locked": false, 33 | "assignee": null, 34 | "assignees": [], 35 | "milestone": null, 36 | "comments": 0, 37 | "created_at": "2018-04-05T06:09:02Z", 38 | "updated_at": "2018-04-05T06:59:48Z", 39 | "closed_at": null, 40 | "author_association": "OWNER", 41 | "body": "hey\nA-Feature", 42 | "closed_by": null, 43 | "reactions": { 44 | "url": "https://api.github.com/repos/issuebot/test/issues/2/reactions", 45 | "total_count": 0, 46 | "+1": 0, 47 | "-1": 0, 48 | "laugh": 0, 49 | "hooray": 0, 50 | "confused": 0, 51 | "heart": 0 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yaml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master, gh-pages ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '34 15 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'javascript' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /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 riyadhalnur@verticalaxisbd.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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### Changelog 2 | 3 | All notable changes to this project will be documented in this file. Dates are displayed in UTC. 4 | 5 | Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). 6 | 7 | #### [v2.2.0](https://github.com/riyadhalnur/issuelabeler/compare/v2.1.0...v2.2.0) 8 | 9 | > 15 February 2021 10 | 11 | - Bot handler and infra update [`#36`](https://github.com/riyadhalnur/issuelabeler/pull/36) 12 | - Bump ini from 1.3.5 to 1.3.7 [`#35`](https://github.com/riyadhalnur/issuelabeler/pull/35) 13 | - Bump node-fetch from 2.6.0 to 2.6.1 [`#34`](https://github.com/riyadhalnur/issuelabeler/pull/34) 14 | - Bump lodash from 4.17.15 to 4.17.19 [`#32`](https://github.com/riyadhalnur/issuelabeler/pull/32) 15 | - ADDED: new deps [`02039e0`](https://github.com/riyadhalnur/issuelabeler/commit/02039e09cf929b707342f5394b4db53e8e6641c0) 16 | - UPDATED: jest to latest version [`aaf560f`](https://github.com/riyadhalnur/issuelabeler/commit/aaf560f970c18d9f1595ac95641ff2bdbb3ef324) 17 | - ADDED: test cases for custom config [`088fdfe`](https://github.com/riyadhalnur/issuelabeler/commit/088fdfe479caeeec69e2d292c29a6def5c7016a2) 18 | 19 | #### [v2.1.0](https://github.com/riyadhalnur/issuelabeler/compare/v2.0.2...v2.1.0) 20 | 21 | > 7 June 2020 22 | 23 | - Fixes uppercase labels not being applied [`#28`](https://github.com/riyadhalnur/issuelabeler/issues/28) 24 | - [CHORE] Update deps [`253ff16`](https://github.com/riyadhalnur/issuelabeler/commit/253ff16520977c20e307c4769218bfbaabc43fce) 25 | - Add support for labeling issues on edit [`6dbafd4`](https://github.com/riyadhalnur/issuelabeler/commit/6dbafd49c3675960a13152041f225e3189c1ea6c) 26 | - Updated CHANGELOG [`440be4e`](https://github.com/riyadhalnur/issuelabeler/commit/440be4e233211deb48ab3a6b27f05779e48d2f49) 27 | 28 | #### [v2.0.2](https://github.com/riyadhalnur/issuelabeler/compare/v2.0.0...v2.0.2) 29 | 30 | > 8 April 2020 31 | 32 | - [CHORE] Update deps [`fa0fa70`](https://github.com/riyadhalnur/issuelabeler/commit/fa0fa701e9906e60047d56f91251adeb9ac0aaad) 33 | - CHORE: update deps [`1f6bb94`](https://github.com/riyadhalnur/issuelabeler/commit/1f6bb94fe6f491ef2a144476aacbcc5bfccfce6b) 34 | - [CHORE] Update security vurnerabilities [`860ee86`](https://github.com/riyadhalnur/issuelabeler/commit/860ee8683c4fb24c29809bcaba07203478d5c406) 35 | 36 | ### [v2.0.0](https://github.com/riyadhalnur/issuelabeler/compare/v1.0.1...v2.0.0) 37 | 38 | > 22 July 2019 39 | 40 | - Add news deps [`957f088`](https://github.com/riyadhalnur/issuelabeler/commit/957f088cf92f65ce99b1c75b3f3214334497208d) 41 | - Add jest as dep and update fixtures [`d642f11`](https://github.com/riyadhalnur/issuelabeler/commit/d642f11cc5735f053da737e8bc9d3c381d209a3e) 42 | - Add serverless config [`06c7ddd`](https://github.com/riyadhalnur/issuelabeler/commit/06c7ddd4f17f23f8c0840317b4bf1708f049ad53) 43 | 44 | #### [v1.0.1](https://github.com/riyadhalnur/issuelabeler/compare/v1.0.0...v1.0.1) 45 | 46 | > 1 June 2019 47 | 48 | - Update nodemon to the latest version 🚀 [`#12`](https://github.com/riyadhalnur/issuelabeler/pull/12) 49 | - Update nodemon to the latest version 🚀 [`#10`](https://github.com/riyadhalnur/issuelabeler/pull/10) 50 | - Update nodemon to the latest version 🚀 [`#9`](https://github.com/riyadhalnur/issuelabeler/pull/9) 51 | - Update nodemon to the latest version 🚀 [`#5`](https://github.com/riyadhalnur/issuelabeler/pull/5) 52 | - Update smee-client to the latest version 🚀 [`#6`](https://github.com/riyadhalnur/issuelabeler/pull/6) 53 | - Update dependencies to enable Greenkeeper 🌴 [`#2`](https://github.com/riyadhalnur/issuelabeler/pull/2) 54 | - Chore audit deps [`190ae0a`](https://github.com/riyadhalnur/issuelabeler/commit/190ae0af6884446b738fce83d1a990f4fb2cd757) 55 | - Add CHANGELOG [`037e233`](https://github.com/riyadhalnur/issuelabeler/commit/037e2333ec1610bb9930529fbceab7ed41d4c760) 56 | - Reposition greenkeep badge and fix link to issues in README [`e8d3760`](https://github.com/riyadhalnur/issuelabeler/commit/e8d3760cbe4f25c8ecdffb4182d69ae70d709928) 57 | 58 | #### v1.0.0 59 | 60 | > 6 April 2018 61 | 62 | - Package deps [`c134064`](https://github.com/riyadhalnur/issuelabeler/commit/c13406484079927922314fe451ed006ef77b8a33) 63 | - Add unit tests [`e7d4eab`](https://github.com/riyadhalnur/issuelabeler/commit/e7d4eab7edd43a3229e2261267d75ebd589e40f0) 64 | - Initial commit [`a788e17`](https://github.com/riyadhalnur/issuelabeler/commit/a788e1777560c7db6b944a3abd22b3b13fcaf07b) 65 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | const { 2 | Probot, 3 | ProbotOctokit, 4 | } = require('@probot/adapter-aws-lambda-serverless'); 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const nock = require('nock'); 8 | nock.disableNetConnect(); 9 | 10 | // const handler = require('../src/handler'); 11 | const app = require('../src/app'); 12 | 13 | const event_opened = require('./fixtures/event_opened'); 14 | const event_opened_custom = require('./fixtures/event_opened_custom'); 15 | const event_edited = require('./fixtures/event_edited'); 16 | const payload = require('./fixtures/payload'); 17 | 18 | describe('issuelabeler', () => { 19 | let probot; 20 | 21 | beforeAll(() => { 22 | probot = new Probot({ 23 | // simple authentication as alternative to appId/privateKey 24 | githubToken: 'test', 25 | appId: '1234', 26 | privateKey: 'test', 27 | // disable logs 28 | logLevel: 'warn', 29 | // disable request throttling and retries 30 | Octokit: ProbotOctokit.defaults({ 31 | throttle: { enabled: false }, 32 | retry: { enabled: false }, 33 | }), 34 | }); 35 | probot.load(app); 36 | }); 37 | 38 | test('labels are applied to an issue when opened excluding 1 label', async () => { 39 | const mock = nock('https://api.github.com') 40 | .get('/repos/issuebot/test/contents/.github%2Flabeler.yml') 41 | .reply(200, Buffer.from(`excludeLabels:\n - hey`).toString()) 42 | .get('/repos/issuebot/test/labels?issue_number=2&per_page=100') 43 | .reply(200, [ 44 | { 45 | id: 889466157, 46 | url: 'https://api.octokit.com/repos/issuebot/test/labels/hey', 47 | name: 'hey', 48 | color: 'f5fc92', 49 | default: false, 50 | }, 51 | { 52 | id: 889466158, 53 | url: 'https://api.octokit.com/repos/issuebot/test/labels/test', 54 | name: 'test', 55 | color: 'f5fc93', 56 | default: false, 57 | }, 58 | { 59 | id: 889466159, 60 | url: 'https://api.octokit.com/repos/issuebot/test/labels/a-feature', 61 | name: 'A-Feature', 62 | color: 'f5fc93', 63 | default: false, 64 | }, 65 | ]) 66 | .get('/repos/issuebot/test/issues/2') 67 | .reply(200, payload) 68 | .post('/repos/issuebot/test/issues/2/labels', (requestBody) => { 69 | expect(requestBody).toEqual({"labels": ["test", "A-Feature"]}); 70 | return true; 71 | }) 72 | .reply(200, []); 73 | 74 | await probot.receive(event_opened); 75 | expect(mock.activeMocks()).toEqual([]); 76 | }); 77 | 78 | test('labels are applied to an issue when opened', async () => { 79 | const mock = nock('https://api.github.com') 80 | .get('/repos/issuebot/test/contents/.github%2Flabeler.yml') 81 | .reply(200, Buffer.from(``).toString()) 82 | .get('/repos/issuebot/test/labels?issue_number=2&per_page=100') 83 | .reply(200, [ 84 | { 85 | id: 889466157, 86 | url: 'https://api.octokit.com/repos/issuebot/test/labels/hey', 87 | name: 'hey', 88 | color: 'f5fc92', 89 | default: false, 90 | }, 91 | { 92 | id: 889466158, 93 | url: 'https://api.octokit.com/repos/issuebot/test/labels/test', 94 | name: 'test', 95 | color: 'f5fc93', 96 | default: false, 97 | }, 98 | { 99 | id: 889466159, 100 | url: 'https://api.octokit.com/repos/issuebot/test/labels/a-feature', 101 | name: 'A-Feature', 102 | color: 'f5fc93', 103 | default: false, 104 | }, 105 | ]) 106 | .get('/repos/issuebot/test/issues/2') 107 | .reply(200, payload) 108 | .post('/repos/issuebot/test/issues/2/labels', (requestBody) => { 109 | expect(requestBody).toEqual({"labels": ["hey", "test", "A-Feature"]}); 110 | return true; 111 | }) 112 | .reply(200, []); 113 | 114 | await probot.receive(event_opened); 115 | expect(mock.activeMocks()).toEqual([]); 116 | }); 117 | 118 | test('labels are applied to an issue when edited excluding 1 label', async () => { 119 | const mock = nock('https://api.github.com') 120 | .get('/repos/issuebot/test/contents/.github%2Flabeler.yml') 121 | .reply(200, Buffer.from(`excludeLabels:\n - hey`).toString()) 122 | .get('/repos/issuebot/test/labels?issue_number=2&per_page=100') 123 | .reply(200, [ 124 | { 125 | id: 889466157, 126 | url: 'https://api.octokit.com/repos/issuebot/test/labels/hey', 127 | name: 'hey', 128 | color: 'f5fc92', 129 | default: false, 130 | }, 131 | { 132 | id: 889466158, 133 | url: 'https://api.octokit.com/repos/issuebot/test/labels/test', 134 | name: 'test', 135 | color: 'f5fc93', 136 | default: false, 137 | }, 138 | { 139 | id: 889466159, 140 | url: 'https://api.octokit.com/repos/issuebot/test/labels/a-feature', 141 | name: 'A-Feature', 142 | color: 'f5fc93', 143 | default: false, 144 | }, 145 | ]) 146 | .get('/repos/issuebot/test/issues/2') 147 | .reply(200, payload) 148 | .post('/repos/issuebot/test/issues/2/labels', (requestBody) => { 149 | expect(requestBody).toEqual({"labels": ["test", "A-Feature"]}); 150 | return true; 151 | }) 152 | .reply(200, []); 153 | 154 | await probot.receive(event_edited); 155 | expect(mock.activeMocks()).toEqual([]); 156 | }); 157 | 158 | test('custom configuration', async () => { 159 | const pathToConfig = path.resolve( 160 | __dirname, 161 | '..', 162 | 'test', 163 | 'fixtures', 164 | 'custom_config.yml' 165 | ); 166 | const mock = nock('https://api.github.com') 167 | .get('/repos/issuebot/test/contents/.github%2Flabeler.yml') 168 | .reply(200, Buffer.from(fs.readFileSync(pathToConfig, 'utf8')).toString()) 169 | .get('/repos/issuebot/test/labels?issue_number=2&per_page=100') 170 | .reply(200, [ 171 | { 172 | id: 889466157, 173 | url: 'https://api.octokit.com/repos/issuebot/test/labels/hey', 174 | name: 'hey', 175 | color: 'f5fc92', 176 | default: false, 177 | }, 178 | { 179 | id: 889466158, 180 | url: 'https://api.octokit.com/repos/issuebot/test/labels/test', 181 | name: 'test', 182 | color: 'f5fc93', 183 | default: false, 184 | }, 185 | { 186 | id: 889466159, 187 | url: 'https://api.octokit.com/repos/issuebot/test/labels/a-feature', 188 | name: 'A-Feature', 189 | color: 'f5fc93', 190 | default: false, 191 | }, 192 | { 193 | id: 889466160, 194 | url: 'https://api.octokit.com/repos/issuebot/test/labels/feature:new', 195 | name: 'feautre:new', 196 | color: 'f5fc93', 197 | default: false, 198 | }, 199 | ]) 200 | .get('/repos/issuebot/test/issues/2') 201 | .reply(200, payload) 202 | .post('/repos/issuebot/test/issues/2/labels', (requestBody) => { 203 | expect(requestBody).toEqual({"labels": ["feature:new", "hey"]}); 204 | return true; 205 | }) 206 | .reply(200, []); 207 | 208 | await probot.receive(event_opened_custom); 209 | expect(mock.activeMocks()).toEqual([]); 210 | }); 211 | }); 212 | -------------------------------------------------------------------------------- /test/fixtures/event_opened.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "issues", 3 | "number": 2, 4 | "payload": { 5 | "action": "opened", 6 | "issue": { 7 | "url": "https://api.github.com/repos/issuebot/test/issues/2", 8 | "repository_url": "https://api.github.com/repos/issuebot/test", 9 | "labels_url": "https://api.github.com/repos/issuebot/test/issues/2/labels{/name}", 10 | "comments_url": "https://api.github.com/repos/issuebot/test/issues/2/comments", 11 | "events_url": "https://api.github.com/repos/issuebot/test/issues/2/events", 12 | "html_url": "https://github.com/issuebot/test/issues/2", 13 | "id": 3114, 14 | "number": 2, 15 | "title": "Test", 16 | "user": { 17 | "login": "issuebot", 18 | "id": 3457, 19 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 20 | "gravatar_id": "", 21 | "url": "https://api.github.com/users/issuebot", 22 | "html_url": "https://github.com/issuebot", 23 | "followers_url": "https://api.github.com/users/issuebot/followers", 24 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 25 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 26 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 27 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 28 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 29 | "repos_url": "https://api.github.com/users/issuebot/repos", 30 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 31 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 32 | "type": "User", 33 | "site_admin": false 34 | }, 35 | "labels": [], 36 | "state": "open", 37 | "locked": false, 38 | "assignee": null, 39 | "assignees": [], 40 | "milestone": null, 41 | "comments": 0, 42 | "created_at": "2018-04-05T06:09:02Z", 43 | "updated_at": "2018-04-05T06:09:02Z", 44 | "closed_at": null, 45 | "author_association": "OWNER", 46 | "body": "hey\nA-Feature" 47 | }, 48 | "repository": { 49 | "id": 1279, 50 | "name": "test", 51 | "full_name": "issuebot/test", 52 | "owner": { 53 | "login": "issuebot", 54 | "id": 3457, 55 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 56 | "gravatar_id": "", 57 | "url": "https://api.github.com/users/issuebot", 58 | "html_url": "https://github.com/issuebot", 59 | "followers_url": "https://api.github.com/users/issuebot/followers", 60 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 61 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 62 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 63 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 64 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 65 | "repos_url": "https://api.github.com/users/issuebot/repos", 66 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 67 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 68 | "type": "User", 69 | "site_admin": false 70 | }, 71 | "private": false, 72 | "html_url": "https://github.com/issuebot/test", 73 | "description": null, 74 | "fork": false, 75 | "url": "https://api.github.com/repos/issuebot/test", 76 | "forks_url": "https://api.github.com/repos/issuebot/test/forks", 77 | "keys_url": "https://api.github.com/repos/issuebot/test/keys{/key_id}", 78 | "collaborators_url": "https://api.github.com/repos/issuebot/test/collaborators{/collaborator}", 79 | "teams_url": "https://api.github.com/repos/issuebot/test/teams", 80 | "hooks_url": "https://api.github.com/repos/issuebot/test/hooks", 81 | "issue_events_url": "https://api.github.com/repos/issuebot/test/issues/events{/number}", 82 | "events_url": "https://api.github.com/repos/issuebot/test/events", 83 | "assignees_url": "https://api.github.com/repos/issuebot/test/assignees{/user}", 84 | "branches_url": "https://api.github.com/repos/issuebot/test/branches{/branch}", 85 | "tags_url": "https://api.github.com/repos/issuebot/test/tags", 86 | "blobs_url": "https://api.github.com/repos/issuebot/test/git/blobs{/sha}", 87 | "git_tags_url": "https://api.github.com/repos/issuebot/test/git/tags{/sha}", 88 | "git_refs_url": "https://api.github.com/repos/issuebot/test/git/refs{/sha}", 89 | "trees_url": "https://api.github.com/repos/issuebot/test/git/trees{/sha}", 90 | "statuses_url": "https://api.github.com/repos/issuebot/test/statuses/{sha}", 91 | "languages_url": "https://api.github.com/repos/issuebot/test/languages", 92 | "stargazers_url": "https://api.github.com/repos/issuebot/test/stargazers", 93 | "contributors_url": "https://api.github.com/repos/issuebot/test/contributors", 94 | "subscribers_url": "https://api.github.com/repos/issuebot/test/subscribers", 95 | "subscription_url": "https://api.github.com/repos/issuebot/test/subscription", 96 | "commits_url": "https://api.github.com/repos/issuebot/test/commits{/sha}", 97 | "git_commits_url": "https://api.github.com/repos/issuebot/test/git/commits{/sha}", 98 | "comments_url": "https://api.github.com/repos/issuebot/test/comments{/number}", 99 | "issue_comment_url": "https://api.github.com/repos/issuebot/test/issues/comments{/number}", 100 | "contents_url": "https://api.github.com/repos/issuebot/test/contents/{+path}", 101 | "compare_url": "https://api.github.com/repos/issuebot/test/compare/{base}...{head}", 102 | "merges_url": "https://api.github.com/repos/issuebot/test/merges", 103 | "archive_url": "https://api.github.com/repos/issuebot/test/{archive_format}{/ref}", 104 | "downloads_url": "https://api.github.com/repos/issuebot/test/downloads", 105 | "issues_url": "https://api.github.com/repos/issuebot/test/issues{/number}", 106 | "pulls_url": "https://api.github.com/repos/issuebot/test/pulls{/number}", 107 | "milestones_url": "https://api.github.com/repos/issuebot/test/milestones{/number}", 108 | "notifications_url": "https://api.github.com/repos/issuebot/test/notifications{?since,all,participating}", 109 | "labels_url": "https://api.github.com/repos/issuebot/test/labels{/name}", 110 | "releases_url": "https://api.github.com/repos/issuebot/test/releases{/id}", 111 | "deployments_url": "https://api.github.com/repos/issuebot/test/deployments", 112 | "created_at": "2018-04-04T02:59:29Z", 113 | "updated_at": "2018-04-04T04:17:02Z", 114 | "pushed_at": "2018-04-04T04:17:00Z", 115 | "git_url": "git://github.com/issuebot/test.git", 116 | "ssh_url": "git@github.com:issuebot/test.git", 117 | "clone_url": "https://github.com/issuebot/test.git", 118 | "svn_url": "https://github.com/issuebot/test", 119 | "homepage": null, 120 | "size": 1, 121 | "stargazers_count": 0, 122 | "watchers_count": 0, 123 | "language": null, 124 | "has_issues": true, 125 | "has_projects": true, 126 | "has_downloads": true, 127 | "has_wiki": true, 128 | "has_pages": false, 129 | "forks_count": 0, 130 | "mirror_url": null, 131 | "archived": false, 132 | "open_issues_count": 1, 133 | "license": null, 134 | "forks": 0, 135 | "open_issues": 1, 136 | "watchers": 0, 137 | "default_branch": "master" 138 | }, 139 | "sender": { 140 | "login": "issuebot", 141 | "id": 3457, 142 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 143 | "gravatar_id": "", 144 | "url": "https://api.github.com/users/issuebot", 145 | "html_url": "https://github.com/issuebot", 146 | "followers_url": "https://api.github.com/users/issuebot/followers", 147 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 148 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 149 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 150 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 151 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 152 | "repos_url": "https://api.github.com/users/issuebot/repos", 153 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 154 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 155 | "type": "User", 156 | "site_admin": false 157 | }, 158 | "installation": { 159 | "id": 141670 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /test/fixtures/event_opened_custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "issues", 3 | "number": 2, 4 | "payload": { 5 | "action": "opened", 6 | "issue": { 7 | "url": "https://api.github.com/repos/issuebot/test/issues/2", 8 | "repository_url": "https://api.github.com/repos/issuebot/test", 9 | "labels_url": "https://api.github.com/repos/issuebot/test/issues/2/labels{/name}", 10 | "comments_url": "https://api.github.com/repos/issuebot/test/issues/2/comments", 11 | "events_url": "https://api.github.com/repos/issuebot/test/issues/2/events", 12 | "html_url": "https://github.com/issuebot/test/issues/2", 13 | "id": 3114, 14 | "number": 2, 15 | "title": "Test", 16 | "user": { 17 | "login": "issuebot", 18 | "id": 3457, 19 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 20 | "gravatar_id": "", 21 | "url": "https://api.github.com/users/issuebot", 22 | "html_url": "https://github.com/issuebot", 23 | "followers_url": "https://api.github.com/users/issuebot/followers", 24 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 25 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 26 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 27 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 28 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 29 | "repos_url": "https://api.github.com/users/issuebot/repos", 30 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 31 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 32 | "type": "User", 33 | "site_admin": false 34 | }, 35 | "labels": [], 36 | "state": "open", 37 | "locked": false, 38 | "assignee": null, 39 | "assignees": [], 40 | "milestone": null, 41 | "comments": 0, 42 | "created_at": "2018-04-05T06:09:02Z", 43 | "updated_at": "2018-04-05T06:09:02Z", 44 | "closed_at": null, 45 | "author_association": "OWNER", 46 | "body": "hey\nA-Feature" 47 | }, 48 | "repository": { 49 | "id": 1279, 50 | "name": "test", 51 | "full_name": "issuebot/test", 52 | "owner": { 53 | "login": "issuebot", 54 | "id": 3457, 55 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 56 | "gravatar_id": "", 57 | "url": "https://api.github.com/users/issuebot", 58 | "html_url": "https://github.com/issuebot", 59 | "followers_url": "https://api.github.com/users/issuebot/followers", 60 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 61 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 62 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 63 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 64 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 65 | "repos_url": "https://api.github.com/users/issuebot/repos", 66 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 67 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 68 | "type": "User", 69 | "site_admin": false 70 | }, 71 | "private": false, 72 | "html_url": "https://github.com/issuebot/test", 73 | "description": null, 74 | "fork": false, 75 | "url": "https://api.github.com/repos/issuebot/test", 76 | "forks_url": "https://api.github.com/repos/issuebot/test/forks", 77 | "keys_url": "https://api.github.com/repos/issuebot/test/keys{/key_id}", 78 | "collaborators_url": "https://api.github.com/repos/issuebot/test/collaborators{/collaborator}", 79 | "teams_url": "https://api.github.com/repos/issuebot/test/teams", 80 | "hooks_url": "https://api.github.com/repos/issuebot/test/hooks", 81 | "issue_events_url": "https://api.github.com/repos/issuebot/test/issues/events{/number}", 82 | "events_url": "https://api.github.com/repos/issuebot/test/events", 83 | "assignees_url": "https://api.github.com/repos/issuebot/test/assignees{/user}", 84 | "branches_url": "https://api.github.com/repos/issuebot/test/branches{/branch}", 85 | "tags_url": "https://api.github.com/repos/issuebot/test/tags", 86 | "blobs_url": "https://api.github.com/repos/issuebot/test/git/blobs{/sha}", 87 | "git_tags_url": "https://api.github.com/repos/issuebot/test/git/tags{/sha}", 88 | "git_refs_url": "https://api.github.com/repos/issuebot/test/git/refs{/sha}", 89 | "trees_url": "https://api.github.com/repos/issuebot/test/git/trees{/sha}", 90 | "statuses_url": "https://api.github.com/repos/issuebot/test/statuses/{sha}", 91 | "languages_url": "https://api.github.com/repos/issuebot/test/languages", 92 | "stargazers_url": "https://api.github.com/repos/issuebot/test/stargazers", 93 | "contributors_url": "https://api.github.com/repos/issuebot/test/contributors", 94 | "subscribers_url": "https://api.github.com/repos/issuebot/test/subscribers", 95 | "subscription_url": "https://api.github.com/repos/issuebot/test/subscription", 96 | "commits_url": "https://api.github.com/repos/issuebot/test/commits{/sha}", 97 | "git_commits_url": "https://api.github.com/repos/issuebot/test/git/commits{/sha}", 98 | "comments_url": "https://api.github.com/repos/issuebot/test/comments{/number}", 99 | "issue_comment_url": "https://api.github.com/repos/issuebot/test/issues/comments{/number}", 100 | "contents_url": "https://api.github.com/repos/issuebot/test/contents/{+path}", 101 | "compare_url": "https://api.github.com/repos/issuebot/test/compare/{base}...{head}", 102 | "merges_url": "https://api.github.com/repos/issuebot/test/merges", 103 | "archive_url": "https://api.github.com/repos/issuebot/test/{archive_format}{/ref}", 104 | "downloads_url": "https://api.github.com/repos/issuebot/test/downloads", 105 | "issues_url": "https://api.github.com/repos/issuebot/test/issues{/number}", 106 | "pulls_url": "https://api.github.com/repos/issuebot/test/pulls{/number}", 107 | "milestones_url": "https://api.github.com/repos/issuebot/test/milestones{/number}", 108 | "notifications_url": "https://api.github.com/repos/issuebot/test/notifications{?since,all,participating}", 109 | "labels_url": "https://api.github.com/repos/issuebot/test/labels{/name}", 110 | "releases_url": "https://api.github.com/repos/issuebot/test/releases{/id}", 111 | "deployments_url": "https://api.github.com/repos/issuebot/test/deployments", 112 | "created_at": "2018-04-04T02:59:29Z", 113 | "updated_at": "2018-04-04T04:17:02Z", 114 | "pushed_at": "2018-04-04T04:17:00Z", 115 | "git_url": "git://github.com/issuebot/test.git", 116 | "ssh_url": "git@github.com:issuebot/test.git", 117 | "clone_url": "https://github.com/issuebot/test.git", 118 | "svn_url": "https://github.com/issuebot/test", 119 | "homepage": null, 120 | "size": 1, 121 | "stargazers_count": 0, 122 | "watchers_count": 0, 123 | "language": null, 124 | "has_issues": true, 125 | "has_projects": true, 126 | "has_downloads": true, 127 | "has_wiki": true, 128 | "has_pages": false, 129 | "forks_count": 0, 130 | "mirror_url": null, 131 | "archived": false, 132 | "open_issues_count": 1, 133 | "license": null, 134 | "forks": 0, 135 | "open_issues": 1, 136 | "watchers": 0, 137 | "default_branch": "master" 138 | }, 139 | "sender": { 140 | "login": "issuebot", 141 | "id": 3457, 142 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 143 | "gravatar_id": "", 144 | "url": "https://api.github.com/users/issuebot", 145 | "html_url": "https://github.com/issuebot", 146 | "followers_url": "https://api.github.com/users/issuebot/followers", 147 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 148 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 149 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 150 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 151 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 152 | "repos_url": "https://api.github.com/users/issuebot/repos", 153 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 154 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 155 | "type": "User", 156 | "site_admin": false 157 | }, 158 | "installation": { 159 | "id": 141670 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /test/fixtures/event_edited.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "issues", 3 | "number": 2, 4 | "payload": { 5 | "action": "edited", 6 | "issue": { 7 | "url": "https://api.github.com/repos/issuebot/test/issues/2", 8 | "repository_url": "https://api.github.com/repos/issuebot/test", 9 | "labels_url": "https://api.github.com/repos/issuebot/test/issues/2/labels{/name}", 10 | "comments_url": "https://api.github.com/repos/issuebot/test/issues/2/comments", 11 | "events_url": "https://api.github.com/repos/issuebot/test/issues/2/events", 12 | "html_url": "https://github.com/issuebot/test/issues/2", 13 | "id": 3114, 14 | "number": 2, 15 | "title": "Test", 16 | "user": { 17 | "login": "issuebot", 18 | "id": 3457, 19 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 20 | "gravatar_id": "", 21 | "url": "https://api.github.com/users/issuebot", 22 | "html_url": "https://github.com/issuebot", 23 | "followers_url": "https://api.github.com/users/issuebot/followers", 24 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 25 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 26 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 27 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 28 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 29 | "repos_url": "https://api.github.com/users/issuebot/repos", 30 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 31 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 32 | "type": "User", 33 | "site_admin": false 34 | }, 35 | "labels": [], 36 | "state": "open", 37 | "locked": false, 38 | "assignee": null, 39 | "assignees": [], 40 | "milestone": null, 41 | "comments": 0, 42 | "created_at": "2018-04-05T06:09:02Z", 43 | "updated_at": "2018-04-05T06:09:02Z", 44 | "closed_at": null, 45 | "author_association": "OWNER", 46 | "body": "hey\nA-Feature" 47 | }, 48 | "changes": {}, 49 | "repository": { 50 | "id": 1279, 51 | "name": "test", 52 | "full_name": "issuebot/test", 53 | "owner": { 54 | "login": "issuebot", 55 | "id": 3457, 56 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 57 | "gravatar_id": "", 58 | "url": "https://api.github.com/users/issuebot", 59 | "html_url": "https://github.com/issuebot", 60 | "followers_url": "https://api.github.com/users/issuebot/followers", 61 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 62 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 63 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 64 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 65 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 66 | "repos_url": "https://api.github.com/users/issuebot/repos", 67 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 68 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 69 | "type": "User", 70 | "site_admin": false 71 | }, 72 | "private": false, 73 | "html_url": "https://github.com/issuebot/test", 74 | "description": null, 75 | "fork": false, 76 | "url": "https://api.github.com/repos/issuebot/test", 77 | "forks_url": "https://api.github.com/repos/issuebot/test/forks", 78 | "keys_url": "https://api.github.com/repos/issuebot/test/keys{/key_id}", 79 | "collaborators_url": "https://api.github.com/repos/issuebot/test/collaborators{/collaborator}", 80 | "teams_url": "https://api.github.com/repos/issuebot/test/teams", 81 | "hooks_url": "https://api.github.com/repos/issuebot/test/hooks", 82 | "issue_events_url": "https://api.github.com/repos/issuebot/test/issues/events{/number}", 83 | "events_url": "https://api.github.com/repos/issuebot/test/events", 84 | "assignees_url": "https://api.github.com/repos/issuebot/test/assignees{/user}", 85 | "branches_url": "https://api.github.com/repos/issuebot/test/branches{/branch}", 86 | "tags_url": "https://api.github.com/repos/issuebot/test/tags", 87 | "blobs_url": "https://api.github.com/repos/issuebot/test/git/blobs{/sha}", 88 | "git_tags_url": "https://api.github.com/repos/issuebot/test/git/tags{/sha}", 89 | "git_refs_url": "https://api.github.com/repos/issuebot/test/git/refs{/sha}", 90 | "trees_url": "https://api.github.com/repos/issuebot/test/git/trees{/sha}", 91 | "statuses_url": "https://api.github.com/repos/issuebot/test/statuses/{sha}", 92 | "languages_url": "https://api.github.com/repos/issuebot/test/languages", 93 | "stargazers_url": "https://api.github.com/repos/issuebot/test/stargazers", 94 | "contributors_url": "https://api.github.com/repos/issuebot/test/contributors", 95 | "subscribers_url": "https://api.github.com/repos/issuebot/test/subscribers", 96 | "subscription_url": "https://api.github.com/repos/issuebot/test/subscription", 97 | "commits_url": "https://api.github.com/repos/issuebot/test/commits{/sha}", 98 | "git_commits_url": "https://api.github.com/repos/issuebot/test/git/commits{/sha}", 99 | "comments_url": "https://api.github.com/repos/issuebot/test/comments{/number}", 100 | "issue_comment_url": "https://api.github.com/repos/issuebot/test/issues/comments{/number}", 101 | "contents_url": "https://api.github.com/repos/issuebot/test/contents/{+path}", 102 | "compare_url": "https://api.github.com/repos/issuebot/test/compare/{base}...{head}", 103 | "merges_url": "https://api.github.com/repos/issuebot/test/merges", 104 | "archive_url": "https://api.github.com/repos/issuebot/test/{archive_format}{/ref}", 105 | "downloads_url": "https://api.github.com/repos/issuebot/test/downloads", 106 | "issues_url": "https://api.github.com/repos/issuebot/test/issues{/number}", 107 | "pulls_url": "https://api.github.com/repos/issuebot/test/pulls{/number}", 108 | "milestones_url": "https://api.github.com/repos/issuebot/test/milestones{/number}", 109 | "notifications_url": "https://api.github.com/repos/issuebot/test/notifications{?since,all,participating}", 110 | "labels_url": "https://api.github.com/repos/issuebot/test/labels{/name}", 111 | "releases_url": "https://api.github.com/repos/issuebot/test/releases{/id}", 112 | "deployments_url": "https://api.github.com/repos/issuebot/test/deployments", 113 | "created_at": "2018-04-04T02:59:29Z", 114 | "updated_at": "2018-04-04T04:17:02Z", 115 | "pushed_at": "2018-04-04T04:17:00Z", 116 | "git_url": "git://github.com/issuebot/test.git", 117 | "ssh_url": "git@github.com:issuebot/test.git", 118 | "clone_url": "https://github.com/issuebot/test.git", 119 | "svn_url": "https://github.com/issuebot/test", 120 | "homepage": null, 121 | "size": 1, 122 | "stargazers_count": 0, 123 | "watchers_count": 0, 124 | "language": null, 125 | "has_issues": true, 126 | "has_projects": true, 127 | "has_downloads": true, 128 | "has_wiki": true, 129 | "has_pages": false, 130 | "forks_count": 0, 131 | "mirror_url": null, 132 | "archived": false, 133 | "open_issues_count": 1, 134 | "license": null, 135 | "forks": 0, 136 | "open_issues": 1, 137 | "watchers": 0, 138 | "default_branch": "master" 139 | }, 140 | "sender": { 141 | "login": "issuebot", 142 | "id": 3457, 143 | "avatar_url": "https://avatars1.githubusercontent.com/u/3457?v=4", 144 | "gravatar_id": "", 145 | "url": "https://api.github.com/users/issuebot", 146 | "html_url": "https://github.com/issuebot", 147 | "followers_url": "https://api.github.com/users/issuebot/followers", 148 | "following_url": "https://api.github.com/users/issuebot/following{/other_user}", 149 | "gists_url": "https://api.github.com/users/issuebot/gists{/gist_id}", 150 | "starred_url": "https://api.github.com/users/issuebot/starred{/owner}{/repo}", 151 | "subscriptions_url": "https://api.github.com/users/issuebot/subscriptions", 152 | "organizations_url": "https://api.github.com/users/issuebot/orgs", 153 | "repos_url": "https://api.github.com/users/issuebot/repos", 154 | "events_url": "https://api.github.com/users/issuebot/events{/privacy}", 155 | "received_events_url": "https://api.github.com/users/issuebot/received_events", 156 | "type": "User", 157 | "site_admin": false 158 | }, 159 | "installation": { 160 | "id": 141670 161 | } 162 | } 163 | } 164 | --------------------------------------------------------------------------------