Hoppa till innehåll

Migration guide · From GitHub

Migrate from GitHub to SIAX Git and CI

GitHub isn't a bad tool, and it's rarely the reason anyone moves. The reasons are usually three: the per-developer license cost that grows with the team, CI minutes that are hard to predict, and the fact that both the code and the build chain sit under US jurisdiction. For companies selling to the public sector or regulated customers, that last argument is often the deciding one.

Our Git and CI is self-hosted Gitea with Actions-compatible runners, all in the EU. The Git protocol is the same, so clones, remotes and tools work unchanged, and the workflow syntax is largely the same as GitHub Actions. The price is 199 kr/mo for ten users, versus per-developer licensing plus variable CI cost.

The honest warning: Actions compatibility is good but not identical. Workflow files can usually be copied straight across, but individual marketplace actions need to be swapped out, and parts of GitHub's ecosystem — Codespaces, Advanced Security, Pages, OIDC federation with cloud providers — have no equivalent. This guide puts the time where the work actually is: in the pipeline, not the code.

Time required

Half a day for a repo with a simple pipeline. For 20-30 repos with active workflows: expect two to three working days, most of which goes to testing workflows — not moving code.

Downtime

None for the code. Git is distributed and everyone has full clones, so the repo move itself isn't noticeable. CI, on the other hand, has a gap: during the rewrite there's a period where the build is only verified on one of the systems. Run both in parallel until the results match before you make our CI mandatory.

01

How to do it

  1. 1

    Inventory repos, workflows and integrations

    List all repos with the latest commit, size, and whether they use LFS. Go through every active workflow and note which actions it uses, which secrets it reads and what it deploys to. Also note everything that sits outside Git: GitHub Apps, webhooks, branch protection, code owners and required status checks. That list is your actual spec — not the repo list.

  2. 2

    Set up organization, users and permissions

    Create the organization with us and set up teams with the same permission levels as in GitHub. Connect login to your existing identity provider via OIDC if you have one, otherwise local accounts with enforced two-factor. Set branch protection right away — it's easy to postpone and you only notice when someone pushes to main.

  3. 3

    Mirror repos and move the issue history

    The migration tool pulls the repo, tags, releases, wiki, issues and pull requests via the GitHub API using a personal access token. Run a test migration of a medium-sized repo first and review the result before taking the rest. LFS objects and container images in ghcr.io move separately and aren't included in the same pass.

  4. 4

    Move secrets — and rotate them at the same time

    Secrets can't be read out of GitHub, so they have to be set again regardless. Use that: rotate every key as part of the move instead of pasting in the same values. Put them at the organization level where several repos share them, and document which pipeline needs which.

  5. 5

    Rewrite workflows and swap out the actions that don't carry over

    The syntax in .gitea/workflows is largely the same as GitHub Actions, so the files can usually be copied straight across. Then test every workflow: common actions like checkout, setup-node and cache work as normal, while ones that call GitHub's own API, use OIDC federation, or assume GitHub's runner image don't. Pin versions explicitly and replace what fails with plain shell steps. Expect this step to take the most time of all.

  6. 6

    Run both systems in parallel until the results match

    Keep GitHub as a mirror and push to both remotes for a period. Compare build log against build log on the same commit — differences usually come from preinstalled tools in the runner image, not your code. Only once ten to fifteen runs in a row give the same result is it reasonable to make our CI a required status check.

  7. 7

    Repoint deploy targets and webhooks, then archive GitHub

    Update deploy keys, container registries and every webhook pointing at github.com. If the pipeline deploys to our App Hosting (from 99 kr/mo), a deploy key and a webhook are all you need. Set the GitHub repos to archived, read-only mode instead of deleting them — otherwise old permalinks in documentation and issues stop working. Keep them for at least a quarter.

02

What's actually tricky

  • Marketplace actions don't always work unchanged. Ones that just run commands are fine; ones that call GitHub's REST or GraphQL API, use OIDC federation with AWS or GCP, or rely on GitHub's runner image, aren't. Test every action, pin versions, and expect to replace a few with shell steps.
  • The runner image isn't GitHub's ubuntu-latest. Pipelines that assume a tool is already installed will fail, often with a cryptic error deep into the build. Install dependencies explicitly in the workflow instead of relying on the image.
  • OIDC federation with cloud providers disappears. Workflows that fetch temporary AWS or GCP credentials via GitHub's identity provider have to switch to long-lived keys or another mechanism. That's a security regression that should be handled deliberately, not discovered after the fact.
  • Parts of GitHub have no equivalent: Codespaces, Advanced Security and code scanning, Pages, Discussions, and org-wide rulesets. If any of that is business-critical, the answer isn't to move everything — it's to move what transfers and pay for the rest.
  • Issue history carries over as text, but pull request review threads, status-check history, and permalinks to github.com don't fully transfer. Links in old documentation still point there — which is why the GitHub repos should be archived, not deleted.
03

Cost example

A team of ten developers on GitHub Team runs about 40 USD per month in licenses, roughly 450 kr, plus whatever the CI minutes cost beyond the included allotment. For an active monorepo with many parallel builds, the CI line often ends up bigger than the licenses. Prices and included volumes change continuously — check the current price list. The equivalent with us: Git and CI 199 kr/mo for ten users. Need heavy parallel builds? We'll size a dedicated runner on a dedicated server from 890 kr/mo, which is still predictable rather than variable.

04

Frequently asked questions

Do our GitHub Actions workflows work as-is?
The files can usually be copied without changes — the syntax is the same. Actions are a different matter: the most common ones work, but ones that talk to GitHub's API or use OIDC federation don't. Expect to test and adjust every workflow, not to lift them over blindly.
Do issues and pull requests come along?
Yes, the migration tool pulls issues, pull requests, releases, tags and wiki via the GitHub API. Review threads and status-check history won't be identical. Run a test migration on one repo and look at the result before deciding on the full move.
Can we keep GitHub in parallel?
Yes, and we recommend it during the transition. Git is distributed, so pushing to two remotes is one line of config. Many teams keep GitHub as a permanent read-only mirror for public repos.
What happens to container images in ghcr.io?
They move separately. Our package registry speaks the same OCI protocol, so it's a matter of retagging and pushing — plus updating all the pull references in Kubernetes manifests, compose files and deploy scripts. Don't forget the image-pull secrets.
Do you have ISO 27001 or SOC 2?
No. We have neither ISO 27001, SOC 2 nor PCI-DSS. What we have is GDPR compliance with all data in the EU, open source all the way down so you can audit what's running, and contracts that give you data export whenever you want. If your procurement process has a certification requirement, you should know that before the project starts.
How do we get out again if it doesn't work?
Clone the repos — they contain the full history. Issues and pull requests export via the API and the workflow files are already in the repo. Same way out as in, which is the point of open formats.