Skip to content

[pull] main from TryGhost:main#1220

Merged
pull[bot] merged 16 commits into
code:mainfrom
TryGhost:main
Jun 8, 2026
Merged

[pull] main from TryGhost:main#1220
pull[bot] merged 16 commits into
code:mainfrom
TryGhost:main

Conversation

@pull

@pull pull Bot commented Jun 8, 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 : )

ErisDS and others added 16 commits June 8, 2026 11:57
…de (#28301)

Fixes the access dropdowns in **Settings → Membership** are clipped
when a site is in pre-launch mode (free trial), so options below the
fold are no longer cut off.

Root cause: in pre-launch mode the Access card was given
`overflow-hidden` to contain the gradient "Pre-launch mode" banner's
glow shadow. That clip is geometric, so it also truncated any `Select`
dropdown that opened past the card's edge.

Fix: drop the card-level `overflow-hidden` and instead contain the
glow on a small `overflow-hidden` wrapper around the gradient banner —
so the card no longer clips anything and the dropdowns render normally.
IndexNow failures were mis-detecting the HTTP status code, so
rate-limits (429) and key-validation errors (422/403) were silently
mislabelled as the generic `indexnow.ping_failed` (with `status_code:
null`).

The classification in the `ping()` catch block keyed off
`err.statusCode`, but for a non-2xx response `got` throws an `HTTPError`
whose status lives at `err.response.statusCode`, **not**
`err.statusCode`. So in production those branches never matched and
every 429/422/403 fell through to the generic failure branch - making
rate-limiting and key problems invisible in structured logs.
…6673)

closes https://linear.app/ghost/issue/BER-3490

During boot, incoming recommendation mentions are revalidated. If the
metadata fetch failed for any reason (including transient errors like
429 rate limits or network timeouts), the mention was immediately
soft-deleted, causing valid recommendations to disappear from Ghost
Admin. Now transient errors are ignored entirely, and hard failures
require 3 consecutive occurrences before deletion. A successful fetch
resets the failure count.

## Changes
- Transient fetch errors (429, 503) during incoming recommendation
revalidation are now ignored instead of immediately deleting the mention
- Hard failures now require 3 consecutive occurrences before a mention
is soft-deleted, tracked via a new `revalidation_failure_count` column
on the `mentions` table
- A successful metadata fetch resets the failure counter to zero
- All failures are logged with a `[Webmention Revalidation]` prefix for
easy diagnosis

---

Co-authored-by: Sag <guptazy@gmail.com>
IndexNow notifies search engines when content is published or updated by
pinging an external API. This gates the ping behind Ghost's existing privacy config.

Meaning it can be disabled via `privacy: {useIndexNow: false}` or `privacy:
{useTinfoil: true}`. 

This keeps it consistent with other features like gravatar, whilst also being useful 
for disabling pings in test mode.
no ref

This change should have no user impact. It just quiets a
development-only warning.

Before this change, our pre-commit hook showed a warning unless your
commit's third line started with "ref", "fixes", or "closes".

Now it supports a wide array of options. These are lifted from some our
internal document, "How to write commit messages".
closes https://linear.app/ghost/issue/NY-1302

This change should have no user impact.

This refactor should (hopefully) make things a bit easier to read.
…8376)

towards https://linear.app/ghost/issue/NY-1286
ref #28120

*I recommend [reviewing this with whitespace changes disabled][0].*

**What:** We want to trigger automations after members are inserted.

**Why:** If we don't do this, automations could run before the member
exists in the database.

[0]: https://github.com/TryGhost/Ghost/pull/28376/changes?w=1
fixes https://linear.app/ghost/issue/ONC-1812/oss-issue-site-favicons-not-showing-inside-ghost-admin

Moved the Ghost Admin favicons from apps/admin/public into apps/admin/src. This lets Vite process, hash, and rewrite the favicon URLs with the same path handling as the rest of the admin assets.
Fixes GHOST-FCP

Once update-check started firing at boot via scheduleBootJob, a
pre-existing latent failure surfaced: a model-layer SQL error from
posts.browse (errno 1054, wrapped by bookshelf-pagination as
BadRequestError 'Could not understand request.') tore out the entire
telemetry collection, the update-check request still went out with
an undefined body, and the failure showed up in Sentry with no
useful context.

