agent and source files

This commit is contained in:
Jason Stedwell
2026-06-29 17:33:15 -05:00
parent e5e071e879
commit b10a4591cd
6 changed files with 1320 additions and 0 deletions
+591
View File
@@ -0,0 +1,591 @@
# AGENT.md
## Project
**Name:** custom-gitea-runner
**Purpose:**
Build a self-owned, versioned, Docker-first Gitea Actions runner platform that avoids opaque upstream behavior, is easy to debug, and is safe to operate on Unraid and general Linux hosts. This project should produce a maintainable runner image, startup logic, configuration templates, and documentation that make runner behavior explicit and reproducible.
This project exists because the stock/self-hosted runner path introduced hard-to-diagnose issues around nested containers, action runtime dependencies, container image behavior, and host/runtime compatibility. The replacement should favor observability, deterministic builds, explicit tooling, and low-surprise operations.
---
## Mission
Create a production-ready custom Gitea runner solution that:
- Runs reliably in Docker on Unraid and standard Linux hosts.
- Supports JavaScript-based actions by shipping the required runtime dependencies explicitly.
- Supports Docker build/push workflows without hidden image assumptions.
- Uses pinned versions wherever practical.
- Separates image build concerns from runtime registration/config concerns.
- Makes debugging first-class through logs, health checks, self-tests, and clear failure modes.
- Keeps all project knowledge versioned in-repo through AGENT.md, README.md, ROADMAP.md, CHANGELOG.md, and example configs.
---
## Product goals
1. Build a custom Docker image for a Gitea-compatible runner.
2. Provide an entrypoint/bootstrap script that prepares the runtime deterministically.
3. Support runner registration through environment variables and/or mounted config.
4. Support common CI workloads for the target environment: checkout, Node-based actions, Docker login, Docker build, Docker push, shell scripts, and future extensibility for additional tooling.
5. Provide a clean path for image tagging, publishing, rollback, and host deployment.
6. Minimize dependence on mutable upstream defaults like `latest`, floating action images, or runtime package installs during startup.
7. Make the image and scripts inspectable, testable, and easy to extend.
---
## Non-goals
- Do not build a full replacement for the Gitea server.
- Do not invent a proprietary CI protocol if standard Gitea runner registration is sufficient.
- Do not optimize first for Kubernetes.
- Do not assume multi-tenant hostile workloads at v1; this is a controlled self-hosted environment.
- Do not rely on runtime `apk add` or ad hoc container mutation as a permanent solution.
---
## Development philosophy
Treat this like an internal platform product, not a one-off container hack.
Principles:
- **Version everything.** Image versions, dependency versions, docs, sample configs, and release notes should all be explicit.
- **Document while building.** If behavior changes, update README.md and ROADMAP.md in the same workstream.
- **Prefer deterministic builds.** Install dependencies at image build time, not container startup.
- **Prefer explicit over magical.** If Node, Git, Docker CLI, certificates, or helper binaries are required, declare and verify them.
- **Design for diagnosis.** Every major startup step should emit useful logs.
- **Keep the bootstrap thin.** Complex logic should live in versioned scripts/modules, not giant one-line container commands.
- **Bias for maintainability.** Small, composable scripts beat clever entrypoints.
---
## User and environment assumptions
Primary operator profile:
- Advanced technical operator.
- Comfortable with Docker, Unraid, Node.js/TypeScript, Bash, and self-hosted infrastructure.
- Prefers documented roadmaps, structured project files, and reusable internal tooling.
Primary target environment:
- Unraid Docker host first.
- Standard Linux Docker host second.
- Gitea instance is self-hosted.
- Registry may be self-hosted Gitea Container Registry.
- Project repositories are hosted in Gitea.
---
## Required deliverables
The agent should scaffold and maintain at minimum:
```text
custom-gitea-runner/
├── AGENT.md
├── README.md
├── ROADMAP.md
├── CHANGELOG.md
├── LICENSE
├── .gitignore
├── .env.example
├── docker/
│ ├── runner/
│ │ ├── Dockerfile
│ │ ├── docker-entrypoint.sh
│ │ ├── healthcheck.sh
│ │ └── smoke-test.sh
│ └── compose/
│ ├── docker-compose.example.yml
│ └── unraid-template-notes.md
├── config/
│ ├── runner.example.yaml
│ ├── labels.example.env
│ └── trusted-ca/
├── scripts/
│ ├── register-runner.sh
│ ├── deregister-runner.sh
│ ├── verify-runtime.sh
│ ├── build-image.sh
│ ├── publish-image.sh
│ └── test-local-runner.sh
├── docs/
│ ├── architecture.md
│ ├── operations.md
│ ├── troubleshooting.md
│ ├── unraid.md
│ └── decisions/
│ └── 0001-base-image.md
├── test/
│ ├── fixtures/
│ ├── sample-workflows/
│ └── smoke/
└── src/
└── optional/
```
Notes:
- `src/` is optional unless the project grows into a TypeScript control plane or helper CLI.
- If a CLI/helper app is introduced, prefer TypeScript for maintainability and consistency with the project stack.
---
## Recommended architecture
### Baseline architecture
Start with a Docker image that wraps or embeds the official `act_runner` binary but controls:
- base image selection,
- runtime package set,
- startup/registration flow,
- mounted config handling,
- Docker socket strategy,
- health checks,
- and diagnostics.
### Preferred v1 design
- Debian or Ubuntu slim base image, not an ultra-minimal image that requires runtime mutation.
- Install at build time:
- ca-certificates
- bash
- curl
- git
- jq
- nodejs
- npm
- docker CLI
- tini
- timezone data
- Copy in a pinned `act_runner` binary or install from a pinned release artifact.
- Use `tini` as PID 1.
- Use a real multi-line `docker-entrypoint.sh`.
- Validate runtime prerequisites before daemon start.
- Prefer mounted `/var/run/docker.sock` for v1 if the host is trusted and this matches the deployment model.
- Expose health check status through a lightweight script.
### Why this design
This directly addresses the observed failure class:
- runtime packages missing in the runner image,
- overreliance on upstream defaults,
- brittle nested-container behavior,
- and low observability when setup fails.
---
## Runner behavior requirements
The custom runner must:
1. Start deterministically with a documented set of environment variables.
2. Fail fast when required inputs are missing.
3. Verify and log the presence of key tools:
- `git`
- `node`
- `npm`
- `docker`
- `act_runner`
4. Emit version information at startup.
5. Support both pre-registered config files and first-boot registration flows.
6. Avoid mutating the filesystem in surprising ways at runtime beyond known writable paths.
7. Support Docker-based build/push jobs cleanly.
8. Provide optional label mapping guidance for common targets like `ubuntu-latest`.
9. Make workspace and temp directories explicit and configurable.
10. Provide a smoke-test path that validates the runner image before production use.
---
## Configuration model
Support two modes.
### Mode A: Pre-generated config
Operator mounts:
- runner config yaml
- optional registration metadata
- optional CA bundle
This is the preferred stable production mode.
### Mode B: Bootstrap registration
Operator provides env vars such as:
- `GITEA_INSTANCE_URL`
- `GITEA_RUNNER_TOKEN`
- `GITEA_RUNNER_NAME`
- `GITEA_RUNNER_LABELS`
- `GITEA_RUNNER_WORKDIR`
- `GITEA_RUNNER_CONFIG_PATH`
Entrypoint performs:
1. validation,
2. one-time registration if config absent,
3. daemon startup.
The agent should design this so reboots are idempotent.
---
## Docker and security model
### v1 security posture
This runner is intended for a trusted, self-hosted environment. Simplicity and reliability are more important than extreme sandbox isolation in v1.
### v1 approach
- Support Docker socket mount for build/push workloads.
- Document the trust implications clearly.
- Keep the runner container itself as minimal and explicit as possible.
- Avoid privileged mode unless a specific feature requires it.
- Prefer read-only mounts where practical except for config/work directories.
- Run as non-root where feasible, but do not force complexity if Docker socket access or upstream tooling makes that unrealistic in v1.
### Future hardening track
Document as roadmap items:
- rootless variants,
- DinD variant,
- dedicated buildkit integration,
- ephemeral one-job runners,
- restricted labels by repo or org,
- network isolation strategies.
---
## Documentation requirements
The agent must keep these files current as the project evolves.
### README.md
Should include:
- project purpose,
- why this exists,
- supported features,
- architecture overview,
- quick start,
- environment variables,
- Docker compose example,
- Unraid deployment notes,
- sample workflow guidance,
- troubleshooting links,
- versioning and release model.
### ROADMAP.md
Must track phases, status, and next actions.
Recommended sections:
- Phase 0: Research and design
- Phase 1: Base image and bootstrap
- Phase 2: Registration/config flows
- Phase 3: Docker workflow support
- Phase 4: Test harness and smoke validation
- Phase 5: Unraid packaging and docs
- Phase 6: Hardening and enhancements
### CHANGELOG.md
Use Keep a Changelog style:
- Added
- Changed
- Fixed
- Removed
### docs/troubleshooting.md
Must be practical and symptom-driven.
Include sections for issues like:
- runner not registering,
- `node` not found,
- Docker socket permission errors,
- workflow checkout failures,
- registry login failures,
- container job image issues,
- CA/certificate trust issues,
- Unraid-specific gotchas.
---
## Functional scope for v1
### Must support
- `actions/checkout`
- `docker/login-action`
- `docker build`
- `docker push`
- shell-based build scripts
- Gitea registry auth patterns
- branch/tag based image builds
### Nice to support in v1 if straightforward
- `buildx`
- cache mounts
- custom CA installation
- repo/org label strategies
- self-test action workflow
### Defer unless easy
- autoscaling
- UI dashboard
- metrics exporter
- multi-runner orchestrator
- web control plane
---
## Testing strategy
The project should include real validation, not just build success.
### Required tests
1. **Image build test**
- Docker image builds successfully from scratch.
2. **Runtime verification test**
- Container starts and confirms key binaries exist.
3. **Registration smoke test**
- Runner can register against a test Gitea instance or mocked flow.
4. **Workflow smoke tests**
- checkout-only workflow,
- Node-based action workflow,
- Docker login workflow,
- Docker build/push workflow against a test registry.
5. **Regression tests**
- specifically capture previously observed failure classes around missing Node and fragile container behavior.
### Testing philosophy
Every bug that costs real debugging time should become:
- a documented issue,
- a troubleshooting entry,
- and ideally a regression test.
---
## Logging and observability
Startup logs should clearly print:
- image version,
- git commit if embedded,
- act_runner version,
- node version,
- docker version,
- registration mode,
- config path,
- work directory,
- labels,
- target Gitea URL.
Do not log secrets.
Health check should verify at minimum:
- runner process exists,
- config is present,
- Docker socket availability if required,
- core binaries exist.
Optional future enhancements:
- structured JSON logs,
- `/healthz` sidecar or helper,
- metrics export.
---
## Versioning and release policy
Use semantic-ish tags for the custom image.
Recommended tagging:
- `v0.1.0`
- `v0.1.1`
- `v0.2.0`
- `latest` only as a convenience alias to the newest stable release
Rules:
- Never deploy unpinned `latest` in production docs as the primary recommendation.
- Every release should map to a Git tag and CHANGELOG entry.
- Embed image metadata labels such as version, vcs ref, build date, and source URL.
---
## Agent operating instructions
When working on this project, the agent must:
1. Update `ROADMAP.md` when a phase changes or a major task is added/closed.
2. Update `README.md` when usage, env vars, image behavior, or deployment steps change.
3. Update `CHANGELOG.md` for user-visible changes.
4. Prefer small, reviewable commits/changesets.
5. Ask for clarification before making irreversible architecture choices when multiple valid paths exist.
6. Keep scripts POSIX/Bash-friendly and easy to audit.
7. Avoid hidden runtime package installation unless explicitly implementing a temporary debug path.
8. Prefer pinned versions in Dockerfile and examples.
9. Add troubleshooting notes whenever a new failure mode is discovered.
10. Preserve portability between Unraid and standard Linux where reasonable.
---
## Implementation preferences
Preferred languages and tooling:
- Bash for bootstrap and operational scripts.
- Dockerfile for image definition.
- TypeScript only if a helper CLI/control plane becomes necessary.
- Markdown for all project documentation.
- Git-based versioning hosted in Gitea.
Preferred project style:
- Modular files.
- Clean naming.
- Self-explanatory scripts.
- No giant inline command strings in container templates.
- Examples should be copy-paste friendly.
---
## Suggested first milestones
### Milestone 1: Foundation
- Initialize repository structure.
- Write README.md skeleton.
- Write ROADMAP.md.
- Write Dockerfile using pinned base image.
- Write entrypoint with startup validation.
- Add healthcheck script.
### Milestone 2: Registration and config
- Add env-driven bootstrap registration flow.
- Add mounted-config mode.
- Add `.env.example`.
- Add example runner config.
### Milestone 3: CI workload support
- Ensure Node, Git, Docker CLI, CA certs all present.
- Validate `actions/checkout` and `docker/login-action` support.
- Build sample workflow fixtures.
### Milestone 4: Unraid packaging
- Create compose example.
- Document Unraid template fields and recommended mounts.
- Add upgrade and rollback instructions.
### Milestone 5: Quality and regression safety
- Add smoke-test script.
- Add local test harness.
- Add troubleshooting guide.
- Capture prior bug classes as regression cases.
---
## Decision log expectations
Create ADR-style notes under `docs/decisions/` for major decisions such as:
- base image choice,
- root vs non-root default,
- socket mount vs DinD,
- bootstrap registration design,
- bundled tools list,
- release strategy.
Each decision note should include:
- context,
- decision,
- consequences,
- alternatives considered.
---
## Success criteria
This project is successful when:
- a fresh operator can build and run the image with documented steps,
- the runner reliably executes checkout + Docker login + build + push workflows,
- Node-based actions work without runtime hacks,
- failures are diagnosable from logs and docs,
- upgrades are explicit and reversible,
- and the entire runner behavior is version-controlled and understandable.
---
## Open questions for early clarification
Before heavy implementation, clarify:
1. Should v1 wrap the official `act_runner` binary or fork/build from source?
2. Is the preferred base image Debian slim or Ubuntu minimal?
3. Should v1 default to socket mount only, or support both socket mount and DinD variants from day one?
4. Should the repository include an Unraid XML/template artifact, or just docs plus compose examples?
5. Should the first release include a small helper CLI for registration/testing, or keep everything shell-only?
6. Should runner labels be opinionated by default, or minimal and operator-supplied?
7. Should custom CA trust be a first-class feature in v1?
If these are unanswered, the agent should pause and ask before overcommitting to a direction.
---
## Build order
When starting implementation, follow this order:
1. AGENT.md
2. README.md
3. ROADMAP.md
4. Dockerfile
5. entrypoint/bootstrap scripts
6. healthcheck/smoke tests
7. config examples
8. compose/unraid examples
9. troubleshooting docs
10. regression fixtures/tests
---
## Final instruction
Optimize for reliability, debuggability, and maintainability over cleverness.
This project should feel like a stable internal platform component that the operator can trust, inspect, extend, and version for years.
+421
View File
@@ -0,0 +1,421 @@
<div align="center">
# custom-gitea-runner
A versioned, Docker-first, self-owned Gitea Actions runner platform for Unraid and Linux hosts.
[Overview](#overview) • [Goals](#goals) • [Architecture](#architecture) • [Repository-layout](#repository-layout) • [Quick-start](#quick-start) • [Environment](#environment) • [Roadmap](#roadmap) • [Operations](#operations)
</div>
---
## Overview
`custom-gitea-runner` is a controlled replacement for opaque runner setups that are difficult to debug, mutate at startup, or break unexpectedly when upstream images or runtime assumptions change.
The project packages a Gitea-compatible runner into a predictable Docker image with pinned dependencies, explicit startup logic, clean documentation, and testable operational workflows. The goal is to make the runner understandable, inspectable, and easy to version over time.
This repository is designed for self-hosted environments where the operator wants direct control over:
- base image selection,
- bundled tooling,
- startup and registration flow,
- Docker socket/build behavior,
- release/version policy,
- troubleshooting and rollback.
---
## Why this exists
This project exists to eliminate common self-hosted runner pain points such as:
- missing runtime dependencies like Node.js, Git, or Docker CLI,
- fragile startup behavior that depends on mutable package installs,
- difficult-to-diagnose nested container failures,
- unclear registration/config persistence,
- and weak operational visibility when jobs fail early.
Instead of treating the runner like a disposable black box, this repository treats it like an internal platform component.
---
## Goals
### Primary goals
- Build a custom Docker image for a Gitea-compatible runner.
- Bundle required CI dependencies at image build time.
- Support checkout, Node-based actions, Docker login, Docker build, and Docker push workflows.
- Provide deterministic bootstrap and registration behavior.
- Provide clean deployment guidance for Unraid and standard Linux Docker hosts.
- Keep all operational knowledge versioned in-repo.
### Secondary goals
- Support custom CA trust.
- Support opinionated label templates.
- Support smoke testing and regression fixtures.
- Support future hardening tracks like rootless or DinD variants.
### Non-goals
- Replacing Gitea itself.
- Building a full control plane or autoscaling runner manager in v1.
- Solving every orchestration model on day one.
---
## Architecture
### Design principles
- Deterministic image builds.
- No hidden runtime package installs in normal operation.
- Explicit entrypoint and healthcheck behavior.
- Pinned versions where practical.
- Clear separation of image build, registration, runtime config, and operations.
- Logs that are useful during failure, not just success.
### Planned v1 stack
- Debian slim or Ubuntu slim base image.
- Pinned `act_runner` binary or pinned upstream release artifact.
- Bundled tooling:
- `bash`
- `curl`
- `git`
- `jq`
- `node`
- `npm`
- `docker`
- `ca-certificates`
- `tini`
- Entrypoint script for validation, registration, and daemon startup.
- Healthcheck script for runtime verification.
- Example config and compose files.
### Runtime model
The runner container is intended to be long-lived and operator-managed.
Preferred v1 modes:
1. Pre-generated config mounted into the container.
2. Environment-driven one-time bootstrap registration when config is absent.
For Docker build/push workflows, v1 assumes a trusted host and supports a mounted Docker socket. Future variants can harden or isolate this behavior.
---
## Repository layout
```text
custom-gitea-runner/
├── AGENT.md
├── README.md
├── ROADMAP.md
├── CHANGELOG.md
├── LICENSE
├── .gitignore
├── .env.example
├── docker/
│ ├── runner/
│ │ ├── Dockerfile
│ │ ├── docker-entrypoint.sh
│ │ ├── healthcheck.sh
│ │ └── smoke-test.sh
│ └── compose/
│ ├── docker-compose.example.yml
│ └── unraid-template-notes.md
├── config/
│ ├── runner.example.yaml
│ ├── labels.example.env
│ └── trusted-ca/
├── scripts/
│ ├── register-runner.sh
│ ├── deregister-runner.sh
│ ├── verify-runtime.sh
│ ├── build-image.sh
│ ├── publish-image.sh
│ └── test-local-runner.sh
├── docs/
│ ├── architecture.md
│ ├── operations.md
│ ├── troubleshooting.md
│ ├── unraid.md
│ └── decisions/
│ └── 0001-base-image.md
├── test/
│ ├── fixtures/
│ ├── sample-workflows/
│ └── smoke/
└── src/
└── optional/
```
---
## Quick start
### 1. Create the repository
Create a new Gitea repository named `custom-gitea-runner` and commit the initial documentation set:
- `AGENT.md`
- `README.md`
- `ROADMAP.md`
- `CHANGELOG.md`
- `.gitignore`
- `.env.example`
### 2. Build the first image
Once the Dockerfile exists:
```bash
docker build -t custom-gitea-runner:v0.1.0 -f docker/runner/Dockerfile .
```
### 3. Provide runtime configuration
Create a `.env` file from `.env.example` and decide whether to:
- mount a pre-generated runner config, or
- let the container self-register on first boot.
### 4. Start the runner
Use Docker Compose or the equivalent Unraid template settings to start the container with:
- persistent config mount,
- persistent work directory,
- Docker socket mount if build/push is required,
- required env vars.
### 5. Run smoke workflows
Before production use, validate at minimum:
- checkout-only workflow,
- Node-based action workflow,
- Docker login workflow,
- Docker build/push workflow.
---
## Environment
Planned environment variables for bootstrap mode:
| Variable | Required | Purpose |
|---|---:|---|
| `GITEA_INSTANCE_URL` | Yes | Base URL of the Gitea instance. |
| `GITEA_RUNNER_TOKEN` | Yes | Registration token for the runner. |
| `GITEA_RUNNER_NAME` | Yes | Human-readable runner name. |
| `GITEA_RUNNER_LABELS` | No | Comma-separated label list. |
| `GITEA_RUNNER_WORKDIR` | No | Working directory inside the container. |
| `GITEA_RUNNER_CONFIG_PATH` | No | Path to the runner config file. |
| `TZ` | No | Time zone for logs and runtime behavior. |
Future environment variables may include:
- custom CA paths,
- logging mode,
- healthcheck tuning,
- Docker socket override,
- feature flags for experimental runner behavior.
---
## Example deployment model
### Docker Compose direction
The project will include a compose example that follows this pattern:
- pinned image tag,
- mounted runner config,
- mounted work directory,
- mounted Docker socket,
- explicit restart policy,
- explicit environment variables.
Example shape:
```yaml
services:
gitea-runner:
image: custom-gitea-runner:v0.1.0
container_name: custom-gitea-runner
restart: unless-stopped
environment:
GITEA_INSTANCE_URL: https://git.example.com
GITEA_RUNNER_NAME: unraid-runner-01
GITEA_RUNNER_TOKEN: ${GITEA_RUNNER_TOKEN}
GITEA_RUNNER_LABELS: ubuntu-latest,docker
TZ: America/Chicago
volumes:
- ./config:/config
- ./work:/work
- /var/run/docker.sock:/var/run/docker.sock
```
### Unraid direction
The Unraid notes should document:
- repository/image field,
- appdata path recommendations,
- variable definitions,
- volume mounts,
- Docker socket usage,
- update workflow,
- rollback workflow.
---
## Operations
### Expected startup behavior
At startup, the container should log:
- image version,
- embedded git revision if available,
- `act_runner` version,
- `node` version,
- `docker` version,
- config path,
- work path,
- registration mode,
- target Gitea URL,
- active labels.
### Health behavior
The healthcheck should confirm:
- runner process is alive,
- config exists,
- required tools exist,
- Docker socket is available when configured.
### Upgrade workflow
Recommended upgrade process:
1. Pull or build a new pinned image tag.
2. Review `CHANGELOG.md`.
3. Stop the existing container.
4. Update image tag in compose or Unraid template.
5. Start the container.
6. Verify logs and healthcheck.
7. Run smoke workflow.
### Rollback workflow
1. Stop the container.
2. Revert to prior known-good image tag.
3. Start the container.
4. Verify registration/config still valid.
5. Confirm smoke workflow success.
---
## Documentation set
This repository should maintain the following docs as first-class assets:
- `AGENT.md` — build rules, architecture constraints, agent instructions.
- `README.md` — project overview, install/use guidance, operational entry point.
- `ROADMAP.md` — phased plan with active status tracking.
- `CHANGELOG.md` — release history.
- `docs/architecture.md` — deeper design details.
- `docs/operations.md` — runtime/admin guidance.
- `docs/troubleshooting.md` — symptom-driven fixes.
- `docs/unraid.md` — Unraid-specific deployment instructions.
- `docs/decisions/*.md` — ADR-style architecture decisions.
---
## Testing strategy
Required validation layers:
- image build verification,
- runtime tool verification,
- registration smoke tests,
- workflow smoke tests,
- regression tests for previously encountered failure classes.
The first workflows to validate should be:
1. `actions/checkout`
2. Node-based action execution
3. `docker/login-action`
4. `docker build`
5. `docker push`
---
## Roadmap
Project planning lives in [`ROADMAP.md`](./ROADMAP.md).
High-level phases:
- Phase 0: Research and design
- Phase 1: Base image and bootstrap
- Phase 2: Registration/config flows
- Phase 3: Docker workflow support
- Phase 4: Test harness and smoke validation
- Phase 5: Unraid packaging and docs
- Phase 6: Hardening and enhancements
---
## Release model
Recommended versioning:
- `v0.1.0`
- `v0.1.1`
- `v0.2.0`
`latest` may exist as a convenience tag, but documentation should always recommend pinned versions for real deployments.
Every release should map to:
- a Git tag,
- a CHANGELOG entry,
- image metadata labels,
- and documented upgrade notes where relevant.
---
## Contributing workflow
Recommended development loop:
1. Update docs first when requirements or behavior change.
2. Make small, reviewable changes.
3. Keep scripts simple and auditable.
4. Add regression coverage for painful bugs.
5. Prefer explicit configuration over implicit behavior.
---
## Current status
This repository is in planning/bootstrap stage.
The immediate next steps are:
- finalize the architecture direction,
- scaffold the repository,
- build the first pinned image,
- implement registration/bootstrap scripts,
- validate smoke workflows,
- document Unraid deployment.
+308
View File
@@ -0,0 +1,308 @@
# ROADMAP.md
## Project
**Name:** custom-gitea-runner
**Status:** Planning / bootstrap
**Objective:**
Deliver a self-owned, versioned, Docker-first Gitea runner platform that is reliable on Unraid and Linux, easy to debug, and explicitly documented from image build through runtime operations.
---
## Guiding outcomes
The project is considered successful when it can:
- run as a pinned Docker image,
- execute checkout + Node-based + Docker build/push workflows reliably,
- register and restart predictably,
- surface actionable logs during failure,
- and be upgraded or rolled back cleanly.
---
## Project phases
## Phase 0 — Research and design
**Status:** Active
### Goals
- Define architecture, scope, and first-release constraints.
- Capture prior failure modes as design inputs.
- Establish documentation and decision-tracking structure.
### Tasks
- [x] Write `AGENT.md`
- [x] Write `README.md`
- [x] Write `ROADMAP.md`
- [ ] Create `CHANGELOG.md`
- [ ] Create `.env.example`
- [ ] Create ADR template under `docs/decisions/`
- [ ] Write `docs/architecture.md`
- [ ] Decide base image strategy
- [ ] Decide socket-mount vs DinD position for v1
- [ ] Decide registration mode defaults
### Exit criteria
- Scope is documented.
- Core repo structure is defined.
- Major open decisions are listed.
- First implementation sequence is agreed.
---
## Phase 1 — Base image and bootstrap
**Status:** Planned
### Goals
- Produce the first buildable runner image.
- Eliminate runtime package mutation.
- Establish deterministic startup behavior.
### Tasks
- [ ] Create `docker/runner/Dockerfile`
- [ ] Pin base image tag
- [ ] Pin `act_runner` source/version
- [ ] Install required dependencies at build time:
- [ ] bash
- [ ] curl
- [ ] git
- [ ] jq
- [ ] nodejs
- [ ] npm
- [ ] docker CLI
- [ ] ca-certificates
- [ ] tini
- [ ] tzdata
- [ ] Create `docker/runner/docker-entrypoint.sh`
- [ ] Create `docker/runner/healthcheck.sh`
- [ ] Add image metadata labels
- [ ] Verify startup prints tool versions
### Exit criteria
- Image builds locally.
- Container starts cleanly.
- `node`, `git`, `docker`, and `act_runner` are all present.
- Healthcheck script returns useful status.
---
## Phase 2 — Registration and config flows
**Status:** Planned
### Goals
- Support both mounted-config and env-driven registration.
- Make bootstrap idempotent.
- Ensure config persistence survives restarts.
### Tasks
- [ ] Create `config/runner.example.yaml`
- [ ] Create `config/labels.example.env`
- [ ] Create `scripts/register-runner.sh`
- [ ] Create `scripts/deregister-runner.sh`
- [ ] Add config path validation
- [ ] Add first-boot registration flow
- [ ] Add re-run safe bootstrap logic
- [ ] Document required environment variables
- [ ] Validate restart behavior with existing config
### Exit criteria
- Runner can register successfully.
- Existing config is reused without duplicate registration.
- Missing configuration fails fast with clear logs.
---
## Phase 3 — Docker workflow support
**Status:** Planned
### Goals
- Prove the runner can handle real Docker-centric CI workloads.
- Ensure JavaScript-based actions work out of the box.
### Tasks
- [ ] Validate `actions/checkout`
- [ ] Validate Node-based action runtime
- [ ] Validate `docker/login-action`
- [ ] Validate `docker build`
- [ ] Validate `docker push`
- [ ] Add support notes for self-hosted Gitea Container Registry
- [ ] Validate mounted Docker socket usage
- [ ] Document permission expectations for `/var/run/docker.sock`
- [ ] Evaluate `buildx` as optional enhancement
### Exit criteria
- Standard Docker build/push workflows pass.
- No runtime install hacks are needed.
- Node-based actions work on first boot.
---
## Phase 4 — Test harness and smoke validation
**Status:** Planned
### Goals
- Convert operational pain into repeatable tests.
- Establish confidence before release.
### Tasks
- [ ] Create `docker/runner/smoke-test.sh`
- [ ] Create `scripts/verify-runtime.sh`
- [ ] Create `scripts/test-local-runner.sh`
- [ ] Add `test/sample-workflows/checkout.yml`
- [ ] Add `test/sample-workflows/node-action.yml`
- [ ] Add `test/sample-workflows/docker-login.yml`
- [ ] Add `test/sample-workflows/docker-build-push.yml`
- [ ] Add regression test cases for:
- [ ] missing `node`
- [ ] broken Docker socket access
- [ ] invalid registration config
- [ ] startup tool validation failures
- [ ] Document how to run smoke tests locally
### Exit criteria
- Smoke tests are runnable by an operator.
- Known painful regressions are covered.
- Runtime validation is part of the normal release flow.
---
## Phase 5 — Unraid packaging and docs
**Status:** Planned
### Goals
- Make deployment smooth in the real target environment.
- Provide operational documentation that matches actual host usage.
### Tasks
- [ ] Create `docker/compose/docker-compose.example.yml`
- [ ] Create `docker/compose/unraid-template-notes.md`
- [ ] Write `docs/unraid.md`
- [ ] Write `docs/operations.md`
- [ ] Write `docs/troubleshooting.md`
- [ ] Document update procedure
- [ ] Document rollback procedure
- [ ] Document appdata path recommendations
- [ ] Document Docker socket trust model
- [ ] Optionally create Unraid XML/template artifact
### Exit criteria
- Operator can deploy from docs alone.
- Unraid-specific steps are explicit.
- Upgrade and rollback are documented and tested.
---
## Phase 6 — Hardening and enhancements
**Status:** Backlog
### Goals
- Expand safety and flexibility after the baseline runner is stable.
### Candidate enhancements
- [ ] Rootless variant
- [ ] DinD variant
- [ ] Dedicated BuildKit support
- [ ] Ephemeral single-job runner mode
- [ ] Structured JSON logging
- [ ] Metrics/exporter support
- [ ] Label policy controls
- [ ] Custom CA bootstrap helpers
- [ ] Small helper CLI in TypeScript
- [ ] Multi-runner orchestration concepts
### Exit criteria
- Enhancements are prioritized based on real operational need.
- Stability is not regressed by added flexibility.
---
## Immediate next actions
### Next 10 actions
1. Create `CHANGELOG.md`
2. Create `.env.example`
3. Scaffold repo directories
4. Write `docs/architecture.md`
5. Write first ADR: base image choice
6. Create initial `Dockerfile`
7. Create `docker-entrypoint.sh`
8. Create `healthcheck.sh`
9. Build first local image
10. Verify runtime toolchain inside container
---
## Risks and watch items
### Technical risks
- Upstream `act_runner` behavior may still impose constraints even with a custom wrapper image.
- Docker socket usage is convenient but increases host trust exposure.
- Self-registration flows can become brittle if not made idempotent.
- Docker build/push success does not guarantee all third-party actions behave as expected.
### Process risks
- Letting docs lag implementation will erode the value of the project quickly.
- Overengineering v1 will delay a usable baseline.
- Supporting too many runtime modes too early may reduce stability.
---
## Decision log to create
Create ADRs for:
- [ ] Base image selection
- [ ] Runner binary acquisition strategy
- [ ] Runtime user model
- [ ] Docker socket vs DinD
- [ ] Registration strategy
- [ ] Release and tagging policy
---
## Definition of done for v0.1.0
`v0.1.0` should mean:
- image builds reproducibly,
- runner registers successfully,
- startup validation is clear,
- `actions/checkout` works,
- Node-based actions work,
- Docker login/build/push works,
- docs cover install, operation, upgrade, rollback, and troubleshooting,
- and the release is tagged and documented in `CHANGELOG.md`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB