Files

5.6 KiB
Raw Permalink Blame History

title, authors, year, venue, doi, ara_version, domain, keywords, claims_summary, abstract
title authors year venue doi ara_version domain keywords claims_summary abstract
SS14 CI/CD Pipeline: Gitea Actions Build System for wylab-station-14 on Unraid
Makar Novozhilov (wylab)
2025 Internal Engineering Notes Not applicable — internal project 1.0 CI/CD Infrastructure / Self-Hosted DevOps
gitea-actions
ci-cd
space-station-14
docker
unraid
act-runner
dotnet
cache-corruption
arm64
x86-64
Mixed-architecture runners cause silent cache corruption: arm64 and x86-64 runners share incompatible .NET build cache entries, producing wrong artifacts without build errors.
Local file cache outperforms native Gitea remote cache: Gitea's built-in cache server times out under load (ETIMEDOUT on port 39913), while local file cache on the runner host is reliable.
Gitea runner DNS resolution fails in container-network mode: runner job containers cannot resolve internal hostnames (git.wylab.me) without host networking or external DNS, causing pipeline non-triggers.
OOM kills dominate under parallel dotnet builds: concurrent job capacity must be capped at 2 for dotnet workloads on a 32GB Unraid host to avoid out-of-memory crashes.
Pinning builds to a single runner architecture eliminates cross-arch cache corruption entirely.
wylab-station-14 is a fork of space-wizards/space-station-14 (Space Station 14 game server) run as a Docker container on an Unraid homelab server (UM790 Pro, 32GB RAM). The CI/CD pipeline is implemented via Gitea Actions on a self-hosted Gitea instance (git.wylab.me) using act-runner. This ARA documents the engineering decisions, failure modes, and dead ends encountered while building and stabilizing this pipeline across three runner configurations: an Unraid-hosted container runner, an external VPS runner (45.137.68.83), and a macOS ARM64 runner via OrbStack. The most critical finding is silent cache corruption from mixed-architecture runners — arm64 macOS and x86-64 Unraid runners sharing cache entries leads to architecturally incompatible build artifacts without any explicit build failure. The solution is architecture-tagged cache keys or strict runner pinning. Secondary findings cover DNS resolution strategies, OOM capacity limits for dotnet workloads, and remote vs. local cache reliability.

SS14 CI/CD Pipeline: Gitea Actions on Unraid

Overview

wylab-station-14 is a self-hosted Space Station 14 (SS14) game server running as a Docker container on an Unraid homelab (UM790 Pro, 32GB RAM, 20+ Docker containers). The build pipeline uses Gitea Actions (git.wylab.me) with act-runner to build the server Docker image on every commit to the wylab/wylab-station-14 repository (fork of space-wizards/space-station-14).

The project encountered a series of progressively subtler failures across three distinct runner configurations. The most dangerous dead end is cache architecture mismatch: when both an arm64 macOS runner (OrbStack) and an x86-64 Unraid runner share a cache backend, .NET build artifacts are written and read across architectures. The build does not fail explicitly — it produces wrong binaries silently. The fix is architecture-tagged cache keys (e.g., cache-key: dotnet-{{ arch }}-{{ hashFiles('**/*.csproj') }}) or strict runner label pinning so only one architecture ever executes a given workflow.

Layer Index

Cognitive Layer (/logic)

File Description
problem.md Observations → gaps → key insight (DNS, OOM, cache)
claims.md 5 falsifiable claims (C01C05)
concepts.md 7 key concepts: act-runner, cache key, runner label pinning, etc.
experiments.md 4 declarative verification plans (E01E04)
solution/architecture.md Pipeline component graph
solution/algorithm.md Build workflow logic + pseudocode
solution/constraints.md Boundary conditions and limitations
solution/heuristics.md 5 operational heuristics (H01H05)
related_work.md Related tools and systems (Gitea, act-runner, OrbStack)

Physical Layer (/src)

File Description Claims
configs/training.md Runner config parameters (capacity, timeout, cache) C01, C04
configs/model.md Workflow YAML configuration patterns C01, C02, C03
execution/cache_key_strategy.py Architecture-tagged cache key generation stub C01
environment.md Build stack: .NET, Node.js, Docker, Gitea runner version All

Exploration Graph (/trace)

File Description
exploration_tree.yaml 11-node research DAG: 3 dead ends, 3 decisions

Evidence (/evidence)

File Description
README.md Full index of 4 tables
tables/table1_runner_configurations.md Runner configs tried, outcome per config
tables/table2_cache_failure_modes.md Cache strategies and their failure modes
tables/table3_capacity_oom_progression.md OOM-driven capacity reduction sequence
tables/table4_dns_approaches.md DNS resolution approaches and outcomes