How migrating from GitHub Actions to Forgejo Actions works in practice
The move from GitHub Actions to Forgejo Actions happens one workflow at a time, with a short list of documented edits applied to each file. Teams usually start because of a renewal, a runner cost change, a data residency requirement or a wish to reduce lock-in, and the work is planned by platform engineering, DevOps and security teams together. Forgejo's documentation says Forgejo Actions is designed to be familiar to GitHub Actions users but not designed to be compatible, and that migrating a workflow will most likely need some minimal tweaking. Plan for review and testing of every workflow, not a bulk copy of files.
Effort depends mostly on how many workflows exist and how much they rely on GitHub-specific features. Forgejo reads workflows from .forgejo/workflows and falls back to .github/workflows when that directory is absent, so a repository can stay in place while its files are checked. The documented differences include runners that use a Debian bookworm image with only Node.js by default, some github context keys that are missing, job keys such as permissions and continue-on-error that are ignored, and OIDC tokens that use the enable-openid-connect key. Inventory each workflow against that list, then run it on a test runner before any production pipeline changes.
Two decisions need an owner before cutover. First, confirm which uses: references point at actions hosted on github.com, because DEFAULT_ACTIONS_URL decides where unqualified references resolve, and mirror or replace any action your builds depend on. Second, plan secrets and runner trust: secrets must be re-entered because GitHub's API does not return their values, and Forgejo's administrator documentation warns that a runner performs remote code execution on its host and network, so the security team should review the guide on securing Forgejo Actions deployments before runners are registered. Ask the Forgejo community or your own test environment to confirm each edit before you rely on it.
Which GitHub Actions capabilities map to Forgejo Actions and which need rework
This table compares the workflow elements most teams rely on in GitHub Actions with how Forgejo Actions handles them. Clean means the workflow should run with little or no change, needs rework means a documented difference requires an edit, and gap means the feature is missing or ignored and needs a replacement design. Confirm each row against your own workflows and a test run on your Forgejo Runner before cutover.
| Capability | Forgejo Actions status | What to check or change |
|---|---|---|
| Workflow file location | Needs rework | Forgejo reads .forgejo/workflows and falls back to .github/workflows only when the former is absent. Keep one folder per repository to avoid confusion. |
| Runner labels and hosting | Needs rework | Map each runs-on label to a Forgejo Runner label you register. Hosted GitHub runner names will not exist on your instance, so plan runner capacity first. |
| github context keys | Needs rework | Some github context keys are missing in Forgejo. Search workflows for github. references and test each one that drives a build, tag or deploy decision. |
| Job keys permissions and continue-on-error | Gap | Forgejo ignores these job keys. Replace permission scoping with credentials limited at the token or repository level, and rework any step that depends on continue-on-error. |
| OIDC tokens | Needs rework | Forgejo uses the enable-openid-connect key for OIDC tokens. Confirm the cloud trust relationships and audience values your deploy jobs expect before switching. |
| Default runner image | Needs rework | Most Forgejo Runners use a Debian bookworm image with only Node.js by default. Pin tooling into your own image or install it in a setup step, and confirm the image your runner uses. |
| Marketplace actions | Needs rework | Actions referenced without an absolute URL resolve through DEFAULT_ACTIONS_URL. Vendor or pin each action you use, and check that its own dependencies run on the Forgejo Runner. |
| Secrets and variables | Gap | GitHub never returns secret values, so they must be re-entered in Forgejo by someone with access to the source system. Record which secrets each workflow reads. |
What data and integrations move, and what must be rebuilt
Repository content, workflow files and run history do not all move the same way. Some data can be exported with Forgejo's own tools, some must be re-created by hand, and some expires on GitHub's clock before cutover. Work through these cards in order so nothing is lost when GitHub is switched off.
Export issues, pull requests and releases
The dump-repo command exports a repository from git, GitHub, Gitea or GitLab, and you choose the units to include: wiki, issues, labels, releases, release_assets, milestones, pull_requests and comments. Run it against a test repository first and check that pull request comments, review threads and release assets arrive as expected. Then load the dump into Forgejo with restore-repo. Confirm the source host and token permissions with the command-line documentation before a bulk run.
Re-create CI secrets by hand
GitHub's REST API returns Actions secret names without their values, so no export tool can copy deployment tokens, signing keys or registry passwords into Forgejo. Make a list of every secret each workflow reads, including organization and environment secrets, and record the owning system for each one. Issue fresh credentials where possible instead of copying old values, and rotate anything that was shared with former staff or third-party tools.
Export artifacts and run logs before cutover
GitHub Actions keeps artifacts and logs for 90 days by default, so older build evidence disappears on its own schedule. Download the artifacts and logs your release records, audits or incident reviews depend on before you stop the GitHub pipelines. Store them in your own retention system, and confirm with your compliance owner which runs must be kept and for how long.
Set DEFAULT_ACTIONS_URL for uses references
Forgejo prepends the DEFAULT_ACTIONS_URL value to any uses: reference that lacks an absolute URL. Set it in the administrator configuration to decide where short action names such as actions/checkout are fetched from, for example a mirror on your own network. Review every workflow for actions that point at GitHub-only paths, and confirm that each one exists at the source you choose before cutover.
Rebuild runner and workflow settings
Forgejo Runner needs its own registration, labels and host hardening, and Forgejo's administrator documentation warns that a runner performs remote code execution that creates risks for its host and network. Confirm which runner images are in use, since most Forgejo Runners use a Debian bookworm image with only Node.js by default. Move the permissions, continue-on-error and OIDC settings that Forgejo does not honor into the design of the new pipeline, and review each change with the security team.
Migration sequence from inventory to decommissioning GitHub Actions
This sequence moves GitHub Actions workflows, secrets and repository hosting to Forgejo in controlled stages, so each step ends with a verified output before the next one starts. Teams keep GitHub as the fallback until the Forgejo pipeline has proven itself.
Inventory repositories, workflows, secrets and actions
Your platform or DevOps team lists every repository with a workflow under .github/workflows, every secret and variable referenced in those files, every artifact and log retention need, and every external action referenced by uses: lines. Secret values cannot be exported from GitHub, so record the secret names and their owners now. The output is a signed-off inventory that marks each workflow as keep, rewrite or retire, and flags actions that point to github.com.
Confirm the Forgejo target and action sources
The platform team installs or confirms the Forgejo version, checks which LTS or stable release fits your support plan, and sets DEFAULT_ACTIONS_URL so that actions referenced without an absolute URL resolve to a source you control. Confirm with your administrators whether actions must be mirrored into the instance or fetched from an approved external host. The output is a written target configuration that security and operations have reviewed.
Pilot one repository with Forgejo Runner
Pick a low-risk repository whose workflow uses few external actions. Migrate it with the dump-repo and restore-repo commands or the Forgejo migration form, register a Forgejo Runner with a dedicated, isolated host, and run the pipeline. Expect small edits, such as the Debian bookworm image with Node.js only, missing github context keys and ignored permissions or continue-on-error keys. The output is a green pipeline run and a list of every edit made, reviewed by the repository owner.
Harden the runner before wider use
Before onboarding more repositories, the security team reviews Forgejo Actions guidance on securing deployments. Because a runner executes code from workflows, separate runner hosts from production networks, limit which repositories and labels can use each runner, and restrict access to secrets. The output is a documented runner design and an access review that the security lead has approved in writing.
Run both systems in parallel
For the agreed period, workflows run on GitHub and on Forgejo for the same commits. Compare job results, test counts, artifacts and deployment behavior, and log every difference. Secrets are re-created in Forgejo at this stage, and deployment jobs stay pointed at GitHub until the comparison is clean. The output is a parity report that lists each mismatch, its cause and the fix, with the owners of each deployment target confirming readiness.
Cut over repository hosting and webhooks
Migrate the remaining repositories, including issues, pull requests, releases and milestones where your records require it, then point webhooks, deploy keys and integrations at Forgejo. Freeze pushes to GitHub for each repository during its move so no commit is lost. The output is a Forgejo repository set with verified history, webhooks delivering events and a short list of any repositories that still need manual follow-up.
Export history and decommission GitHub workflows and runners
Before retention expires, export the run logs and artifacts you must keep, then disable GitHub workflows, remove self-hosted runners and revoke tokens and deploy keys that GitHub used. Archive the GitHub repositories as read-only where policy allows. The output is a decommissioning record that lists each removed runner, revoked credential and archived export, signed by the owner of the CI platform.
What drives the cost and duration of the migration
This table lists each cost component of moving from GitHub Actions to Forgejo Actions, who is paid for it, whether it is one-time or recurring, and what pushes it up or down. Use it to shape a written scope, because no migration duration or price is set until that scope is agreed.
| Cost driver | Why it changes cost or effort | How to keep it down |
|---|---|---|
| Forgejo instance and hosting | Someone must install, back up, patch and monitor the Forgejo server in your infrastructure, a one-time setup plus recurring hosting and upgrade work | Size the instance from the repository and user count, and plan upgrades on Forgejo's LTS cycle to avoid frequent unplanned changes |
| Runner hosts | Each Forgejo Runner needs a host, and runners execute workflow code, so hosts need isolation and capacity planning | Start with a small runner pool, add capacity only when queue times show a need, and confirm the hardware and isolation model in writing |
| Workflow edits | Forgejo documents that migrated workflows most likely need minimal tweaking, and each edit needs review and testing, so cost scales with workflow count and complexity | Inventory workflows first, group the ones that share patterns, and retire unused workflows before migrating |
| Marketplace actions | Each action referenced by a uses: line must be checked for availability, and actions without an absolute URL depend on DEFAULT_ACTIONS_URL or a copy you host | List every external action, prefer ones already available on your instance, and vendor or mirror the rest under your control |
| Runner image and missing context keys | Forgejo's default runner image is Debian bookworm with only Node.js, and some github context keys are missing, so tooling and expression fixes add effort | Pin a runner image that carries the tools your builds use, and test workflows that rely on github context values |
| Secret re-creation | GitHub's REST API returns secret names without values, so each secret must be re-entered by someone with the original value, which takes staff time and access approvals | Record owners and the systems that issue each credential beforehand, and rotate secrets during the move rather than copying old ones |
| Artifact and log export volume | Run history and artifacts expire on GitHub's retention schedule, so the amount to export and store grows with history depth and artifact size | Decide which history must be kept for audit or release traceability, export it before retention expires, and cap what is moved |
| Repository metadata export | The dump-repo and restore-repo commands move issues, pull requests, releases and related units, and the chosen units and data volume drive run time and checks | Select only the units you need, test a restore on a copy, and verify counts and links after each run |
| Security hardening of runners | Forgejo warns that a runner performs remote code execution, so isolation, token scopes and network rules need design and review | Use separate runners for trusted and untrusted code and follow Forgejo's guide on securing Forgejo Actions deployments |
| Staff time and parallel running | Engineers time the cutover, validate builds on both systems and handle exceptions, and this is usually the largest recurring effort during the move | Migrate in batches, keep GitHub workflows running until each batch passes, and agree acceptance criteria in the written scope |
How the move differs for small teams, large estates and air-gapped sites
A small team with a handful of repositories and workflows usually has the simplest move. The main work is reading each workflow against Forgejo's documented differences, deciding whether the existing .github/workflows directory can stay in place, and rebuilding a runner. Because Forgejo falls back to .github/workflows when .forgejo/workflows is absent, a team can often run its current files first and add a Forgejo-specific directory later, once the edits are clear.
- Fallback first: Leave the files in
.github/workflowsfor an initial test, then move them to.forgejo/workflowswhen the team is ready to own them on Forgejo. - Small edits: Check jobs that use
permissionsorcontinue-on-error, since Forgejo documents that it ignores these job keys. - Runner image: Confirm that the default Debian bookworm image with Node.js meets each job's tooling needs, or add the tools the workflow installs.
- Secrets: Re-create each secret by hand, because GitHub's API returns secret names without values.
- One runner: A single runner host can serve a small team, but it still executes workflow code, so isolate it as the Forgejo administrator guide describes.
Before cutting over, confirm with the team which workflows depend on OIDC tokens, which use the enable-openid-connect key in Forgejo, and which pull actions from GitHub.
A large estate with many repositories, shared composite actions and reusable workflows changes the work from file editing to inventory and standardization. The key decision is how uses: references resolve. Forgejo prepends the DEFAULT_ACTIONS_URL setting to references that lack an absolute URL, so a single configuration value can decide whether actions come from a Forgejo instance, from a mirror, or from a public source. Teams should set that value deliberately rather than inherit a default.
- Inventory: List every repository, workflow, shared action and secret before moving any of them, and group repositories by workflow pattern.
- Action resolution: Set
DEFAULT_ACTIONS_URLonce for the instance and document which references point to internal copies. - Bulk repository moves: Use the dump-repo and restore-repo commands with selected units such as issues, pull requests, releases and labels, and test each batch on a copy first.
- Runner fleet: Register runners with separate labels for build, test and deployment work, and restrict which repositories can use each one.
- Upgrades: Plan Forgejo version upgrades around the support windows in the upgrade documentation, since stable releases and LTS releases have different support lengths.
Before starting, ask the platform team which shared actions depend on GitHub-specific context keys that Forgejo documents as missing.
A regulated or isolated network has no route to github.com or other public action sources, so every dependency must be present inside the boundary before the first build. Forgejo Actions can run in that setting only if the actions, container images and runner binaries are mirrored or copied in ahead of time. The team must decide how actions are sourced, who approves new versions and how an offline runner receives updates, since those steps happen outside the network.
- Mirror actions locally: Copy every referenced action into the internal Forgejo instance, then point
DEFAULT_ACTIONS_URLat that instance so references resolve without internet access. - Runner images: Build or import the container images the runners use, because the default Debian bookworm image will not update itself from a public registry.
- Repository transfer: Export repositories with dump-repo on a connected system, then load them with restore-repo inside the isolated network, after reviewing the dump contents.
- Secret handling: Re-enter secrets through an approved process, since they cannot be exported from GitHub.
- Runner isolation: Treat each runner as a remote code execution point and limit its host and network access as the administrator guide describes.
Before committing to a design, confirm with the security team how new actions and images enter the enclave and who signs off on them.
What usually goes wrong in a GitHub to Forgejo CI migration
Most migration problems come from treating Forgejo Actions as a drop-in copy of GitHub Actions. The risks below cover compatibility, runner security, data that does not move on its own and missing tools, and each card pairs a risk with a check to run before cutover.
Assuming full compatibility
Forgejo Actions is designed to be familiar to GitHub Actions users but not designed to be compatible, and its documentation says a migrated workflow will most likely need minimal tweaking. Teams that copy .github/workflows unchanged often find jobs that fail late or pass for the wrong reason. Prevention: run every migrated workflow on a non-production Forgejo runner and compare its results with the GitHub run history before you retire the old pipeline.
Silent permission and job key changes
Forgejo documents that job keys such as permissions and continue-on-error are ignored, and some github context keys are missing. A workflow that relied on a read-only token scope or on a failing step being tolerated can behave differently without raising an error. Prevention: search every workflow for these keys, decide what behavior each one protected, and add an explicit check or step where that behavior still matters.
Runners executing untrusted code
Forgejo's administrator documentation warns that a runner performs remote code execution, which creates risks for its host and network. A runner that serves several repositories, or accepts workflows from forks and pull requests, can run code written by people you do not trust. Prevention: give runners dedicated hosts or disposable containers, limit which repositories may use them, and follow the Forgejo Actions security guide before you open the runner to pull requests.
Artifacts lost at retention expiry
Hosted CI keeps artifacts for a limited time, with GitHub Actions defaulting to 90 days, so older build outputs may already be gone before the migration starts. Teams that assume the new system will rebuild everything can lose release binaries, test reports and audit evidence. Prevention: list which artifacts your compliance or release process needs, export them through the GitHub REST API or CLI before retention expires, and store them in your own registry or object store.
Secrets that never arrive
GitHub's REST API returns Actions secret names without their values, so secrets cannot be copied into Forgejo automatically. A workflow that depends on a missing token will fail on its first deployment step, and the failure may appear only after a merge. Prevention: inventory every secret by name and owner, rotate credentials at the source system, and enter them into Forgejo through a controlled process before the first run.
Runner image lacking tools
Forgejo documents that most runners use a Debian bookworm image with only Node.js by default, so compilers, cloud CLIs and language SDKs that were present on GitHub-hosted runners may be absent. Jobs then fail with missing command errors that look like code defects. Prevention: list every tool each workflow calls, build a custom runner image or install tools as an explicit workflow step, and confirm the image version with your Forgejo administrator.
Securing Forgejo Runner before workflows go live
Treat the Forgejo Runner as a privileged system before any workflow runs on it. The Forgejo administrator documentation warns that a runner performs remote code execution, which creates risk for the runner's host and for the network it can reach. Every workflow job is code from a repository that someone can push to, so a runner that can reach production databases, internal registries or deployment credentials gives any contributor a path into those systems. Decide the isolation model first, then enable workflows.
Start with network placement. Run runners in a segment that can reach the Forgejo instance and the artifact or package sources the builds need, and nothing else. Block direct paths to production networks, and give deployment jobs only the credentials and endpoints for the specific target. Next, limit which repositories may use which runners, so a runner registered for internal projects does not accept jobs from a repository that anyone can fork or open to outside contributors. Review who can register runners and who can change the Actions settings on each repository, since both change what code runs where.
Follow the Forgejo guide on securing Forgejo Actions deployments and turn each recommendation into a written control with an owner. Confirm the exact hardening steps, runner labels, isolation method and secret handling with your security team and with the Forgejo documentation for the version you run, because these details change between releases. Ask the security team to test the setup with a deliberately malicious test workflow in a non-production repository before any production project is migrated. Record the results as evidence for your change review.
Questions buyers ask before migrating from GitHub Actions to Forgejo Actions
How much effort and cost should we expect for a move from GitHub Actions to Forgejo Actions?
The cost depends mainly on how many repositories, workflows and secrets you have, how many of them depend on GitHub Marketplace actions, and how much of the Forgejo platform you must host. Forgejo itself is free software, so the recurring costs are the servers and storage for the forge and runners, staff time to operate and patch them, and any external support you buy. One-time costs include translating workflows, re-creating secrets and migrating history. Ask any provider for a quote built from a written scope that lists repositories, workflows, runners, environments and the migration of issues and releases. No cost figure for this move is published here, so use your own inventory to size it.
How long does a migration to Forgejo Actions usually take?
The timeline is set by inventory and testing, not by the Forgejo install itself. Teams usually need to list their workflows, check which ones call marketplace actions or use keys Forgejo ignores, rebuild secrets, run a pilot repository and then move the rest in batches. Repositories with many release assets, long issue histories or complex deploy jobs take longer to verify. Forgejo's documentation says migrating a workflow will most likely need some minimal tweaking, so plan for a test cycle per workflow. No duration is published for this work, so agree a timeline in writing against the workflow count and the pilot results.
What does our team need to provide for a Forgejo Actions migration?
You need people who own the source repositories, the deployment targets and the secrets, because those cannot be read back from GitHub. Expect to involve an administrator for the Forgejo server and its runners, a platform engineer who knows your deploy pipeline, and a security reviewer for runner trust boundaries. GitHub's REST API returns secret names without values, so your team must supply the values again from the original source. Confirm who approves changes to production deploy jobs and who will run the runners day to day after handover.
Can our own engineers migrate to Forgejo Actions without an outside partner?
Yes, a capable internal team can move simple workflows using Forgejo's documentation, the dump-repo and restore-repo commands, and a pilot repository. Teams often find the harder parts are securing the runners, rebuilding secrets and handling marketplace actions, which need careful testing. An outside partner can help with a fixed-scope plan, implementation, hardening, backups and documentation, and DeployOpen works this way in the client's own infrastructure. Decide based on your staff capacity and on whether you need evidence for an audit, which independent auditors assess rather than DeployOpen.
Is Forgejo free software, and what license does it use?
Forgejo is free software. According to the Forgejo FAQ, it is licensed GPL-3.0-or-later from v9.0 onward, while earlier versions were under MIT. Codeberg e.V., a non-profit association registered in Berlin, owns the project's domains, and project governance stays independent. Have your legal team confirm what the GPL-3.0-or-later terms mean for your internal use and any modifications you plan to make, especially if you distribute software built with it.
Which Forgejo release should we choose for a new Actions deployment?
For a conservative deployment, most teams look at the LTS release. According to Forgejo's releases page, v15 is the LTS release and is supported until July 15, 2027, while v17.0.0 was released on October 15, 2026 with support until January 28, 2027. Forgejo's upgrade documentation says LTS releases receive critical bugfixes and security support for one year and three months, while stable releases receive full support for three months plus a two-week window. Confirm the current release list before you install, and plan an upgrade path for your chosen version.
Can we keep GitHub as the source while Forgejo Actions runs builds?
Forgejo Actions is built into the Forgejo forge, so moving builds to it usually means moving the repositories too. If you want to keep code on GitHub and only move builds in-house, a different engine such as Woodpecker CI can connect to GitHub as a forge, according to its forge documentation. For a Forgejo move, you would migrate repositories, issues, pull requests and releases with the dump-repo and restore-repo commands, which can export from GitHub. Confirm which units you need to carry over and test the restored data before you switch.
What security risks come with Forgejo runners, and how do we manage them?
Forgejo's administrator documentation warns that a runner performs remote code execution, which creates risks for the runner host and the network it can reach. Treat runners as trusted code execution environments: isolate them, limit their network access, keep their secrets scoped to the jobs that need them, and rebuild them regularly. Follow the guide on securing Forgejo Actions deployments and have a security team review the setup. DeployOpen can test and harden these systems as a separate engagement, but no security outcome is guaranteed.
Forgejo license, governance and release support
Before you commit a CI platform to a multi-year plan, confirm the license and support terms that govern the forge running your Forgejo Actions. Forgejo is licensed under GPL-3.0-or-later from v9.0 onward, while earlier versions were released under MIT. For a regulated organization, the practical consequence is that any fork, modification or internal distribution you make from v9.0 onward carries GPL obligations, and your legal team should confirm how those apply to custom runner images, workflow tooling and patches your engineers maintain. The Forgejo FAQ explains the licensing history and is the natural starting point for that review.
Governance is a separate question from licensing. Codeberg e.V., a non-profit association registered in Berlin, owns the Forgejo domains, while project governance stays independent. Ask whether that split affects you: it matters if your procurement policy requires a named legal entity to hold domain, trademark or signing responsibilities, and it determines who you contact for security disclosures. Document the answer in your vendor register so the platform owner and compliance lead can point to the same facts during an assessment. Release support is what turns the platform into a plan. Stable releases receive full support for three months plus a two-week window, and LTS releases, published in the first quarter of each year, receive critical bugfixes and security support for one year and three months. Forgejo v15 is the current LTS release, supported until July 15, 2027, and v17.0.0 was released on October 15, 2026 with support until January 28, 2027. Schedule upgrades against those dates and pin your Forgejo Runner version to a supported line. If you are coming from Gitea, the upgrade guide documents a two-step path up to Gitea v1.22, first to Forgejo v10.0.x and then to a later Forgejo version, so confirm your current Gitea version before you plan the cutover.
How DeployOpen scopes, runs and supports the Forgejo migration
DeployOpen plans, implements, integrates, documents and supports self-hosted open-source platforms inside your own infrastructure, including Forgejo and its runners. For a move from GitHub Actions to Forgejo Actions, we start with an inventory of your repositories, workflows and secrets, then agree the scope in writing before any work begins.
How we scope
- Inventory repositories, workflows, marketplace actions and the secrets each pipeline needs, recorded per repository
- Agree in writing which repositories, units (issues, pull requests, releases) and workflows move in this engagement
- Confirm the target hosting, runner placement and any default action sources your network allows before work starts
How we build
- Set up the Forgejo instance and Forgejo Runner in your environment and configure DEFAULT_ACTIONS_URL for your policy
- Adapt workflows for documented differences such as runner images, missing github context keys and ignored job keys
- Test each migrated workflow against representative branches and record the results before cutover
How we hand over
- Deliver the runbook, configuration records, dump and restore logs, and a list of workflows that still need manual changes
- Document how runners are secured against remote code execution on the host and network, with the controls you agreed
- Walk your platform and security teams through operation, upgrades and rollback before the handover is closed
How we support
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts
- Ongoing support, upgrades and continuous security testing are available as a retainer after handover
- Pricing follows from the written scope; ask for a quote that separates one-time migration work from recurring support

