Commit Graph

19 Commits

Author SHA1 Message Date
c8bbd35f2a 1c/E2E-TESTME finding+fix: inject bridge_drone_token as Drone bot MACHINE TOKEN (DRONE_USER_CREATE token:)
All checks were successful
continuous-integration/drone/push Build is passing
Clean-room finding caught by the e2e: DRONE_USER_CREATE had no token: => a fresh-DB rebuild's Drone
auto-generates a random bot token, so the committed (sops) bridge_drone_token gets 401 and the bridge
can't trigger builds. The original cc-ci only matched because its token was captured out-of-band. Now
the bot's machine token == bridge_drone_token deterministically on every rebuild. (Evolves the toplevel
again; re-establish byte-identical on cc-ci after the e2e + Adversary re-verifies C1.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 19:27:00 +01:00
7563d47228 1c/W4: serialize abra reconcilers (proxy->drone->bridge->dashboard->backupbot)
All checks were successful
continuous-integration/drone/push Build is passing
On a FRESH host the reconcile oneshots ran abra concurrently against an uninitialised ~/.abra and
raced on catalogue/recipe init, leaving deploy-proxy/deploy-drone failed after a blank-VM rebuild
(observed on the W4 throwaway). Ordering-only `after` chain serializes them so a single
nixos-rebuild switch converges. Logically correct too (all need the proxy/abra state first).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 17:57:25 +01:00
9cc678853b 1c/W4: add sops.age.keyFile for bootstrap age key (recovery key on clones; host-derived on cc-ci)
All checks were successful
continuous-integration/drone/push Build is passing
cc-ci /var/lib/sops-nix/key.txt provisioned = host-derived age key (pub == &host recipient), so
adding keyFile is safe (sops-install-secrets aborts if a configured keyFile is missing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 17:24:39 +01:00
f79e542149 1c/W2a: mount cc-ci-secrets as submodule at secrets/; cert+key now sops-decrypted to /var/lib/ci-certs/live
All checks were successful
continuous-integration/drone/push Build is passing
- secrets/ is now the private cc-ci-secrets repo (submodule). defaultSopsFile path unchanged.
- secrets.nix: add wildcard_cert/wildcard_key sops secrets -> path=/var/lib/ci-certs/live/*.
- proxy.nix: cert is sops-from-git, not an operator file drop (reframed; FATAL guard kept as decrypt-path check).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:32:10 +01:00
c277029f84 M10/D10: enable real-!testme path — fetch upstream tags + enroll 6 recipes in POLL_REPOS
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
fetch_recipe (SRC+REF/PR path) now read-only fetches published version tags from the public upstream
into the mirror clone, so the upgrade stage finds a previous published version (mirror PR branches
carry no tags → upgrade would skip). Guardrail-safe: only fetches tags, never pushes to the recipe
repo; plain git so the bot token isn't sent to upstream. Adds the 6 D10 recipes to the bridge
POLL_REPOS so !testme on their PRs triggers runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 08:21:43 +01:00
2c8ee4297c M8/D7: bridge reflects final pass/fail onto the PR comment + content-hash image tag
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is failing
After triggering a build, the bridge spawns a watcher thread that polls the Drone build to
completion and edits its run-link PR comment to  passed /  <status> (Gitea PATCH
issues/comments/{id}, verified). post_comment now returns the comment id. Also gives the bridge
image a content-hash tag so the swarm service actually rolls on bridge.py changes (was stuck on
:latest). Completes the D7 'PR comment reflects outcome' requirement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 08:00:40 +01:00
2f3d1df1c7 dashboard: content-hash image tag so stack deploy rolls on code change (not stuck on :latest)
All checks were successful
continuous-integration/drone/push Build is passing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 07:24:21 +01:00
60d917646b M8/D7: results dashboard — overview + SVG badges at ci.commoninternet.net
All checks were successful
continuous-integration/drone/push Build is passing
Stdlib HTTP service (like the bridge): polls the Drone API for recipe-CI builds (event=custom),
groups latest-run-per-recipe, renders a YunoHost-CI-like overview table with pass/fail/running
badges + links to the canonical Drone run, plus /badge/<recipe>.svg. Nix-built OCI image, swarm
service on proxy, traefik Host(ci.commoninternet.net) (the bridge's /hook rule stays higher
priority by length). Reuses the Drone token (read-only). Reconcile oneshot like bridge/drone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 07:17:12 +01:00
451cca3ebd fix: set_env newline-safe — RESTIC_REPOSITORY was glued onto a comment line (backups broke)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
backup-bot-two's .env.sample ends with a newline-less comment, so set_env's bare
append concatenated RESTIC_REPOSITORY onto it (commenting it out). The backupbot
container then lacked RESTIC_REPOSITORY and 'abra app backup create' KeyError'd —
breaking the backup stage for recipes without a custom backup hook (cryptpad).
set_env now ensures a trailing newline before appending (applied to drone.nix too,
same latent bug). Re-verify keycloak backup, which earlier passed off an older deploy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 04:50:16 +01:00
72ff8e213d resource safety: MAX_TESTS=capacity=1 + per-build 60m timeout (orchestrator design change)
All checks were successful
continuous-integration/drone/push Build is passing
Bound live test apps on the single 28GiB node. DRONE_RUNNER_CAPACITY=1 (MAX_TESTS)
caps concurrent builds; Drone auto-queues the rest natively. deploy-drone reconcile
sets the cc-ci repo build timeout to 60m (best-effort PATCH, non-fatal) so a hung
build is killed and frees its slot. Janitor remains the backstop for SIGKILL'd builds.

Verified on host: DRONE_RUNNER_CAPACITY=1; repo timeout=60 via Drone API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 02:53:29 +01:00
7addb9686c bridge: polling primary + org-membership auth (orchestrator design change)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
Polling is now the primary, read-only trigger (always-on thread); the /hook
webhook is an optional admin-registered push optimization deduped by comment id.
Authorize commenters via GET /orgs/{owner}/members/{user} (204, read-level) +
optional allowlist, replacing the admin-requiring /collaborators permission
endpoint. Bot never self-registers webhooks. Enroll = POLL_REPOS + tests/<recipe>/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 02:41:25 +01:00
7eb0dd3c77 M5: upgrade + backup/restore stages green (custom-html); backup-bot-two oneshot
All checks were successful
continuous-integration/drone/push Build is passing
3-stage run green (install/upgrade/backup), clean teardown. backupbot deployed
via reconcile oneshot; PTY (script) for abra backup/restore; -m for secret generate
(no value leak). M5 CLAIMED.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 00:53:16 +01:00
38a145fd9c M4: harness + green install stage (custom-html + Playwright); guaranteed teardown; M4 CLAIMED
All checks were successful
continuous-integration/drone/push Build is passing
run_recipe_ci.py + conftest + abra/lifecycle wrappers + Nix python/playwright env.
deploy_app forces LETS_ENCRYPT_ENV='' (addresses A1). Short per-run domain scheme
for the 64-char swarm name limit. 2 passed; teardown leaves zero orphans.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 00:23:55 +01:00
2d6a312d44 M3: bridge deployed + verified publicly reachable; webhook delivery blocked at Gitea (ALLOWED_HOST_LIST)
All checks were successful
continuous-integration/drone/push Build is passing
Bridge healthz 200 over public DNS; HMAC verified. Gitea sends no deliveries
(suspect webhook host allowlist). Recorded in STATUS Blocked + operator options.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:46:43 +01:00
a385148af9 M2: Drone server + exec runner up; infra as idempotent-reconcile oneshots
Convert proxy+drone bring-up to writeShellApplication systemd oneshots that
reconcile every activation (orchestrator steer). pkgs.abra overlay. Runner
connected via RPC (polling, capacity=2). install.md = clone + nixos-rebuild switch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 22:59:59 +01:00
12f86fd3fb M1: proxy via real coop-cloud/traefik (abra, wildcard/no-ACME); recipe deploy+teardown; M1 CLAIMED
Orchestrator decision: deploy canonical coop-cloud traefik via abra instead of a
hand-rolled module. abra packaged in Nix (pinned). custom-html deployed over HTTPS
(200) via the gateway and torn down clean. docs/install.md seeded.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 22:21:12 +01:00
51b18841bc M1: Traefik swarm stack (wildcard cert via file provider); HTTPS path proven E2E
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:55:08 +01:00
ab839ae61d M1: Docker + single-node swarm via Nix (swarm-init + proxy overlay)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:47:42 +01:00
deb4a0fbed M0 complete: sops-nix wiring + decrypt-a-test-secret; M0 gate CLAIMED
Host decrypts /run/secrets/test_secret via its ssh host key (age identity);
off-box master recovery recipient. sops-nix pinned to a buildGoModule-era rev
for nixpkgs 24.11 compat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:41:45 +01:00