GitHub Repository Rules are now generally available
Protected branches have been around for a while, and we’ve made numerous improvements over time. We’ve added new rules to protect multiple branches and introduced additional permissions. However, it’s still challenging to consistently protect branches and tags throughout organizations. Managing scripts, cron jobs, various API calls, or third-party tooling to have consistent branch protections is not only annoying but also time-consuming. You won’t know the rules in place as an engineer until you encounter a pull request.
It’s time for a new approach
We’re excited to announce the general availability of repository rules.
Repository rules enable you to easily define branch protections in your public repositories. With flexible targeting options, you can protect multiple branch patterns using a single ruleset. Layering makes bypass scenarios dynamic; a GitHub App can skip status checks with no additional permissions, and administrators can bypass pull requests while still requiring the important CodeQL checks to run.
In line with our mission to be the home for all developers, we have integrated GitHub Repository Rules to ensure that everyone collaborating on a repository knows the rules in play for them. An overview page provides visibility on rules applicable to a branch. Relevant information about rule enforcement is available at multiple touchpoints on GitHub.com, Git, and the GitHub CLI. There are also helpful prompts on ensuring the responsible use of bypass permissions.
Twilio has been using GitHub Repository Rules to balance developer experience and security.
GitHub Enterprise Cloud customers can enforce these rules across all or a subset of their repositories in an organization. No more tedious audits checking to see if a rule existed; now, you can ensure consistency in one location. If you’re not ready to commit to a ruleset, you can trial them in evaluate mode. Rule insights allow you to see what could happen if you dismiss stale reviews or enable linear merge history. No more guessing and no more testing in “production.”
Policy enforcement is a big reason Thomson Reuters has been an early adopter of repository rules across their organization.
Regarding consistency, repository rules can deliver that with new metadata rules. Branch names, commit messages, and author email addresses of the commit can be governed to help ensure organizational standards. So, set all those protected tags to use SemVer and commit messages on the Emoji-Log standard.
Let’s jump in with a few scenarios where repository rules can help level up your code integrity.
We’re just normal repositories.
Typical rules for production repositories.
Setting up repository rules can help maintain code quality, prevent mistakes, and improve collaboration. There are numerous decisions to make about the security goals of a repository, let alone multiple repositories. We want to share best practices that are broadly applicable.
Adding rules can create friction for developers contributing to your repository. Therefore, you should clearly articulate the goals for your repository and limit the number of rules necessary to achieve these goals.
A production repository will have a few well-known branches. These branches should require peer-reviewed pull requests, use CI/CD for running unit tests and controlling releases, and support certain namespaces of topic branches with minimal restrictions. Here’s how you’d implement that with the repository rules REST API for a single repository.
REST API Example
POST /repos/{owner}/{repo}/rulesets
{
"name": "team rules-ex-1",
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": {
"include": [
"~DEFAULT_BRANCH",
"refs/heads/feature-*"
],
"exclude": [
"refs/heads/dev-*"
]
}
},
"rules": [
{
"type": "pull_request",
"parameters": {
"require_code_owner_review": false,
"require_last_push_approval": true,
"dismiss_stale_reviews_on_push": false,
"required_approving_review_count": 2,
"required_review_thread_resolution": false
}
},
{
"type": "required_status_checks",
"parameters": {
"required_status_checks": [
{
"context": {status check context name}",
"integration_id":{integration ID that this status check must originate from.}
}
],
"strict_required_status_checks_policy": false
}
},
{
"type": "deletion"
},
{
"type": "non_fast_forward"
}
]
}
One ruleset to rule them all
Rules for governance across an organization.
Setting review standards across all of your repositories, such as requiring “two sets of eyes” on pull requests, can help ensure your repositories more readily meet regulatory or compliance standards.
One area to consider is how to handle exceptions and bypasses. Having a designated team on the bypass list for organization rulesets ensures that someone can always intervene in “break-glass” scenarios. Another option is to carefully craft organization rules to limit situations when an exception is needed. Using a ruleset in evaluate mode allows you to model potential scenarios requiring exceptions. You can try this out in a dry run and then review those events in ruleset insights.
REST API example
POST /orgs/{org}/rulesets
{
"name": "???? + ????",
"target": "branch",
"source_type": "Organization",
"enforcement": "active",
"bypass_actors": [
{
"actor_id": 1,
"actor_type": "OrganizationAdmin",
"bypass_mode": "pull_request"
}
],
"conditions": {
"repository_name": {
"exclude": [],
"include": [
"~ALL"
]
},
"ref_name": {
"exclude": [],
"include": [
"~DEFAULT_BRANCH"
]
}
},
"rules": [
{
"type": "deletion"
},
{
"type": "non_fast_forward"
},
{
"type": "pull_request",
"parameters": {
"require_code_owner_review": false,
"require_last_push_approval": false,
"dismiss_stale_reviews_on_push": false,
"required_approving_review_count": 2,
"required_review_thread_resolution": false
}
}
]
}
Bypass with ease—or how I learned to stop worrying and love the bot
GitHub Apps may not need to run status checks when committing for various reasons, but they should not have admin access. This was the only option in branch protections and led to scenarios with overpowered bots.
Repository rules support layering, meaning you can write a couple of rulesets, one with a bypass list narrowly scoped, layered with another ruleset containing an empty bypass list. A bot can skip status checks but can’t delete branches or force push.
In this case, you’d create two rulesets in your repository. We’ll name one ruleset “Bots and Friends” and the other “For all.”
“For all” ruleset
- Bypass list: none
- Target branches:
default branch
- Branch Protections:
- Enable: “Restrict Deletions”
- Enable: “Block force pushes”
- Enable: “Require a pull request before merging”
“Bots and Friends” ruleset
- Bypass list: your favorite bot
- Target branches:
default branch
- Branch Protections:
- Enable: “Require status checks to pass before merging” and “Require branches to be up to date before merging”
More about GitHub Repository Rules
We’d love to hear about how you use rules in our community. And to learn more about GitHub Repository Rules, visit our documentation.