A CLI for managing large-scale code changes across a GitHub organisation, and the lifecycle of Pull Requests created.
As any company grows, you accumulate small pieces of tech debt, particularly for products that use software built by infrastructure and platform teams.
For 50 engineers, it's acceptable to ask for a 10-line change. At 500 engineers, it's a lot less reasonable.
Hopefully this CLI helps manage those code changes and the pull request lifecycle required to get them applied.
- π€ Github App creds for higher ratelimits and impersonal attribution.
- π Progress saving which lets you stop, start and resume migrations any time, or in the event of an error.
- π Batching so you can space out the work over multiple days/weeks.
- β Assign reviewers as a default if codeowners don't get assigned, never leave a PR unreviewed again
- π View a list of PRs related to the migration, in any state
darwin-arm64(macOS with Apple Silicon)darwin-amd64(macOS with Intel)linux-amd64(Linux x86_64)
export ARCH="darwin-arm64" # Change to your architecture
curl -o banshee -L "https://github.com/TheJokersThief/Banshee/releases/latest/download/banshee-${ARCH}" \
&& chmod +x banshee \
&& sudo mv banshee /usr/local/bin/Verify installation:
banshee versionCreate your global configuration (config.yaml):
github:
use_github_app: false
token: "gha_YOUR_PERSONAL_ACCESS_TOKEN"
defaults:
git_email: "your-email@example.com"
git_name: "Your Name"
organisation: "your-org"
code_reviewer: "team-slug"
options:
log_level: info
save_progress:
enabled: true
directory: ".banshee"Create your migration configuration (migration.yaml):
search_query: "file:old_config.json"
organisation: "your-org"
branch_name: "chore/update-config"
actions:
- action: replace
description: "Update old config references"
input:
glob: "**/*.json"
old: "old_config"
new: "new_config"
pr_title: "Update config references"
pr_body_file: "pr_body.md"Before running migrations, clone the target repositories:
banshee clone migration.yaml --config config.yamlExecute the migration across all matching repositories:
banshee migrate migration.yaml --config config.yamlList all PRs created by the migration:
banshee list migration.yaml --config config.yamlAutomatically merge PRs that pass all branch protections:
banshee merge migration.yaml --config config.yaml-c, --configPath to global CLI config file (default:./config.yaml)-h, --helpShow help message
version- Print banshee CLI versionclone <path>- Clone all repositories involved in the migrationmigrate <path>- Run the migration actions across repositories-j, --concurrency <n>- Number of repos to process in parallel (requirescache_repos.enabled: true)
list <path>- List PRs associated with a migrationmerge <path>- Merge PRs that pass all branch protections
For detailed help on any command, run banshee <command> --help
banshee clone examples/migration_config/migration.yaml \
--config examples/global_config/config.yaml \banshee migrate examples/migration_config/migration.yaml \
--config examples/global_config/config.yamlbanshee list examples/migration_config/migration.yaml \
--config examples/global_config/config.yaml \
--state all \
--format jsonThis assumes that you block merge to mainline branches with branch protections like "requires a PR", "required approvers: 1", "required status checks" and that they're not handled on the honour system.
This just checks the GitHub "mergeable state" is "clean" (terms determined by GitHub)
to see if the PR can be merged.
banshee merge examples/migration_config/migration.yaml \
--config examples/global_config/config.yamlBanshee requires two configuration files:
The global config file (config.yaml) contains:
- GitHub authentication (Personal Access Token or GitHub App credentials)
- Default values (git email, name, organization, code reviewer)
- Options (logging level, caching, progress saving, merge strategy)
See docs/global_config.md for complete documentation and examples/global_config/config.yaml for a full example.
Each migration has its own config file that defines:
- Repository selection (by search query, list, or all repos in org)
- Actions to perform (find/replace, run commands, YAML modifications, add files)
- PR details (title, body, draft status)
See docs/migrations.md for action documentation and examples/migration_config/migration.yaml for a complete example.
- Bash script and file template - Run a bash script and add files
- CODEOWNERS addition - Add CODEOWNERS file to repos
- JSON package version bump - Update package.json version, add a field, and remove a deprecated field
For more information, see docs/:
