Skip to content

Latest commit

 

History

59 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gh-migrate-rulesets

GitHub Release PR Checks License: MIT Go Report Card Go Version

A GitHub gh CLI extension to create a report containing repository rulesets for a single repository, list of repositories, and/or organization, as well as create repository rulesets from a file.

Note

The authenticated user must be an organization owner and a GitHub Personal Access Token needs the admin:read scope at the organization level to use this CLI extension to it's fullest.

Installation

  1. Install the gh CLI - see the installation instructions.

  2. Install the extension:

    gh extension install katiem0/gh-migrate-rulesets

For more information: gh extension install.

Usage

The gh-migrate-rulesets extension supports GitHub.com and GitHub Enterprise Server, through the use of --hostname and the following commands:

$ gh migrate-rulesets -h
List and create repository/organization level rulesets for repositories in an organization.

Usage:
  migrate-rules [command]

Available Commands:
  create      Create repository rulesets
  list        Generate a report of rulesets for repositories and/or organization.

Flags:
  -h, --help   help for migrate-rules

Use "migrate-rules [command] --help" for more information about a command.

List Repository Rulesets

The gh migrate-rulesets list command will create a csv report of repository rulesets for the specified <organization> and/or [repo ..] list, with the ability to specify the --host-name and --token associated to a Server instance. If only <organization> is provided, all repositories will be used.

To specify the type of ruleset to list, setting the --ruleType flag will either list:

  • all: Organization level, and repository level rulesets
  • repoOnly: Repository level rulesets for list of repos or all repos under <organization>
  • orgOnly: Organization level rulesets only
$ gh migrate-rulesets list -h
Generate a report of rulesets for a list of repositories and/or organization.

Usage:
  migrate-rules list [flags] <organization> [repo ...]

Flags:
  -d, --debug                To debug logging
  -h, --help                 help for list
      --hostname string      GitHub Enterprise Server hostname (default "github.com")
  -o, --output-file string   Name of file to write CSV list to (default "ruleset-20240819094546.csv")
  -r, --ruleType string      List rulesets for a specific application or all: {all|repoOnly|orgOnly} (default "all")
  -t, --token string         GitHub Personal Access Token (default "gh auth token")

The output csv file contains the following information:

