Files
forge/docs/testing.md
zeekayandHanzo Dev b88ecbec1c ci: this fork's own law applies to this fork — one file on GitHub
.github/workflows held 13 files. It now holds one: the sync nudge, which runs
zero CI. Everything real is in .hanzo/workflows.

This repo is what ENFORCES that everywhere else. modules/actions/workflows.go
`listWorkflowsInDirs` walks setting.Actions.WorkflowDirs — .hanzo/workflows,
.gitea/workflows, .github/workflows — and BREAKS at the first directory that
exists. So the moment a repo has .hanzo/workflows, its .github/workflows is
invisible to the forge entirely. One dir wins; there is no merging. That is
also why the 13 files here were dead twice over.

DELETED — five workflows that cannot do work in a fork. Each is hard-guarded
`if: github.repository == 'go-gitea/gitea'`, and cron-translations/cron-licenses
push to `[email protected]:go-gitea/gitea.git` while cron-renovate names
RENOVATE_REPOSITORIES: ["go-gitea/gitea"]. Measured on main today: every recent
run of cron-renovate, giteabot and giteabot backport is `completed/skipped`.
They cost a run record per push and can never produce one useful result.

MOVED, verbatim — the seven that are real CI: pull-compliance, pull-db-tests,
pull-docker-dryrun, pull-e2e-tests, pull-labeler, files-changed (their
`workflow_call` reusable, whose local `uses: ./` path follows them) and
cache-seeder. Only three things changed: `runs-on: ubuntu-latest` → the
canonical `hanzo-linux-amd64` pool (RUNNERS.md), the reusable's path, and
cache-seeder's own `paths:` filter. This is the first time these suites can run
at all in this fork: they trigger on `pull_request`, we work on main, and the
forge could not see them behind .hanzo/workflows anyway. Zero runs on record.

REPLACED — build.yml, which shelled `buildctl-daemonless.sh`. That binary is not
in the image this fleet serves for its amd64 pool: every label maps to
catthehacker/ubuntu:act-24.04 (universe:infra/k8s/git-runner/statefulset.yaml).
The one builder this repo had could not run. hanzo.yml already declares the
image and the setting gate, which is exactly what the org's canonical builder
consumes, so cicd.yml is now the same ~7-line caller commerce, cloud and console
use — docker buildx, which the runner has, and the standard immutable
`sha-<sha7>-amd64` tag instead of an ad-hoc `:<sha8>`. Rollout is unchanged and
still a reviewed pin in hanzoai/universe: the `kubectl patch` build.yml carried
never took, because cd.hanzo.ai's selfHeal restores the CR on its next poll.

ADDED — sync.yml (the nudge, on our pool: GitHub-hosted minutes are billing-
blocked for this org) and .hanzo/workflows/sync-from-github.yml, the same
fast-forward-only pull every migrated repo runs. This fork is canonical on the
forge (mirror=false), so the sync is a catch-up from the GitHub remote, never a
force in either direction.

Docs follow the files: README ×3, docs/testing.md's `gitea-runner exec -W` paths,
and hanzo.yml's own header. The READMEs also still said "the arc pool" — arcd is
retired; act_runner is the one runner.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-25 15:19:40 -07:00

4.7 KiB

Testing

Gitea has four kinds of automated tests: backend unit tests, integration tests, end-to-end (e2e) tests, and migration tests. Local runs default to SQLite, so no extra services are required to get started.

For prerequisites see build-setup.md; for the build workflow see development.md.

Unit tests

Backend unit tests live in *_test.go files next to the code they cover. Set GIT_TEST_LOG_SQL=1 to log all SQL statements executed during the tests.

make test-backend

To run a single backend test, use go test directly or the # selector:

go test -run '^TestName$' ./modulepath/
make test-backend#TestName

Frontend unit tests run with Vitest:

make test-frontend
# single file:
pnpm exec vitest <path-filter>

Integration tests

