Migrate from GitHub to Forgejo

Moving from GitHub to self-hosted Forgejo carries repositories, issues, pull requests, releases, labels, milestones, comments and wikis through documented commands, while Actions, secrets and integrations need deliberate rework. This page sets out the sequence, risks and cost drivers.

On this page

Migrate from GitHub to Forgejo: what moves, who does it, and how much effort

Git history and most collaboration metadata move from GitHub to Forgejo with documented commands, while GitHub Actions workflows and secrets need rework. If your renewal, licensing change, residency requirement or lock-in concern is pushing you toward a self-hosted forge, expect the repositories, issues, pull requests, releases, labels, milestones, comments and wikis to come across through dump-repo and restore-repo, and plan a separate track for CI and credentials. The Forgejo command-line documentation lists the selectable units, so run a trial export on one representative repository and check the restored issue numbers, comments and wiki pages before you schedule the full move.

In most organizations the platform or DevOps team runs the migration, because it owns the forge, the runners and the access model. An implementation partner usually adds value on scope, cutover sequencing and hardening: deciding which repositories move first, how to freeze pushes during the final sync, how branch protection and team permissions are rebuilt, and how backups and monitoring are set up on the new server. Ask any partner for a written scope that names the repositories, the metadata units in scope and the acceptance checks, since a fixed scope is what keeps effort predictable.

Effort depends mainly on the number of repositories, how many workflows they contain, and how many secrets and external integrations point at GitHub. Forgejo's documentation falls back to .github/workflows when .forgejo/workflows is absent, but it notes that migrated workflows will most likely need some minimal tweaking, and Actions secrets never export, so each one must be re-created by its owner. The Forgejo upgrade and release documentation also describes support windows you should weigh when choosing a version to standardize on. Confirm exact effort and timing with your own inventory of repositories and pipelines, not with generic estimates.

Which GitHub features map cleanly to Forgejo and which need rework

This table maps each GitHub feature to its Forgejo equivalent and marks it as clean, needs rework or gap. Read the migration column first, then check the notes on Actions, webhooks and app integrations, which need testing against the Forgejo version you run.

FeatureForgejo equivalentStatusWhat to check
Repositories and Git historyGit repositories hosted in ForgejoCleanMirror with all refs so branches and tags move unchanged.
IssuesForgejo issues, carried by dump-repoCleanConfirm issue numbering and closed states after restore-repo.
Pull requestsForgejo pull requests, carried by dump-repoCleanReview merged and closed PRs, plus any PR review comments.
CommentsIssue and PR comments, carried by dump-repoCleanCheck that comment authors and timestamps appear as expected.
Labels and milestonesForgejo labels and milestones, carried by dump-repoCleanSpot-check colors, descriptions and milestone due dates.
Releases and release assetsForgejo releases and assets, carried by dump-repoCleanConfirm asset downloads work and large files were not truncated.
WikiForgejo wiki, carried by dump-repoCleanVerify internal links, since wiki link paths can differ.
Actions workflowsForgejo Actions, with fallback to .github/workflowsNeeds reworkForgejo Actions is not compatible with GitHub Actions. Expect to adjust runners, actions and syntax.
Actions secretsForgejo repository and organization secretsNeeds reworkSecrets do not export from GitHub. Re-create each one and record its owner.
WebhooksForgejo webhooksNeeds reworkRecreate endpoints and payload settings, then confirm behavior in the Forgejo documentation for your version.
Branch protection rulesForgejo branch protectionNeeds reworkConfirm required reviews, status checks and push rules match your policy in the Forgejo documentation for your version.
GitHub Apps and OAuth integrationsNo direct equivalent in ForgejoGapIdentify each app, then find a replacement, a webhook-based integration or a custom service. Confirm with the Forgejo documentation.

What data leaves GitHub and how to carry it over

Moving from GitHub to Forgejo is four separate jobs, not one export. Git history, repository metadata, Actions workflows and secrets each leave GitHub by a different route, and each needs its own check. The cards below cover what moves, what does not, and what must be rebuilt around the repositories.

Git history by clone or mirror

Commits, branches and tags move with a mirror clone of each repository, which is the most reliable part of the migration. Run the mirror against every branch and tag you intend to keep, then confirm commit counts and tag lists on both sides. Check the size of each repository early, because GitHub recommends keeping the .git folder under 10 GB and enforces a 100 MB file limit. Large binaries in history will need a separate plan, such as Git LFS or removal before the move.

Metadata with dump-repo and restore-repo

