Skip to main content

Provision a repo across self-hosted GitLab, GitLab.com, and GitHub with push mirroring.

Project description

๐Ÿ‰ Hydra

One source, many mirrors. Provision a single repo on self-hosted GitLab, GitLab.com, and GitHub in one shot โ€” with push mirroring wired up so every push fans out automatically.

Hydra is a small Python CLI for teams who keep code on a self-hosted GitLab but also need it on GitLab.com and/or GitHub โ€” for open-source releases, customer access, vendor integrations, or backup. You run one command and Hydra creates the project on all three hosts, then configures GitLab's built-in push mirrors so the self-hosted copy is the only place you ever push.

                                       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                  โ”Œโ”€โ”€โ–ถ โ”‚   GitLab.com     โ”‚
                                  โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  push
   โ”‚  Self-hosted GitLab    โ”‚ โ”€โ”€โ”ค
   โ”‚  (source of truth)     โ”‚  push
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
            โ–ฒ                    โ””โ”€โ”€โ–ถ โ”‚     GitHub       โ”‚
            โ”‚                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       git push (you)

Requirements

  • Python 3.9 or newer
  • Permission to create projects/repos on each host you want to use (self-hosted GitLab, GitLab.com, GitHub)
  • A personal access token for each host (Hydra tells you exactly which scopes during setup โ€” see Token scopes)

Install

From PyPI:

pip install hydra-repo-syncer
hydra --version

