/mergeable

πŸ€– All the missing GitHub automation πŸ™‚ πŸ™Œ

Primary LanguageJavaScriptGNU Affero General Public License v3.0AGPL-3.0


Mergeable

Mergeable

Free Install

πŸ€– Mergeable helps automate your team's GitHub workflow without a single line of code.

Some examples of what you can do:


πŸ“– Contents: Usage β—¦ Configuration β—¦ Roadmap β—¦ Support β—¦ Contributions β—¦ Authors


Usage

  1. Install the Mergeable GitHub App.
  2. Create your recipe(s). Here are some examples.
  3. Commit and push the recipes to your repository at .github/mergeable.yml

☝ NOTE: You can also deploy to your own server.

Configuration

Mergeable is highly configurable. Define your recipes by creating a .github/mergeable.yml file in your repository.

Basics

The configuration consists of any number of recipes. Recipes are created by tying events with a set of validators and actions together:

version: 2
mergeable:
  - when: {{event}}, {{event}} # can be one or more
    validate:
      # list of validators. Specify one or more.
      - do: {{validator}}
        {{option}}: # name of an option supported by the validator.
          {{sub-option}}: {{value}} # an option will have one or more sub-options.
    pass: # list of actions to be executed if all validation passes. Specify one or more. Omit this tag if no actions are needed.
      - do: {{action}}   
    fail: # list of actions to be executed when at least one validation fails. Specify one or more. Omit this tag if no actions are needed.
      - do: {{action}}            
    error: # list of actions to be executed when at least one validator throws an error. Specify one or more. Omit this tag if no actions are needed.
      - do: {{action}}      

Take a look at some example recipes.

☝ NOTE: Earlier versions used a different set of convention. It will be supported in the foreseeable future but will eventually be phased out.

Events

Events are specified in the when tag like this:

- when: pull_request.opened

Multiple events for a recipe are declared comma delimited like this:

- when: pull_request.opened, issues.opened

Events supported for pull requests are as follows: pull_request.opened, pull_request.edited, pull_request_review.submitted, pull_request_review.edited, pull_request_review.dismissed, pull_request.labeled, pull_request.unlabeled, pull_request.milestoned, pull_request.demilestoned, pull_request.assigned, pull_request.unassigned, pull_request.synchronize,

And for issues: issues.opened, issues.edited, issues.labeled, issues.unlabeled, issues.milestoned, issues.demilestoned, issues.assigned, issues.unassigned, issues.synchronize

☝ NOTE: More details about events can be found on the GitHub events page.

For convenience, wildcards can be used: pull_request.*, issues.*, pull_request_review.*

☝ NOTE: Each validator and action declares it's own supported events. Read the validator and action sections to find out which events are supported respectively.

Validators

approvals

- do: approvals
  min:
    count: 2 # Number of minimum reviewers. In this case 2.
    message: 'Custom message...'
  required:
    reviewers: [ user1, user2 ]   # list of github usernames required to review
    owners: true # accepts boolean. When true,  the file .github/CODEOWNER is read and owners made required reviewers
    message: 'Custom message...'

Supported events:

'pull_request.*', 'pull_request_review.*'

assignee

- do: assignee
  max:
    count: 2 # There should not be more than 2 assignees
    message: 'test string' # this is optional
  min:  
    count: 2 # min number of assignees
    message: 'test string' # this is optional

Supported events:

'pull_request.*', 'pull_request_review.*', 'issues.*'

dependent

  - do: dependent
    files: ['package.json', 'yarn.lock'] # list of files that are dependent to one another and must all be together part of the added or modified file list in a PR.
    message: 'Custom message...' # this is optional, a default message is used when not specified.

Supported events:

'pull_request.*', 'pull_request_review.*'

description

  - do: description
    no_empty:
       enabled: false # Cannot be empty when true.
       message: 'Custom message...' # this is optional, a default message is used when not specified.
    must_include:
       regex: '### Goals|### Changes'
       message: >
        Please describe the goals (why) and changes (what) of the PR.
      # message is is optional, a default message is used when not specified.
    must_exclude:
       regex: 'DO NOT MERGE'
       message: 'Custom message...' # optional
    begins_with:
       match: '### Goals' # or array of strings
       message: 'Some message...' #optional
    ends_with:
       match: 'Any last sentence' # array of strings
       message: 'Come message...' # optional    

Supported events:

'pull_request.*', 'pull_request_review.*', 'issues.*'

label

  - do: label
    no_empty:
       enabled: false # Cannot be empty when true.
       message: 'Custom message...'
    must_include:
       regex: 'type|chore|wont'
       message: 'Custom message...'
    must_exclude:
       regex: 'DO NOT MERGE'
       message: 'Custom message...'
    begins_with:
       match: 'A String' # or array of strings
       message: 'Some message...'
    ends_with:
       match: 'A String' # or array of strings
       message: 'Come message...'
    # all of the message sub-option is optional   

Supported events:

'pull_request.*', 'pull_request_review.*', 'issues.*'

milestone

- do: milestone
  no_empty:
     enabled: true # Cannot be empty when true.
     message: 'Custom message...'
  must_include:
     regex: 'type|chore|wont'
     message: 'Custom message...'
  must_exclude:
     regex: 'DO NOT MERGE'
     message: 'Custom message...'
  begins_with:
     match: 'A String' # array of strings
     message: 'Some message...'
  ends_with:
     match: 'A String' # array list of strings
     message: 'Come message...'
  # all of the message sub-option is optional   

☝ NOTE: When a closing keyword is used in the description of a pull request. The annotated issue will be validated against the conditions as well.

Supported events:

'pull_request.*', 'pull_request_review.*', 'issues.*'

project

- do: project
  no_empty:
     enabled: true # Cannot be empty when true.
     message: 'Custom message...'
  must_include:
     regex: 'type|chore|wont'
     message: 'Custom message...'
  must_exclude:
     regex: 'DO NOT MERGE'
     message: 'Custom message...'
  begins_with:
     match: 'A String' # array of strings
     message: 'Some message...'
  ends_with:
     match: 'A String' # array of strings
     message: 'Come message...'
     # all of the message sub-option is optional

☝ NOTE: When a closing keyword is used in the description of a pull request. The annotated issue will be validated against the conditions as well.

Supported events:

'pull_request.*', 'pull_request_review.*', 'issues.*'

stale

  - do: stale
    days: 20 # number of days ago.
    type: pull_request, issues # what items to search for.

Supported events:

'schedule.repository'

☝ NOTE: This is a special use case. The schedule event runs on an interval. When used with stale, it will search for issues and/or pull request that are n days old. See a full example »

title

- do: title
  no_empty:
     enabled: true # Cannot be empty when true. A bit redundant in this case since GitHub don't really allow it. :-)
     message: 'Custom message...'
  must_include:
     regex: 'doc|feat|fix|chore'
     message: 'Custom message...'
  must_exclude:
     regex: 'DO NOT MERGE|WIP'
     message: 'Custom message...'
  begins_with:
     match: ['doc','feat','fix','chore']  
     message: 'Some message...'
  ends_with:
     match: 'A String' # or array of strings
     message: 'Come message...'
     # all of the message sub-option is optional   

Advanced Logic

Validators can be grouped together with AND and OR operators:

- do: description
  and:
    - must_include:
        regex: 'Test Plan'
        message: 'Test plan must be included'
    - must_include:
        regex: 'Goal'
        message: 'Please include the goal of the PR'                 

AND and OR operators can also be nested

- do: label
  or:
    - and:
      - must_include:
          regex: 'release notes: yes'
          message: 'Please include release note: yes'
      - must_include:
          regex: '^lang\/'
           message: 'Please include a language label'
    - must_include:
        regex: 'release notes: no'
        message: 'Please include release note: no'

Note : AND and OR are not validators

Actions

Actions are listed for execution at the pass, fail and error tags for a recipe based on the results of the validation.

comment

Creates comments in issues and/or pull requests depending on the event specified in the when tag.

- do: comment
  payload:
    body: >
      Your very long comment can go here.

Supported events:

'schedule.repository', 'pull_request.*', 'issues.*'

checks

- do: checks,
  status: 'success' # Can be: success, failure, neutral, cancelled, timed_out, or action_required
  payload:
    title: 'Mergeable Run have been Completed!'
    summary: `All the validators have return 'pass'! \n Here are some stats of the run: \n {{validationCount}} validations were ran`

Supported events:

'pull_request.*', 'pull_request_review.*'

Examples

Pull Requests

Validate pull requests for mergeability based on content and structure of your PR (title, labels, milestone, project, description, approvals, etc). Here are a few examples:

Work In Progress: Prevent accidental merging of Pull Requests that are work in progress by labeling it WIP or prefixing the title with the abbreviation.

πŸ”– See Recipe

version: 2
mergeable:
  - when: pull_request.*
    validate:
      - do: title
        must_exclude:
          regex: ^\[WIP\]
      - do: label
        must_exclude:
          regex: 'wip'


Description: Ensure all Pull Requests have a description so that reviewers have context.

πŸ”– See Recipe

version: 2
mergeable:
  - when: pull_request.*
    validate:
      - do: description
        no_empty:
          enabled: true
          message: Description matter and should not be empty. Provide detail with **what** was changed, **why** it was changed, and **how** it was changed.


Dependent Files: Certain files are related and you want to ensure that they are updated as part of the PR (i.e. if package.json is updated, so should yarn.lock)

πŸ”– See Recipe

version: 2
mergeable:
  - when: pull_request.*
    validate:
      - do: dependent
        files: ['package.json', 'yarn.lock']


Milestone: Ensure that all Pull Requests have a milestone associated. Mergeable will also detect when you are closing an issue that is associated with the specified milestone.

πŸ”– See Recipe

version: 2
mergeable:
  - when: pull_request.*
    validate:
      - do: milestone
        must_include:
          regex: Release 1


Read the configuration options for more options.

Issues

Automatically create a comment when a new issue is openened to remind the author when the title does not follow conventions or is missing a label.

πŸ”– See Recipe

version: 2
mergeable:
  - when: issues.opened
    validate:
      - do: title
        begins_with:
          match: ['AUTH', 'SOCIAL', 'CORE']
      - do: label
        must_include:
          regex: bug|enhancement
    fail:
      - do: comment
        payload:
          body: >
            The following problems were found with this issue:
              - Title must begin with `AUTH`, `SOCIAL` or `CORE`
              - The issue should either be labeled `bug` or `enhancement`


Read the configuration options for more options.

Staleness

Detect issues and pull requests that are n days old (stale) and notify authors and collaborators by creating a comment.

πŸ”– See Recipe

version: 2
mergeable:
  - when: schedule.repository
    validate:
      - do: stale
        days: 20
        type: pull_request, issues
    pass:
      - do: comment
        payload:
          body: This is old. Is it still relevant?

Roadmap

  • Additional actions like label and assign
  • Potentially, integration with external tools like pivotal tracker, slack and trello.
  • More likely coveralls or sonarqube.
  • Able to prevent merging based on the size of pull request.

Support

Found a bug? Have a question? Or just want to chat?

Contributions

We need your help:

☝️ NOTE: For development and testing. You'll want to read about how to run it locally.

Authors


AGPL, Copyright (c) 2019 Justin Law & Shine Lee