The Forgejo command-line tools export issues, pull requests, reviews, labels, milestones, releases, comments and the wiki from GitHub, then load them into Forgejo. Choose units explicitly so you do not carry data you do not need, and run a test dump on one repository first. Expect some drift in attribution and timestamps for imported comments, and confirm that pull request references still resolve after the restore.

Actions workflows through the fallback

Forgejo reads workflows from .forgejo/workflows and falls back to .github/workflows when that directory is missing, so existing files can run without being renamed first. Forgejo Actions is built to feel familiar to GitHub Actions users but is not compatible with it. Plan to review each workflow for marketplace actions, runner labels, event names and cache steps, and test them on a Forgejo runner before cutting over.

Secrets must be re-created by hand

GitHub Actions secrets and variables do not export, so every token, deploy key and cloud credential must be issued again in Forgejo. Inventory which workflows read which secrets before the cutover, rotate credentials that were shared widely, and record the new values in your secrets manager rather than in repository settings alone. Ask the team who owns each deploy key, since that owner is usually the person who must approve its replacement.

Integrations to rebuild

Webhooks, GitHub Apps and OAuth connections point at GitHub and stop working once repositories move. Rebuild the links to CI runners, container registries, chat notifications and deployment tools, and confirm that each one accepts events from the new forge. Build an inventory from the GitHub organization settings and from the deployment tools' configuration, since many of these connections were created by individuals and are not listed centrally.

API limits on bulk export

Scripted exports through the GitHub REST API are capped at 5,000 requests per hour for personal access tokens, so a large organization may need to run exports in batches over several hours. Use a dedicated token for the migration, schedule the largest repositories first, and log which items failed so a rerun picks them up. Confirm the token scopes you need before you start, because a failed export late in the window costs time you may not have.

The migration sequence from inventory to decommission

This sequence moves GitHub repositories and their collaboration metadata to Forgejo in controlled stages, so each repository reaches a verified state before GitHub access is removed. Each step closes with a named record that the next step depends on.

  1. Inventory repositories, dependencies and integrations

    Start by listing every repository in scope with its owner, size, default branch, open issues and pull requests, releases, wiki use and Actions workflows. Record every dependency on GitHub, including webhooks, GitHub Apps, OAuth applications, deploy keys, package registries, badges, bots and external CI systems that call GitHub APIs. Note which Actions secrets exist, since secret values never export and must be re-created in Forgejo. The output is an inventory register with one row per repository and one row per integration, reviewed by the repository owners. Confirm repository size limits and any files above GitHub's 100 MB file limit before the pilot, because large files need a decision on Git LFS or removal.

  2. Pilot one repository with dump-repo and restore-repo

    Choose a low-risk repository with issues, pull requests, labels, milestones and a wiki, then run Forgejo's dump-repo command against it with the unit selection that matches your inventory. Load the result into a test Forgejo instance with restore-repo, and compare counts of issues, pull requests, comments, releases, labels and milestones against GitHub. Check that attachments and wiki pages arrived and that authors and timestamps look right. The output is a pilot restore report listing what matched, what was missing and any manual fixes, which becomes the template for the rest of the migration. Agree the report with the repository owner before scaling up.

  3. Adapt workflows and map secrets in the test instance

    Forgejo falls back to .github/workflows when .forgejo/workflows is absent, so existing workflows may run without changes. Migrated workflows will most likely need minimal tweaks, because Forgejo Actions is designed to be familiar to GitHub Actions users but is not compatible with it. Move the workflows into .forgejo/workflows where you want Forgejo-specific behavior, check actions referenced by the workflows exist on your Forgejo runners, and assign runners to labels the jobs require. Re-create each secret manually in the Forgejo repository or organization settings, using the list from the inventory. The output is a workflow test log showing which jobs passed on Forgejo runners and a secrets checklist signed by the repository owner.

  4. Run a parallel period with mirrored history

    Keep GitHub as the system of record while teams work in both places. Mirror the Git history to Forgejo with a clone or mirror push, and schedule repeated runs of the export and restore steps for the metadata that changes, such as new issues and comments, so the two sides stay close. Compare branch heads, tag lists and open item counts on each sync, and record every difference. Confirm that webhooks and CI triggers fire only once, so builds and notifications are not duplicated. The output is a parallel run log showing the sync results and a list of open discrepancies with owners, which must reach zero before cutover.

  5. Execute cutover with a freeze window

    Announce a freeze window in which no one merges, opens or edits items on GitHub for the affected repositories. Run a final dump-repo export, restore it into Forgejo, and repeat the comparison from the parallel run. Then update remote URLs on developer machines and in build systems, move DNS or internal links that point to the old location, and enable the production Forgejo runners and webhooks. Confirm access for each team before lifting the freeze. The output is a cutover runbook with timestamps for each action, the names of the people who executed and verified each step, and a rollback path that states who decides to revert and how.

  6. Verify production and decommission GitHub access

    After a defined stabilization period agreed in advance, check that builds, deployments, package publishing and integrations work from Forgejo, and that teams can clone, push, review and file issues. Remove or disable GitHub webhooks, deploy keys, GitHub Apps and tokens, revoke personal access tokens used for migration, and set GitHub repositories to archived or read-only if you keep them for reference. Record the retention decision for GitHub data and where the exported archive is stored. The output is a signed-off decommission checklist covering each repository, each revoked credential and the owner who approved the change.

How to run GitHub and Forgejo side by side before cutover

Run GitHub as the system of record until cutover, and treat Forgejo as a rehearsal copy that is refreshed on a schedule. Git history is the part that can stay live: keep a mirror of each repository current so that every branch and tag is available on Forgejo before anyone depends on it. The metadata is different. Issues, pull requests, comments, labels, milestones, releases and the wiki come across through the dump-repo and restore-repo commands in the Forgejo command-line interface, and a restore is a snapshot of GitHub at the moment it ran. Each refresh overwrites the picture, so the team should record which export produced the copy that people are reviewing.

Decide, per repository, which platform accepts new pull requests and who can change that decision. Until the freeze, GitHub should keep accepting pull requests and issues, and Forgejo should be used for verification only. Assign one owner per repository for the switch, and make the owner responsible for telling contributors where to open work. Test workflows on Forgejo runners in parallel: the Forgejo documentation says Forgejo falls back to .github/workflows when .forgejo/workflows is absent, but migrated workflows will most likely need some tweaking, and Forgejo Actions is not compatible with GitHub Actions. Keep a list of failing jobs, and confirm which secrets must be re-created by hand, since Actions secrets do not export.

Schedule the final metadata export inside the freeze window, after GitHub stops accepting new pull requests and issues for the repository. Any export taken earlier will miss comments and reviews added since, so the freeze, the final dump-repo run, the restore-repo run and the switch of contributor links should happen in that order. Check each restored repository against GitHub for issue counts, pull request states and attachments that did not carry over, and record the gaps. Before the freeze begins, confirm with your own platform team the export account, the token scopes and any API limits that will slow a large repository, because the rate limits for hosted services apply to bulk exports as well.

What drives migration cost and duration, and how to keep each down

This table lists the factors that change the effort and cost of moving GitHub repositories to Forgejo, with how each one moves the total and what to do about it. Read it as a checklist for scoping and for the questions to put in a written quote.

DriverWhy it changes cost or effortHow to keep it down
Number of repositoriesEach repository needs its own dump, restore, permission mapping and verification, so effort grows with count even when repositories are small.Group repositories by owner and purpose, migrate low-risk ones first, and confirm in the quote whether the scope is a fixed list or open-ended.
Total .git sizeGitHub recommends keeping a repository's .git folder under 10 GB, and larger histories take longer to clone, mirror and restore.Identify oversized repositories early, clean up binary history where the team agrees, and plan separate transfer windows for the largest ones.
Volume of issues, pull requests and commentsThe dump-repo command exports issues, pull requests, comments and reviews, so large trackers lengthen export and restore and need more checking.Agree which closed history must move, archive the rest in read-only form, and sample restored items against the source.
Reliance on GitHub Actions and marketplace actionsForgejo Actions is not compatible with GitHub Actions. Forgejo falls back to .github/workflows, but migrated workflows will most likely need some minimal tweaking, and each third-party action must be checked for support on Forgejo runners.Inventory every workflow and action reference, rank them by business impact, and test the top workflows on a Forgejo runner before cutover.
Secrets and integrationsActions secrets do not export, so each secret must be re-created by its owner. Webhooks, deploy keys, GitHub Apps and external services must be repointed.Build a secrets register with owners and rotation status, and re-issue credentials during the pilot rather than at cutover day.
Hardening and backup designThe server, TLS, authentication, backup target and restore testing are sized by data sensitivity and availability needs, not by repository count.Reuse a standard server template, define backup frequency and retention in writing, and include a restore test in the scope.
Staff time for testing and cutoverDevelopers must verify clones, branch protection, reviews and pipelines, and platform staff must run the cutover and rollback plan. This is usually the largest one-time item.Run a pilot with one or two teams, write acceptance checks per repository, and schedule cutover outside release freezes.
One-time costsAssessment, migration scripting, workflow conversion, secret re-creation, testing and cutover are paid once, whether by internal staff or a services firm.Ask for each activity as a separate line with a named owner and a fixed deliverable.
Recurring costsServer or cloud capacity, storage, backups, Forgejo upgrades, security patching and any support contract continue after go-live, and staff time for operations is recurring too.Ask for the upgrade and patch cadence, the support model and a monthly run cost estimate that names each component.
What to ask for in a written quoteA quote is comparable only when scope, exclusions and assumptions are explicit.Request the repository inventory assumptions, the number of workflows and secrets in scope, test and rollback criteria, backup and restore testing, handover documents and the upgrade path to later Forgejo releases, including any upgrade from Gitea.

