Skip to main content

ghfanout

GitHub Pages Coverage PyPI version Python versions License: MIT

Configuration-as-Code for many GitHub repositories. Manage shared configuration files (.gitignore, pom.xml, pyproject.toml, package.json, …) in one place — a single source of truth — and fan them out as pull requests (or direct pushes). Edit a file once, run one command, and every affected repository gets a PR.

  • No git clone of target repositories — everything goes through the GitHub Git Data API, so it works with nothing more than pip install
  • Kustomize-like base + overlay composition, with Jinja2 templating for per-repository values and per-repository remapping of distribution paths
  • Designed for microservice fleets that cannot be consolidated into a monorepo

Installation

pip install ghfanout        # or: uv tool install ghfanout

Requires Python 3.11 or later (tested on 3.11–3.14).

To upgrade to the latest release:

pip install --upgrade ghfanout   # or: uv tool upgrade ghfanout

Quick start

# 1. Generate a config repository scaffold (with a working sample)
ghfanout init ./my-config --org myorg
cd my-config

# 2. Compose base + overlay locally and inspect the result (no git operations, no network)
ghfanout build example-service           # output: dist/example-service/

# 3. Authenticate, preview the diff against the real repository, then deploy
export GHFANOUT_TOKEN=ghp_xxxx
ghfanout deploy example-service --dry-run
ghfanout deploy example-service          # opens a PR if there is a diff

How it fits together — base/ holds the content, overlays/ selects who gets it:

ghfanout.yaml                # destination host / org
.ghfanoutignore              # optional: files under base/ to exclude (.gitignore syntax)
base/
  common/                    # distributed to every repository
    .gitignore
  java-service/              # a profile: distributed only to repos that opt in
    pom.xml.jinja            # .jinja = Jinja2 template, rendered per repository
  python-service/
    pyproject.toml
  node-service/
    package.json
overlays/
  user-service/              # directory name = target repository name
    manifest.yaml            # which profiles / branches this repo receives
  api-gateway/
    manifest.yaml

Documentation

Full documentation: https://seiya-koji.github.io/ghfanout/

  • Getting Started — install → init → build → deploy, end to end
  • Configuration — config repository layout, ghfanout.yaml, manifest.yaml, per-branch overrides
  • Templates — embedding per-repository values with Jinja2
  • Authentication — PAT and GitHub App
  • CLI Reference — commands, options, and behavior details
  • Development — local setup, tests, lint, and commit conventions

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ghfanout-0.3.0.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ghfanout-0.3.0-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

Details for the file ghfanout-0.3.0.tar.gz.

File metadata

  • Download URL: ghfanout-0.3.0.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ghfanout-0.3.0.tar.gz
Algorithm Hash digest
SHA256 fef4dcad42cbccc8f5839a8021bb1a0b1c1078ce6dcf23da1c2b4af146179581
MD5 55ea61568828aca105c1671476c25701
BLAKE2b-256 33bb28673e41fb7726f807927f7eddd51cf4b4a78477c8a05a9a46b7cb1b219c

See more details on using hashes here.

File details

Details for the file ghfanout-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: ghfanout-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 26.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ghfanout-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0d7bfca8eba09ec19b1cc7bd3428d59f680300e2e7a576fd233a9b9a445d1f6e
MD5 f2e39d3566955a43dce7fd62880f0765
BLAKE2b-256 bcc240602163b80a2cd0c014a6672c18d71a33f54167479fc76781262f9e3dde

See more details on using hashes here.

Release history Release notifications | RSS feed

0.4.0

2 files

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page