Script to batch-delete all existing labels in the repositories of a GitHub organization and recreate them based on a standard configuration defined in a local JSON file.
- GitHub CLI (
gh) installed jqinstalled- An active
ghauthentication with sufficient permissions on the org (reposcope, plusadmin:orgif you need to read private repos/org settings)
gh auth loginIf you already have a GITHUB_TOKEN environment variable set, gh will use it automatically instead of the interactive login. To use the credentials saved by gh auth login instead:
unset GITHUB_TOKEN
gh auth loginCheck authentication status with:
gh auth statusThe script also checks this automatically at startup and will fail with an error if gh is not authenticated.
Create a labels.json file (or any name you prefer) with the list of desired labels:
[
{ "name": "bug", "color": "d73a4a", "description": "Something isn't working" },
{ "name": "enhancement", "color": "a2eeef", "description": "New feature or request" },
{ "name": "Low Priority", "color": "cfd3d7", "description": "Low priority issue" }
]chmod +x reset-labels.sh
./reset-labels.sh [options] [org] [labels.json][org]— GitHub organization name (optional, default:top-solution)[labels.json]— path to the JSON file with the labels (optional, default:labels.jsonin the current directory)
-h,--help— show usage and exit--dry-run— show what would be deleted/created without making any actual changes
# use default org (top-solution) and labels.json in the current directory
./reset-labels.sh
# specify a different org
./reset-labels.sh my-org
# use a different JSON file
./reset-labels.sh my-org config/labels-prod.json
# preview changes without applying them
./reset-labels.sh --dry-run my-org
# show help
./reset-labels.sh -hFor each repository in the organization:
- Deletes all existing labels in the repo
- Creates the new labels read from the JSON file
With --dry-run, the script only prints what it would delete and create, without performing any actual changes.
- This operation is destructive: deleting labels also removes their association with issues/PRs that used them.
- The script iterates over all repositories in the org (limit 1000). For orgs with many repos, consider adding a
sleepbetween iterations to avoid hitting GitHub's API rate limit. - Recommended: run with
--dry-runfirst, or test on a single repo / staging org, before running the script for real in production.