What usually goes wrong in a GitHub to Forgejo move

Most failed migrations break at the edges rather than in the Git history itself. The risks below cover workflows, secrets, integrations, file sizes, data freshness and support timing, and each one has a check to run before cutover.

Assuming workflows run unchanged

Forgejo Actions is designed to be familiar to GitHub Actions users but is not compatible with it. Forgejo falls back to .github/workflows when .forgejo/workflows is absent, but migrated workflows will most likely need some minimal tweaking. Before cutover, run each workflow on a test runner, check actions referenced from the marketplace, and confirm that runner labels match the jobs that expect them.

Losing secrets that never export

Actions secrets are not included in a repository dump, so every secret used by a pipeline, deploy job or registry login must be re-created in Forgejo by hand. Inventory the secret names from each workflow, assign owners who can supply the values, and rotate any credential whose value cannot be confirmed. Do not copy secret values through a chat tool or spreadsheet.

Broken webhooks and deploy keys

Webhooks, deploy keys and integrations tied to GitHub will stop firing once the repository moves, and some deploy keys may have been registered only on GitHub. List every hook in the repository settings, recreate it against the Forgejo URL, and send a test event. Confirm that each external system accepts the new endpoint and that deploy keys are added to Forgejo with the same read or write scope.

Large files over GitHub limits

GitHub enforces a 100 MB file limit and a 2 GB push limit, and recommends keeping a repository's .git folder under 10 GB. Repositories that passed those limits on GitHub, often through Git LFS or committed binaries, may carry objects that are slow to move or that the target server rejects. Measure the repository size with git count-objects before the move, confirm LFS objects are copied, and plan storage on the Forgejo server accordingly.

Stale metadata after a snapshot

A dump-repo export is a point-in-time copy, so issues, comments, labels and pull request reviews created on GitHub after the export will not appear in Forgejo. Freeze new activity on the source repository, or schedule a final export and restore just before cutover. Then compare issue and pull request counts between the two systems and record the cutover time in the team's change log.

Unclear Forgejo version support windows

Stable Forgejo releases receive full support for three months plus a two-week window, while LTS releases receive critical bugfixes and security support for one year and three months. Choosing a release without checking its end date can leave the server unpatched soon after go-live. Pick an LTS release for production, record its support end date, and set a calendar reminder for the upgrade plan. Forgejo v15 is the LTS release supported until July 15, 2027.

How the migration changes by team size and starting point

A small team with a handful of repositories and simple CI usually has a short inventory and few moving parts. The work is mostly running the dump and restore for each repository, checking that issues, pull requests and wikis arrived intact, and rewriting a few workflow files. Most of the effort sits in deciding who owns the new server and how it gets patched.

  • Inventory: List each repository, its default branch, open pull requests and whether anyone still uses its wiki or releases.
  • Workflows: Forgejo falls back to .github/workflows when .forgejo/workflows is absent, but migrated workflows will most likely need some minimal tweaking, so test them on a branch first.
  • Secrets: Plan to re-create Actions secrets by hand in Forgejo, since they do not export.
  • Operations: Assign one owner for updates, backups and the Forgejo runner, because a small team rarely has a spare administrator.
  • Cutover: A single weekend window is often enough when the repository count is low, though this depends on your own environment.

Before starting, confirm the release line you will install and its support window in the Forgejo releases and upgrade documentation.

Questions buyers ask before moving from GitHub to Forgejo

What does a migration from GitHub to Forgejo cost, and what drives it?

The software itself is free to download under GPL-3.0-or-later from v9.0 onward, so the cost is in the work and the infrastructure around it. Expect one-time costs for planning, the migration run, Actions rework and cutover, plus recurring costs for servers, storage, backups, patching, upgrades and staff time. The main drivers are the number of repositories, how much metadata (issues, pull requests, releases, wikis) you need to keep, how many workflows and secrets depend on GitHub Actions, and whether you need data residency or high availability. Ask any provider for a written scope that lists these items separately so you can compare quotes on the same basis.

