Skip to content

[pull] main from TryGhost:main - #1438

Merged
pull[bot] merged 11 commits into
code:mainfrom
TryGhost:main
Aug 24, 2026
Merged

pull[bot] merged 11 commits into
code:mainfrom
TryGhost:main

Conversation

@pull

@pull pull Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

kevinansfield and others added 11 commits August 24, 2026 12:10
no issue

Offer management now lives in React Admin, but Ember still carried remnants of the old management screens.

- Removes management-only adapter, validation, dead history helper, mock write endpoints, styles, and static assets
- Keeps offer reads used by editor link suggestions and the state bridge
no ref
- run the existing Oxfmt check before lint and tests in pnpm check
- update contributor documentation to reflect the expanded validation
pipeline
ref
[DES-1421](https://linear.app/ghost/issue/DES-1421/improve-theme-installationactivation-modal-layout-and-copy)

The upload dialog led with a large green banner that repeated what the
title already said, then stacked three different treatments underneath
it: a show/hide toggle, bordered cards per issue, and a red card for
bare error strings. The result buried the one decision the dialog exists
to ask — activate this theme, or not.

## What changed

- **Status summary replaces the green banner.** One sentence naming the
theme and the outcome, in three states: uploaded successfully / uploaded
but has issues / couldn't be uploaded.
- **Error state gets `[Cancel] [Re-upload]`**, and Re-upload reopens the
upload dialog. Labels are per-caller, so the activation and editor-save
failures still read accurately.
- **Issue list is always visible** under a plain `2 errors, 3 warnings`
heading, contextual to the severities actually present. The show/hide
toggle is gone, and the section stays hidden when the theme validates
cleanly.
- **One hairline-separated list** instead of per-issue cards, each row
expanding in place. Bare error strings now render as rows in the same
list rather than as a separate red card.
- **Sticky footer** no longer leaves dead space below it, and its
buttons sit right-aligned to match Shade's dialog default.
- **Chevron rotates 180°** instead of a full turn back to where it
started.
no ref

The React admin's Unsplash request config (including the hard-coded
client key) was a literal in `main.tsx`, duplicated again in the
acceptance harness. It now lives once in the framework as
`defaultUnsplashConfig` (typed against
`FrameworkProviderProps['unsplashConfig']`, exported from the root);
`main.tsx` uses it and the harness shares the shape while keeping its
deliberately empty `Authorization` so tests never hit Unsplash. Ember's
two copies are untouched (they die with Ember).
Analysis of CodeRabbit responses in the last week showed a pattern in 
false-positives, of reporting pre-existing problems during moves, renames, 
conversions etc.

This attempts to prevent this behaviour from CodeRabbit, unless the diff 
introduces or worsens the problem, makes itnewly reachable, or prevents
 the transformation from being correct.
no ref

Ten admin-x-framework exports are React hooks (built from the query
factories) but were named `get*`/`gen*`/`verify*` — they dodge
rules-of-hooks linting and misread as plain functions at call sites.
Pure renames, no logic change:

| Old | New |
|---|---|
| `getMember` | `useMember` |
| `getPost` | `usePost` |
| `getMemberSigninUrl` | `useMemberSigninUrl` |
| `getTagBySlug` | `useTagBySlug` |
| `getStaffToken` | `useStaffToken` |
| `genStaffToken` | `useGenerateStaffToken` |
| `verifyEmailToken` | `useVerifyEmailToken` |
| `getFeaturebaseToken` | `useFeaturebaseToken` |
| `getPostFeedback` | `usePostFeedbackQuery` |
| `getTinybirdToken` | `useTinybirdTokenQuery` |
…0216)

ref https://linear.app/ghost/project/4b2edbd66469/ Milestone 4

Each commit references its own Linear issue

This PR adds the UI for mapping fields when importing a CSV file,
borrowing patterns from the Member importer for consistency. It also
adds some Markdown & HTML processing for post content by introducing a
[`@tryghost/mg-clean-html`](https://github.com/TryGhost/migrate/tree/main/packages/mg-clean-html)
from the `migrate` tools, which converts common HTML like `<span
style="font-weight: bold;">Hello</span>` to `<b>Hello</b>` for imported
content.

The importer now:
- Automatically maps exact, case-sensitive header matches
- Requires exactly one Title mapping
- Provides a searchable, grouped picker covering Ghost’s supported
editorial post fields
- Supports content, publishing, image, SEO, social, and advanced
metadata
- Validates and coerces supported boolean, type, status, and visibility
values
- Handles explicit slugs and dates while preserving Ghost’s existing
defaults
- Supports either HTML or Markdown content
- Cleans imported markup before converting it to Lexical
- Isolates malformed or failed rows so valid posts continue importing
- Preserves identity-header imports for direct API clients without a
mapping
closes
https://linear.app/ghost/issue/NY-1543/figure-out-tagging-for-automation-session-replays

Tag manually started Automations replays so they can be filtered
reliably in Sentry. This only adds metadata and has no user-facing
impact.
)

no ref

Prepares the ground for a lint ban on out-of-bounds bridge access. Every `window.EmberBridge` read now lives in `src/ember-bridge`.
ref https://linear.app/ghost/issue/BER-3854
ref https://linear.app/ghost/issue/BER-3889

Gift buyers need to choose when recipient email is sent without delaying access to the gift or shortening gifted membership. Scheduled and immediate email delivery now share one lifecycle, while Gift owns a fixed claim deadline independent of delivery retries and outcomes.

- Added a Portal delivery-date picker and schedule-aware success and email previews, limited to 365 publication-calendar days and 09:00 publication-local delivery
- Persisted scheduledAt on GiftDelivery and used indexed due queries, atomic claims, bounded recovery, and existing failure handling for immediate and scheduled sends
- Consolidated reminder and delivery timing in GiftFlushScheduler, preserving stale-send recovery and legacy job cleanup
- Kept gift links viewable and redeemable from purchase, cancelled pending delivery after early redemption, and kept gifted access anchored to redemption
- Anchored expiration to scheduled delivery, or purchase for immediate gifts, without allowing email attempts or outcomes to move it
- Added scheduled purchase and sent confirmations, translator context, and end-to-end coverage
- Released Portal 2.70 and updated the Ghost default so backend and UI support ship together
@pull pull Bot locked and limited conversation to collaborators Aug 24, 2026
@pull pull Bot added the ⤵️ pull label Aug 24, 2026
@pull
pull Bot merged commit fd66817 into code:main Aug 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants