go-gitea/gitea
Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓27+ active contributors
- ✓Distributed ownership (top contributor 26% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/go-gitea/gitea)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/go-gitea/gitea on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: go-gitea/gitea
Generated by RepoPilot · 2026-05-07 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/go-gitea/gitea shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 27+ active contributors
- Distributed ownership (top contributor 26% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live go-gitea/gitea
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/go-gitea/gitea.
What it runs against: a local clone of go-gitea/gitea — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in go-gitea/gitea | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of go-gitea/gitea. If you don't
# have one yet, run these first:
#
# git clone https://github.com/go-gitea/gitea.git
# cd gitea
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of go-gitea/gitea and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "go-gitea/gitea(\\.git)?\\b" \\
&& ok "origin remote is go-gitea/gitea" \\
|| miss "origin remote is not go-gitea/gitea (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "cmd/web.go" \\
&& ok "cmd/web.go" \\
|| miss "missing critical file: cmd/web.go"
test -f "modules/git" \\
&& ok "modules/git" \\
|| miss "missing critical file: modules/git"
test -f "models" \\
&& ok "models" \\
|| miss "missing critical file: models"
test -f "routers/api/v1" \\
&& ok "routers/api/v1" \\
|| miss "missing critical file: routers/api/v1"
test -f "go.mod" \\
&& ok "go.mod" \\
|| miss "missing critical file: go.mod"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/go-gitea/gitea"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Gitea is a self-hosted Git service written in Go that provides Git repository hosting, code review, team collaboration, package registry, and CI/CD capabilities in a single binary. It runs on all platforms supported by Go (Linux, macOS, Windows, ARM, PowerPC) and is designed to be the simplest, fastest way to set up a private Git server without external dependencies. Monolithic Go backend with a segregated frontend layer. Backend: cmd/ contains entry points, modules/git* handles Git operations, routers/ defines HTTP endpoints, services/ contains business logic, models/ defines data structures. Frontend: web_src/ contains Vue/TypeScript components compiled to assets via web/ directory. Build split: make backend (Go) and make frontend (Node.js/pnpm), with bindata tag embedding frontend assets into the binary.
👥Who it's for
DevOps engineers, system administrators, and organizations that need to self-host a Git platform (like GitHub or GitLab) on their own infrastructure without cloud vendor lock-in or complex setup. Also contributes to: Go developers maintaining backend services, frontend developers using Vue/TypeScript/Handlebars for the web UI, and teams needing on-premises code collaboration.
🌱Maturity & risk
Production-ready and actively maintained. The project has comprehensive CI/CD workflows (.github/workflows/ with pull-db-tests.yml, pull-e2e-tests.yml, release workflows), extensive Go test coverage, and an active community (Discord badge, translation infrastructure via Crowdin, multiple issue templates). Last observable commit activity is recent (cache-seeder and release workflows indicate ongoing maintenance).
Moderate risk: 50+ direct Go dependencies (Azure SDK, AWS SDK, various storage backends, crypto libraries) create a large attack surface and maintenance burden. Single monorepo architecture means breaking changes affect all features simultaneously. The 14M+ lines of Go code require careful review for security issues (it handles Git operations and authentication). Dependency quality varies—some are high-stakes (cryptography, authentication, storage).
Active areas of work
Active development across multiple areas: pull-db-tests.yml and pull-e2e-tests.yml indicate ongoing testing infrastructure improvements, cron-translations.yml shows continuous localization, pull-labeler.yml and pull-pr-title.yml suggest process automation enhancements, and release workflows (release-nightly.yml, release-tag-version.yml) indicate regular versioning cycles. The .changelog.yml and CHANGELOG.md are actively maintained.
🚀Get running
Clone and build: git clone https://github.com/go-gitea/gitea.git && cd gitea && TAGS="bindata" make build. For development: install Go (version in go.mod), Node.js LTS, and pnpm. Run make backend to build the Go binary and make frontend to build web assets. See .devcontainer/devcontainer.json for containerized dev setup.
Daily commands:
Development: make build produces ./gitea binary. Run ./gitea web to start the server (listens on http://localhost:3000 by default). Alternatively use Docker: docker build -t gitea:latest . && docker run -p 3000:3000 gitea:latest. For frontend dev with hot reload, see .air.toml configuration for live server during make backend.
🗺️Map of the codebase
cmd/web.go— Main web server entry point; all HTTP routes and middleware initialization flow through heremodules/git— Core Git operations abstraction layer; handles all repository cloning, pushing, and ref managementmodels— Data models and ORM definitions for users, repos, issues, PRs, and all persistent entitiesrouters/api/v1— RESTful API v1 endpoints; defines all public API contracts for integrations and clientsgo.mod— Dependency manifest with critical versions (Go 1.26.2, SDK, Actions proto); drift here breaks buildsMakefile— Build orchestration; defines how to compile, test, and package Gitea for all platforms.github/workflows— CI/CD automation; validates PRs, builds releases, and manages nightly deployments
🛠️How to make changes
Add a New REST API Endpoint
- Define API handler in routers/api/v1 (e.g., routers/api/v1/repo.go) (
routers/api/v1/repo.go) - Register route in routers/api/v1/swagger.go using Swagger annotations (
routers/api/v1/swagger.go) - Implement business logic in services (e.g., services/repository/repository.go) (
services/repository/repository.go) - Use model queries from models (e.g., models/repo.go for GetRepositoryByID) (
models/repo.go) - Add integration test in routers/api/v1/repo_test.go (
routers/api/v1/repo_test.go)
Add a New Authentication Method
- Create auth provider in modules/auth (e.g., modules/auth/ldap.go) (
modules/auth/ldap.go) - Define auth source model in models/auth/source.go (
models/auth/source.go) - Add admin CLI command in cmd/admin_auth_*.go (
cmd/admin_auth_ldap.go) - Register middleware in routers/common/auth.go (
routers/common/auth.go) - Add test file cmd/admin_auth_*_test.go (
cmd/admin_auth_ldap_test.go)
Add a New Git Operation (e.g., Rebase, Cherry-Pick)
- Implement Git command wrapper in modules/git (e.g., modules/git/repo.go) (
modules/git/repo.go) - Add service function in services/gitoperations/ or services/pull/ (
services/pull/merge.go) - Expose via API endpoint in routers/api/v1/repo_*.go (
routers/api/v1/repo_commits.go) - Add integration test in modules/git/*_test.go (
modules/git/repo_test.go)
Add a New Database Model & Migration
- Define model struct in models/*.go (e.g., models/issue.go) (
models/issue.go) - Create migration file in models/migrations/*.go (
models/migrations) - Register model hooks in models/*.go (BeforeSave, AfterLoad, etc.) (
models/issue.go) - Add query methods in models/*_methods.go (
models/issue_methods.go) - Add API endpoints in routers/api/v1/ (
routers/api/v1/issue.go)
🔧Why these technologies
- Go 1.26.2 & goroutines — High concurrency for handling thousands of concurrent Git operations and API requests with minimal memory footprint
- go-chi (gitea.com/go-chi/*) — Lightweight HTTP router with built-in middleware for binding, caching, sessions, and captcha
- Git CLI commands (modules/git) — Delegates to native Git binary for correctness and safety rather than implementing Git protocol from scratch
- SQL ORM (XORM-like) — Multi-database support (PostgreSQL, MySQL, SQLite) with automatic migrations and query builder
- Actions Proto & Gitea Runner — Native CI/CD pipeline execution compatible with GitHub Actions syntax
⚖️Trade-offs already made
-
Use Git CLI wrapper instead of Go Git library
- Why: Gitea needs to handle complex Git operations (hooks, submodules, LFS) that match server-side enforcements
- Consequence: Requires Git binary on server; slower than pure Go but ensures compatibility with system Git config
-
Single-process monolith with no queue/message broker in core
- Why: Simplifies deployment for self-hosted users; reduces operational complexity
- Consequence: Long-running tasks (large pushes, migrations) block request threads; horizontal scaling requires external task queue
-
Embedded UI assets and templates (no separate frontend server)
- Why: Single binary deployment; no CDN or frontend build step required
- Consequence: UI updates require recompilation; asset versioning harder; template rendering slower than pre-built static HTML
-
Support multiple auth backends (OAuth, LDAP, SMTP, local)
- Why: Enterprise deployments often require integration with existing identity systems
- Consequence: Auth code path is complex with many conditional branches; testing matrix explodes
🚫Non-goals (don't propose these)
- Real-time collaboration (no WebSocket sync for live editing)
- Distributed consensus (single database, not a raft cluster)
- Cloud-native multi-tenant SaaS (designed for self-hosted single-tenant deployment)
- GraphQL API (REST v1 is the primary API; GraphQL not implemented)
- Mobile apps (web UI responsive but no native iOS/Android apps)
- Windows native port (runs on Windows but Git operations assume POSIX shell)
🪤Traps & gotchas
Be aware: (1) Bindata tag requirement—must use TAGS="bindata" make build to embed frontend assets; omitting this breaks web UI. (2) Git CLI dependency—Gitea shells out to system git command; requires Git installed at runtime, not just build time. (3) Default SQLite in development—migrations must work across SQLite, PostgreSQL, MySQL; test database changes thoroughly. (4) File permissions on Linux—running as non-root requires careful ownership setup; see Dockerfile.rootless for pattern. (5) Large monorepo—git clone is slow; consider --depth=1 for faster initial clone.
🏗️Architecture
💡Concepts to learn
- Git plumbing vs porcelain — Gitea wraps Git CLI (porcelain) commands in modules/git/*.go; understanding when to use raw git objects vs high-level commands affects how new features shell out to git
- OAuth 2.0 / OpenID Connect — Gitea's authentication system (modules/auth/oauth2.go) supports external identity providers; critical for enterprise deployments and understanding user federation
- Database migrations — Gitea supports SQLite, PostgreSQL, MySQL with schema migrations in models/migrations/*.go; breaking changes require careful versioning to avoid data loss
- Full-text search indexing (Bleve) — Repository search and issue search use Bleve (github.com/blevesearch/bleve/v2 in go.mod); understanding inverted indexes helps optimize search performance and query handling
- Public-key cryptography (SSH) — Git over SSH requires SSH key verification; modules/auth/sshauthentication.go and ProtonMail/go-crypto handle signing and verification critical for secure Git push/pull
- NTLM authentication — Azure/go-ntlmssp in dependencies enables Windows Active Directory auth for enterprises; understanding NTLM v2 challenge-response helps debug auth failures in corporate environments
- Content-addressable storage (Git objects) — Git internally uses SHA-1 hashing to content-address blobs, trees, commits; Gitea's garbage collection and object storage logic depends on this immutability guarantee
🔗Related repos
go-gitea/gitea-runner— Official CI/CD runner for Gitea (already vendored as gitea.com/gitea/runner in go.mod); handles act workflow execution on self-hosted machinesgo-gitea/gitea-sdk-go— Official Go SDK for Gitea API (code.gitea.io/sdk/gitea in go.mod); what external Go clients use to interact with Gitea instancesgo-gitea/docs— Official documentation repository; single source of truth for deployment, administration, and user guides referenced in main READMEgogs/gogs— Spiritual predecessor that Gitea forked from in November 2016; similar self-hosted Git service in Go that some teams use as an alternativegitea/tea— Official CLI tool for Gitea; allows command-line interaction with Gitea servers, complementary to the web UI
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add missing workflow for OpenAPI schema validation in pull requests
The repo has build/openapi3gen for generating OpenAPI specs but no CI workflow validates that OpenAPI schemas remain consistent across PRs. Given the presence of .github/actionlint.yaml and multiple PR-focused workflows, a dedicated workflow should validate OpenAPI schema changes don't break API compatibility.
- [ ] Create .github/workflows/pull-openapi-validation.yml to run build/openapi3gen/convert.go tests
- [ ] Add validation that compares OpenAPI spec diffs between base and PR branches
- [ ] Ensure workflow fails if breaking changes are detected (e.g., removed endpoints, changed parameter types)
- [ ] Reference existing similar workflows like pull-db-tests.yml for structure
Add comprehensive unit tests for build/openapi3gen/convert.go
The OpenAPI generation code at build/openapi3gen/convert.go has a corresponding convert_test.go but lacks coverage verification. As this is critical infrastructure for API documentation, test coverage should be explicit and comprehensive.
- [ ] Expand build/openapi3gen/convert_test.go with edge cases (nested types, circular references, custom formats)
- [ ] Add tests for all exported functions in convert.go
- [ ] Add integration test validating the generated OpenAPI schema passes openapi3gen validation
- [ ] Consider adding fuzz tests for malformed input handling
Add workflow for validating Go module dependencies security in pull requests
The go.mod shows heavy dependency usage (Azure SDK, AWS SDK, crypto libraries) but there's no PR workflow running security scanning. With SECURITY.md present, a dedicated dependency audit workflow would prevent vulnerable packages from being merged.
- [ ] Create .github/workflows/pull-go-security.yml running 'go list -json -m all | nancy sleuth' or similar
- [ ] Alternatively integrate Dependabot security alerts workflow if not already active
- [ ] Add workflow that runs 'govulncheck ./...' on PR branches (requires Go 1.18+)
- [ ] Fail CI if any CVEs are detected in direct or transitive dependencies
🌿Good first issues
- Add missing API endpoint documentation: routers/api/v1/*.go has many endpoints lacking godoc comments; audit a subsystem (e.g., issues, pull requests, releases) and add structured documentation matching the patterns in existing files
- Implement missing unit tests for models/user.go or models/access.go: coverage gaps exist for edge cases in permission checking; add table-driven tests following the pattern in existing *_test.go files
- Improve error messages in modules/auth/oauth2.go: add user-facing error context (currently returns generic 'authentication failed'); add logging and structured error types to help users debug OAuth provider misconfigurations
⭐Top contributors
Click to expand
Top contributors
- @wxiaoguang — 26 commits
- @silverwind — 20 commits
- @GiteaBot — 9 commits
- @Copilot — 7 commits
- @bircni — 6 commits
📝Recent commits
Click to expand
Recent commits
2200ed7— fix: use consistent GetUser family functions (#37553) (bircni)19f0169— fix(api): return 409 message instead of empty JSON for wrong commit id (#37572) (Exgene)6302584— fix(actions): prevent panic when workflow contains null jobs (#37570) (Exgene)cf48aa0— [skip ci] Updated translations via Crowdin (GiteaBot)a39af1a— refactor: use modernc sqlite driver as default (#37562) (wxiaoguang)b093c2c— refactor(templates): remove ctxData from tmpl files, use ctx.RootData instead (#37567) (Copilot)ebc058f— ci: increase renovate frequency and fix RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS (#37565) (silverwind)35dfc6b— fix(deps): update go dependencies (#37541) (GiteaBot)97211bf— refactor(deps): migrate fromnektos/actfork togitea/runner(#37557) (silverwind)45ffe5a— ci: lint PR titles with commitlint (#37498) (bircni)
🔒Security observations
Gitea demonstrates a reasonable security posture with proper vulnerability disclosure channels (security@gitea.io) and PGP key for encrypted reporting. However, several areas require attention: (1) The intentional relaxation of x509 certificate validation presents a medium-severity concern that warrants periodic review; (2) Supply chain risks from numerous third-party dependencies require automated scanning and continuous monitoring; (3) Docker build practices need hardening around cache management and git data exposure. The project would benefit from implementing automated dependency scanning, maintaining an SBOM, and documenting security baselines. Overall, as a mature self-hosted Git platform with active security focus, the security posture is acceptable but requires continuous vigilance given its role as infrastructure software.
- Medium · Outdated Go Version —
go.mod (go 1.26.2). The project uses Go 1.26.2 which may contain known vulnerabilities. While this is a recent version, it's important to ensure all dependencies are regularly updated and security patches are applied promptly. Fix: Regularly monitor Go security advisories and update to the latest stable version. Use 'go get -u' and review security patches in release notes. - Medium · Permissive x509 Certificate Serial Number Validation —
go.mod (godebug x509negativeserial=1). The codebase explicitly disables x509 negative serial number validation via 'godebug x509negativeserial=1'. While documented as a workaround for certain CAs (MSSQL), this relaxes certificate validation and could potentially be exploited if untrusted certificates are accepted. Fix: Review if this relaxed validation is still necessary. Consider implementing additional certificate pinning or validation layers for critical connections. Document the security implications and monitor for alternative solutions from upstream CAs. - Medium · Third-Party Dependency Supply Chain Risk —
go.mod (all dependencies). The project depends on numerous third-party packages including cryptographic libraries, authentication handlers, and storage backends. Multiple dependencies from various sources increase the attack surface and supply chain risk. Fix: Implement automated dependency scanning using tools like 'go list -json -m all | nancy sleuth' or GitHub Dependabot. Regularly audit and update dependencies. Use go.sum verification and consider using a software composition analysis (SCA) tool. - Low · Docker Build Cache Security —
Dockerfile (lines with RUN --mount=type=cache). The Dockerfile uses caching mounts for package managers (/root/.local/share/pnpm/store) which could potentially cache malicious packages across builds if a supply chain attack occurs. Fix: Consider cache invalidation strategies. Use 'pnpm install --frozen-lockfile' (already in place) and verify lock file integrity. Monitor for compromised packages in security advisories. - Low · Git Directory Mounting in Docker Build —
Dockerfile (comment about .git mounting). The Dockerfile comment mentions '.git directory is mounted separately later only for version data'. If git history or tags contain sensitive information, this could leak data during builds. Fix: Ensure git credentials are not stored in repository history. Use git filtering tools (git-filter-repo) to remove sensitive data. Consider using build args for version instead of git data when possible. - Low · Missing SBOM and Security Baseline Documentation —
Project root / SECURITY.md. While SECURITY.md provides vulnerability reporting instructions, there's no visible Software Bill of Materials (SBOM) or documented security baseline for this complex project with many dependencies. Fix: Generate and maintain an SBOM using tools like 'syft' or 'cyclonedx'. Document security baseline requirements and compliance targets. Provide supply chain security documentation.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.