2.8 KiB
Writing a Script
Use uv to create a script that depends on this library.
$ uv init --script mod.py
$ uv add --script mod.py modify-repos
Subclass {class}.GitHubScript
to define the repositories to change and what
changes to make. This uses the gh GitHub CLI, which must already be installed
and logged in.
from modify_repos import GitHubScript, GitHubRepo
class MyScript(GitHubScript):
# title used in commit and PR
title = "..."
# description used in commit and PR
body = "..."
# branch to merge into, defaults to main
target = "main"
# branch to create and PR
branch = "my-changes"
# one or more users/orgs to clone repos from
orgs = ["username"]
def select_for_clone(self, repo: GitHubRepo) -> bool:
# filter to only clone some of the available repos
return repo.name in {"a", "b", "d"}
def modify(self, repo: GitHubRepo) -> None:
# make any changes, such as add/remove files, here
...
if __name__ == "__main__":
MyScript().run()
Call uv run mod.py
, and it will clone and modify all the selected repos. PRs
will not be created unless you use MyScript(submit=True)
instead, so you can
develop and preview your changes first.
Automatic Commit
After calling modify
, the script will automatically add any tracked files
and create a commit if it detects there are uncommitted changes.
If you add a completely new file, it will not be tracked by Git yet, and this
won't be detected or committed. Therefore, you should call
{meth}.Repo.add_files
to track any new files. Other modifications, such as
changing an existing file or using {meth}.Repo.rm_files
, will already be
tracked by Git.
You can set {attr}.GitRepo.add_untracked
to also detect and add completely
new untracked files. This is disabled by default as it might end up adding files
that were generated as a side effect of other changes.
class MyScript(GitHubScript):
def modify(self, repo: GitHubRepo) -> None:
repo.add_untracked = True
...
Merge vs PR
By default, the GitHub provider creates PRs. You can instruct a repo to merge and push directly to the target instead. This is disabled by default because it provides one less opportunity to ensure your script worked correctly.
Set {attr}GitHubRepo.direct_submit
to True
to enable this merge and push
behavior.
class MyScript(GitHubScript):
def modify(self, repo: GitHubRepo) -> None:
repo.direct_submit = True
...
Updating
You may have run your script with submit enabled, then noticed that more is needed. If a branch and open PR already exist from a previous run of the script that, a force push will be used to update.