Click to Expand output csv file contents
Field NameDescription
RulesetLevelIndicates whether the ruleset is at the organization or repository level.
SourceRepositoryNameIf repository level ruleset, the name of the repository where the data is extracted from. For Organization rulesets, this is N/A.
TargetRepositoryNameThe destination repository name used when creating rulesets with --from-file. Defaults to the same value as SourceRepositoryName on export; edit this column to rename the destination repository during a --from-file migration. For Organization rulesets, this is N/A.
RuleIDUnique identifier for the rule.
RulesetNameName of the ruleset.
TargetIndicates the type of ruleset, can be branch, tag, or push.
EnforcementEnforcement level of the ruleset (e.g., active, evaluate, or disabled).
BypassActorsActors who can bypass the ruleset, specified in the format ID;Role;Name;Condition.
ConditionsRefNameIncludeArray of ref names to include in the ruleset conditions.
ConditionsRefNameExcludeArray of ref names to exclude from the ruleset conditions.
ConditionsRepoNameIncludeArray of repository names to include in the ruleset conditions.
ConditionsRepoNameExcludeArray of repository names to exclude from the ruleset conditions.
ConditionsRepoNameProtectedIndicates whether renaming of target repositories is prevented.
ConditionRepoPropertyIncludeArray of repository properties values to include in the ruleset conditions.
ConditionRepoPropertyExcludeArray of repository properties values to exclude from the ruleset conditions.
RulesCreationOnly allow users with bypass permission to create matching refs.
RulesUpdateOnly allow users with bypass permissions to delete matching refs.
RulesDeletionPrevent merge commits from being pushed to matching refs.
RulesRequiredLinearHistoryPrevent merge commits from being pushed to matching refs.
RulesMergeQueueMerges must be performed via a merge queue. In the format check_response_timeout_minutes|grouping_strategy|max_entries_to_build|max_entries_to_merge|merge_method|min_entries_to_merge|min_entries_to_merge_wait_minutes
RulesRequiredDeploymentsChoose which environments must be successfully deployed to before refs can be pushed into a ref that matches this rule. Includes required_deployment_environments array.
RulesRequiredSignaturesCommits pushed to matching refs must have verified signatures.
RulesPullRequestRequire all commits be made to a non-target branch and submitted via a pull request before they can be merged. In the format DismissStaleReviewsOnPush:<bool>|RequireCodeOwnerReview:<bool>|RequireLastPushApproval:<bool>|RequiredApprovingReviewCount:<int>|RequiredReviewThreadResolution:<bool>. Optionally includes AllowedMergeMethods:[merge squash rebase] (allowed merge methods), DismissalRestriction:{Enabled=<bool>\|ActorID=<int>\|ActorType=<User\|Team\|IntegrationInstallation\|RepositoryRole>};... (restrict who can dismiss reviews), and RequiredReviewers:{FilePatterns=<space-separated globs>\|MinimumApprovals=<int>\|ReviewerID=<int>\|ReviewerType=Team};... (require review from specific teams). Note: actor and team IDs in DismissalRestriction/RequiredReviewers are exported and imported as-is; when migrating across organizations they are not remapped, so update them manually in the target org.
RulesRequiredStatusChecksChoose which status checks must pass before the ref is updated. An array of required status check rules, in the format do_not_enforce_on_create|required_status_checks:{context|integration}|strict_required_status_checks_policy
RulesNonFastForwardPrevent users with push access from force pushing to refs.
RulesCommitMessagePatternIndicates commit message patterns and matching. In the format Name|Negate|Operator|Pattern
RulesCommitAuthorEmailPatternIndicates commit author email patterns and matching. In the format Name|Negate|Operator|Pattern
RulesCommitterEmailPatternIndicates committer email patterns and matching. In the format Name|Negate|Operator|Pattern
RulesBranchNamePatternIndicates branch name patterns and matching. In the format Name|Negate|Operator|Pattern
RulesTagNamePatternIndicates tag name patterns and matching. In the format Name|Negate|Operator|Pattern
RulesFilePathRestrictionPrevent commits that include changes in specified file paths from being pushed to the commit graph.
RulesFilePathLengthPrevent commits that include file paths that exceed a specified character limit from being pushed to the commit graph.
RulesFileExtensionRestrictionRestrictions on file extensions for the ruleset.
RulesMaxFileSizeMaximum file size allowed to be pushed to the commit.
RulesWorkflowsRequire all changes made to a targeted branch to pass the specified workflows before they can be merged. An array of workflow rules, in the format do_not_enforce_on_create|workflows:{Path|ref|repository_id|sha}
RulesCodeScanningChoose which tools must provide code scanning results before the reference is updated. An array of code scanning rules in the format {Tool|SecurityAlertsThreshold|AlertsThreshold}
RulesCodeQualityRequire code quality checks to pass before the ref is updated. In the format Severity:<level>, where level is one of errors, warnings_and_higher, notes_and_higher, or all.
RulesCopilotCodeReviewRequest an automatic review from Copilot on matching pull requests. In the format ReviewDraftPullRequests:<bool>|ReviewOnPush:<bool>.
RulesLicenseComplianceScanningRequire license compliance scanning results before the ref is updated.
RulesCodeCoverageRequire a minimum code coverage threshold before the ref is updated. In the format MinimumCoverage:<int>|MaxCoverageDrop:<int>.
CreatedAtTimestamp of when the ruleset was created.
UpdatedAtTimestamp of when the ruleset was last updated.

Note

Fields within multi-value columns (e.g. RulesBranchNamePattern, RulesCommitMessagePattern) are written in a stable, alphabetically-sorted order. This keeps exports deterministic so re-running list produces byte-identical output for unchanged rulesets, making before/after diffs reliable.

Create Repository Rulesets

Repository Rulesets can be created from a csv file using --from-file following the format outlined in gh-migrate-rulesets list, or specifying the --source-org and/or --repos to retrieve rulesets from.

Warning

If your rulesets include the following rules, ensure that the csv has been updated to point to the updated information under your organization:

  • Bypass Actors: Update Actor ID for Teams, Roles, and Integrations
  • Status Checks: Ensure Context name exists and update Integration ID
  • Code Scanning: Ensure Tool name exists
  • Workflows: Update Repository ID to point to the correct repo/workflow
  • Required Deployments: Ensure deployment names exist for the repository
$ gh migrate-rulesets create -h                                                   
Create repository rulesets at the repo and/or org level from a file or list.

Usage:
  migrate-rules create [flags] <organization>

