GITHUB2FORGEJO
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.
Install / Use
/learn @PatNei/GITHUB2FORGEJOREADME
[!WARNING] Known Issue: There is a bug in Forgejo where authentication credentials (personal access tokens) are not properly saved when creating mirrors. The initial clone succeeds, but subsequent sync attempts fail. Consider using the
clonestrategy as a workaround until this is fixed.
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.
- Smart Detection: Automatically detects if the account is a User or Organization.
- Supports both public and private repositories.
- 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.
- 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
bashcurljqdocker(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 |
| 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) |
| 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.
-
Configure Environment: Create a
.envfile (or usedirenvwith the provided.envrc):cp .envrc.example .env # Edit .env and add your GITHUB_USER and GITHUB_TOKEN -
Launch Environment and Run Migration:
./setup_and_test.shThis script will:
- Launch a Forgejo container on
http://localhost:3000. - Create an admin user (
testuser). - Generate a Forgejo token and save it to your
.env. - Automatically execute the migration script.
- Launch a Forgejo container on
-
Inspect Results: Visit
http://localhost:3000and log in with:- User:
testuser - Password:
Password123!
- User:
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)
- Go to
Settings->Developer settings->Personal access tokens->Fine-grained tokens. - Click
Generate new token. - Set Resource owner to your account.
- Set Repository access to
All repositories(or select specific ones). - Set Permissions:
Contents: Read-onlyMetadata: Read-only
- Click
Generate token.
Classic Token
- Go to
Settings->Developer settings->Personal access tokens->Tokens (classic). - Click
Generate new token (classic). - Select scope:
repo. - Click
Generate token.
Generate FORGEJO_TOKEN
- Navigate to Forgejo
- Click your profile at the top right
- Click
Settings - Click
Applicationson the left - Generate a token 5a. Expand the select permissions 5b. Set
repositorytoRead and Write - Either enter when prompted or save to FORGEJO_TOKEN w/
export FORGEJO_TOKEN=<Your token here>
What It Does
- Account Auto-Detection: Checks if the specified GitHub account is a User
or an Organization (can be overridden via
GITHUB_IS_ORG). - Repository Discovery: Fetches all repositories (or specific ones if using a restricted token) belonging to the target account.
- Cleanup (Optional): Deletes any Forgejo mirrored repositories that no longer have a source on GitHub.
- Migration: Migrates each repository to Forgejo using the selected
strategy (
mirrororclone). - 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
clonestrategy. Forgejo mirrors cannot be manually archived via the API.
- Note: This currently only applies to the
FAQ
❓ What is the difference between mirroring and cloning?
- Mirroring: Keeps the Forgejo repository in sync with the GitHub source.
- Cloning: Copies the repo once. No updates will occur after that.
❓ 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.
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/>.
Related Skills
apple-reminders
344.1kManage Apple Reminders via remindctl CLI (list, add, edit, complete, delete). Supports lists, date filters, and JSON/plain output.
gh-issues
344.1kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
oracle
344.1kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
