If company code can’t go to an external cloud like GitHub, what should you pick to install a Git repository and CI/CD (a setup that automatically builds, tests, and deploys every time code is pushed) in-house? With that question, I checked the candidates one by one against their official documentation. The short answer: there was no single “best” option; the answer split depending on what you need to get for free. All versions and prices below are as of October 2026.
The conditions
There were six conditions.
- On-premises: code must not leave the company. Cloud services are out.
- Repository and CI/CD in one place: a separate repo and a separate CI server means more systems to manage.
- Official support from domain tools: whether the development tools in use (here, model-based development tools like MATLAB and Simulink) officially support that CI.
- Required review approval: for safety-critical software, “it merges only once someone approves” is the core of the process.
- Account integration: log in with company accounts, and permissions should follow the company org chart.
- Scaling: start with a team of a few people and grow to the whole company.
The candidates were GitHub, GitLab, Gitea, Forgejo (forked from Gitea), Gogs (the project Gitea itself forked from), and OneDev. I also looked at CI-only tools like Jenkins and TeamCity, and the cloud service Azure DevOps.
Dropped first: GitHub Enterprise Server, Gogs, Jenkins
The only way to install GitHub in-house is GitHub Enterprise Server. Per the official docs, installing it requires a paid Enterprise license file, and there’s no free edition. Even the smallest configuration (up to 10 light users) calls for 4 CPU cores, 32 GB of memory, and 400 GB and 500 GB disks, and turning on GitHub Actions requires at least 8 CPU cores and 64 GB of memory. Actions needs separate external storage for run results (Azure Blob, Amazon S3, Google Cloud Storage, or S3-compatible MinIO), and only self-hosted runners can be used. To use actions published on github.com, you have to connect out through GitHub Connect or sync them manually. Unless the company already standardizes on GitHub Enterprise, it’s the heaviest choice for starting fresh.
Keeping code in the cloud, as with GitHub.com or Azure DevOps, fails condition 1. For reference, for organizations GitHub.com needs a paid plan of GitHub Team or higher to put rules like required approvals (rulesets) on private repositories, and Azure DevOps is free for the first 5 users.
Gogs is the lightest. According to its README, 2 CPU cores and 512 MB of memory are enough for team work, and a Raspberry Pi will do. But its feature list has no CI/CD, package registry, or project boards. It doesn’t fit if CI is the goal.
Since Jenkins has an official MATLAB plugin, I first assumed it would obviously be needed. But both GitLab and Gitea do CI themselves, and what the official plugin did can be called directly from the command line. One more system adds servers, accounts, permissions, and upgrades along with it, so I dropped it unless the company already standardizes on Jenkins.
Specs of the remaining three: GitLab is heavy, Gitea and OneDev are light
- GitLab: the official docs’ default recommendation is 8 CPU cores and 16 GB of memory. They say it can run with a minimum of 8 GB in memory-constrained environments.
- Gitea: known as a lightweight server, easy to run on a small VPS or an old PC.
- OneDev: per its official description, all features run on a machine with 1 CPU core and 2 GB of memory for medium-sized projects.
When I actually checked, even an old desktop at home (Ryzen with 6 cores and 12 threads, 27 GiB of usable memory) exceeded GitLab’s recommended specs. The guess “GitLab is too much for an old PC” was wrong, and specs turned out less decisive than I thought.
All three do CI/CD; what differs is the format and official support (MATLAB CI)
All three candidates install the CI executor (runner) separately. The difference is the CI configuration format.
- GitLab CI: its own format. Mature, given how long it’s been around.
- Gitea Actions: the same YAML format as GitHub Actions, so most published actions can be reused as is. Its
official comparison doc says deployment environment protection (
environment) and error location display (error annotations) are ignored. - OneDev: its own format, with jobs built in the UI. Not compatible with the other two formats.
I checked official support for the domain tool in the MATLAB documentation. The officially supported CIs are Jenkins, GitLab CI/CD, GitHub Actions, Azure DevOps, CircleCI, Bamboo, and TeamCity, and for platforms not on the list it says to run MATLAB directly in command-line batch mode. Simulink Check’s CI/CD support package, which automates Simulink model verification, also generates pipeline configuration automatically for GitLab, GitHub, Jenkins, and Azure DevOps. Gitea and OneDev aren’t on these lists. But the same documentation has a separate section on running outside the supported CIs, with these requirements: an executor machine with MATLAB and the support package installed, a process model file at the project root, a connection to the remote git repository, and, for incremental builds, preserving task outputs and the digital thread database files between runs. The run command is a single line that opens the project and runs all defined tasks. So it does run on Gitea or OneDev. But you write the configuration files by hand, and when something goes wrong you can’t lean on “an officially supported platform.”
Seeing test results on the PR page: the strength of GitLab’s free tier (JUnit, coverage)
From the free tier on, GitLab shows JUnit test results and coverage percentage on the merge request (MR) page, and displays coverage line by line on the changed code (official docs, Tier: Free).
Gitea gained Job Summary in 1.27 (July 2026), a feature that shows a summary the workflow writes in Markdown on the run results page (PR #37500). If you turn test results into a table and write it to the summary, you can see it right on that page, but I didn’t find a feature that reads JUnit directly to list failures or shows line-by-line coverage the way GitLab does. You can fill this gap yourself: have CI post a result summary as a PR comment, attach a detailed report link to the commit status, or use diff-cover to pull out Markdown coverage for just the lines changed in this change. On the other hand, SonarQube Community Edition’s PR decoration plugin supports only GitHub, GitLab, Bitbucket, and Azure, so it couldn’t be used with Gitea.
OneDev publishes JUnit test results and Cobertura and JaCoCo coverage, and shows coverage and issues line by line on the PR change view. On this item alone it’s similar to GitLab’s free tier.
That said, if the verification tools have their own web results page (a dedicated server that collects static analysis or test results, for example), the PR page only needs a pass/fail summary and a link. In that case this item carries less weight.
Required review approval: not in free GitLab, but in free Gitea
This was the most surprising part of the safety process.
- Gitea (free): protected branch settings include a required number of approvals, counting only approvals from designated users and teams, dismissing existing approvals when new commits are pushed, blocking merges when there are change-request reviews, required passing of designated CI, rejecting changes to protected files, and allowing only signed commits.
- OneDev (free): you can set fine-grained rules like “if this user touches these files on this branch, review or CI verification is required.”
- GitLab free tier: multi-approver rules and preventing self-approval start at Premium. On the free tier, protected branches can only restrict “who can merge.”
On required approval alone, free Gitea and OneDev beat free GitLab.
Account integration: look at login and group sync separately (LDAP, SAML, OIDC)
For account integration, the differences show only when you split it into two steps: “log in with a company account” and “automatically assign permissions based on company groups.”
| Company account login | Company groups → permission sync | |
|---|---|---|
| GitLab free | LDAP, SAML, OIDC all free | LDAP, SAML, OIDC group sync all from Premium |
| Gitea | LDAP, OIDC free; SAML paid (Enterprise) | LDAP group check, OIDC groups → admin and team membership free |
| OneDev | LDAP/AD, OIDC, Entra ID integration free | LDAP groups, OIDC group claims → groups free |
GitLab’s free tier allows company account login even via SAML, but deciding which group and permission each logged-in person gets has to be managed by hand inside GitLab. That burden grows with the organization. Gitea is the opposite: group sync is free, but SAML login is paid. Most company identity systems today also support OIDC, so unless the company allows only SAML, Gitea’s weakness isn’t big.
The cost of scaling to company size (Enterprise pricing compared)
None of the candidates need a paid plan because of user count. GitLab’s self-managed free tier has no user limit (the 5-user limit applies only to private groups on the gitlab.com cloud). What makes paid plans necessary is management and control features.
| Price per user per month | Main features in the paid plan | |
|---|---|---|
| GitLab Premium | $29 (billed annually) | Multi-approver rules, protected environments, push rules, LDAP/SAML group sync, audit logs, Geo replication |
| Gitea Enterprise | $9.50–$19 (1-year commitment) | SAML 2.0, org-wide protected branch inheritance, dependency vulnerability scanning |
| OneDev Enterprise | $6 (minimum 12 user-months per order) | Audit logs, cluster redundancy, security scanning, statistics and trend analysis |
| GitHub Enterprise Server | From $21 (GitHub Enterprise plan, Cloud and Server alike) | (the license itself is paid) |
Audit logging came to free Gitea in 28.0 (September 2026), and instance-wide enforced two-factor authentication in 1.24.
The moment GitLab is used company-wide, required approvals and group sync mean you effectively have to plan for Premium.
Can it last? OneDev’s one-person development structure
On features alone, OneDev is the most balanced. Its free edition has required approvals, PR-page result display, a project tree (children inherit parent settings), and account group integration, and its paid edition is the cheapest. What gave me pause is how it’s developed. On its GitHub repository, the top commit contributor has 4,426 commits and the second 188, so it depends heavily on one core developer. With 15k GitHub stars, its user base is also smaller than GitLab’s or Gitea’s. That’s a risk for a company-standard tool meant to last.
Gitea is actively developed (after 1.27 it switched to version 28 numbering; v28.2.0 on October 18, 2026). Forgejo is run by its contributor community, with its domains held by the nonprofit Codeberg e.V. It started as a branch tracking Gitea, but from early 2024 its code diverged and it became a separate project. GitLab has the largest user base and documentation.
Side by side
| Criterion | GitLab free | Gitea | OneDev |
|---|---|---|---|
| On-premises | Yes | Yes | Yes |
| Specs | Heavy | Light | Light |
| CI format | Own format | GitHub Actions format | Own format |
| Official domain-tool CI support (e.g., MATLAB) | Yes | No (run via command) | No (run via command) |
| Test results and coverage on PR page | Free | Summary only (Job Summary) | Free |
| Required review approval | Premium | Free | Free |
| Company account login | Free (incl. SAML) | Free (excl. SAML) | Free |
| Group → permission sync | Premium | Free | Free |
| Org structure | Subgroups | None | Project tree |
| Paid price at company scale | $29 | $9.50–$19 | $6 |
| Long-term stability | Highest | High | Low (one-person concentration) |
So which one?
- If you want to follow the domain tool’s official setup as is, GitLab. It generates pipeline configuration automatically and goes from personal practice to company scale with the same product. But at the company stage, be ready for the Premium cost.
- If you want to run company-wide for free, Gitea. Required approvals and group sync are free. But you have to write the pipeline configuration and result display yourself.
- If you want the most features in a free edition and can accept the one-person development risk, OneDev.
- If the company already uses GitHub Enterprise, GitHub Enterprise Server. It’s the heaviest choice for starting fresh.
The decision narrowed down to two questions. Do you need required review approvals and group sync for free from the start? And does the company identity system allow OIDC, or only SAML?
Final thoughts
At first I had half-reached a conclusion on two guesses: “GitLab is heavy, so it won’t run on a home PC” and “Gitea’s results view is weak.” When I checked, both were wrong or only half right. The specs were ample, and Gitea had gained a summary view in a recent version. Instead, “free GitLab has no required approvals” and “group sync is paid,” which I hadn’t even looked at at first, were what actually decided it. A tool comparison table only became useful once I redrew it not as a feature list, but as “what’s free under my conditions.”