How long does a GitHub to Forgejo migration usually take?

The duration depends on the scope rather than on the software. The biggest factors are the number of repositories, the volume of issues, pull requests and releases per repository, the size of the repositories themselves, and how many CI workflows need changes. Hosted platforms also impose API rate limits on bulk exports, and GitHub's REST limit of 5,000 requests per hour for personal access tokens means large exports can take time to run. Confirm a schedule with your provider or internal team against a pilot batch of repositories before committing to a cutover date.

What does our internal team need to provide for the migration?

You need named owners who can approve scope, a GitHub token with access to the repositories being exported, a target Forgejo instance with storage and backup in place, and a list of teams, users and access rules to map. Engineering leads should identify which repositories are active, which workflows and secrets they depend on, and which external systems post to GitHub webhooks. Security and compliance staff should confirm where the data may be stored and who may administer the instance. Ask whether your provider expects these inputs in writing before work starts.

Can our own engineers run the migration with the documented commands?

Yes, for many teams the documented route is straightforward. Forgejo's command-line interface provides dump-repo, which exports a repository from GitHub with selectable units such as issues, labels, releases, milestones, pull requests, comments and wiki, and restore-repo, which loads the dump into Forgejo. The harder parts are repeatable batch runs across many repositories, handling exceptions, mapping users and permissions, and validating the results. Self-run teams should test on a few repositories, check the restored data against GitHub, and decide who signs off. An outside team can take on the parts that are not worth your staff's time.

How do Forgejo's license and LTS support windows affect planning?

Forgejo's license is GPL-3.0-or-later from v9.0, with earlier versions under MIT, so confirm with your legal team which terms apply to the version you deploy. For support, stable releases get full support for three months plus a two-week window, while LTS releases receive critical bugfixes and security support for one year and three months. Forgejo v15 is the LTS release supported until July 15, 2027, and v17.0.0 is supported until January 28, 2027. Plan your upgrade path around the LTS you choose, and schedule upgrades before the end of each support window.

How are GitHub Actions workflows and secrets handled after the move?

Forgejo Actions is designed to be familiar to GitHub Actions users but is not compatible with it. Forgejo falls back to .github/workflows when .forgejo/workflows is absent, so many workflows run with minimal tweaks, though Forgejo's documentation says migrated workflows will most likely need some adjustment. Actions secrets do not export from GitHub, so every secret must be re-created in Forgejo by its owner and validated against a test run. Budget time for runner setup, testing each pipeline, and replacing any third-party actions that do not behave the same way.

Does Forgejo keep our data in the region we choose?

Self-hosting means the location of your data is determined by where you install Forgejo, such as your own data center or a cloud region you select. Hosted GitHub options vary: GitHub Enterprise Cloud with data residency offers EU, Australia, US and Japan regions, and Azure DevOps stores customer data in the geography chosen for the organization. Your compliance team should confirm how backups, logs and runner caches are stored and replicated in your own environment, since those can sit outside the primary instance.

How DeployOpen scopes and runs a GitHub to Forgejo migration

DeployOpen is a Chainscore Labs company that plans, implements, customizes, integrates, hardens, backs up, upgrades, documents and supports self-hosted open-source platforms inside the client's own cloud accounts, data centers or air-gapped networks. A GitHub to Forgejo move is scoped in writing first, then built, tested and handed over with documentation for the team that will run it.

How we scope

  • Inventory repositories, issues, pull requests, releases, wikis and Actions workflows that must move, and note which ones can be archived instead.
  • Agree in writing which Forgejo dump-repo units are in scope, such as issues, labels, milestones, comments and wikis.
  • Record where Forgejo will run, which data location applies and who owns the GitHub token used for export.

How we build

  • Stand up the Forgejo instance in your environment, with the configuration, storage and backup design agreed in the scope.
  • Run test migrations of sample repositories with dump-repo and restore-repo, and compare issues, pull requests and labels against the source.
  • Adapt migrated workflows from .github/workflows to Forgejo Actions, then re-create secrets in Forgejo and verify each pipeline runs.

How we hand over

  • Deliver runbooks covering the cutover order, repository mapping, user access and rollback steps for the migration.
  • Document the Forgejo version in use, its upgrade path and how to confirm the support window for that release.
  • Walk your administrators and developers through the new repositories, pull request flow and Actions runners before cutover closes.

How we support

  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
  • Ongoing support, upgrades and continuous testing are available as a retainer after handover.
  • Ask for the written scope to list who is responsible for runners, backups and Forgejo upgrades after go-live.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.