Skip to content

CI

.forgejo/workflows/ci.yml is the whole automation surface: a gate that builds, vets, and tests the runtime on every push and pull request, and a publish step that, on a push to main or an authorized manual dispatch of main, builds the image, publishes it to Forgejo OCI under the full source sha, and verifies the remote manifest.

gate

Runs on the docker label, the only label this Forgejo instance's runners advertise, inside the moving :release aos dev-base image which already ships Go and the Docker CLI. GOPRIVATE=forgejo.coilysiren.me keeps umbra, a private module fetched anonymously, off the public proxy and sumdb, and the Dockerfile sets the same var for its own fetch. Then go build, go vet, go test.

publish

Runs on the trusted deploy label with needs: [gate], guarded by the push or workflow_dispatch event plus refs/heads/main. Never on a pull request, never on a feature branch. The manual path recovers a commit whose original push did not queue Actions.

scripts/publish-image.sh creates a temporary Docker config, authenticates through password-stdin, builds one source-sha tag, and pushes it. Then docker manifest inspect must resolve the exact pushed reference before the job succeeds. There is no :latest: the fleet keys rollouts by sha.

Why CI never ran (mcp-beaver#10)

Two facts must line up for a run to queue, and this repo missed one.

The Actions unit must be active when the push lands. A valid workflow on the default branch does not queue a run by itself. Check has_actions and toggle it through the forgejo operator verbs.

The gate must name a label the runner advertises. It was pinned to ubuntu-latest, a GitHub-mirror label the Forgejo runners do not carry, so it matched no runner. Pinning to docker fixed it.