Skip to content

PatNei/GITHUB2FORGEJO

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Important

Mirror mode requires Forgejo v15.0.0+. A bug where authentication credentials were not properly saved when creating mirrors has been fixed in Forgejo v15.0.0 LTS. Please update to v15+ to use the mirror strategy reliably.

This script is inspired by and based on RGBCube's original version, rewritten in Bash.

GitHub ➡️ Forgejo Migration Script in Bash

This is a Bash script for migrating repositories from a GitHub user or organization account to a specified Forgejo instance. By default, it migrates all repositories, but you can filter them by using a fine-grained GitHub token with specific repository access. It supports mirroring or one-time cloning and includes a cleanup feature for removing repositories on Forgejo that no longer exist on GitHub.

Features

  • Migrates all (or selected) repositories for a GitHub user or organization.
  • User or Org Detection: Automatically detects if the account is a User or Organization.
  • Supports selecting public, private, or both repository visibilities.
  • Mirror mode: repositories stay in sync with GitHub.
  • Clone mode: one-time copy without ongoing sync.
  • Archive Transfer: Optionally transfers the archived status so archived repos remain read-only on Forgejo.
  • Skip Forks: Option to ignore forked repositories during migration.
  • Visibility Filter: Migrate only private, only public, or all repositories.
  • Dry Run Mode: Preview what would happen without making changes.
  • Optional cleanup of outdated mirrors on Forgejo.
  • Fully terminal-interactive or configurable via environment variables.

Requirements

  • bash
  • curl
  • jq
  • docker (optional, for development environment)
  • direnv (optional, for automated configuration)

Usage

1. Manual Approach

You can run the script directly:

./github-forgejo-migrate.sh

You will be prompted for required values unless you provide them via environment variables:

Variable Description
GITHUB_USER GitHub username or organization name
GITHUB_IS_ORG (Optional) Force account type (Yes/No). Auto-detected if omitted.
GITHUB_TOKEN GitHub access token. Required for private repos or Organizations.
FORGEJO_URL Full URL to your Forgejo instance (e.g., https://forgejo.example.com)
FORGEJO_USER Forgejo username or organization to own the migrated repos
FORGEJO_TOKEN Forgejo personal access token
STRATEGY Either mirror (default) or clone
MIRROR_DIRECTION When mirror: pull (GitHub→Forgejo, default) or push (Forgejo→GitHub)
PUSH_MIRROR_INTERVAL Push mirror sync interval, e.g. 8h, 1h (default: 8h). Push mirrors only
PUSH_MIRROR_SYNC_ON_COMMIT Sync push mirror on every commit (default: Yes). Push mirrors only
FORCE_SYNC Set to Yes to delete Forgejo repos that no longer exist on GitHub
MIGRATE_ARCHIVE_STATUS Set to Yes (default) to transfer the archived status of repositories
MIGRATE_FORKS Set to No to skip fork repositories during migration (default: Yes)
VISIBILITY Filter by visibility: private, public, or both (default: both)
SORT Sort repos by: created, updated, pushed, or full_name (default: pushed)
SORT_DIRECTION Sort direction: asc or desc (default: desc)
DRY_RUN Set to Yes to preview actions without executing (dry run mode, default: No)

2. Automated Development & Testing Environment

If you want to test the script without setting up a real Forgejo instance, you can use the provided Docker environment.

Validation Tests (no Docker required)

bats test/validation.bats

Input validation, default values, and settings summary output. No credentials needed.

E2E Tests (requires Docker + GitHub credentials)

The E2E tests migrate repos from your GitHub account into a throwaway Forgejo container. They assume your test account has a mix of repo types:

  • At least one public and one private repo
  • At least one forked repo
  • At least one archived repo
GITHUB_USER=youruser GITHUB_TOKEN=ghp_xxx bats test/

Or run individual suites:

bats test/strategy.bats     # clone, mirror pull, mirror push
bats test/visibility.bats   # public, private, both
bats test/options.bats      # dry-run, forks, archive, sort, force-sync

Each file spins up its own Forgejo container and tears it down after.

Full suite

./setup_and_test.sh                                # validation only
GITHUB_USER=you GITHUB_TOKEN=ghp_xxx ./setup_and_test.sh  # everything

Generate GITHUB_TOKEN

You can use either a Fine-grained token (recommended) or a Classic token.

Important

For Organizations: To migrate private repositories belonging to an organization, your token must have sufficient permissions. For Fine-grained tokens, ensure the Resource owner is set to the specific organization if your personal token doesn't grant access.

Fine-grained Token (Recommended)

  1. Go to Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens.
  2. Click Generate new token.
  3. Set Resource owner to your account.
  4. Set Repository access to All repositories (or select specific ones).
  5. Set Permissions:
    • Contents: Read-only
    • Metadata: Read-only
  6. Click Generate token.

Classic Token

  1. Go to Settings -> Developer settings -> Personal access tokens -> Tokens (classic).
  2. Click Generate new token (classic).
  3. Select scope: repo.
  4. Click Generate token.

Generate FORGEJO_TOKEN

  1. Navigate to Forgejo
  2. Click your profile at the top right
  3. Click Settings
  4. Click Applications on the left
  5. Generate a token 5a. Expand the select permissions 5b. Set repository to Read and Write
  6. Either enter when prompted or save to FORGEJO_TOKEN w/ export FORGEJO_TOKEN=<Your token here>

What It Does

  1. Account Auto-Detection: Checks if the specified GitHub account is a User or an Organization (can be overridden via GITHUB_IS_ORG).
  2. Repository Discovery: Fetches all repositories (or specific ones if using a restricted token) belonging to the target account.
  3. Cleanup (Optional): Deletes any Forgejo mirrored repositories that no longer have a source on GitHub.
  4. Migration: Migrates each repository to Forgejo using the selected strategy (mirror or clone).
  5. Archive Status (Optional): If enabled, ensures repositories archived on GitHub are also archived (read-only) on Forgejo after migration.
    • Note: This currently only applies to the clone strategy. Forgejo mirrors cannot be manually archived via the API.

FAQ

❓ What is the difference between mirroring and cloning?

  • Mirror pull (MIRROR_DIRECTION=pull): Forgejo periodically fetches updates from GitHub. The GitHub repo is the source of truth.
  • Mirror push (MIRROR_DIRECTION=push): Forgejo pushes local changes back to GitHub. The Forgejo repo is the source of truth.
  • Cloning (STRATEGY=clone): One-time copy. No ongoing sync.

❓ Can I migrate specific repositories?

Yes! While the script defaults to migrating all accessible repositories, you can limit the scope by using a GitHub Fine-grained Personal Access Token. When creating the token, select "Only select repositories" instead of "All repositories". The script will then only see and migrate the repositories you explicitly selected.

❓ What about the sort order?

The sort order returned by the GitHub API is preserved through the entire migration pipeline — repos are migrated in the exact order requested. Note that full_name uses case-sensitive ASCII ordering (e.g. Z sorts before a), which is a GitHub API limitation.

License

GPL-3.0

Copyright (C) 2024-present

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

About

Github 2 Forgejo: This script migrates your GitHub repositories to a Forgejo instance using the Forgejo API. It fetches your repositories from GitHub and automatically creates matching repositories on Forgejo. It’s ideal for backup, migration, or maintaining a self-hosted mirror of your GitHub projects.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages