/ghrepocleanup

A tool for working with the GitHub API to clean up repositories.

Primary LanguageSwiftMIT LicenseMIT

ghrepoclean

In its current form, this is a tool which iterates over all of the active repositories in a single GitHub organization and, where necessary, invokes GitHub's "rename branch" functionality to switch the default branch name from master to main. See below for detailed information on the tool's operation at runtime.

This version of the implementation (as of March 2021) makes heavy use of the new experimental concurrency support in Swift 5.4. A few informative references:

Successful Use By Vapor

This tool, as it existed at commit 9c27894a4afe5b7d29931c525189086698b45f09, was invoked for the Vapor GitHub organization on March 11, 2021; it processed 63 repositories, correctly bypassed those whose default branch was already correctly named, and successfully renamed every remaining repository's default branch with zero errors. The code was built and run using the 2021-02-26 Swift trunk development snapshot toolchain (several later versions having had showstopping issues with the actively evolving concurrency implementation) in Xcode 12.5 beta 3. It took approximately 6 minutes to build and run from start to finish from a fully cleaned state, of which the build step (as expected) took by far the majority.

GitHub API interface

The interface to GitHub uses the traditional REST API. All of the common model types accepted by and/or returned by the various APIs used by this code have been built out manually as Codable types with NetworkRequest conformances (see the dependencies section below). These models, along with a set of namespaced utility methods for invoking the APIs (those which have been coded thus far, at least), are set out in separate source files in what is intended to be modular fashion, with the intent of either extending them further, or possibly switching to making use of the OpenAPI description for automated coverage.

Dependency Notes and Praise

The code invokes GitHub's API through AsyncHTTPClient, as encapsulated by Thomas Krajacic's excellent NetworkClient package (the latter of which is a work in progress but well worth keeping an eye on!).

ArgumentParser and Logging also make appearances, and the code also borrows a few utilities from Vapor's AsyncKit.

Note: While Vapor's ConsoleKit is listed as a dependency in Package.swift, at the time of this writing, it is not actually used by this code. That may or may not change later.

Some details

Private and archived repositories are ignored, as are any repository whose default branch is not master. Forks and pull requests are updated as per GitHub's guidelines for renaming the default branch; the rules are identical to performing the rename through the Web interface. Those rules, as they were presented by GitHub at the time of this writing, are as follows:

Renaming this branch:

Will update [N] pull requests targeting this branch across [N] repositories. Will update [N] branch protection rule that explicitly targets main. Will not update your members' local environments.

Your members will have to manually update their local environments. We'll let them know when they visit the repository, or you can share these commands:

git branch -m main <BRANCH>
git fetch origin
git branch -u origin/<BRANCH> <BRANCH>