Skip to content

About

Utility to synchronize some labels between GitHub repositories

Topics

Resources

Security policy

Stars

0 stars

Watchers

7 watching

Forks

Repository files navigation

Docker Repository on Quay

GitHub label synchronization utility

Synchronize labels from one repository (leader) to other repos.

The tool takes a source repository (the private giantswarm/giantswarm) and any number of target repositories (our public giantswarm/roadmap as well as customer repositories). Configured rules decide which labels are synchronized.

If the term "synchronization" raises high expectations: labels are actually copied in one direction only, from the leader repo to the target repo(s). If a label already exists in the target, it gets updated for color and description.

Configuration

Take look at config.yaml for an example configuration file.

The rules part defines a list of rules, which get applied from first to last.

A rule applies if the label name fully matches the pattern (which is a Python regex). Partial matches are not enough.

If several rules apply, the last applying rule defines whether the label is included or ignored.

If a label (by its name) is not matched to any rule's pattern, it gets ignored (not synced).

Usage

docker build -t quay.io/giantswarm/github-label-sync .

docker run --rm -ti \
  -v $HOME:/home/user \
  quay.io/giantswarm/github-label-sync \
  --token-path /home/user/.github-token

The tool will present you all actions that it would take, then you have to confirm that you want to proceed.

If used with --dry-run, no synchronization is happening and no confirmation is requested.

Use the --conf option to specify a configuration file path other than the default ./config.yaml.

Automated synchronization

Label sync runs automatically once a week (Mondays 06:00 UTC) via the .github/workflows/label-sync.yaml GitHub Actions workflow, so target repos stay in sync without anyone running the container by hand. It authenticates as the dedicated giantswarm-label-sync GitHub App and runs cli.py --yes. The App is installed on all repositories of the org with issues:write (labels are read and written through the Issues API) and contents:read (only used to fetch data/customers.yaml from the leader).

You can also trigger it manually from the Actions tab ("Sync labels to customer repos" → Run workflow), with a dry_run toggle to preview the plan without applying any changes.

Unattended flags

  • --yes — apply the plan without the interactive confirmation prompt (for CI / cron runs).
  • --max-jobs N — apply at most N label operations per run (default 400, 0 = no limit) and defer the rest to the next run. The full plan is still printed, the deferred count shows up as a ::notice:: annotation, and the run stays green. GitHub allows roughly 500 content-creating API requests per hour and 80 per minute per App installation, and the installation token is only valid for one hour, so a larger plan (for example the first sync of a new customer repository, or the initial backlog) is spread over several runs. Writes are paced at a little under 80 per minute. To catch up faster than weekly, dispatch the workflow by hand with the max_jobs input, leaving at least 75 minutes between the starts of two runs.
  • GITHUB_TOKEN env var — read the token from the environment instead of the default ~/.github-token file, so unattended runs need not write the secret to disk. An explicit --token-path always takes precedence over the env var, so local use is unaffected by a GITHUB_TOKEN exported for other tools (e.g. the gh CLI).

A target or customer repository that cannot be read is logged and skipped, so the other repositories are still synchronized. A repository that provably does not exist (for example a stale entry in data/customers.yaml) only produces a warning (a ::warning:: annotation on the Actions run) and the run stays green. "Provably" means: the run uses an App installation token with access to all repositories of the organization, and the repository is not in the installation's repository list. Every other read error, including a 404 that may also mean "no access" (a personal token, or an installation limited to selected repositories), still ends the run with exit code 1.

If a scheduled run fails, the workflow posts a warning with the run log link to #team-planeteers (via the TEAM_PLANETEERS_SLACK_WEBHOOK_URL secret), so a broken Monday run does not silently let label drift creep back in.

About

Utility to synchronize some labels between GitHub repositories

Topics

Resources

Security policy

Stars

0 stars

Watchers

7 watching

Forks

Releases

Used by

Contributors

Languages