feat(gitea): add initial implementation of Gitea act_runner addon with configuration and runtime scripts
This commit is contained in:
88
gitea-act-runner/DOCS.md
Normal file
88
gitea-act-runner/DOCS.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Gitea act_runner — Home Assistant Addon
|
||||||
|
|
||||||
|
Runs the [Gitea Actions runner](https://gitea.com/gitea/act_runner) as a native Home Assistant addon, allowing your HAOS machine to execute Gitea CI/CD jobs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. A running **Gitea instance** (version ≥ 1.21) with Actions enabled.
|
||||||
|
In Gitea: **Site Administration → Configuration** — confirm `[actions] ENABLED = true`.
|
||||||
|
2. A **runner registration token** from your Gitea instance (see below).
|
||||||
|
3. The Gitea instance must be reachable from your HA machine by a **LAN IP address** (e.g. `http://192.168.1.50:3000`), not `localhost`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting the Registration Token
|
||||||
|
|
||||||
|
1. Log in to Gitea as a **site administrator**.
|
||||||
|
2. Navigate to **Site Administration → Actions → Runners**.
|
||||||
|
3. Click **Create new runner**.
|
||||||
|
4. Copy the displayed registration token — you will paste it into the addon options.
|
||||||
|
|
||||||
|
> **Tip:** Tokens can also be scoped to an organisation or a single repository via the respective *Settings → Actions → Runners* page if you don't want a global runner.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
| Option | Required | Default | Description |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `gitea_url` | ✅ | — | Full URL of your Gitea instance, e.g. `http://192.168.1.50:3000` |
|
||||||
|
| `runner_token` | ✅ | — | Registration token from the Gitea Runners page |
|
||||||
|
| `runner_name` | | `haos-runner` | Display name shown in Gitea's runner list |
|
||||||
|
| `runner_labels` | | `ubuntu-latest:docker://catthehacker/ubuntu:act-22.04` | Comma-separated list of labels this runner accepts |
|
||||||
|
| `log_level` | | `info` | Verbosity: `debug`, `info`, `warn`, or `error` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Runner Labels Format
|
||||||
|
|
||||||
|
Labels tell Gitea which job `runs-on:` values this runner handles, and which Docker image to use for each:
|
||||||
|
|
||||||
|
```
|
||||||
|
<label>:docker://<image>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```
|
||||||
|
ubuntu-latest:docker://catthehacker/ubuntu:act-22.04
|
||||||
|
ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04,ubuntu-20.04:docker://catthehacker/ubuntu:act-20.04
|
||||||
|
```
|
||||||
|
|
||||||
|
The label on the left must match the `runs-on:` string in your workflow YAML. Multiple labels are comma-separated.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why `full_access: true`?
|
||||||
|
|
||||||
|
`full_access: true` in the addon manifest mounts `/var/run/docker.sock` inside the container. This is required so `act_runner` can communicate with the host Docker daemon to **spawn and manage job containers** for each CI run.
|
||||||
|
|
||||||
|
Without this, the runner starts but will fail every job that uses a `container:` or `docker://` image.
|
||||||
|
|
||||||
|
> ⚠️ This grants the addon broad access to the host Docker daemon. Only install this addon if you trust the Gitea instance and the workflow definitions it will run.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Persistent State
|
||||||
|
|
||||||
|
The runner's registration file (`.runner`) and the generated runtime config are stored in `/data/` inside the addon, which is **persisted across restarts and updates**. The runner will **not** re-register on every boot.
|
||||||
|
|
||||||
|
To force re-registration (e.g. if the token is revoked):
|
||||||
|
1. Stop the addon.
|
||||||
|
2. SSH into HAOS and delete `/data/addon_configs/gitea_act_runner/.runner` (exact path may vary).
|
||||||
|
3. Update the `runner_token` option with a new token.
|
||||||
|
4. Start the addon.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Symptom | Likely cause | Fix |
|
||||||
|
|---|---|---|
|
||||||
|
| Runner shows **Offline** in Gitea immediately | `gitea_url` uses `localhost` or `127.0.0.1` | Use the LAN IP of the Gitea machine |
|
||||||
|
| `[ERROR] runner_token is not configured` | Token field is blank | Paste the token from Gitea Runners page |
|
||||||
|
| Jobs fail with *"Cannot connect to the Docker daemon"* | `full_access` not effective | Verify the addon config has `full_access: true` and restart |
|
||||||
|
| Runner registers but jobs stay **Waiting** | Labels mismatch | Ensure workflow `runs-on:` matches a label configured in `runner_labels` |
|
||||||
|
| Want more detail in logs | — | Set `log_level` to `debug` and restart |
|
||||||
10
gitea-act-runner/Dockerfile
Normal file
10
gitea-act-runner/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
ARG BUILD_FROM
|
||||||
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
|
# Install jq to parse /data/options.json provided by the HA supervisor
|
||||||
|
RUN apk add --no-cache jq
|
||||||
|
|
||||||
|
COPY run.sh /run.sh
|
||||||
|
RUN chmod +x /run.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/run.sh"]
|
||||||
35
gitea-act-runner/config.yaml
Normal file
35
gitea-act-runner/config.yaml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: Gitea act_runner
|
||||||
|
version: "1.0.0"
|
||||||
|
slug: gitea_act_runner
|
||||||
|
description: Run Gitea Actions jobs natively on your Home Assistant machine
|
||||||
|
url: "https://github.com/martemme/HomeAssistantAddons/tree/main/gitea-act-runner"
|
||||||
|
|
||||||
|
arch:
|
||||||
|
- amd64
|
||||||
|
- aarch64
|
||||||
|
|
||||||
|
startup: services
|
||||||
|
boot: auto
|
||||||
|
init: false
|
||||||
|
|
||||||
|
# full_access grants access to /var/run/docker.sock so act_runner can
|
||||||
|
# spawn job containers on the host Docker daemon.
|
||||||
|
full_access: true
|
||||||
|
|
||||||
|
build_from:
|
||||||
|
amd64: "gitea/act_runner:latest"
|
||||||
|
aarch64: "gitea/act_runner:latest"
|
||||||
|
|
||||||
|
options:
|
||||||
|
gitea_url: ""
|
||||||
|
runner_token: ""
|
||||||
|
runner_name: "haos-runner"
|
||||||
|
runner_labels: "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04"
|
||||||
|
log_level: "info"
|
||||||
|
|
||||||
|
schema:
|
||||||
|
gitea_url: str
|
||||||
|
runner_token: str
|
||||||
|
runner_name: str
|
||||||
|
runner_labels: str
|
||||||
|
log_level: "match(debug|info|warn|error)"
|
||||||
73
gitea-act-runner/run.sh
Normal file
73
gitea-act-runner/run.sh
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
CONFIG="/data/options.json"
|
||||||
|
ACT_RUNNER="/usr/local/bin/act_runner"
|
||||||
|
RUNNER_FILE="/data/.runner"
|
||||||
|
ACT_RUNNER_CONFIG="/data/act_runner_config.yaml"
|
||||||
|
|
||||||
|
echo "[INFO] Reading configuration from ${CONFIG}..."
|
||||||
|
|
||||||
|
GITEA_URL=$(jq -r '.gitea_url' "$CONFIG")
|
||||||
|
RUNNER_TOKEN=$(jq -r '.runner_token' "$CONFIG")
|
||||||
|
RUNNER_NAME=$(jq -r '.runner_name' "$CONFIG")
|
||||||
|
RUNNER_LABELS=$(jq -r '.runner_labels' "$CONFIG")
|
||||||
|
LOG_LEVEL=$(jq -r '.log_level' "$CONFIG")
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Validate required fields
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
if [[ -z "$GITEA_URL" || "$GITEA_URL" == "null" ]]; then
|
||||||
|
echo "[ERROR] gitea_url is not configured. Set it in the addon options and restart."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$RUNNER_TOKEN" || "$RUNNER_TOKEN" == "null" ]]; then
|
||||||
|
echo "[ERROR] runner_token is not configured. Set it in the addon options and restart."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Registration (only on first boot — .runner persists in /data/)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# act_runner writes .runner into the current working directory, so
|
||||||
|
# we change into /data/ so the file ends up on the persistent volume.
|
||||||
|
cd /data
|
||||||
|
|
||||||
|
if [[ ! -f "$RUNNER_FILE" ]]; then
|
||||||
|
echo "[INFO] Registering runner '${RUNNER_NAME}' with ${GITEA_URL}..."
|
||||||
|
"$ACT_RUNNER" register \
|
||||||
|
--no-interactive \
|
||||||
|
--instance "$GITEA_URL" \
|
||||||
|
--token "$RUNNER_TOKEN" \
|
||||||
|
--name "$RUNNER_NAME" \
|
||||||
|
--labels "$RUNNER_LABELS"
|
||||||
|
echo "[INFO] Registration complete. .runner saved to /data/."
|
||||||
|
else
|
||||||
|
echo "[INFO] Runner already registered, skipping registration."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Generate act_runner runtime config
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
echo "[INFO] Writing act_runner config to ${ACT_RUNNER_CONFIG}..."
|
||||||
|
cat > "$ACT_RUNNER_CONFIG" <<EOF
|
||||||
|
log:
|
||||||
|
level: ${LOG_LEVEL}
|
||||||
|
|
||||||
|
runner:
|
||||||
|
capacity: 2
|
||||||
|
|
||||||
|
container:
|
||||||
|
network: bridge
|
||||||
|
valid_volumes: []
|
||||||
|
|
||||||
|
cache:
|
||||||
|
enabled: false
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Start the daemon
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
echo "[INFO] Starting act_runner daemon..."
|
||||||
|
exec "$ACT_RUNNER" daemon --config "$ACT_RUNNER_CONFIG"
|
||||||
Reference in New Issue
Block a user