Monitoring primarily
This commit is contained in:
@@ -0,0 +1,317 @@
|
||||
#+TITLE: Gitea Actions Runner — Workflows & Usage Guide
|
||||
#+DATE: 2026-05-04
|
||||
#+AUTHOR: homey project
|
||||
#+OPTIONS: toc:2 num:t
|
||||
|
||||
* Overview
|
||||
|
||||
This document covers the Gitea Actions runner setup on pi-main, how the runner
|
||||
works, the label system, and example workflows for both host-based ("ubuntu")
|
||||
and Nix-native jobs.
|
||||
|
||||
** Architecture
|
||||
|
||||
The runner is configured in =modules/services/gitea-runner.nix= and uses the
|
||||
NixOS native =services.gitea-actions-runner= module. Jobs run with the *host*
|
||||
executor: each step executes directly on the Pi 4 as the =gitea-runner-pi-main=
|
||||
system user. There is no container isolation per job.
|
||||
|
||||
#+BEGIN_EXAMPLE
|
||||
Gitea (podman container)
|
||||
│ HTTPS → Cloudflare tunnel → Caddy → git.zakobar.com
|
||||
│ (runner connects outbound via HTTPS, same path as a browser)
|
||||
▼
|
||||
gitea-actions-runner (systemd service)
|
||||
│ host executor
|
||||
▼
|
||||
Jobs run as: gitea-runner-pi-main (unprivileged system user)
|
||||
PATH includes: nix, git, bash + system packages
|
||||
#+END_EXAMPLE
|
||||
|
||||
** Runner labels
|
||||
|
||||
Labels are advertised to Gitea and matched against =runs-on:= in workflow
|
||||
files. The default labels configured in this project are:
|
||||
|
||||
| Label | Executor | Notes |
|
||||
|---------------+----------+--------------------------------------------|
|
||||
| =native:host= | host | Canonical label for "run on this machine" |
|
||||
| =ubuntu-latest= | host | Matches common GitHub Actions workflows |
|
||||
| =debian-latest= | host | Alternative for Debian-targeting workflows |
|
||||
| =nix:host= | host | Explicit label for Nix-native jobs |
|
||||
|
||||
All four labels route to the same runner process and the same host environment.
|
||||
The difference is purely semantic — pick the label that makes your workflow's
|
||||
intent clear.
|
||||
|
||||
** Nix daemon trust
|
||||
|
||||
The runner user is added to =nix.settings.trusted-users=, which means it can:
|
||||
- Evaluate flakes (=nix flake check=, =nix build=)
|
||||
- Write derivation outputs to the Nix store
|
||||
- Pass =--extra-experimental-features= flags to the daemon
|
||||
- Use =nix copy= to push/pull store paths to a remote cache
|
||||
|
||||
It cannot modify NixOS system configuration or run privileged operations.
|
||||
|
||||
* Example workflows
|
||||
|
||||
Workflow files live in =.gitea/workflows/= inside each repository (or
|
||||
=.github/workflows/= — Gitea Actions supports both paths).
|
||||
|
||||
** Minimal smoke test (host)
|
||||
|
||||
The simplest possible workflow — runs a shell command on the runner.
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/smoke.yaml
|
||||
on: [push]
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: native:host
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: echo "Runner is alive on $(hostname)"
|
||||
#+END_SRC
|
||||
|
||||
** Standard shell-based CI (ubuntu-latest label)
|
||||
|
||||
Use this for repos that want to stay compatible with GitHub Actions. The
|
||||
workflow looks identical to what you'd push to GitHub; it just runs on your Pi.
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/ci.yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main, master]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# On the host executor, use nix-shell or system packages.
|
||||
# apt/yum are NOT available — this is NixOS, not Ubuntu.
|
||||
# Use nix-shell -p for one-off tools:
|
||||
nix-shell -p nodejs --run "node --version"
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
nix-shell -p nodejs --run "npm test"
|
||||
#+END_SRC
|
||||
|
||||
*Important:* Despite the label =ubuntu-latest=, the host is NixOS. =apt=,
|
||||
=yum=, and FHS paths like =/usr/bin/python3= are not available. Use
|
||||
=nix-shell -p <pkg>= to bring in any tool you need.
|
||||
|
||||
** Nix flake check
|
||||
|
||||
Validate a flake on every push — the most common use case for this runner.
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/flake-check.yaml
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
check:
|
||||
runs-on: nix:host
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Check flake
|
||||
run: nix flake check --no-build
|
||||
|
||||
- name: Build default package
|
||||
run: nix build
|
||||
#+END_SRC
|
||||
|
||||
** Nix build with caching
|
||||
|
||||
Build a derivation and push the result to a binary cache so subsequent builds
|
||||
are fast. Requires a Cachix account or an S3-compatible cache configured in
|
||||
=nix.settings=.
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/build-and-cache.yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: nix:host
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build
|
||||
run: nix build --print-build-logs
|
||||
|
||||
- name: Push to cache
|
||||
# nix copy requires the runner user to be in trusted-users (already set).
|
||||
# Replace the URI with your actual cache.
|
||||
run: |
|
||||
nix copy --to "s3://your-cache-bucket?region=us-east-1" ./result
|
||||
#+END_SRC
|
||||
|
||||
** NixOS configuration check (this repo)
|
||||
|
||||
Check that the homey flake evaluates cleanly on every change. Add this to the
|
||||
homey repo itself.
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/nixos-check.yaml
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
eval:
|
||||
runs-on: nix:host
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Evaluate NixOS configurations
|
||||
run: |
|
||||
nix flake check --no-build
|
||||
# Optionally build a specific host config (slow on Pi):
|
||||
# nix build .#nixosConfigurations.pi-main.config.system.build.toplevel
|
||||
|
||||
- name: Check formatting (optional)
|
||||
run: |
|
||||
nix-shell -p nixpkgs-fmt --run "nixpkgs-fmt --check ."
|
||||
#+END_SRC
|
||||
|
||||
** Multi-step pipeline with artifacts
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
# .gitea/workflows/pipeline.yaml
|
||||
on:
|
||||
push:
|
||||
tags: ['v*']
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: nix:host
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build release
|
||||
run: nix build --out-link result
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: release-binary
|
||||
path: result/bin/
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: native:host
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: release-binary
|
||||
|
||||
- name: Deploy
|
||||
run: ./deploy.sh
|
||||
#+END_SRC
|
||||
|
||||
* Caveats and gotchas
|
||||
|
||||
** No apt/brew/yum
|
||||
|
||||
The host is NixOS. Package managers from other distros do not work. Use
|
||||
=nix-shell -p <pkg> --run "..."= for ad-hoc tools, or add a =shell.nix= /
|
||||
=flake.nix= devShell to your repo and enter it with =nix develop=.
|
||||
|
||||
** No Docker/Podman per job
|
||||
|
||||
The host executor does not launch a fresh container per job. All jobs share the
|
||||
same filesystem (under =/home/gitea-runner-pi-main/=) and the same running
|
||||
system. This means:
|
||||
|
||||
- No isolation between concurrent jobs (though concurrency defaults to 1).
|
||||
- Side effects (files written, packages installed with nix) persist between
|
||||
runs unless you clean up explicitly.
|
||||
- Use =nix build= output symlinks (=./result=) rather than writing to system
|
||||
paths.
|
||||
|
||||
** actions/checkout and git
|
||||
|
||||
The =actions/checkout@v3= action works fine on the host executor. It clones
|
||||
into the runner's working directory. Subsequent steps run in that directory by
|
||||
default.
|
||||
|
||||
If you use =actions/checkout@v4=, note that it requires a newer Node.js. On
|
||||
NixOS you can't rely on a system Node, so either pin to v3 or use:
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
- uses: actions/checkout@v3 # v3 bundles its own Node runtime
|
||||
#+END_SRC
|
||||
|
||||
** Nix experimental features
|
||||
|
||||
Flake commands require =nix-command= and =flakes= experimental features. These
|
||||
are typically enabled system-wide in =nix.settings.experimental-features= in
|
||||
=modules/common.nix=. If a job fails with "experimental feature not enabled",
|
||||
you can pass it inline:
|
||||
|
||||
#+BEGIN_SRC yaml
|
||||
- run: nix --extra-experimental-features "nix-command flakes" flake check
|
||||
#+END_SRC
|
||||
|
||||
Or ensure =common.nix= has:
|
||||
|
||||
#+BEGIN_SRC nix
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
#+END_SRC
|
||||
|
||||
** Token rotation
|
||||
|
||||
The registration token in =gitea/runner_token= is consumed on first
|
||||
registration. The runner then stores its own credentials in
|
||||
=/var/lib/gitea-runner/pi-main/.runner=. If you need to re-register (e.g.
|
||||
after wiping the state directory), generate a new token from Gitea's admin UI
|
||||
and update the sops secret before restarting the service.
|
||||
|
||||
** Pi 4 performance
|
||||
|
||||
The Pi 4 is capable but not fast for heavy builds. Tips:
|
||||
- Enable the Nix binary cache (=nixos-cache.nixos.org= is on by default) so
|
||||
pre-built derivations are fetched instead of compiled.
|
||||
- Set =nix.settings.max-jobs= to =4= to use all cores for parallel builds.
|
||||
- Avoid building large packages (LLVM, Chromium) locally — push to a remote
|
||||
builder or use Cachix.
|
||||
|
||||
* Debugging
|
||||
|
||||
** Check runner status
|
||||
#+BEGIN_SRC sh
|
||||
systemctl status gitea-runner-pi-main
|
||||
journalctl -u gitea-runner-pi-main -f
|
||||
#+END_SRC
|
||||
|
||||
** Runner registration state
|
||||
#+BEGIN_SRC sh
|
||||
cat /var/lib/gitea-runner/pi-main/.runner
|
||||
#+END_SRC
|
||||
|
||||
** Force re-registration
|
||||
#+BEGIN_SRC sh
|
||||
# Stop, wipe state, restart (runner will re-register using the token file)
|
||||
systemctl stop gitea-runner-pi-main
|
||||
rm /var/lib/gitea-runner/pi-main/.runner
|
||||
systemctl start gitea-runner-pi-main
|
||||
#+END_SRC
|
||||
|
||||
** Test a workflow locally
|
||||
|
||||
Use =act= (the local runner) to test workflow files before pushing:
|
||||
#+BEGIN_SRC sh
|
||||
nix-shell -p act --run "act push"
|
||||
#+END_SRC
|
||||
|
||||
Note: =act= spins up Docker containers for each job, so results may differ
|
||||
slightly from the host-executor runner, but it is useful for syntax checking
|
||||
and logic testing.
|
||||
Reference in New Issue
Block a user