Files
the-custodian/docs/forgejo-repo-migration-pilot-glas-harness.md
codex dd0ee14f50 Document Forgejo tier 2.5: operator SSH, templates, railiance stack promotion
Record tegwick SSH identity, enablement workflow templates, and five railiance
repos on Forgejo with ci-smoke. Update state-hub gate checklist.
2026-07-04 12:51:05 +02:00

162 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Forgejo Repo Migration Pilots (tier 12)
Date: 2026-07-03 (tier 1), 2026-07-04 (tier 2)
Workplan: `CUST-WP-0054-T04`, `RAIL-HO-WP-0005-T10`
Pilots: `glas-harness` (tier 1), `key-cape` (tier 2)
---
## Tier 1 — glas-harness
Pilot repo: `coulomb/glas-harness` (non-production tooling; safe routing drill)
## Why this repo
| Criterion | glas-harness |
| --- | --- |
| Production dependency | None — harness meta-framework, not deployed |
| Size / complexity | 3 commits, no container image, no submodules |
| Blast radius | Low — wrong remote or CI failure does not break triage, State Hub, or emission |
| State Hub registration | Not in active production sweep set |
Use lessons here before migrating `state-hub` (high value, high risk).
## Pilot outcome (2026-07-03)
| Step | Result | Notes |
| --- | --- | --- |
| Create repo on Forgejo | **pass** | `POST /api/v1/orgs/coulomb/repos` |
| Mirror git history (HTTPS) | **pass** | `main` @ `e35e287` pushed with admin token |
| SSH `forgejo-remote` push | **pass** | After adding `id_gitea.pub` to `forgejo_admin`; NodePort `92.205.62.239:30022` |
| `origin` → Forgejo, `gitea` legacy remote | **pass** | `origin=forgejo-remote:…`, `gitea=gitea-remote:…` |
| Actions `ci-smoke` (host + container) | **pass** | `host-smoke` (`self-hosted`) + `container-smoke` (`ubuntu-latest`) both `success` |
| Gitea left intact | **pass** | No delete; Gitea still at `e35e287` until mirror sync policy defined |
## Routing that works
### Git remotes (workstation)
Add to `~/.ssh/config` (see `FORGEJO-REMOTE` block):
```ssh
Host forgejo-remote
HostName 92.205.62.239
Port 30022
User git
IdentityFile ~/.ssh/id_gitea
StrictHostKeyChecking accept-new
```
Per-repo layout after cutover:
```bash
git remote rename origin gitea # if still on Gitea
git remote add origin forgejo-remote:coulomb/<repo>.git
git push -u origin main
```
Canonical URL: `https://forgejo.coulomb.social/coulomb/<repo>.git`
### HTTPS fallback (automation / first push)
Admin or user token with `write:repository`:
```bash
git push "https://<user>:<token>@forgejo.coulomb.social/coulomb/<repo>.git" main
```
### CI runner labels (railiance01-build-01)
| Label | Works for | Evidence |
| --- | --- | --- |
| `self-hosted` | Host runner smoke | glas-harness `host-smoke` |
| `ubuntu-latest` | Container step jobs | glas-harness `container-smoke` |
| `container-build` | Docker build/push jobs | forgejo-actions-probe `image-build` |
### Registry / image CI (from prior probe)
- Org secrets `REGISTRY_USER` / `REGISTRY_TOKEN` via `PUT /api/v1/orgs/coulomb/actions/secrets/{name}` with plaintext `data` (HTTPS API).
- Host runner has **no** `docker` CLI and **cannot** `apk add` (non-root). Use **static docker binary** in the job step.
- `actions/checkout@v4` **fails** on host runner — use `git clone` in the job until resolved.
## Routing that does not work yet
| Gap | Impact | Mitigation for next repos |
| --- | --- | --- |
| ~~`tegwick` not on Forgejo~~ | **Resolved 2026-07-04**`tegwick` admin user + `workstation-automation` SSH key; `forgejo-remote` greets `Hi there, tegwick!` | Add other operator keys before team cutover |
| No automated Gitea→Forgejo mirror | Gitea copy drifts after Forgejo becomes canonical | Staged cutover: freeze Gitea pushes, one-way mirror, or retire Gitea remote after verification |
| `actions/checkout@v4` on host runner | Breaks multi-step workflows that depend on checkout | `git clone` in `run:` step (see image-build probe) |
| Issues/wiki/releases/LFS | Not exercised in pilot | Classify per repo in migration inventory before production repos |
| State Hub `remote_url` field | Still points at `gitea-remote:…` for most repos | Update registration when repo is promoted (separate step; not done for glas-harness) |
## Repeatable procedure (non-production repo)
1. Confirm repo is **not** in a production drain wave or has explicit operator approval.
2. Create empty repo on Forgejo (`auto_init: false` if mirroring existing history).
3. Push all branches/tags from workstation clone (HTTPS or SSH).
4. Add `forgejo-remote` remote; rename Gitea remote to `gitea`; set `origin` to Forgejo.
5. Add `.forgejo/workflows/` smoke (and image workflow if applicable).
6. Verify Actions green on Forgejo runner.
7. Leave Gitea repo read-only; do not delete (safety contract).
8. Record results in this doc or a per-repo row in the migration inventory.
## Tier 2 — key-cape (2026-07-04)
Pilot repo: `coulomb/key-cape` — non-production identity tooling with a real
multi-stage `Dockerfile` (Go build + distroless).
| Step | Result | Notes |
| --- | --- | --- |
| Mirror git to Forgejo | **pass** | `main` mirrored; `origin=forgejo-remote` |
| Port `.gitea/workflows/image.yaml``.forgejo/workflows/image.yaml` | **pass** | Archive checkout + static docker-cli; no `actions/checkout` |
| Build and push on `container-build` | **pass** | `build-and-push` workflow `success` @ `ec706da` |
| k3s pull on railiance01 | **pass** | `sudo crictl pull forgejo.coulomb.social/coulomb/key-cape:latest` |
Workflow pattern (tier 2+):
```yaml
# Checkout: repo archive (no git binary required on non-root runner)
wget -qO /tmp/repo.tar.gz "https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
tar xzf /tmp/repo.tar.gz -C buildctx --strip-components=1
# Build: static docker-cli + DOCKER_HOST=tcp://127.0.0.1:2375
```
Image: `forgejo.coulomb.social/coulomb/key-cape:latest`
## Tier 2.5 — railiance stack (2026-07-04)
Infra/platform repos promoted before tier-3 production set. Canonical remote is
Forgejo; Gitea `gitea` remote retained for rollback mirror.
| Repo | Forgejo | `origin` | CI workflow | Notes |
| --- | --- | --- | --- | --- |
| `railiance-enablement` | yes | `forgejo-remote` | `ci-smoke` + templates in `workflows/` | S4 canonical templates |
| `railiance-infra` | yes | `forgejo-remote` | `ci-smoke` | |
| `railiance-apps` | yes | `forgejo-remote` | `ci-smoke` | |
| `railiance-platform` | yes | `forgejo-remote` | `ci-smoke` | Local uncommitted `Makefile`/helm edits not in promotion |
| `railiance-cluster` | yes | `forgejo-remote` | `ci-smoke` | |
Promotion helper: `railiance-enablement/tools/promote-repo-to-forgejo.sh`
Template docs: `railiance-enablement/docs/forgejo-actions-workflow-templates.md`
Operator SSH (2026-07-04): user `tegwick` on Forgejo (admin, `coulomb` Owners
team); workstation key moved from `forgejo_admin` to `tegwick`.
## Not ready for state-hub yet
Before `state-hub`, the ladder still needs:
- [x] Operator/user SSH identity on Forgejo (`tegwick` + workstation key)
- [x] Reusable workflow templates in `railiance-enablement` (incl. multi-repo / `hub-core` context template)
- [ ] State Hub `remote_url` + sweep checkout path update playbook
- [ ] Gitea read-only mirror or push-disable policy for repos after cutover
- [ ] Scheduled Forgejo backups (disaster-control track; restore drill passed)
## References
- `docs/forgejo-production-decisions.md`
- `railiance-forge/docs/forgejo-actions-runner-substrate.md`
- `railiance-apps/docs/forgejo-on-railiance01.md`
- Tier 1: https://forgejo.coulomb.social/coulomb/glas-harness
- Tier 2: https://forgejo.coulomb.social/coulomb/key-cape