π€ 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 of Pull Requests.
- 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 comma delimited list of strings
message: 'Some message...' #optional
ends_with:
match: 'Any last sentence' # or comma delimited list 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 comma delimited list of strings
message: 'Some message...'
ends_with:
match: 'A String' # or comma delimited list 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' # or comma delimited list of strings
message: 'Some message...'
ends_with:
match: 'A String' # or comma delimited 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' # or comma delimited list of strings
message: 'Some message...'
ends_with:
match: 'A String' # or comma delimited 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: 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 comma delimited list of strings
message: 'Come message...'
# all of the message sub-option is optional Validators can be grouped together with AND and OR operators:
TODO: Show examples.
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
