Skip to content

Instantly share code, notes, and snippets.

@andrew222651
Last active June 17, 2026 14:43
Show Gist options
  • Select an option

  • Save andrew222651/4d6e57b1564612dc0464d8f387b58758 to your computer and use it in GitHub Desktop.

Select an option

Save andrew222651/4d6e57b1564612dc0464d8f387b58758 to your computer and use it in GitHub Desktop.
Check if branch only updates submodules to commits from protected GitHub branches
#!/usr/bin/env python3
# /// script
# dependencies = [
# "pygit2==1.19.3",
# "typer==0.16.0",
# "PyGithub==2.6.1",
# ]
# ///
import os
import github
import pygit2
import typer
g = github.Github(auth=github.Auth.Token(os.environ["GH_TOKEN"]))
repo = pygit2.Repository(".")
def main(base_sha: str, head_sha: str):
diff = repo.diff(base_sha, head_sha)
changed_files = {patch.delta.new_file.path for patch in diff}
submodules = set(repo.listall_submodules())
if not changed_files.issubset(submodules):
print("not all changed files are submodules")
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("only_submodules=false\n")
return
for changed_subrepo in changed_files:
subrepo = pygit2.Repository(changed_subrepo)
branches = subrepo.branches.local
containing_branches = {
b for b in branches
if subrepo.descendant_of(subrepo.branches.get(b).target, subrepo.head.target)
or subrepo.branches.get(b).target == subrepo.head.target
}
remote = subrepo.remotes["origin"].url.removeprefix("https://github.com/").removeprefix("git@github.com:").removesuffix(".git")
gh_repo = g.get_repo(remote)
for gh_branch in gh_repo.get_branches():
if gh_branch.name not in containing_branches:
continue
if gh_branch.protected:
break
else:
print(f"{changed_subrepo} is not from a protected branch")
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("only_submodules=false\n")
return
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("only_submodules=true\n")
if __name__ == "__main__":
typer.run(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment