Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Batch GitHub Repository Operations Using GitHub Rest API

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

import shutil
from pathlib import Path

from dulwich import porcelain
from dulwich.repo import Repo
from github_rest_api import Organization, Repository, RepositoryType
org = Organization(token="", owner="legendu-net")
org
<github_rest_api.github.Organization at 0x7f40d4203b60>

Get Non-archived Public Repositories

repos = org.get_repositories(RepositoryType.PUBLIC)
repos_active = [repo for repo in repos if not repo["archived"]]
len(repos_active)
65

Clone Non-archived Repositories

for repo in repos_active:
    porcelain.clone(repo["ssh_url"])

Update GitHub Actions Workflow

!ls -lha aiutil.git/.github/
total 0
drwxrwxr-x+ 1 dclong docker  18 Jan 20 12:20 .
drwxrwxr-x+ 1 dclong docker 154 Jan 20 12:20 ..
drwxrwxr-x 1 dclong docker 156 Jan 20 12:20 workflows
!ls -lha aiutil.git/.github/workflows/
total 24K
drwxrwxr-x+ 1 dclong docker 156 Jan 20 12:20 .
drwxrwxr-x+ 1 dclong docker  18 Jan 20 12:20 ..
-rw-r--r-- 1 dclong docker 495 Jan 20 12:20 automerge.yml
-rw-r--r-- 1 dclong docker 637 Jan 20 12:20 create_pull_request.yml
-rw-r--r-- 1 dclong docker 609 Jan 20 12:20 lint.yml
-rw-r--r-- 1 dclong docker 720 Jan 20 12:20 pre-release.yml
-rw-r--r-- 1 dclong docker 546 Jan 20 12:20 release.yml
-rw-r--r-- 1 dclong docker 907 Jan 20 12:20 test.yml
def update_workflow(path: Path) -> None:
    if path.name == "docker-jupyterlab.git":
        return
    dir_wf = path / ".github/workflows"
    if not dir_wf.is_dir():
        return
    file = dir_wf / "create_pull_request.yml"
    if file.is_file():
        file.unlink()
    shutil.copy2(
        "docker-jupyterlab.git/.github/workflows/create_pr_dev_to_main.yml", dir_wf
    )


def push_changes(path):
    repo = Repo(path)
    status = porcelain.status(repo)
    if status.untracked or status.unstaged:
        porcelain.add(path)
        porcelain.commit(path, message="update workflows")
        porcelain.push(Repo(path))
for path in Path().glob("*.git/"):
    update_workflow(path)
for path in Path().glob("*.git/"):
    push_changes(path)