Skip to content

[pull] main from TryGhost:main#1162

Merged
pull[bot] merged 15 commits into
code:mainfrom
TryGhost:main
May 21, 2026
Merged

[pull] main from TryGhost:main#1162
pull[bot] merged 15 commits into
code:mainfrom
TryGhost:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 21, 2026

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 : )

aileen and others added 15 commits May 21, 2026 07:22
ref https://app.incident.io/ghost/incidents/284

BMA now sends an explicit readiness message after rendering a visible shell, so Admin should keep its fallback UI active until that validated message arrives instead of treating early token, route, or subscription messages as loaded.
A new button under Settings → Advanced → Danger Zone rotates every API key secret, locks every staff user (rotating their password and writing a `security_action` audit row), wipes every staff session, and asks each registered scheduler to reissue queued URLs under the new keys.

This lets a site owner recover from a suspected credential compromise in one click instead of editing the database directly. Suspended staff users have their password rotated but stay suspended; active staff hit the standard reset-on-signin flow on their next sign-in. Members are unaffected.
no ref

Two minor robustness follow-ups to CodeRabbit feedback on #28009
(already merged).
A new button under Settings → Advanced → Danger Zone that lets an
owner rotate every API key, lock every staff user, and destroy every
active staff session in a single click. Active staff hit the standard
reset-on-signin flow on their next sign-in. Suspended staff have
their password rotated but stay suspended. Members aren't affected.

For recovery after a suspected credential compromise: instead of
editing the database directly to invalidate keys and force password
resets, an owner can run the full rotation from the admin UI. The
action writes an audit row recording who triggered it.
Added a simple access code generator, using a carefully curated word list and a 3-number suffix. Replaces the temporary fake generator using a format that gives private mode sites short, human-readable access codes that are easy to copy and share.

Generation remains server-side and uses crypto randomness, so callers never provide the access code value when in private mode.
no ref

The pnpm catalog now pins ~60 shared dependencies, and `catalogMode` is `strict` — so a contributor running `pnpm add` will see the dependency routed into `pnpm-workspace.yaml` automatically, with nothing in the repo explaining why.
no ref

Finishes the `ghost/core/test/unit` migration from mocha to vitest
(following #27898 / #27900 / #27974 / #27991 / #27992 / #27996 /
#28009). The last 3 mocha holdouts now run on vitest, so **the mocha
unit-test path is retired** — all of `test/unit` (550 files / 6573
tests) runs on vitest.
no ref

- Skips lifecycle scripts in the setup job dependency install.
- Filters the i18n job install to `@tryghost/i18n...` so it does not
install the full monorepo.
- Runs the i18n package test directly with `pnpm --filter @tryghost/i18n
test`.
no ref

This branch finishes the ghost/core unit-test migration to Vitest and
builds on it to deliver a unified `pnpm test:watch` across the monorepo.

`pnpm test:watch` now runs a **single Vitest watcher across all 14
Vitest packages** (ghost/core + 13 apps) via a root `vitest.config.mjs`
that registers each package as a Vitest project — each keeps its own
environment, setup and pool. Previously only `apps/portal` and
`apps/stats` had a watch script, each watching just itself.

- `pnpm test:watch` — watch everything
- `pnpm test:watch apps/posts` — path filter to scope
- `cd ghost/core && pnpm test:watch` — a single package
no ref

Tailwind's packages move in lockstep with each release but were pinned
per-package, and had already drifted: `tailwindcss` was `4.2.1` in
`shade` and `admin-x-design-system` and `4.2.2` in five other apps.

This moves the Tailwind ecosystem into the pnpm catalog:

- **Default catalog** (Tailwind v4): `tailwindcss`, `@tailwindcss/vite`,
`@tailwindcss/postcss` and `tw-animate-css`, all at `4.2.2`.
`@tailwindcss/vite` and `@tailwindcss/postcss` were bumped `4.2.1` →
`4.2.2` to align with `tailwindcss`.
- **New `tailwind3` named catalog**: the public apps (`comments-ui`,
`signup-form`, `sodo-search`) intentionally stay on Tailwind v3, and the
default catalog can only hold one version of a package, so they
reference `catalog:tailwind3` (`3.4.18`).

With `catalogMode: strict` already in place, future Tailwind bumps
become a one-line change in `pnpm-workspace.yaml`.
no ref

Build-only Docker base image digest bumps go through Renovate's manual
merge queue every week. Today only `ghost/traffic-analytics` and
`tinybirdco/tinybird-local` are on the digest-automerge allowlist;
`python`, `ghcr.io/astral-sh/uv`, `axllent/mailpit`, `caddy`, and
`stripe/stripe-cli` rotate digests weekly and get hand-merged each time.

## What this changes

`.github/renovate.json5`: extends the existing "Automerge internal
Docker digest updates after CI passes" rule to cover those five images.
They're pinned purely for build reproducibility — a digest rotation
can't change runtime behavior — so they're safe to automerge once CI is
green, the same as the two images already on the list.

## Test plan

- [ ] CI passes (`renovate.json5` is parsed by Renovate, not Ghost CI —
success here is JSON5 validity)
- [ ] After merge: the next digest bump for one of these images
automerges once its CI checks are green
no ref

CI is failing on `main` at the `pnpm install --frozen-lockfile` step —
before any test runs:

The Tailwind catalog move (`ee123bbc08`) regenerated `pnpm-lock.yaml`,
and the resolution picked up a transitive `lightningcss` bump (`1.31.1`
→ `1.32.0`) as a side effect. The rewrite was incomplete: all 123
package snapshots were rewritten to `lightningcss@1.32.0`, but the
**root importer's `vitest` devDependency** kept the stale `1.31.1` peer
hash in its resolved `version:` string.

That left the lockfile internally inconsistent — `--frozen-lockfile`
can't find a snapshot keyed by the stale `1.31.1` variant and aborts, so
every CI run on `main` fails at install.
closes https://linear.app/ghost/issue/NY-1296

## Summary

- Added a loading and disabled state to the Post analytics export button
while the CSV export is running
- Guarded against duplicate export clicks during an in-flight request
- Added acceptance coverage for the loading and disabled button state

### Before

https://github.com/user-attachments/assets/6be392d2-33ec-41ef-8344-407028c9472a

### After

https://github.com/user-attachments/assets/9d2989da-24bf-4d00-bf44-fbab25fdc414
@pull pull Bot locked and limited conversation to collaborators May 21, 2026
@pull pull Bot added the ⤵️ pull label May 21, 2026
@pull pull Bot merged commit 263ee04 into code:main May 21, 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.

6 participants