Flags:
      --actor-mapping string     Path and Name of CSV file mapping source bypass actor IDs to target IDs (for predefined repository roles and renamed actors)
  -d, --debug                    To debug logging
      --dry-run                  Preview ruleset creates without writing changes
  -f, --from-file string         Path and Name of CSV file to create rulesets from
  -h, --help                     help for create
      --hostname string          GitHub Enterprise Server hostname (default "github.com")
  -R, --repos strings            List of repositories names to recreate rulesets for separated by commas (i.e. repo1,repo2,repo3)
  -r, --ruleType string          List rulesets for a specific application or all: {all|repoOnly|orgOnly} (default "all")
      --source-hostname string   GitHub Enterprise Server hostname where rulesets are copied from (default "github.com")
  -s, --source-org string        Name of the Source Organization to copy rulesets from
  -p, --source-pat string        GitHub personal access token for Source Organization (default "gh auth token")
  -T, --target-repo string       Rename the destination repository when migrating a single repository's rulesets
  -t, --token string             GitHub personal access token for organization to write to (default "gh auth token")

When migrating a single repository with --source-org, use --target-repo to create the rulesets under a different repository name (a repository rename). This is useful when the destination repository has been renamed relative to the source. --target-repo requires exactly one repository via --repos and cannot be combined with --from-file (a file already contains the destination repository name).

# Rename during a single-repo migration from a source organization
$ gh migrate-rulesets create target-org --source-org source-org --repos old-repo --target-repo new-repo

When creating rulesets with --from-file, repository renames are driven by the CSV itself. Each repository-level row carries both a SourceRepositoryName and a TargetRepositoryName column. On export these values are identical; edit TargetRepositoryName to create the ruleset under a different destination repository. If TargetRepositoryName is empty, the destination defaults to SourceRepositoryName. Files exported by earlier versions that only contain a RepositoryName column remain supported and are treated as the source (and target) repository name.

If specifying --source-org and/or --repos, the CLI extension performs a live read from the source organization and attempts to map each object based on name to the new ID under the target organization:

  • Bypass Actors
    • Teams
    • Custom Repository Roles
    • Integrations
  • Status Checks
    • Context
  • Required Workflow
    • Repository

This automatic name-based translation applies to the live --source-org (and optional --repos) path and resolves the IDs called out in the warning above for teams, integrations, custom roles, required workflow repositories, and status check integrations. The --from-file path is assumed to already contain the correct target IDs; edit the exported csv directly before importing it.

create supports GitHub.com, GitHub Enterprise Server, and GitHub Enterprise Cloud with data residency through --hostname and --source-hostname. Both hostname flags default to github.com; use the target hostname with --hostname and the source hostname with --source-hostname.

Previewing changes

Use --dry-run to log the org and repository rulesets that would be created without writing any changes to the target:

gh migrate-rulesets create <target-org> --source-org <source-org> --dry-run

Mapping bypass actor IDs

When moving rulesets between organizations or instances, bypass actor IDs for teams, custom repository roles, and apps often differ on the target. Use --actor-mapping to supply a csv that maps source bypass actor IDs to their target IDs — this is required for predefined repository roles (e.g. Write, Maintain, Admin), which cannot be resolved automatically by name. The mapping applies only to the live --source-org path and cannot be combined with --from-file (for file imports, set the target IDs directly in the exported csv's bypass actor column).

See docs/predefined-repository-roles.md for the mapping csv format, a fillable template, per-platform role ID reference, and override behavior.

Note

If a bypass actor ID is not mapped and cannot be resolved automatically, the ruleset is skipped and written to the error csv file for manual follow-up.

When the command finishes it logs a summary of how many rulesets were created successfully and how many failed, for example:

Summary: 12 ruleset(s) created successfully, 2 failed

Note

Any ruleset that fails to be created is captured and written to a csv file in the current directory with the name format <org>-ruleset-errors-<date>.csv, containing the Source, RulesetName, and Error. Source is where creation was attempted: for repository-level rulesets it is in org/repo format (reflecting any --target-repo or TargetRepositoryName rename), and for organization-level rulesets it is the organization name. This includes per-ruleset creation failures as well as failures to fetch organization or repository rulesets from the source (recorded with a RulesetName of N/A), so all issues are available for easy review.

About

GitHub CLI extension to create and generate a report of repository rulesets for repos and orgs.

Topics

Resources

Contributing

Stars

12 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages