v26.05.26.5 — extension CORS unblock + UI gap closes + CI workflow cleanup #27

Merged
bvandeusen merged 0 commits from dev into main 2026-05-26 20:15:07 -04:00
bvandeusen commented 2026-05-26 20:13:19 -04:00 (Migrated from git.fabledsword.com)

Summary

Four-commit release. The CORS fix is the main deploy-blocker — without it the Firefox extension can't talk to FC at all (the operator hit this during the first install).

c7001f4 — fix(extension): CORS preflight for moz-extension:// + chrome-extension://

The extension's Test connection returned a generic NetworkError because /api/credentials POSTs with X-Extension-Key trigger a browser preflight OPTIONS request. Quart had no OPTIONS handler and no Access-Control-Allow-* response headers, so the preflight 405'd before the actual request. Browser blocked the fetch with no useful error.

Fix: two app-level hooks in create_app():

  • @app.before_request short-circuits OPTIONS from moz-extension:// / chrome-extension:// origins with 204
  • @app.after_request stamps Access-Control-Allow-Origin (mirroring the request origin), Allow-Methods, Allow-Headers: Content-Type, X-Extension-Key, Max-Age: 86400

Whitelist is intentionally narrow (extension schemes only) — normal browser usage doesn't get permissive CORS. Five integration tests pin the contract.

85b640f — fix(views): close the 24-32px gap below TopNav across all 12 views

Every view's root <v-container> used py-6 (24px top + bottom), pushing the first content item well below where TopNav's fade-to-transparent gradient bottoms out. Operator-flagged the empty space. Switched to pt-2 pb-6 (8px top, 24px bottom unchanged) across all 12 views. PlaceholderView kept its larger bottom padding via pt-3 pb-8.

f827612 — fix(artist-header): close gap below TopNav + center the tab strip

ArtistHeader's top: 64px left a visible gap because TopNav's actual rendered height is ~48px (0.75rem padding + ~24px content). Dropped to top: 48px so the two bars sit flush. Added a right-side spacer cell so the tab strip is geometrically centered (1fr | auto | 1fr layout, mirroring TopNav).

3f0153c — ci(workflows): dedupe + versioned image tags

  • ci.yml: dropped the pull_request: trigger — push: branches: [dev, main] already covered the same code; pull_request was duplicating CI runs on every dev push with an open PR.
  • build.yml: dropped dev from push triggers (operator confirmed they don't use :dev), added tags: ['v*'] trigger + Determine-tag logic for immutable per-version images (:v26.05.26.5). Extended the XPI-download step to fire on tag pushes so versioned images still carry the signed extension.

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

Test plan

  • Deploy :latest
  • Extension Test connection from about:addons → expect green "Connected" instead of NetworkError
  • Browse any view — gap between TopNav and first content is ~8px, not ~24px
  • Artist view header sits flush against TopNav; tabs centered horizontally
  • Bonus: the v26.05.26.5 tag-push should now produce :v26.05.26.5 immutable image alongside :latest

🤖 Generated with Claude Code

## Summary Four-commit release. The CORS fix is the main deploy-blocker — without it the Firefox extension can't talk to FC at all (the operator hit this during the first install). ### `c7001f4` — fix(extension): CORS preflight for moz-extension:// + chrome-extension:// The extension's `Test connection` returned a generic `NetworkError` because `/api/credentials` POSTs with `X-Extension-Key` trigger a browser preflight `OPTIONS` request. Quart had no `OPTIONS` handler and no `Access-Control-Allow-*` response headers, so the preflight 405'd before the actual request. Browser blocked the fetch with no useful error. Fix: two app-level hooks in `create_app()`: - `@app.before_request` short-circuits `OPTIONS` from `moz-extension://` / `chrome-extension://` origins with 204 - `@app.after_request` stamps `Access-Control-Allow-Origin` (mirroring the request origin), `Allow-Methods`, `Allow-Headers: Content-Type, X-Extension-Key`, `Max-Age: 86400` Whitelist is intentionally narrow (extension schemes only) — normal browser usage doesn't get permissive CORS. Five integration tests pin the contract. ### `85b640f` — fix(views): close the 24-32px gap below TopNav across all 12 views Every view's root `<v-container>` used `py-6` (24px top + bottom), pushing the first content item well below where TopNav's fade-to-transparent gradient bottoms out. Operator-flagged the empty space. Switched to `pt-2 pb-6` (8px top, 24px bottom unchanged) across all 12 views. `PlaceholderView` kept its larger bottom padding via `pt-3 pb-8`. ### `f827612` — fix(artist-header): close gap below TopNav + center the tab strip ArtistHeader's `top: 64px` left a visible gap because TopNav's actual rendered height is ~48px (0.75rem padding + ~24px content). Dropped to `top: 48px` so the two bars sit flush. Added a right-side spacer cell so the tab strip is geometrically centered (1fr | auto | 1fr layout, mirroring TopNav). ### `3f0153c` — ci(workflows): dedupe + versioned image tags - `ci.yml`: dropped the `pull_request:` trigger — push: branches: [dev, main] already covered the same code; pull_request was duplicating CI runs on every dev push with an open PR. - `build.yml`: dropped `dev` from push triggers (operator confirmed they don't use `:dev`), added `tags: ['v*']` trigger + Determine-tag logic for immutable per-version images (`:v26.05.26.5`). Extended the XPI-download step to fire on tag pushes so versioned images still carry the signed extension. Net per hotfix cycle: 5 CI runs → 3 (no tag) / 4 (with tag). ## Test plan - [ ] Deploy `:latest` - [ ] Extension Test connection from `about:addons` → expect green "Connected" instead of NetworkError - [ ] Browse any view — gap between TopNav and first content is ~8px, not ~24px - [ ] Artist view header sits flush against TopNav; tabs centered horizontally - [ ] Bonus: the v26.05.26.5 tag-push should now produce `:v26.05.26.5` immutable image alongside `:latest` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/FabledCurator#27