The daily cron normally dodged this because the next_update_check
gate returns early on a settled site — the queries weren't being
exercised. forceUpdate at boot bypasses the gate, executing the
full check end-to-end, exposing the underlying bug.

Each telemetry source is now gathered independently. A failing call
logs and falls back to a sensible default (0 / empty string); the
rest of the data still ships and the check completes. The underlying
error is still surfaced via logging.error so the SQL issue can be
tracked down separately.

Added structured logs around the full check lifecycle so production
diagnostics aren't limited to error-level Sentry captures:

  update-check.check.start          — at the top of check()
  update-check.check.skipped-by-gate — when next_update_check defers
  update-check.telemetry.error      — per failing telemetry source
  update-check.request.start        — before HTTP request
  update-check.request.complete     — after HTTP request, with statusCode
  update-check.request.no-notifications — 404 short-circuit
  update-check.request.error        — HTTP failure
  update-check.response.received    — with notificationCount
  update-check.check.complete       — successful end-to-end
  update-check.error                — top-level check failure
ref https://linear.app/ghost/issue/BER-3281/remove-direct-replies-replies-fallback-in-comment-moderation-metrics

The direct replies count is now fully deployed, so the moderation metrics no longer need to read the legacy replies aggregate during rollout.
no ref

`pnpm reset:data` broke after #28388 converted the topological-sort
seeder utility to TypeScript.

The `generate-data`/`repl`/`timetravel` CLI commands run via bare `node
index.js`, which has no TypeScript resolution — unlike `pnpm dev`
(nodemon `--import=tsx`) or the production build (`tsc`). So
`require('./utils/topological-sort')` failed with `Cannot find module`.

These commands are dev/local-only, where tsx is always installed.
Registering the tsx CommonJS loader at the CLI dispatch point lets them
require `.ts` files regardless of how they're invoked, covering all
three `reset:data*` scripts and the VS Code task.
no ref

This is a test- and types-only change.

[`Promise.withResolvers`][0] is a helpful function that we were
rewriting ourselves. Let's not do that, and use the built-in.

[0]:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| caddy | final | digest | `86deaf5` → `77c07d5` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/28155) for more information.

---

### Configuration

📅 **Schedule**: (in timezone Etc/UTC)

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
- Between 11:00 PM and 11:59 PM, Monday through Friday (`* 23 * * 1-5`)
- Between 12:00 AM and 04:59 AM, Monday through Saturday (`* 0-4 * *
1-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
- Between 11:00 PM and 11:59 PM, Monday through Friday (`* 23 * * 1-5`)
- Between 12:00 AM and 04:59 AM, Monday through Saturday (`* 0-4 * *
1-6`)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTQuMiIsInVwZGF0ZWRJblZlciI6IjQzLjIxNC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: tryghost-renovate[bot] <269725441+tryghost-renovate[bot]@users.noreply.github.com>
Co-authored-by: Steve Larson <9larsons@gmail.com>
no ref

We previously had code like this:

```js
let foo;
if (condition) {
    foo = initializeFoo();
    // ...
}
```

But because that variable was never initialized outside the conditional,
we can simplify it to:

```js
if (condition) {
    const foo = initializeFoo();
    // ...
}
```

This also fixes a type error.
The previous PR collapsed updateCheckResponse's response-shape handling
down to {notifications: [...]} on the assumption the legacy bare-object
and bare-array branches were dead. They weren't — both update-check
services emit a single notification at the top level today, so the
collapse silently stopped any notification from ever reaching the DB.

Restored the polymorphic normalisation with three accepted shapes:
- Wrapped {notifications: [...]}
- Bare array
- Single notification with messages at the top level (the current
  contract)

Added tests that exercise each shape end-to-end through check() so a
future refactor can't strip a still-needed branch.
@pull pull Bot locked and limited conversation to collaborators Jun 8, 2026
@pull pull Bot added the ⤵️ pull label Jun 8, 2026
@pull pull Bot merged commit a1c2d30 into code:main Jun 8, 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