Files
cc-ci/tests/ghost/PARITY.md
autonomic-bot 1bd7c7a1d3 feat(2): Q4.4 ghost + DEPLOY_TIMEOUT plumb-through for heavy recipes
Harness change (small, surgical):
- runner/harness/lifecycle.deploy_app gains a deploy_timeout param (default 900s); passes
  through to abra.deploy(timeout=...). For heavy recipes (ghost, matrix-synapse, lasuite-meet),
  the orchestrator + dep resolver now read recipe_meta.DEPLOY_TIMEOUT and pass it so the Python
  subprocess wrapping abra deploy doesn't SIGKILL it before the recipe's INTERNAL TIMEOUT
  (via EXTRA_ENV) finishes swarm convergence.
- runner/run_recipe_ci.py + runner/harness/deps.py: thread recipe_meta.DEPLOY_TIMEOUT into
  the per-recipe deploy_app call.

Q4.4 ghost enrollment:
- recipe_meta.py: HEALTH_PATH=/, DEPLOY_TIMEOUT=1200 (subprocess), EXTRA_ENV={TIMEOUT: 1200}
  (recipe internal). Ghost cold-start with theme + DB migration runs ~12-15min on cc-ci.
- functional/test_health_check.py: GET / returns 200 (themed site).
- functional/test_content_api.py: GET /ghost/api/content/settings/ returns 200 (settings JSON)
  or 401/403 (Ghost error envelope) — distinguishes ghost-server up + JSON API working from
  static fallback.
- functional/test_admin_redirect.py: GET /ghost/ returns 200 or 302 + Ghost branding;
  proves admin route is wired through nginx proxy.
- PARITY.md: recipe-maintainer corpus has no ghost tests/, Phase-2 health_check is the
  parity baseline; create-a-post deeper test deferred (DEFERRED.md, --extra-tests linked).

Cold-verifiable (log /root/ccci-q44-ghost-r3.log):
  RECIPE=ghost STAGES=install,custom cc-ci-run runner/run_recipe_ci.py
  install + 3 functional tests PASS, deploy-count=1. 28/28 unit tests still PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:23:40 +01:00

2.1 KiB

Parity — ghost

The recipe-maintainer corpus has no recipe-info/ghost/tests/ directory — ghost was not in their parity suite. This PARITY.md documents the Phase-2 health_check (parity-aligned baseline)

  • recipe-specific tests beyond.

Recipe-specific tests (Phase-2 P3, ≥2 beyond parity)

Ghost is a publishing platform with a public themed site at /, an admin UI at /ghost/, and a JSON Content/Admin API at /ghost/api/*. Defining behaviors exercised:

cc-ci file what's verified rationale
tests/ghost/functional/test_content_api.py GETs /ghost/api/content/settings/; asserts 200 with {"settings": {...}} envelope OR 401/403 with a Ghost error envelope. Distinguishes "the ghost-server JS process is up + emitting its API" from "a static themed page is served at /." A wedged Ghost backend → 5xx; misrouted nginx → 404.
tests/ghost/functional/test_admin_redirect.py GETs /ghost/; asserts 200 or 302 + Ghost branding/SPA references in the response (or a redirect to /ghost/#/setup on fresh deploy). Proves the admin route is wired through the nginx proxy. Distinguishes "admin SPA bound" from "404 (route missing)" or "5xx (broken)."

Two specific tests + parity health_check = ≥2 floor met.

Plan §4.3 prescribed deeper test (deferred to Q4 follow-up)

§4.3 named "create-a-post round-trip" for ghost. That requires:

  1. Setup the Ghost owner (POST /ghost/api/v3/admin/authentication/setup/) with a per-run admin email+password.
  2. Login → JWT bearer token.
  3. POST /ghost/api/v3/admin/posts/ to create a post.
  4. GET /ghost/api/v3/admin/posts/<id>/ to read it back.

Doable; adds a per-run setup secret + token-management. Tracked for Q4 follow-up.

Backup data-integrity (P4)

Lifecycle overlays not authored. The base recipe stores state in SQLite + a content volume; backup-capable is auto-detected from compose. Q5 catch-up if backup data-integrity proves needed for this recipe.

Playwright (P6)

Not yet authored. Ghost's admin UI is an Ember SPA; a Playwright flow would exercise the setup wizard + post creation. Q4 follow-up.