π€ Mergeable helps automate your team's GitHub workflow without a single line of code.
Some examples of what you can do:
- Ensure pull requests follow conventions and prevent merging when it is not followed.
 - Notify author of failed guidelines when opening an issue.
 - Schedule detection for obsolete (stale) issues and pull requests and notify author and collaborators.
 - And more
 
π Contents: Usage β¦ Configuration β¦ Roadmap β¦ Support β¦ Contributions β¦ Authors
- Install the Mergeable GitHub App.
 - Create your recipe(s). Here are some examples.
 - Commit and push the recipes to your repository at 
.github/mergeable.yml 
β NOTE: You can also deploy to your own server.
Mergeable is highly configurable.
Define your recipes by creating a .github/mergeable.yml file in your repository.
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 are specified in the when tag like this:
- when: pull_request.openedMultiple events for a recipe are declared comma delimited like this:
- when: pull_request.opened, issues.openedEvents 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
validatorandactiondeclares it's own supported events. Read the validator and action sections to find out which events are supported respectively.
- 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.*'- 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 optionalSupported events:
'pull_request.*', 'pull_request_review.*', 'issues.*'  - 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.*'  - 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.*'  - 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.*'- 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.*'- 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.*'  - 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 Β»
- 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   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 are listed for execution at the pass, fail and error tags for a recipe based on the results of the validation.
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.*'- 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.*'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 1Read the configuration options for more options.
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.
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?- Additional actions like 
labelandassign - 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.
 
Found a bug? Have a question? Or just want to chat?
We need your help:
- Have an π‘idea for a new feature? Please create a new issue and tell us!
 - Fix a bug, implement a new validator or action and open a pull request!
 
βοΈ NOTE: For development and testing. You'll want to read about how to run it locally.
- Originally created by @jusx π follow him on Twitter.
 - Co-authored by @shine2lay
 - Logo by @minap0lis π follow her on Instagram.
 
AGPL, Copyright (c) 2019 Justin Law & Shine Lee
