Two integration tests fail when run inside act_runner because the job container shares the host's docker socket — networks created on the host daemon aren't always visible in-process, and ports published by sibling containers aren't reachable on the job's 127.0.0.1. Skip them when GITEA_ACTIONS=true. Document the limitation in docs/ci.md as a follow-up to revisit. Assisted-by: Claude Code
3.9 KiB
CI
The test workflow lives at .gitea/workflows/test.yml.
It runs tests/run_tests.py (full suite — unit + integration) on:
- every push to a branch with an open pull request, and
- every push to
main.
Integration tests need Docker on the runner; they skip cleanly via
tests/_docker.skip_unless_docker when no daemon is reachable.
A small subset of integration tests skip when running specifically
under Gitea Actions (GITEA_ACTIONS=true), because act_runner runs
the job inside a container with the host's /var/run/docker.sock
mounted in. That topology breaks two assumptions those tests make:
- networks created via the host daemon aren't always visible to a
same-process
docker network lscall from inside the job container, and - ports published by sibling containers land on the host's loopback,
not on the job container's
127.0.0.1— so HTTP probes againsthttp://127.0.0.1:<host_port>from inside the job time out.
The affected tests (test_orphan_cleanup.test_create_and_remove,
test_pipelock_sidecar_smoke.test_smoke) still run locally where the
test process and Docker daemon share a host. Making them work in CI
is a follow-up: either re-write them to discover container IPs via
docker inspect, or reconfigure the runner with host networking.
Branch protection on main
Branch protection is not captured in tree — Gitea applies it via the repo settings UI / API, not a checked-in config file. Reproducing the rule on a fresh clone or migration therefore means re-applying the same setting through one of the two paths below.
Via the Gitea UI
- Go to the repo on
gitea.dideric.is. - Settings → Branches → Branch protection rules → Add rule.
- Branch name pattern:
main. - Enable Enable Status Check and select the check named
test / run tests/run_tests.py(the workflow's job display name). The check has to have run at least once on the repo for Gitea to list it; push a no-op commit on a feature branch first if needed. - (Recommended) Also enable Require pull request before merging
so changes to
mainalways go through a PR — otherwise a direct push tomainbypasses the status check entirely. - Save.
After saving, open a PR. The "Merge" button should be disabled until the test check is green.
Via the Gitea API
Equivalent call (requires an admin token in $GITEA_TOKEN):
curl -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
https://gitea.dideric.is/api/v1/repos/didericis/claude-bottle/branch_protections \
-d '{
"rule_name": "main",
"enable_status_check": true,
"status_check_contexts": ["test / run tests/run_tests.py"],
"required_approvals": 0,
"block_on_outdated_branch": false
}'
The exact field for the check name is
status_check_contexts (an array of glob patterns). The Gitea
Actions check appears under
<workflow-name> / <job-name> — here test / run tests/run_tests.py.
Confirm the actual rendered context string in Repo → Actions →
→ Job summary before pasting into the API call; Gitea
versions occasionally tweak the formatting and a typo here silently
matches no checks (rule loads, but never blocks).
To inspect the live rule:
curl -H "Authorization: token $GITEA_TOKEN" \
https://gitea.dideric.is/api/v1/repos/didericis/claude-bottle/branch_protections
Verifying the gate
Once the rule is in place, prove it works once with a deliberately-failing test on a throwaway branch:
- Create a branch (
gate-test-DELETEME), add a test that fails (e.g.self.assertTrue(False)), push, open a PR. - Wait for the check to go red. Confirm the "Merge" button is disabled / shows the unmet status check.
- Close the PR and delete the branch. Do not merge.
This is a one-time check after applying the rule, not a recurring exercise.