Integration tests exercise Gitea against a real database. They live in tests/integration/ and require Git LFS to be installed. The database is selected with GIT_TEST_DATABASE; an empty value defaults to SQLite, which needs no external service:

make test-integration

Run a single integration test with the # selector:

make test-integration#TestName

If you hit errors such as a mismatched database version or SSH push failures, try a clean rebuild first:

make clean build

Running against other databases

Set GIT_TEST_DATABASE together with the matching TEST_* connection variables. The commands below start a throwaway database container (press Ctrl-C to stop and remove it) and then run the tests against it.

MySQL

docker run -e "MYSQL_DATABASE=test" -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" -p 3306:3306 --rm --name mysql mysql:latest
GIT_TEST_DATABASE=mysql TEST_MYSQL_HOST=localhost:3306 TEST_MYSQL_DBNAME=test TEST_MYSQL_USERNAME=root TEST_MYSQL_PASSWORD='' make test-integration

PostgreSQL

PostgreSQL tests also use a MinIO container for object storage:

docker run -e "POSTGRES_DB=test" -e "POSTGRES_USER=postgres" -e "POSTGRES_PASSWORD=postgres" -p 5432:5432 --rm --name pgsql postgres:latest
docker run --rm -p 9000:9000 -e MINIO_ROOT_USER=123456 -e MINIO_ROOT_PASSWORD=12345678 --name minio bitnamilegacy/minio:2023.8.31
GIT_TEST_DATABASE=pgsql TEST_MINIO_ENDPOINT=localhost:9000 TEST_PGSQL_HOST=localhost:5432 TEST_PGSQL_DBNAME=postgres TEST_PGSQL_USERNAME=postgres TEST_PGSQL_PASSWORD=postgres make test-integration

MSSQL

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_PID=Standard" -e "SA_PASSWORD=MwantsaSecurePassword1" -p 1433:1433 --rm --name mssql microsoft/mssql-server-linux:latest
GIT_TEST_DATABASE=mssql TEST_MSSQL_HOST=localhost:1433 TEST_MSSQL_DBNAME=gitea_test TEST_MSSQL_USERNAME=sa TEST_MSSQL_PASSWORD=MwantsaSecurePassword1 make test-integration

Running the database test workflow with Gitea Runner

The CI database test jobs can be run locally with Gitea Runner. Running every job is resource-intensive and not recommended:

gitea-runner exec -W ./.hanzo/workflows/pull-db-tests.yml --event=pull_request --default-actions-url="https://github.com" -i catthehacker/ubuntu:runner-latest

List the available job names, then run a single one:

gitea-runner exec -W ./.hanzo/workflows/pull-db-tests.yml --event=pull_request --default-actions-url="https://github.com" -i catthehacker/ubuntu:runner-latest -l
gitea-runner exec -W ./.hanzo/workflows/pull-db-tests.yml --event=pull_request --default-actions-url="https://github.com" -i catthehacker/ubuntu:runner-latest -j <job_name>

End-to-end tests

End-to-end tests drive a running Gitea instance with Playwright:

make test-e2e

To run a single e2e test file, pass it via GIT_TEST_E2E_FLAGS:

GIT_TEST_E2E_FLAGS='<filepath>' make test-e2e

Useful environment variables:

Variable Description
GIT_TEST_E2E_DEBUG When set, show the Gitea server output.
GIT_TEST_E2E_FLAGS Additional flags passed to Playwright, e.g. --ui.
GIT_TEST_E2E_TIMEOUT_FACTOR Timeout multiplier (default: 4 on CI, 1 locally).

Migration tests

If you change a database-persisted struct under models/ you will usually need a new migration in models/migrations/. Run the migration tests with:

make test-migration

Continuous integration

CI runs the unit tests, runs the integration tests against every supported database, and tests migration from several recent Gitea versions. Please submit your pull request with additional unit and integration tests as appropriate. Prefer unit tests when the logic can be tested in isolation, and keep local integration and e2e tests fast (aim for sub-2s runtime).