No description
  • Shell 97.3%
  • Dockerfile 2.7%
Find a file
Ghibranalj 920673d96d
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m15s
chore: change repo name & use my registry for docker compose
2026-04-01 22:25:37 +07:00
.forgejo/workflows chore: change repo name & use my registry for docker compose 2026-04-01 22:25:37 +07:00
.dockerignore add docker 2026-03-31 16:32:25 +07:00
.gitignore feat: add new stategy to sync with --reverse using forgejo API 2026-04-01 10:14:50 +07:00
convert-mirrors.sh feat: add new stategy to sync with --reverse using forgejo API 2026-04-01 10:14:50 +07:00
docker-compose.yml chore: change repo name & use my registry for docker compose 2026-04-01 22:25:37 +07:00
Dockerfile Add GitHub organization repository sync support 2026-03-31 17:28:13 +07:00
github2forgejo.sh feat: add new stategy to sync with --reverse using forgejo API 2026-04-01 10:14:50 +07:00
README.md feat: add new stategy to sync with --reverse using forgejo API 2026-04-01 10:14:50 +07:00
template.env Add GitHub organization repository sync support 2026-03-31 17:28:13 +07:00

github2forgejo

Note: This is a fork of github2forgejo by MohamedElashri.

Oneway bulk GitHub to Forgejo mirror script. Non-destructive (no deletes). Imports all repositories owned by a user or organization into a Forgejo user or organization as mirrors (default) or one-time clones. On reruns, mirrors are force-synced and the default branch HEAD is verified to match GitHub.

Features

  • Oneway mirror: GitHub -> Forgejo only
  • Bulk, all-or-nothing import of owned repos
  • Always authenticated to GitHub
  • No tokens in clone URLs (auth passed via API payload)
  • Optional .env loading
  • Optional cron install for continuous mirroring
  • Automatic mirror sync on rerun and HEAD verification

Usage

Quick start with .env:

# 1) Copy and edit the template
cp template.env .env

# 2) Run a mirror import (safe to rerun; will sync and verify)
./github2forejo.sh --env ./.env --strategy mirror

# 3) Optional: install a daily cron at 02:00 using your .env
./github2forejo.sh --env ./.env --strategy mirror --install-cron

Run with CLI args (no .env):

export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export FORGEJO_TOKEN=forgejo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Sync personal user repos
./github2forejo.sh \
  --github-user <Github_Username> \
  --forgejo-url https://forgejo.example.com \
  --forgejo-user <Forgejo_Username> \
  --strategy mirror

Sync organization repos:

./github2forejo.sh \
  --github-org <Github_Org> \
  --forgejo-url https://forgejo.example.com \
  --forgejo-user <Forgejo_Org> \
  --strategy mirror

Clone once (no continuous updates):

./github2forejo.sh --env ./.env --strategy clone

Reverse mode (Forgejo → GitHub):

./github2forejo.sh \
  --github-user <Github_Username> \
  --forgejo-url https://forgejo.example.com \
  --forgejo-user <Forgejo_Username> \
  --reverse

Custom cron schedule:

./github2forejo.sh --env ./.env --strategy mirror \
  --install-cron \
  --cron-schedule "30 3 * * *"

Options (CLI)

Option Required Type Default Description
--github-user Conditional* string none GitHub username for personal repos. Use --github-org for organizations.
--github-org Conditional* string none GitHub organization name for organization repos. Use --github-user for personal repos.
--forgejo-url Yes string none Forgejo base URL. Must start with https://. Can be set by FORGEJO_URL.
--forgejo-user Yes string none Forgejo user or org to receive the repos. Can be set by FORGEJO_USER.
--strategy No enum mirror mirror for continuous updates, clone for one-time import. Can be set by STRATEGY.
--reverse No flag false Reverse mode: mirror Forgejo → GitHub instead of GitHub → Forgejo. Requires git.
--env No path none Load key=value pairs from a .env file. CLI overrides .env.
--install-cron No flag false Append a crontab entry for periodic mirroring. Can be set by INSTALL_CRON=true.
--cron-schedule No string 0 2 * * * Cron expression for --install-cron. Can be set by CRON_SCHEDULE.
-h, --help No flag n/a Show help and exit.

*Exactly one of --github-user or --github-org is required (unless set via environment variable).

Environment variables

Variable Required Purpose
GITHUB_TOKEN Yes GitHub PAT with read access to your repos. Always used.
FORGEJO_TOKEN Yes Forgejo token that can create/import repos for the target user/org.
GITHUB_USER Conditional* GitHub username for personal repos. May be provided via CLI instead.
GITHUB_ORG Conditional* GitHub organization name for org repos. May be provided via CLI instead.
FORGEJO_URL Yes Forgejo base URL (must be https). May be provided via CLI.
FORGEJO_USER Yes Forgejo user/org target. May be provided via CLI.
STRATEGY No mirror or clone. Defaults to mirror.
REVERSE No true or false. Enable Forgejo → GitHub mode. Defaults to false.
CRON_SCHEDULE No Cron expression, defaults to 0 2 * * *.
INSTALL_CRON No true or false. Defaults to false.

*Exactly one of GITHUB_USER or GITHUB_ORG is required (unless specified via CLI flag).

Docker usage

Docker support is available for scheduled (cron) mirroring.

Quick start with Docker Compose

# 1) Create a .env file with your configuration
cp template.env .env
# Edit .env with your tokens and settings

# 2) Start the container (runs on schedule)
docker-compose up -d

# 3) View logs
docker-compose logs -f

# 4) Stop the container
docker-compose down

Environment variables for Docker

All required variables must be set in .env or docker-compose.yml:

Variable Required Purpose
GITHUB_TOKEN Yes GitHub PAT with read access to your repos.
FORGEJO_TOKEN Yes Forgejo token that can create/import repos for the target user/org.
GITHUB_USER Conditional* GitHub username for personal repos.
GITHUB_ORG Conditional* GitHub organization name for org repos.
FORGEJO_URL Yes Forgejo base URL (must be https).
FORGEJO_USER Yes Forgejo user/org target.
STRATEGY No mirror or clone. Defaults to mirror.
CRON_SCHEDULE No Cron expression, defaults to 0 2 * * * (daily at 2 AM).

*Exactly one of GITHUB_USER or GITHUB_ORG is required.

Note: The Docker setup runs in cron mode only. For one-time imports, use the script directly on your host.

Reverse mode (Forgejo → GitHub)

By default, this script syncs from GitHub to Forgejo. The --reverse flag flips the direction, mirroring your Forgejo repositories back to GitHub.

How it works:

  • Fetches all repos from the specified Forgejo user or organization
  • Creates corresponding repos on GitHub if they don't exist
  • Uses git clone --mirror to copy all branches and tags
  • Skips repos that are already up-to-date (verified by SHA comparison)
  • Preserves repository visibility (private/public)

Requirements:

  • git must be installed on the system
  • GITHUB_TOKEN must have repo creation permissions
  • FORGEJO_TOKEN must have read access to your Forgejo repos

Example:

# Sync Forgejo user repos to GitHub user
./github2forgejo.sh \
  --github-user myghuser \
  --forgejo-url https://forgejo.example.com \
  --forgejo-user myforgejouser \
  --reverse

# Sync Forgejo org repos to GitHub org
./github2forgejo.sh \
  --github-org myghorg \
  --forgejo-url https://forgejo.example.com \
  --forgejo-user myforgejoorg \
  --reverse

Important notes:

  • Reverse mode uses git for syncing, not the Forgejo mirror API
  • Only one-way sync is supported (use --reverse for Forgejo→GitHub, omit it for GitHub→Forgejo)
  • Existing repos on GitHub are updated in-place
  • Verification is performed after each sync to ensure the SHA matches

Helper scripts

Convert mirror repos to regular repos

The convert-mirrors.sh helper script converts mirror repositories to regular repositories. This is useful when you want to stop mirroring and maintain the repos independently on your Forgejo instance.

# Interactive mode - select repos with fzf
./convert-mirrors.sh

# Convert all mirror repos
./convert-mirrors.sh --all

# With custom URL and token
./convert-mirrors.sh --url https://forgejo.example.com --token your_token

# Get help
./convert-mirrors.sh --help

Options:

Option Description
--token API access token
--url Forgejo instance URL (default: from .env or CLI)
--all Convert all mirror repos (skip fzf selection)
-h Show help message

Environment variables:

  • FORGEJO_TOKEN - API access token
  • FORGEJO_URL - Forgejo instance URL

.env example

# Required tokens
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FORGEJO_TOKEN=forgejo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Required source: specify exactly one
GITHUB_USER=<Github_Username>    # For personal repos
# GITHUB_ORG=<Github_Org>        # For organization repos

# Required targets
FORGEJO_URL=https://forgejo.example.com
FORGEJO_USER=<Forgejo_Username>

# Optional
STRATEGY=mirror
CRON_SCHEDULE=0 2 * * *
INSTALL_CRON=false

Behavior and scope

  • One way only: GitHub to Forgejo.
  • Bulk, all or nothing: imports all repos from the specified GitHub user or organization; no per-repo selection.
  • On reruns in mirror mode: each existing mirror is force-synced, then the default branch HEAD is verified to match GitHub. If mismatched, the script reports it.
  • Private repos are mirrored when the GitHub token permits access.
  • Tokens are not embedded in clone URLs; authentication is passed via the Forgejo migrate API payload.