12e6135042
CI Smoke / toolchain (push) Successful in 1s
- publish-image.sh: add REGISTRY_NAMESPACE for Gitea Container Registry path - sample workflows: run docker login/build/push on host label (bundled docker CLI + mounted socket); fix doubled image path in build/push sample - docs: record v0.1.0 publish and remaining secret-gated push validation Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
325 lines
8.9 KiB
Markdown
325 lines
8.9 KiB
Markdown
# 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:** Complete
|
|
|
|
### 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`
|
|
- [x] Create `CHANGELOG.md`
|
|
- [x] Create `.env.example`
|
|
- [x] Create ADR template under `docs/decisions/`
|
|
- [x] Write `docs/architecture.md`
|
|
- [x] Decide base image strategy
|
|
- [x] Decide socket-mount vs DinD position for v1
|
|
- [x] 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:** Complete
|
|
|
|
### Goals
|
|
|
|
- Produce the first buildable runner image.
|
|
- Eliminate runtime package mutation.
|
|
- Establish deterministic startup behavior.
|
|
|
|
### Tasks
|
|
|
|
- [x] Create `docker/runner/Dockerfile`
|
|
- [x] Pin base image tag
|
|
- [x] Pin `act_runner` source/version
|
|
- [x] Install required dependencies at build time:
|
|
- [x] bash
|
|
- [x] curl
|
|
- [x] git
|
|
- [x] jq
|
|
- [x] nodejs
|
|
- [x] npm
|
|
- [x] docker CLI
|
|
- [x] ca-certificates
|
|
- [x] tini
|
|
- [x] tzdata
|
|
- [x] Create `docker/runner/docker-entrypoint.sh`
|
|
- [x] Create `docker/runner/healthcheck.sh`
|
|
- [x] Add image metadata labels
|
|
- [x] Verify startup prints tool versions
|
|
|
|
### Notes
|
|
|
|
- First successful build: `custom-gitea-runner:v0.1.0` (act_runner v0.2.11, node v20.20.2, npm 10.8.2, git 2.34.1, docker CLI 29.6.1).
|
|
- Runtime smoke test passes 17/17 via `./scripts/verify-runtime.sh`.
|
|
|
|
### 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:** Complete
|
|
|
|
### Goals
|
|
|
|
- Support both mounted-config and env-driven registration.
|
|
- Make bootstrap idempotent.
|
|
- Ensure config persistence survives restarts.
|
|
|
|
### Tasks
|
|
|
|
- [x] Create `config/runner.example.yaml`
|
|
- [x] Create `config/labels.example.env`
|
|
- [x] Create `scripts/register-runner.sh`
|
|
- [x] Create `scripts/deregister-runner.sh`
|
|
- [x] Add config path validation
|
|
- [x] Add first-boot registration flow
|
|
- [x] Add re-run safe bootstrap logic
|
|
- [x] Document required environment variables
|
|
- [x] 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.
|
|
|
|
### Notes
|
|
|
|
- Validated live against `git.alwisp.com` (Gitea 1.26.4): runner `forgerunner-01` registered as instance-level runner (id 5), came online and healthy, and a container restart reused the existing config with no duplicate registration.
|
|
- Registration token obtained via `POST /api/v1/admin/actions/runners/registration-token`; deregistration via `DELETE /api/v1/admin/actions/runners/{id}` (act_runner has no unregister command).
|
|
|
|
---
|
|
|
|
## Phase 3 — Docker workflow support
|
|
|
|
**Status:** Active (host-toolchain validated; registry push pending credentials)
|
|
|
|
### Goals
|
|
|
|
- Prove the runner can handle real Docker-centric CI workloads.
|
|
- Ensure JavaScript-based actions work out of the box.
|
|
|
|
### Tasks
|
|
|
|
- [x] Validate `actions/checkout`
|
|
- [x] Validate Node-based action runtime
|
|
- [ ] Validate `docker/login-action`
|
|
- [ ] Validate `docker build`
|
|
- [ ] Validate `docker push`
|
|
- [ ] Add support notes for self-hosted Gitea Container Registry
|
|
- [x] Validate mounted Docker socket usage
|
|
- [ ] Document permission expectations for `/var/run/docker.sock`
|
|
- [ ] Evaluate `buildx` as optional enhancement
|
|
|
|
### Notes
|
|
|
|
- `.gitea/workflows/ci-smoke.yml` (run 110, `success`) validated on the live runner via the `host` label: `actions/checkout@v4`, bundled node/npm/git/docker versions, and Docker-socket access (`docker info`) all pass.
|
|
- Image published: `registry.alwisp.com/jason/custom-gitea-runner:v0.1.0` + `:latest` (login via the jason Gitea account succeeded; push validated the registry round-trip).
|
|
- `docker/login-action` + `docker build` + `docker push` **from a workflow** still pending: needs repo Action secrets `REGISTRY_USER`/`REGISTRY_TOKEN`. Recommend a dedicated scoped package token rather than the admin API token. Corrected sample workflows (`test/sample-workflows/docker-login.yml`, `docker-build-push.yml`) are ready to run on the `host` label once the secrets exist.
|
|
|
|
### 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
|
|
|
|
- [x] Create `docker/runner/smoke-test.sh`
|
|
- [x] Create `scripts/verify-runtime.sh`
|
|
- [x] Create `scripts/test-local-runner.sh`
|
|
- [x] Add `test/sample-workflows/checkout.yml`
|
|
- [x] Add `test/sample-workflows/node-action.yml`
|
|
- [x] Add `test/sample-workflows/docker-login.yml`
|
|
- [x] 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`.
|