Protecting important Git branches is essential for maintaining code quality and preventing accidental changes to production-bound code. Many development teams use GitHub branch protection rules to require pull requests, enforce status checks, restrict direct pushes, and ensure that changes receive the necessary reviews before merging.
As repositories grow, these requirements can become difficult to manage. Different branches may have different protection rules, teams may need exceptions for specific workflows, and administrators may struggle to understand which settings apply to a particular branch.
GitHub rulesets provide another way to manage repository policies. They allow teams to define rules that apply to selected branches or tags, configure enforcement behavior, and manage policies across repositories when organization-level rulesets are available.
Migrating from branch protection rules to rulesets requires more than copying settings. Some controls have different names, certain behaviors are configured differently, and existing rules may continue to apply after a ruleset is introduced.
This article explains how to review existing branch protection rules, map them to rulesets, configure the new policies, test enforcement, and complete the migration without disrupting development workflows.
Understanding Branch Protection Rules and Rulesets
Before migrating, understand how the two mechanisms work and how they differ.
What Are Branch Protection Rules?
Branch protection rules control how developers can modify or merge changes into selected branches.
For example, a repository may protect the main branch by requiring pull requests and successful automated checks before merging.
A typical policy might require:
Pull requests instead of direct pushes.
At least one approving review.
Successful build and test checks.
Resolution of review conversations.
Restrictions on force pushes and branch deletion.
These controls help ensure that changes are reviewed and validated before they reach important branches.
However, managing multiple branch protection rules can become complicated when a repository has several long-lived branches or when an organization needs consistent policies across many repositories.
What Are GitHub Rulesets?
Rulesets allow administrators to define policies that apply to selected branches or tags. Depending on the ruleset type and repository configuration, policies can be enforced at the repository or organization level.
Rulesets can include conditions that determine which references are affected, along with rules controlling how those references can be changed.
Common use cases include:
Requiring pull requests before changes are merged.
Requiring reviews and status checks.
Restricting force pushes.
Preventing branch or tag deletion.
Requiring signed commits where supported and appropriate.
Applying consistent policies across multiple repositories through organization-level rulesets.
Rulesets also provide enforcement modes, including an active mode and an evaluate mode. Evaluate mode can help administrators understand how a policy would affect activity before enforcing it, where that mode is supported.
Key Differences
Area | Branch protection rules | Rulesets |
|---|
Policy management | Uses branch-specific protection configuration | Uses a ruleset with target conditions and rules |
Target selection | Matches branch names or patterns | Uses targeting conditions for branches or tags |
Enforcement | Applies the configured protection policy | Supports enforcement modes, including evaluation where available |
Organization-wide management | Requires separate configuration or other management mechanisms | Organization rulesets can centralize policy across repositories when supported |
Bypass handling | Uses the permissions and exceptions supported by branch protection | Provides configurable bypass permissions for eligible actors |
Policy visibility | Requires reviewing branch protection configuration | Offers a dedicated view of applicable rulesets |
Migration approach | Existing configuration must be reviewed | Policies must be mapped and tested before enforcement |
The available features depend on repository type, organization configuration, and GitHub plan. Verify the options available in your environment before designing the migration.
Review Existing Branch Protection Rules
The first step is to document the current configuration. Migrating without a baseline can accidentally remove an important restriction or introduce a policy that blocks legitimate development work.
Identify Protected Branches
Open the repository on GitHub and navigate to its settings.
Under the repository's branch-related settings, review the configured branch protection rules. Record which branches or patterns each rule covers.
For example, a repository might have rules for:
main
release/*
hotfix/*
development
Do not assume that the same protection settings apply to every branch. A production branch may require two approvals, while a development branch may require only one.
Record the current requirements before changing anything.
Create a Protection Inventory
A simple inventory makes the migration easier to review.
Branch or pattern | Existing requirement | Migration consideration |
|---|
main | Pull request and two approvals | Preserve the review requirement |
main | Build and test checks must pass | Map the required checks accurately |
release/* | Pull request and one approval | Verify that the target pattern matches all intended release branches |
hotfix/* | Restricted updates | Confirm the equivalent policy and any emergency bypass requirements |
All protected branches | Force pushes disabled | Ensure the new ruleset applies to the intended references |
This table is illustrative. Use your repository's actual settings rather than copying these example policies.
Also document who can bypass the existing controls, whether administrators are exempt, and whether any workflows depend on direct pushes.
Identify Dependencies on Existing Policies
Some deployment pipelines and release processes depend on the current protection configuration.
For example, a workflow may expect a release manager to update a release branch after a pull request has been approved. Another process may depend on an automated bot being allowed to update generated files.
List these dependencies before migration.
The goal is to preserve legitimate workflows without creating broad exceptions that weaken repository security.
Map Branch Protection Settings to Rulesets
Once the current policies are documented, map each requirement to the corresponding ruleset configuration.
Do not assume that every branch protection setting has an exact one-to-one equivalent. Review the behavior of each relevant rule in your repository.
Pull Request Requirements
If the existing policy requires pull requests before merging, configure the corresponding pull request rule in the ruleset.
Then review the review requirements, including the number of approvals and any supported restrictions involving code owners or review changes.
For example, a production branch may require two approvals before merging. The ruleset should preserve that requirement if it is part of the existing policy.
Pay particular attention to how approvals interact with dismissed reviews, newly pushed commits, and required review conversations. These details can affect whether a pull request is allowed to merge.
Required Status Checks
Build and test checks are often among the most important branch protection requirements.
Identify the exact status checks required by the existing policy and configure the corresponding ruleset requirements.
For example, the repository may require these checks:
build
unit-tests
integration-tests
security-scan
Use the actual check names produced by your CI system. A name mismatch can prevent merging even when the workflow has completed successfully.
Also verify that the required checks cannot be satisfied by an unintended or untrusted workflow.
Restrict Force Pushes and Deletion
Production branches should normally be protected against accidental deletion and history rewriting.
Review the existing configuration for restrictions on force pushes and branch deletion. Configure the corresponding ruleset protections where supported.
These settings are especially important for branches used by deployment pipelines or long-lived release processes.
Review Bypass Permissions
Bypass permissions determine who can skip or bypass particular rules under the supported conditions.
A migration that grants broad bypass access can undermine the protections it was intended to preserve.
Review each bypass actor and its purpose. Consider whether the actor needs to bypass the entire policy or only requires a narrowly scoped exception for a specific operational task.
For emergency changes, document the approval process and ensure that bypass activity remains visible and auditable.
Create a Ruleset for the Target Branch
After mapping the existing requirements, create a ruleset and configure it for the intended branch or branches.
Configure the Ruleset in GitHub
For a repository-level ruleset, open the repository settings and navigate to the rulesets area. Create a new branch ruleset and provide a descriptive name.
For example, a ruleset might be named:
Production Branch Protection
Configure the target branches so that the ruleset covers the intended production branch. If the policy applies to several branches, verify that the targeting conditions include all required references without matching unrelated branches.
Next, configure the required protections, such as pull requests, approvals, status checks, and restrictions on force pushes.
Finally, review the enforcement mode and bypass settings before saving the configuration.
The exact interface and available options can change. Use the current settings displayed by GitHub rather than relying on assumptions about a particular interface layout.
Choose the Right Enforcement Mode
Where supported, evaluate mode can help teams assess the effect of a ruleset before fully enforcing it.
This is useful when a repository has complicated branch patterns, automated workflows, or multiple contributors.
During evaluation, examine the results and identify operations that would be affected by the policy. Resolve unexpected matches and missing exceptions before moving to active enforcement.
Evaluate mode should not be treated as a substitute for reviewing the configuration. Confirm the specific behavior available for your ruleset type and environment.
When the ruleset is ready, enable active enforcement according to the migration plan.
Test the New Ruleset Before Removing Existing Rules
The safest migration uses a staged approach. Create and validate the ruleset while keeping the existing branch protection configuration available.
This makes it easier to identify missing requirements before removing the old configuration.
Test Pull Request Behavior
Create a test pull request targeting the protected branch.
Verify that the expected review requirements are applied. If the policy requires two approvals, confirm that one approval is not enough to satisfy the requirement.
Also check whether the ruleset behaves correctly when a reviewer requests changes or when a new commit is pushed after approval.
Test Required Status Checks
Open a pull request and allow the CI workflows to run.
Confirm that the required checks are recognized and that a failed check prevents merging.
Then run a successful build and verify that the checks allow the pull request to progress when all other requirements are satisfied.
A common problem is configuring a status check with a name that does not match the actual check reported by GitHub.
Test Restricted Operations
Where practical, verify that direct pushes, force pushes, or deletion attempts are blocked according to the policy.
Use a test branch or a controlled test repository when testing potentially destructive operations.
Do not experiment with force pushes or deletion on a production branch.
Verify Bypass Behavior
If emergency bypass permissions are part of the policy, verify that the intended actors can perform the required operations and that ordinary contributors cannot bypass restrictions unexpectedly.
Keep bypass access limited and document how it should be used.
Automate Ruleset Management With the GitHub API
Repositories with many branches or organizations with many repositories may benefit from automating ruleset inspection and management.
GitHub provides REST API endpoints for repository and organization rulesets. The available endpoints and permissions depend on the operation and resource being managed.
For example, an administrator can retrieve repository rulesets to inspect their configuration.
A general API request has this structure:
GET /repos/OWNER/REPO/rulesets
Accept: application/vnd.github+json
X-GitHub-Api-Version: <SUPPORTED_API_VERSION>
Authorization: Bearer <TOKEN>
Replace OWNER and REPO with the repository owner and name, use a supported API version, and supply an appropriately scoped token through a secure mechanism.
Do not commit real tokens into source control or place them directly into a script that may be shared.
Example Using PowerShell
The following example retrieves repository rulesets using PowerShell and the GitHub REST API.
$Owner = "YOUR_ORGANIZATION"
$Repo = "YOUR_REPOSITORY"
$Token = $env:GITHUB_TOKEN
if ([string]::IsNullOrWhiteSpace($Token)) {
throw "Set the GITHUB_TOKEN environment variable first."
}
$Headers = @{
Accept = "application/vnd.github+json"
Authorization = "Bearer $Token"
"X-GitHub-Api-Version" = "<SUPPORTED_API_VERSION>"
}
$Uri = "https://api.github.com/repos/$Owner/$Repo/rulesets"
$Rulesets = Invoke-RestMethod `
-Method Get `
-Uri $Uri `
-Headers $Headers
$Rulesets |
Select-Object id, name, source, enforcement |
Format-Table -AutoSize
Replace the API version placeholder with a version currently supported by GitHub. Ensure the token has the permissions required to read the relevant ruleset configuration.
This example is intended for inspection. It does not migrate branch protection rules or change enforcement settings.
Before automating a migration, build a tested mapping between the existing configuration and the target ruleset. Validate the generated configuration in a non-production repository first.
Automation Considerations
When using the API for a migration, account for:
Token permissions and repository access.
Pagination when retrieving large collections.
Organization and repository rulesets that may both apply.
API errors and rate limits.
Differences between the existing configuration and ruleset capabilities.
Auditability of configuration changes.
Safe handling of partial failures.
Do not assume that creating a repository ruleset removes or overrides every existing branch protection rule. Multiple applicable policies can interact, and their combined effect must be reviewed.
Common Migration Problems
Required Checks Are Missing
A ruleset may refer to a check that no longer exists or uses a name that differs from the check produced by the workflow.
Inspect the actual check names in pull request results and update the configuration accordingly.
Branch Patterns Match Too Many References
A broad pattern may affect branches that were not previously protected.
Test the target conditions against the repository's branch naming conventions and verify which branches are affected before enabling enforcement.
Contributors Cannot Merge Valid Pull Requests
This can happen when the new ruleset adds requirements that were not part of the old configuration or when the ruleset overlaps with another applicable policy.
Inspect the effective requirements, status checks, approvals, and bypass permissions. Fix the underlying policy mismatch instead of granting broad bypass access.
Existing Branch Protection Rules Are Removed Too Early
Deleting the old configuration before validating the new ruleset can leave important branches without the expected protection.
Keep the existing configuration during the initial migration and remove it only after the replacement has been tested and verified.
Automation Uses Excessive Permissions
Scripts that manage repository settings can have significant privileges.
Use narrowly scoped tokens, restrict access to migration scripts, and log configuration changes. Separate read-only inspection from operations that modify security settings whenever practical.
Best Practices for a Safe Migration
Follow these practices when moving from branch protection rules to rulesets:
Inventory all existing rules and the branches they protect.
Record required reviews, status checks, restrictions, and bypass permissions.
Map each existing requirement to the corresponding ruleset capability.
Test branch targeting conditions before enforcing them.
Use evaluation mode where supported to identify unexpected effects.
Validate pull request, CI, and bypass behavior.
Keep existing protections until the replacement is confirmed.
Review organization-level and repository-level rulesets together.
Automate configuration inspection before automating changes.
Document exceptions and establish an owner for ongoing maintenance.
A migration is successful when it preserves the intended controls and makes them easier to manage. A new configuration is not automatically safer merely because it uses a newer feature.
Advantages and Limitations of Rulesets
Rulesets can make policy management clearer by grouping related requirements and supporting more flexible targeting. Organization-level rulesets can also help teams maintain consistent standards across multiple repositories.
Their enforcement and bypass options can improve governance when configured carefully.
However, migration requires an understanding of the existing configuration and the interaction between multiple applicable policies. Some settings may need to be mapped differently, and availability can vary by plan or repository context.
Rulesets also require ongoing maintenance. Branch naming conventions, CI workflows, and team responsibilities change over time, so policies should be reviewed periodically.
Summary
Migrating GitHub branch protection rules to rulesets can simplify repository governance and make branch policies easier to manage. The process should begin with a complete inventory of existing protections, including required reviews, status checks, restricted operations, and bypass permissions.
Map those requirements to the available ruleset capabilities, configure the correct target branches, and test the policy before removing existing rules. Where supported, evaluation mode can help identify unexpected effects before enforcement.
For larger organizations, the GitHub API can help inspect and manage rulesets, but automated migration should include configuration validation, appropriate permissions, and audit logging.
The most important goal is to preserve the security requirements that protect your development and release process while improving the consistency and maintainability of repository policies.
Join the conversation! Your thoughts help the community grow.