How to Migrate from GitHub Actions to Gitea Actions
In December 2025, GitHub announced a $0.002-per-minute fee on self-hosted runners for private repositories. The backlash was immediate — hundreds of comments, cost calculations showing $3,500/month increases for mid-size teams, and a 24-hour reversal. GitHub "postponed" the change. Not canceled — postponed.
That word choice tells you everything. GitHub views self-hosted runner orchestration as something they intend to monetize. The only question is when. If your CI/CD pipeline depends entirely on GitHub Actions, you have a vendor risk problem — and now is the time to solve it.
Enter Gitea Actions
Gitea Actions is a built-in CI/CD system that ships with Gitea, the lightweight open-source Git platform. Here's what makes it interesting: it's designed to be nearly compatible with GitHub Actions YAML syntax. You can literally copy your workflow files from .github/workflows/ to .gitea/workflows/ and most will run without changes.
Same YAML structure. Same on:, jobs:, steps: blocks. Same uses: action references — GitHub Marketplace actions work. Same secrets.* and env: syntax. Same matrix strategies. It's not a spiritual successor — it's a deliberate compatibility layer.
Gitea Actions has been production-stable since Gitea 1.19, and Gitea uses it across all their own repositories. The act_runner (v0.3.0, February 2026) executes jobs in Docker containers and supports ephemeral mode for security-hardened setups.
The Migration: 5 Steps
Step 1: Deploy Gitea
The fastest path is through Elestio — pick Gitea from the marketplace, choose a provider (2 CPU / 4 GB RAM is plenty), and deploy. You'll have a running instance with SSL, backups, and monitoring in under five minutes. Cost: ~$16/month on Netcup.
Step 2: Import Your Repositories
Gitea has a built-in migration tool that imports directly from GitHub — repositories, issues, pull requests, labels, milestones, and releases. Go to New Migration > GitHub, paste your repo URL, authenticate with a personal access token, and import.
Step 3: Copy Your Workflow Files
This is where Gitea Actions shines. Take your existing .github/workflows/ directory and copy it to .gitea/workflows/ in your repository. Most workflows work immediately. The key differences to watch for:
runs-on:— Use simple labels only (no complex expressions)concurrency:— Ignored (remove to keep things clean)permissions:— Ignored (Gitea uses its own permission model)timeout-minutes:— Ignored (configure at the runner level)
Actions from the GitHub Marketplace work by default. You can also use absolute URLs: uses: https://github.com/actions/checkout@v4.
Step 4: Register a Runner
Gitea uses the act_runner — a lightweight Go binary. On your Elestio Gitea instance, register a runner:
act_runner register --instance https://your-gitea.example.com --token YOUR_REGISTRATION_TOKEN
act_runner daemon
For Docker-based job execution (recommended), make sure Docker is available on the runner host. The runner pulls container images and executes each job in isolation.
Step 5: Enable Actions and Test
In your Gitea app.ini, ensure Actions are enabled:
[actions]
ENABLED = true
Push a commit to trigger your workflows. Check the Actions tab in your repository to see results. Fix any edge cases — the most common ones involve complex runs-on expressions or Gitea-unsupported features like continue-on-error.
What Doesn't Work (Yet)
Let's be honest about the gaps. Gitea Actions is production-ready but not feature-complete compared to GitHub Actions:
concurrencygroups are ignored — no built-in queue managementenvironmentprotection rules aren't supportedcontinue-on-erroris ignored- Problem matchers and error annotations don't work
- Kubernetes-native runners aren't available (use Docker-in-Docker instead)
For most standard CI/CD workflows — build, test, lint, deploy — these limitations won't matter. If you rely heavily on environment protection rules or concurrency groups, you'll need workarounds.
The Cost Math
Here's what the numbers look like if GitHub's per-minute fee returns:
| Monthly CI Minutes | GitHub Self-Hosted Fee | Gitea on Elestio |
|---|---|---|
| 10,000 | $20/month | $16/month (flat) |
| 50,000 | $100/month | $16/month (flat) |
| 100,000 | $200/month | $29/month (flat) |
| 500,000 | $1,000/month | $59/month (flat) |
The fundamental difference: GitHub's fee scales linearly with usage. Gitea on Elestio is a flat infrastructure cost — you pay for the VM, not per minute. And Gitea has zero per-user licensing fees. A 20-person team on GitHub Team pays $960/year before CI costs. That same team on Gitea pays ~$192/year total.
Why Not Jenkins?
Jenkins is a legitimate alternative — it's on Elestio too — but the migration cost is significantly higher. Jenkins uses Groovy-based Jenkinsfiles, which means rewriting every pipeline from scratch. Gitea Actions lets you keep your existing YAML workflows with minimal changes. If you're coming from GitHub Actions, Gitea is the lowest-friction path.
Jenkins still makes sense for large enterprises with complex, multi-stage pipelines and deep integrations across dozens of tools. But for teams that just want their CI/CD to keep working without per-minute fees, Gitea Actions is the pragmatic choice.
Troubleshooting
Actions tab doesn't appear in Gitea Make sure ENABLED = true is set under [actions] in app.ini, and restart Gitea. On Elestio, restart the service with docker-compose restart.
Workflow runs but jobs stay pending Your act_runner isn't connected or the runs-on label doesn't match. Check runner registration with act_runner list and verify the labels match your workflow's runs-on value.
GitHub Marketplace action fails Some actions use GitHub-specific APIs (like actions/upload-artifact). Check the Gitea Actions compatibility docs for known differences. Most popular actions — checkout, setup-node, setup-python, cache — work without issues.
Don't Wait for the Invoice
Look, GitHub backed down once. They might back down again. But "postponed" isn't "canceled," and the direction is clear — GitHub wants to monetize every touchpoint. Whether the fee comes back in six months or two years, the teams that will be scrambling are the ones that didn't plan ahead.
Gitea Actions gives you a realistic escape route that preserves your existing workflows. The migration takes an afternoon, not a quarter. And at ~$16/month on Elestio with no per-minute fees and no per-seat licensing, the math works at any scale.
Thanks for reading. See you in the next one 👋