From source (if you'd rather pin to a checkout, or want to hack on Hydra itself):

git clone <this-repo-url>
cd hydra
python -m venv venv && source venv/bin/activate
pip install -e .
hydra --version

After installing, the hydra command is on your PATH.


Quickstart

# 1. One-time setup โ€” pick hosts, defaults, and store tokens
hydra configure

# 2. See what *would* happen, without making any API calls
hydra create my-first-repo --dry-run

# 3. Do it for real
hydra create my-first-repo

That's it. The repo now exists on all three hosts, and any future git push to the self-hosted GitLab will mirror automatically to the other two.


Configure (one-time)

hydra configure

A four-step wizard walks you through:

Step What you provide
1. Hosts URLs for self-hosted GitLab, GitLab.com, and GitHub
2. GitHub account Your GitHub user, or an organisation name
3. Defaults Default group path; default visibility (private/public)
4. Tokens API tokens for each host, plus where to store them

Non-secret settings are saved to ~/.config/hydra/config.yaml. Tokens go to your OS keyring (macOS Keychain, Linux Secret Service) โ€” never to the YAML.

Token scopes

When you mint personal access tokens, use these scopes:

Host Required scope Mint a token at
Self-hosted GitLab api <your-host>/-/user_settings/personal_access_tokens
GitLab.com api https://gitlab.com/-/user_settings/personal_access_tokens
GitHub repo (plus admin:org if creating under an organisation) https://github.com/settings/tokens

Token resolution order

For each host, Hydra looks up the token in this order and stops at the first hit:

  1. OS keyring โ€” set via hydra configure, or directly: keyring set hydra <github|gitlab|self_hosted_gitlab>
  2. Environment variable โ€” HYDRA_GITHUB_TOKEN, HYDRA_GITLAB_TOKEN, HYDRA_SELF_HOSTED_GITLAB_TOKEN
  3. .env file in the current working directory (see .env.example)
  4. Interactive prompt (only if attached to a TTY)

This lets you use the keyring on your laptop and env vars in CI without changing anything else.


Creating repos

Two modes โ€” interactive wizard (good for one-offs), or flag-driven (good for scripts).

Interactive

hydra create

The wizard collects the repo name, description, group, visibility, GitHub destination, and mirror toggle, shows a review summary, then asks you to create now, dry-run, or cancel.

Flags

# Dry-run โ€” recommended for the first try, no API calls
hydra create my-repo -d "demo" -g platform/services --dry-run

# Real run, using defaults from config.yaml
hydra create my-repo -d "demo" -g platform/services

# Public repo, under a GitHub org, skip mirror setup
hydra create my-repo --public --github-org acme --no-mirror

Omit the name to launch the wizard; pass a name to stay in flag mode.

Flag Meaning
-d, --description Repo description
-g, --group Group path on self-hosted GitLab
--public Create as public (default is private)
--github-org <name> Create under this GitHub org instead of your user
--no-mirror Skip push-mirror setup
--dry-run Print planned actions without making API calls
--config <path> Use a non-default config file
-v, --verbose Print extra detail (group IDs, etc.)

Inspecting mirrors

hydra status my-repo --group platform/services

Shows the enabled state, last-sync status, and any errors per mirror โ€” useful when you push something and it doesn't appear on GitLab.com or GitHub.


Commands

Command Description
hydra create [name] Create the repo across all three hosts. Without name, runs the wizard.
hydra configure Onboarding wizard โ€” config + tokens.
hydra status <name> Show the self-hosted project's mirror state.
hydra config-path Print the resolved config-file path.

Run hydra <cmd> --help for full flags.


Error handling

Hydra translates HTTP failures into actionable messages:

โœ— GitLab.com authentication failed (401) while searching for group 'platform/services'

  The GitLab.com token was rejected. Rotate it at
  https://gitlab.com/-/user_settings/personal_access_tokens
  and re-run `hydra configure`, or set HYDRA_GITLAB_TOKEN in your environment.

If a failure happens after some resources have been created, the partial state is reported so you can clean up before retrying:

โš  Partial progress before the failure:
  โ€ข self-hosted GitLab repo: https://gitlab.example.com/sandbox/demo
  โ€ข gitlab.com group: https://gitlab.com/repo-syncer-managed-groups/sandbox-20260508131245

  These resources exist now. Delete them manually before retrying,
  or use a different repo name.

Config file

Lives at ~/.config/hydra/config.yaml by default. Override with --config <path> or the HYDRA_CONFIG environment variable. See config.yaml.example for the full schema:

self_hosted_gitlab:
  url: https://gitlab.example.com

gitlab:
  url: https://gitlab.com
  managed_group_prefix: repo-syncer-managed-groups

github:
  url: https://api.github.com
  org: null         # null = create under your user; or set an org name

defaults:
  private: true
  group: ""         # optional default group path on the self-hosted GitLab

Security notes

  • Tokens are never written to the YAML config.
  • Tokens injected into mirror URLs (https://oauth2:<token>@host/...) are stored on the self-hosted GitLab's remote_mirrors table. Anyone with project admin access can read them back via the GitLab API โ€” use scoped tokens.
  • Keep .env gitignored. It already is in this repo.

Development

Clone the repo and install with the dev extras:

git clone <this-repo-url>
cd hydra
python -m venv venv && source venv/bin/activate
pip install -e '.[dev]'
pytest

Unit tests cover error translation, slug generation, wizard validators, and credential injection. CI runs the same suite plus a hydra --help smoke test on every push (.gitlab-ci.yml).


License

MIT. See LICENSE.

Project details


Download files

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

Source Distribution

hydra_repo_syncer-0.0.4.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.

hydra_repo_syncer-0.0.4-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file hydra_repo_syncer-0.0.4.tar.gz.

File metadata

  • Download URL: hydra_repo_syncer-0.0.4.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for hydra_repo_syncer-0.0.4.tar.gz
Algorithm Hash digest
SHA256 b60dbb4b843ead039413b78f0d5c79e31ba6ce4e8b625072a39d9c62cc0de538
MD5 224e70cab9717b5497ac25fa471a87b0
BLAKE2b-256 add76e42d7248aa1f4e76175c2888882f115195434b932ed0749599e59c83d5f

See more details on using hashes here.

File details

Details for the file hydra_repo_syncer-0.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for hydra_repo_syncer-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 0b6f44ac7edc92b710ae63a8d71a729413977bbbdb0addd9f4f9a34f8701fa67
MD5 290513465e5b67c81eb24c1a5c6d1f18
BLAKE2b-256 d80ffac2731a2e028338eb932adffa9685933c18905d2bd55198647739906ab0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page