Commit Graph

22 Commits

Author SHA1 Message Date
bvandeusen 79269da802 fix(agent): prompt stop + lazy curator polling + build marker; add agent to CI
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 26s
CI / integration (push) Successful in 3m25s
Addresses operator reports: Stop never finishes, the agent polls curator
constantly, and stale-cached pages get mistaken for a failed deploy.

- Stop is prompt: flip _running BEFORE any lock so /status + worker loops see
  "stopped" immediately, and add a stop/shrink checkpoint in _process (after
  decode, before the expensive detect+embed) that releases the job and bails —
  so a Stop doesn't wait out heavy GPU work.
- Lazy curator polling: the queue snapshot is fetched only while a browser is
  actually watching (a /status hit within UI_IDLE_GRACE) and on a 5s cadence,
  not a constant background loop. The work loop's own lease/submit is curator's
  only visitor otherwise — nothing polls just to poll.
- Build marker: VERSION is embedded in the page and reported on /status; the UI
  shows a "reload" banner when they differ, so a browser-cached page can't be
  mistaken for "the new image didn't deploy" (complements the no-store header).

CI: the lint lane now also `ruff check`s agent/ and compileall-parses it, so the
GPU agent is linted + syntax-checked before its image builds (build.yml only
`docker build`s it). Fixed the agent's pre-existing UP037/B905 so it passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
2026-06-30 21:39:00 -04:00
bvandeusen 3f6ea601f8 perf(ci): collapse the 3 integration shards into one job
CI / lint (push) Successful in 2s
CI / backend-lint-and-test (push) Successful in 12s
CI / frontend-build (push) Successful in 21s
CI / integration (push) Successful in 2m55s
With fsync-off the whole integration suite runs in ~45s (was ~13min across
shards), so the 3-way split only triplicated the ~2min fixed overhead
(container + install + migrate) and consumed 3 of 6 runner slots for no
wall-clock gain. Merge intapi/intimp/intcore into one `integration` job:
spin up once, install once, migrate once, run `pytest -m integration` over
the whole suite. Frees 2 runner slots (6 jobs -> 4) and drops ~140 lines of
near-duplicate YAML.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 08:17:50 -04:00
bvandeusen 6a25db4b8b perf(ci): relax Postgres durability in integration shards (fsync off)
CI / lint (push) Successful in 2s
CI / backend-lint-and-test (push) Successful in 12s
CI / frontend-build (push) Successful in 17s
CI / intimp (push) Successful in 2m15s
CI / intcore (push) Successful in 2m28s
CI / intapi (push) Successful in 2m34s
Option 1 (pooling the teardown connection) left teardowns at ~1.5-2s/test, so
the cost is the per-test TRUNCATE's commit forcing an fsync, not the connect
handshake. Each shard now ALTER SYSTEM SETs fsync/synchronous_commit/
full_page_writes off + pg_reload_conf() right after deps install, before
alembic — sighup/user-context GUCs apply with no restart. The DB is ephemeral
(rebuilt per run) so fsync-off is safe; the step is non-fatal so a perms
surprise can't red a shard. Speeds up every test's commit (setup inserts +
the teardown TRUNCATE), stacking on the pooled engine from the prior commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 07:45:21 -04:00
bvandeusen e76aa36a29 ci(I1): dedicated fast-fail ruff lint lane
ruff is pre-installed in the ci-python image, so a new `lint` job runs it
with no dependency install and fails in seconds — surfacing the common lint
bounce class without waiting on the backend job's ~30-60s wheel install.
Dropped the now-redundant ruff step from backend-lint-and-test (same job
name, required-checks unchanged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 12:22:33 -04:00
bvandeusen 3f0153cba5 ci(workflows): dedupe + versioned image tags
ci.yml: drop pull_request: trigger — push: branches: [dev, main] already covers it; pull_request was duplicating ci.yml runs on every dev push with an open PR. (No fork PRs in this repo.)

build.yml: drop dev from push triggers — operator doesn't use the :dev image. Add tags: ['v*'] trigger + tag-push branch in the Determine-tag logic so cutting a release tag publishes an immutable :v26.05.26.X image (rollback story) without re-publishing :latest. Extend the XPI-download step to fire on tag pushes too so the versioned image carries the signed extension.

Net per hotfix cycle: 5 runs → 3 (no tag) / 4 (with tag).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:26:56 -04:00
bvandeusen 1803a09306 ci(workflow): remove the 4 Cache pip wheels steps entirely — act_runner's cache backend has been broken for 11+ days and the cached path (~/.cache/pip) wasn't even the primary install tool's cache anyway (uv uses ~/.cache/uv). Net cost ~30s/job of wheel downloads. Long-term: mount ~/.cache/uv as a docker volume at the runner level (skips actions/cache entirely) or fix the runner-side cache backend.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 16:54:05 -04:00
bvandeusen 7b0dd4182c ci(workflow): continue-on-error on Cache pip wheels — act_runner's cache backend has been broken since 2026-05-15 and now hard-fails ('Cannot find module .../dist/restore/index.js') instead of warning. Install step handles cold caches natively; ~30s wheel-download cost per job until the runner-side cache backend is fixed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 16:35:26 -04:00
bvandeusen ac39509a74 fix(ci): rename shard jobs to no-separator names (intapi/intimp/intcore) + add diagnostic docker ps dump so next bounce surfaces the real act_runner naming convention — Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> 2026-05-25 20:59:17 -04:00
bvandeusen e50f92d900 perf(ci): shard integration suite into 3 parallel jobs (int_api, int_imp, int_core) — newly feasible after act_runner capacity 2→6 — Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> 2026-05-25 20:05:15 -04:00
bvandeusen b0bb7ae6cc ci: pip wheel cache (actions/cache on requirements.txt hash) + uv-when-available — ~2 min saved on warm runs, no risk
uv falls back to pip install on runners without uv binary, so this
change is forward-compatible with the current ci-python image. When
the runner image gets uv pre-installed in a future bump, the warm
install path drops from ~2 min to ~10 seconds.

pytest-xdist parallelization is OUT OF SCOPE for this commit:
tests/conftest.py uses a TRUNCATE ALL TABLES RESTART IDENTITY CASCADE
fixture after every integration test against a single shared
database; xdist workers running in parallel would nuke each other's
mid-test state. A future refactor to per-worker databases or
per-worker schema isolation is the prerequisite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 13:47:27 -04:00
bvandeusen 1bbe478fd0 ci: report slowest 25 integration tests via pytest --durations=25 — instrumentation pass before deciding parallelization vs targeted slow-test fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 13:09:25 -04:00
bvandeusen 4a09cca46e feat(ci): pin container.image to ci-python:3.14 + ship ci-requirements.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 09:19:30 -04:00
bvandeusen 65a055408b ci(integration): reach services by bridge IP via docker socket, no host ports 2026-05-15 22:18:01 -04:00
bvandeusen cd8d0bd606 ci(integration): publish service ports, connect via localhost (host runner) 2026-05-15 22:02:43 -04:00
bvandeusen 827a4180a9 ci(integration): add pgvector+redis integration job; amend lint-only policy 2026-05-15 21:46:10 -04:00
bvandeusen 6bc7689f6e build(fc2c-i): add Vitest harness and run it in CI 2026-05-15 21:09:52 -04:00
bvandeusen 22bc24b6b6 fix(fc2a): align CI with FabledRulebook — lint + short unit tests only
The CI failure resolving 'postgres' hostname was the symptom; the cause is
that the workflow violated FabledRulebook/forgejo.md's "CI philosophy —
lint + short unit tests only" rule. Integration tests against a real
Postgres are supposed to run locally via docker-compose, not in CI.

Changes:
- Marked 8 DB-dependent test files with @pytest.mark.integration:
  test_tag_service, test_importer, test_gallery_service, test_api_gallery,
  test_api_tags, test_api_settings, test_api_import_admin, test_maintenance.
- CI workflow drops the postgres/redis service containers and the alembic
  upgrade smoke step entirely.
- Pytest invocation in CI changes to `pytest -v -m "not integration"`.
- Added pytest marker registration to pyproject.toml.
- DB_PASSWORD and SECRET_KEY env vars retained because config.py reads
  them at import time even though unit tests don't actually use them
  (set to placeholder values).

What CI now runs:
- ruff check
- pytest on the 6 unit test files: test_slug, test_paths,
  test_migration_0002, test_thumbnailer, test_celery_smoke,
  test_tasks_register.
- npm install + npm run build

What CI no longer runs:
- alembic upgrade (no live DB)
- the 8 integration test files (these run locally via docker-compose)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 15:23:07 -04:00
bvandeusen 80a5690740 fix(fc2a): apply ruff autofix + skip vue-tsc check (no tsconfig)
Ruff:
The remaining I001 errors came from ruff treating `alembic` as a first-
party module (because the alembic/ directory exists in the repo root)
rather than third-party. Ran `ruff check --fix` locally — auto-sorted
import groupings to put alembic/sqlalchemy alongside backend.* as first-
party, and trimmed redundant blank lines after a few import blocks.

Frontend:
`npm run check` (vue-tsc --noEmit) was failing because vue-tsc has no
tsconfig.json to read against, and the frontend is pure JS without
JSDoc annotations — vue-tsc had nothing to do. Skipping the step until
we add a tsconfig + convert to TS or add JSDoc annotations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 14:24:25 -04:00
bvandeusen 117873423b fix(fc2a): use npm install (no lockfile required) for frontend CI
Per feedback-no-local-runs we don't run npm locally, so no
package-lock.json is tracked. npm ci fails without a lockfile; npm
install works fine. We lose strict reproducibility, which is acceptable
for a pre-v1 project — if we want it later, commit a package-lock.json
and flip back to npm ci.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:58:03 -04:00
bvandeusen 15b47777ae chore(fc2a): move ruff version ownership to the runner image
Per FabledRulebook forgejo.md, toolchain versions live on the runner
image, not in the workflow. Two changes here, paired with the runner
image bump (RUFF_VERSION 0.9.7 -> 0.15.13 in CI-Runner/CI-python):

- Drop "ruff>=0.9,<1.0" from ci.yml's pip install — the runner image's
  pre-installed ruff is authoritative now. Previously this constraint
  matched the existing 0.9.7 in the image so pip never upgraded.
- Flip ruff.toml's target-version back to py314 now that the runner
  has a ruff new enough to know about it.

Next bump path: edit RUFF_VERSION in CI-Runner/CI-python/Dockerfile,
'make push', done. No workflow churn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:24:19 -04:00
bvandeusen ff122c55eb ci: switch runner label from fabledcurator-ci to python-ci
Generic python-ci runner is reusable across the family (FabledScribe,
FabledSteward, NhenArchiver, StashHandler, etc.) rather than scoped to
just this project. Runner image lives at CI-Runner/CI-python/ in the
operator's workspace; pattern mirrors CI-Runner/CI-go and CI-Runner/CI-flutter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 08:45:48 -04:00
bvandeusen 8cbe963b37 ci: add Forgejo CI workflow — backend lint+tests, frontend build
Backend job spins up Postgres+pgvector and Redis as services, runs ruff,
applies the initial migration to confirm it's clean, and runs pytest.
Frontend job runs vue-tsc and vite build.

Requires a runner labeled "fabledcurator-ci" with Python 3.14, ruff,
and Node 22 pre-installed. Integration tests run locally via
docker-compose with testing.Short() gating per FabledRulebook
verification.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:52:30 -04:00