Build and publish / Test and build (darwin) (push) Successful in 1m25s
Build and publish / Test and build (windows) (push) Successful in 3m6s
Build and publish / Test and build (linux) (push) Successful in 3m59s
Build and publish / Build and publish Docker image (push) Successful in 2m41s
The workflow now verifies that all three DinD TLS certificates are readable before attempting registry login or Buildx operations. The check fails early with instructions to apply runner-compose.yaml if the runner has not mounted /certs/client into job containers. Buildx now creates a named Docker context from the TLS environment variables, as Buildx cannot use TLS endpoints without an explicit context. Each CI run uses a uniquely named builder (based
138 lines
6.2 KiB
Markdown
138 lines
6.2 KiB
Markdown
# Gitea CI/CD
|
|
|
|
The workflow in `.gitea/workflows/build.yml` runs on branch pushes, `v*` tag
|
|
pushes, pull requests, and manual dispatches. Each platform runs formatting,
|
|
vet, and unit checks before building static AMD64 and ARM64 binaries. Linux
|
|
also runs the mock Ombi integration suite. No live Ombi credentials are needed.
|
|
|
|
Download the `ombi-mcp-darwin`, `ombi-mcp-linux`, or `ombi-mcp-windows` artifacts
|
|
from the workflow run. Each contains two `.tar.gz` archives, one per architecture,
|
|
with the executable and README. Tar preserves Unix executable permissions.
|
|
|
|
## Runner setup
|
|
|
|
Enable Actions in the repository settings and register these runner labels:
|
|
|
|
| Label | Host / requirements |
|
|
| --- | --- |
|
|
| `macos` | macOS host runner, Git, Bash, tar, Node.js 20 |
|
|
| `windows` | Windows host runner, Git for Windows (Bash on PATH), tar, Node.js 20; public-repository access |
|
|
| `ubuntu-latest` | Linux runner with Git, Bash, tar, Node.js 20, Docker Engine, curl, and Docker daemon access |
|
|
|
|
The Linux jobs use the `ubuntu-latest` runner label. The Windows job uses Git
|
|
directly because the self-hosted Windows runner cannot start the Node-based
|
|
checkout action; it therefore requires access to the public repository URL.
|
|
`setup-go` installs the version specified in `go.mod`.
|
|
Runners need network access to GitHub actions, Go downloads/modules, Docker Hub,
|
|
GitHub release downloads, and `git.i3omb.com`. For a Docker-in-Docker runner,
|
|
the Docker job expects the sibling service at `docker:2376` with TLS enabled and
|
|
the client certificates mounted at `/certs/client` inside the job container.
|
|
The workflow sets `DOCKER_HOST`, `DOCKER_TLS_VERIFY`, and `DOCKER_CERT_PATH`
|
|
explicitly because act_runner service environment variables are not inherited
|
|
by job containers. If Buildx is absent, the workflow installs its pinned CLI
|
|
plugin before building. Artifact uploads use `upload-artifact@v3` for
|
|
compatibility with Gitea's older artifact API.
|
|
|
|
The workflow requests a bind mount of `/certs/client` and maps `docker` to
|
|
`host-gateway`. The bind source is resolved inside the DinD daemon's filesystem,
|
|
where its client certificates exist. Job containers run inside that daemon;
|
|
they do not share the outer Compose service network.
|
|
|
|
The runner must also permit that bind source in its **active** configuration:
|
|
|
|
```yaml
|
|
container:
|
|
valid_volumes:
|
|
- /certs/client
|
|
```
|
|
|
|
Run 41655's job 43221 confirmed the runner discarded the requested mount:
|
|
`[/certs/client] is not a valid volume, will be ignored`. Adding workflow
|
|
options does not override this runner allowlist. This occurs before registry
|
|
authentication or Buildx can run.
|
|
|
|
For the existing TrueNAS deployment, [runner-compose.yaml](runner-compose.yaml)
|
|
is a complete replacement Compose definition. Apply it to the **existing**
|
|
Compose project, preserving its volume names and data directories. It embeds
|
|
the allowlist using Compose `configs.content` (requires Compose 2.23.1+) and
|
|
sets `CONFIG_FILE=/etc/act_runner/config.yaml`, which the official entrypoint
|
|
passes to the daemon.
|
|
It reuses the existing `/data/.runner` registration, so no registration token
|
|
is needed. The old `/data/config.yaml` remains on disk but is no longer used.
|
|
|
|
Before applying, verify the registered runner and DinD certificates exist:
|
|
|
|
```sh
|
|
docker exec gitea-runner test -s /data/.runner
|
|
docker exec gitea-dind test -s /certs/client/ca.pem
|
|
```
|
|
|
|
After saving the replacement YAML as the existing project's Compose file:
|
|
|
|
```sh
|
|
docker compose config --quiet
|
|
docker compose up -d --no-deps --force-recreate act-runner
|
|
docker exec gitea-runner cat /etc/act_runner/config.yaml
|
|
```
|
|
|
|
The printed config must contain `/certs/client` under `container.valid_volumes`.
|
|
Then rerun CI. Its first Docker step verifies that all three TLS files are
|
|
readable and that `docker version` can reach the daemon before attempting
|
|
registry login. This repository change cannot update the running TrueNAS
|
|
container itself.
|
|
|
|
References: [Gitea runner volume configuration](https://docs.gitea.com/runner/2/configuration/#container),
|
|
[Docker bind mount source paths](https://docs.docker.com/engine/storage/bind-mounts/),
|
|
and [Compose inline configs](https://docs.docker.com/reference/compose-file/configs/).
|
|
|
|
## Container publishing
|
|
|
|
After all binary jobs succeed, Buildx builds a non-root, scratch-based image for
|
|
`linux/amd64` and `linux/arm64`. Cross-compilation runs on the builder's native
|
|
architecture, so no QEMU installation is needed. The image includes public CA
|
|
certificates for HTTPS connections to Ombi. Authentication and the Ombi URL are
|
|
supplied at runtime.
|
|
|
|
The image job creates a named Docker context containing the DinD TLS endpoint
|
|
and certificate paths; Buildx cannot create a builder from TLS environment
|
|
variables alone. Each CI attempt uses its own builder and removes it on exit.
|
|
|
|
Set these repository Actions secrets before publishing:
|
|
|
|
| Secret | Value |
|
|
| --- | --- |
|
|
| `REGISTRY_USERNAME` | Gitea username with permission to publish packages under the repository owner |
|
|
| `REGISTRY_TOKEN` | That user's personal access token with `write:package` scope |
|
|
|
|
The destination is `git.i3omb.com/<repository-owner>/<repository-name>` (lowercase),
|
|
which is `git.i3omb.com/gronod/ombi-mcp` for this repository.
|
|
|
|
- Default-branch pushes publish `latest` and `sha-<full-commit-sha>`.
|
|
- Version-tag pushes publish the exact tag (for example `v1.2.3`) and the SHA tag.
|
|
They do not replace `latest`, including prerelease tags.
|
|
- Pull requests, other branches, and manual runs build without logging in or pushing.
|
|
|
|
Gitea's job token is not used for registry login; see the documented
|
|
[package authorization limitation](https://docs.gitea.com/usage/actions/comparison/#package-repository-authorization)
|
|
and [container registry instructions](https://docs.gitea.com/usage/packages/container/).
|
|
Publishing uploads the image; it does not restart any running deployment.
|
|
|
|
## Running the image
|
|
|
|
For stdio, keep stdin open and do not allocate a TTY:
|
|
|
|
```sh
|
|
docker run --rm -i --env-file .env git.i3omb.com/gronod/ombi-mcp:latest
|
|
```
|
|
|
|
For HTTP/SSE:
|
|
|
|
```sh
|
|
docker run --rm --env-file .env -e MCP_TRANSPORT=sse \
|
|
-p 8080:8080 git.i3omb.com/gronod/ombi-mcp:latest
|
|
```
|
|
|
|
Build locally with `docker build -t ombi-mcp .`. CI passes the Go version from
|
|
`go.mod` as a build argument; when upgrading Go, also update the Dockerfile's
|
|
default `GO_VERSION` for local builds.
|