diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ecdcc391..6d51cfb1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -176,6 +176,39 @@ non-destructive version of "tidy the history" without touching a single commit. - Fill in the PR template checklist. Reference the issue you close with `Closes #NN` in the description or a commit message. +## CI (self-hosted runners) + +Every workflow starts by cloning `${{ github.server_url }}/${{ github.repository }}`. +On a self-hosted Forgejo runner that URL is usually the instance's *internal* +address (e.g. `http://forgejo:3000`), so **the job container must be able to +resolve it**. The runner puts each job on a fresh per-job network by default, +which the Forgejo container is not attached to — so the clone fails with: + +``` +fatal: unable to access 'http://forgejo:3000/…': Could not resolve host: forgejo +``` + +Give the runner a config that pins job containers to a network Forgejo is also +on. A dedicated network is better than the general application network, so a CI +job cannot reach unrelated services: + +```yaml +# the runner's config.yml, passed with: forgejo-runner daemon --config … +container: + network: forgejo-ci +``` + +with `forgejo-ci` attached to the Forgejo container as well. Verify it without +running a workflow: + +```bash +docker run --rm --network forgejo-ci alpine:3 getent hosts forgejo +``` + +This failure mode is intermittent if left unfixed: Docker forwards names it +cannot resolve to the host's resolver, which may answer for the container name +often enough that CI looks healthy for a while. + ## Reporting issues Use the templates under [`.forgejo/issue_template/`](.forgejo/issue_template): diff --git a/changes/ci-runner-dns.md b/changes/ci-runner-dns.md new file mode 100644 index 00000000..c6067d37 --- /dev/null +++ b/changes/ci-runner-dns.md @@ -0,0 +1,8 @@ +bump: patch +type: docs +CONTRIBUTING documents what a self-hosted Forgejo runner needs for CI to work at +all: every workflow clones `${{ github.server_url }}`, which on a self-hosted +instance is an internal address, so job containers must be able to resolve it. +The runner's default is a fresh per-job network the Forgejo container is not on, +which fails the clone — intermittently, because Docker forwards unresolved names +to the host resolver, so CI can look healthy for a while before it stops.