feat(hrafn): author the CI deploy that replaces the hand-rsync path
hrafn was handed to infra-ops for uptime ownership with no CI deploy and no commit provenance -- the image was always local/hrafn:v1 and the whole working tree lived in the compose directory. These two files fix both. They are authored here because infra-ops owns hrafn's uptime, but they belong in vh/hrafn; claude-bot is not a collaborator there, so they are handed to the repo holder rather than committed directly. - playbooks-deploy.yaml -> vh/hrafn playbooks/deploy.yaml - gitea-workflows-deploy.yaml -> vh/hrafn .gitea/workflows/deploy.yaml Design calls recorded in the README: the build context travels as one tarball rather than per-file upload steps (nevermore's pattern fails open when a new source file has no matching step), and the playbook refuses to deploy unless .env exists at 0600 -- a guard prompted by it arriving 0644 with a live bearer token in it. Validated with `elway --dry-run`, which caught a real interpolation bug during authoring. No new Actions secrets needed.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# hrafn CI deploy — authored here, lands in `vh/hrafn`
|
||||
|
||||
These two files replace hrafn's hand-rsync deploy. They are **authored and
|
||||
version-controlled here** because infra-ops owns hrafn's uptime, but they
|
||||
**belong in the `vh/hrafn` repo** — infra-ops has no write access to it
|
||||
(claude-bot is not a collaborator), so they are handed to the repo holder
|
||||
rather than committed directly.
|
||||
|
||||
| file here | destination in `vh/hrafn` |
|
||||
|---|---|
|
||||
| `playbooks-deploy.yaml` | `playbooks/deploy.yaml` |
|
||||
| `gitea-workflows-deploy.yaml` | `.gitea/workflows/deploy.yaml` |
|
||||
|
||||
Keep this copy in sync if the deployed version changes, or delete it once
|
||||
infra-ops has write access to `vh/hrafn` and the repo copy is canonical.
|
||||
|
||||
## What the change buys
|
||||
|
||||
The pre-CI shape was: rsync a working tree into `/opt/docker/compose/hrafn/`,
|
||||
then `docker compose build && up`. Two problems, both fixed here.
|
||||
|
||||
1. **No provenance.** The image was always `local/hrafn:v1`, so nothing on
|
||||
the box could answer "what commit is running". The image is now tagged
|
||||
with the commit SHA, and `/opt/docker/compose/hrafn/.deployed` records
|
||||
the SHA and timestamp. Rollback becomes a retag.
|
||||
2. **The whole repo lived in the compose directory** — `tests/`, `docs/`,
|
||||
`ROADMAP.md`, `persistent-memory.md`, `CLAUDE.md`. Only the build context
|
||||
ships now (`Dockerfile`, `compose.yaml`, `pyproject.toml`, `README.md`,
|
||||
`src/`).
|
||||
|
||||
## Two design calls worth knowing
|
||||
|
||||
- **Tarball, not per-file upload steps.** nevermore's playbook enumerates
|
||||
every source file as its own `upload:` step. That is explicit, but it
|
||||
fails *open*: add `src/hrafn/newthing.py`, forget the matching step, and
|
||||
the deploy silently ships without it. hrafn's build context travels as one
|
||||
archive so it cannot go partial.
|
||||
- **`.env` is never deployed.** It is host-owned, `0600`, and holds the
|
||||
bearer token. The playbook *refuses to run* if it is missing or not `0600`
|
||||
— a guard added because the file arrived at `0644` on handoff.
|
||||
|
||||
## Validation
|
||||
|
||||
The playbook parses and interpolates clean under elway's own parser:
|
||||
|
||||
```bash
|
||||
scripts/elway ana-docker --playbook stacks/hrafn/ci/playbooks-deploy.yaml \
|
||||
--var hrafn_sha=abc123def456 --dry-run
|
||||
```
|
||||
|
||||
That dry-run is worth running after any edit — it caught a real bug during
|
||||
authoring, where a comment containing a literal `{{ ... }}` identifier was
|
||||
picked up by elway's variable substitution and failed the run.
|
||||
|
||||
No new Actions secrets are required: `DEPLOY_SSH_KEY` and `MGMT_REPO_TOKEN`
|
||||
already exist at user scope on `vh` from the nevermore/task-board wiring.
|
||||
Reference in New Issue
Block a user