Skip to content

Sync with upstream Ghost v6.28.0#64

Open
madewithlove-machine-user wants to merge 540 commits intomainfrom
chore/sync-v6.28.0
Open

Sync with upstream Ghost v6.28.0#64
madewithlove-machine-user wants to merge 540 commits intomainfrom
chore/sync-v6.28.0

Conversation

@madewithlove-machine-user
Copy link
Copy Markdown

Syncing fork to upstream release v6.28.0.

github-actions bot and others added 30 commits March 27, 2026 15:17
ref https://linear.app/ghost/issue/DES-1321/update-shade-storybook

- Upgraded Shade Storybook to latest version so that we can utilize all the new features
ref https://linear.app/ghost/issue/BER-3337/

Pages fully migrated to React (settings, posts, stats, activitypub,
tags) no longer need Ember route handlers or AdminX wrapper components.
This removes them along with related controllers, templates, and tests,
and updates link-to helpers to use href-to for hash-based navigation
to the React app.
ref https://linear.app/ghost/issue/BER-3337/

With Ember routes removed, the browser handles hash navigation directly,
bypassing Ember's willTransition hooks. This adds a centralized
unsaved-changes service and trailing-hash initializer to intercept
hash changes and prompt for confirmation when there are unsaved changes
in the editor or other routes.
The members-forward feature needs comprehensive test coverage for
list rendering, search/filter, bulk actions, export, and saved views
)

ref https://linear.app/ghost/issue/BER-3334/

## What changed
- added first-class `ValueSource` support to `shade` filters, including
clearer loading states and load-more support for async option sources
- introduced composable filter-source factories in `posts` for remote,
local, hybrid, combined, and Ghost browse-backed value sources
- migrated the comments and members filters to field-owned value sources
and removed the old bespoke search hooks they depended on
- updated the label picker and label sources to preserve selected labels
during search, keep edit/delete flows working, and invalidate label
queries safely after mutations
- kept the analytics filters on the simpler static-options path while
restoring the loading bridge in `shade` so their UI behavior does not
regress
- added focused unit coverage for the `shade` filter path and the hybrid
value-source behavior

## Why
The old filter implementations duplicated the same search, hydration,
and loading logic across screens while still leaking those concerns into
the filter UI layer. This leaves the end state with one model: `shade`
owns transient search UI, each field owns its value lookup strategy,
small datasets can stay local, large datasets can stay remote or hybrid,
and the existing members/comments/label UX keeps working while the
remaining admin surfaces continue to converge.
…t#27004)

ref https://linear.app/ghost/issue/PLA-10/
- Migrated 7 deterministic publishing tests from
`ghost/core/test/e2e-browser/admin/publishing.spec.js` to the e2e suite
- Tests moved: publish only, publish+email, email only, delete saved
post, delete with unsaved changes, primary lexical editor, secondary
hidden lexical editor
- Extended `PostEditorPage` with publish flow close/delete methods,
`createDraft()` helper, and lexical editor locators
- Extended `PostPage` with `articleTitle` and `articleBody` locators
…st#26975)

closes
https://linear.app/ghost/issue/NY-1179/insert-default-email-design-settings-row

## Summary

Seeds a default row into the `email_design_settings` table. This row
will be referenced by all existing `automated_emails` rows when the FK
is added in a subsequent migration.

## Changes

- Added DML migration to insert a default `email_design_settings` row
with slug `default-automated-email`, using schema defaults for all
design columns. Idempotent — skips if the row already exists.
- Added `EmailDesignSetting` Bookshelf model (required by the fixture
system)
- Added fixture entry in `fixtures.json` so new databases created via
`knex-migrator init` also get the default row
- Updated fixtures integrity hash
ref
https://linear.app/ghost/issue/BER-3497/new-header-component-in-shade

- The current header component is broken in Shade, especially on mobile. This PR creates a new, cleaner version which will be migrated on all screens in separate PRs.
no issue

- the `feature.inAdminForward` getter was removed in cleanup but the
`ajax` service check was left in place causing a regression with the
banner display in development and continuous-delivery environments
- Admin is now always in "adminForward" so the check in the ajax service
to add the `X-Ghost-Version` header when not in "adminForward" no longer
makes sense
no issue

- the banner trigger was removed when running under the React Admin
shell but has re-surfaced unintentionally when related "dead" code was
cleaned up
- removed all version check/refresh banner related code from the Ember
Admin to prevent any further accidental triggers
ref https://linear.app/ghost/issue/BER-3453

When using multi-filter mode (allowMultiple), adding a second label filter
would update the existing filter instead of creating a new one. The
addFilterWithOption callback unconditionally checked for and updated
existing filters for the same field, which prevented stacking multiple
filters. Refactored addFilter and addFilterWithOption to only merge into
existing filters in single-filter mode, allowing multiple filters on the
same field to be combined with AND logic.
ref
https://linear.app/ghost/issue/BER-3470/member-list-fails-to-render-in-chrome-for-massive-member-counts

- Added a shared virtual list window for the large members, comments,
and tags tables so they stop expanding their rendered range
indefinitely. The lists now unlock additional rows in 1,000-item
increments through an explicit Load more action.
- Fixed the existing sticky header implementation 
- Reworked the column sizing 

<img width="1624" height="1060" alt="Screenshot 2026-03-31 at 14 07 13"
src="https://github.com/user-attachments/assets/cd6aa3d8-1c24-4e6f-a3ca-eab63abe8dfd"
/>

---------
closes
https://linear.app/ghost/issue/NY-1181/add-email-design-setting-permissions

Adds CRUD permissions for the new `email_design_setting` resource,
restricted to `Administrator` and `Admin Integration` roles.

**Changes:**
- Added database migration to create browse, read, edit, add, and
destroy permissions for `email_design_setting`
- Updated fixtures to include the new permissions and assign them to
Administrator and Admin Integration roles
- Updated fixtures hash in integrity test
…host#27008)

closes
https://linear.app/ghost/issue/NY-1180/add-email-design-setting-id-fk-to-automated-emails

## Summary

- Added nullable `email_design_setting_id` FK column to
`automated_emails` table
- Plan to backfill all existing `automated_emails` rows with the default
`email_design_settings` row, then make this column non-nullable in two
follow up migration PRs to come.

Stacked on TryGhost#27006
…yGhost#27022)

closes
https://linear.app/ghost/issue/NY-1184/backfill-the-email-design-setting-id-column-on-automated-emails-table

Stacked on TryGhost#27008

## Summary

- Added a backfill migration that sets `email_design_setting_id` to the
default email design setting (`default-automated-email` slug) for all
existing `automated_emails` rows
- Added an `onCreating` hook to the `AutomatedEmail` model that
auto-assigns the default email design setting when none is provided
- Added test fixtures for `EmailDesignSetting` and updated e2e API
snapshots
- Added unit tests for the `onCreating` behavior

## Test plan

- [x] Unit tests for `onCreating` hook (default assignment, custom ID
preserved, missing default throws)
- [x] Updated e2e API snapshots include `email_design_setting_id` in
responses
- [x] Backfill migration has reversible `down` function
…mated_emails` table (TryGhost#27033)

closes
https://linear.app/ghost/issue/NY-1185/drop-nullable-on-the-email-design-setting-id-column-on-automated

## Summary
- Changed `email_design_setting_id` column on `automated_emails` table
from nullable to non-nullable
- Added a database migration using `createDropNullableMigration` to
alter the column constraint
- Updated schema definition and schema integrity hash

This is the final step after backfilling existing rows in TryGhost#27022,
completing the column constraint tightening.

## Test plan
- [x] Schema integrity test updated with new hash
- [x] Run `yarn test:unit` in `ghost/core` to verify schema integrity
- [x] Run migration against a database with existing `automated_emails`
rows to confirm no errors
…nce tests (TryGhost#27034)

ref https://github.com/TryGhost/Ghost/actions/runs/23812667343/attempts/1

We had a flaky test. In general, these browser tests have been incredibly fussy. I'm going to look at shifting more of them into acceptance/component tests rather than E2E and pare E2E back to more of the 'core' workflow/validation.

- Refactored 4 visibility/access e2e tests to create posts via the Admin
API instead of driving the full admin UI (editor → settings sidebar →
dropdown → publish flow), eliminating the `waitForResponse`,
`waitForFunction`, and `clearVisibilityTiers` workarounds that were
causing CI flakiness
- Added `tiers` field to the e2e `Post` interface so the factory can
create posts with tier-based visibility directly
- Added Ember acceptance tests for the editor sidebar visibility
dropdown (members, paid, tiers selector appearance, API save
verification) to cover the UI interaction removed from e2e
- Kept the publish-flow e2e tests (publish-only, email-only, schedule,
update) as full UI flows since the modal interaction is what they test
…Ghost#27036)

ref https://linear.app/ghost/issue/PLA-10/

The test verifies that the post settings menu date-time-picker displays
the correct time when the site timezone changes. This is a client-side
formatting concern that doesn't need a full browser e2e test — Mirage
can mock the settings and post data directly - it likely never should've
been an e2e test.
…ryGhost#27037)

ref https://linear.app/ghost/issue/PLA-10/

The test verifies that the publish flow defaults to "Publish" (not "Publish and email") when newsletter defaults are set to "Usually nobody" — this is a client-side setting read that Mirage can mock directly.
ref https://linear.app/ghost/issue/PLA-10/
- Removes the entire `ghost/core/test/e2e-browser/` directory and all
associated infrastructure
- Removes the `job_browser-tests` CI workflow job (saves ~60min CI time
per run)
- Removes `@playwright/test` devDependency from ghost/core
- Removes `test:browser` scripts from root and ghost/core package.json
- Removes Playwright config, browser test runner script, and Nx browser
test targets
no issue

When seeder database timestamp strings were reparsed in non-UTC CI
environments, they could shift into the future and make Faker reject
inverted date ranges causing flaky CI failures. Parsing those values as
UTC and guarding the date range logic keeps the data generator test
stable across timezones.

## What this does
- parse seeder database timestamp strings as UTC instead of local time
- guard date generation against inverted ranges when referenced records
are at or after the current time
- add regression coverage for timezone parsing and date range handling

Example flaky runs:
https://github.com/TryGhost/Ghost/actions/runs/23592298819/job/68700344677?pr=26958
https://github.com/TryGhost/Ghost/actions/runs/23839885077/job/69492642560
ref https://linear.app/ghost/issue/ONC-1609/

- Promoted webhook delivery failure logs from `warn` to `error` level so
they surface in error-level monitoring
- Added structured `[WEBHOOK_DELIVERY_FAILURE]` prefix with `url`,
`status`, `error_code`, and `message` fields for easy SLO alerting
ref https://linear.app/ghost/issue/BER-3313/

Consolidates the Ghost-Release private repo into the Ghost monorepo.
The release orchestration (version bumping, theme updates, tag creation)
becomes scripts/release.js, triggered by a workflow_dispatch + scheduled
workflow in release.yml. Tag-triggered npm publishing via OIDC and
GitHub Release creation are absorbed into ci.yml, eliminating the
redundant full rebuild that Ghost-Release performed. The npm package
published to self-hosters is now the same artifact that CI tested.
ref https://linear.app/ghost/issue/BER-3408/design-clean-up

- There's been a lot of missing details in how the new members list
header worked, especially around responsiveness and other UI/UX details.
renovate bot and others added 28 commits April 9, 2026 14:59
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [fs-extra](https://redirect.github.com/jprichardson/node-fs-extra) |
[`11.3.0` →
`11.3.4`](https://renovatebot.com/diffs/npm/fs-extra/11.3.0/11.3.4) |
![age](https://developer.mend.io/api/mc/badges/age/npm/fs-extra/11.3.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fs-extra/11.3.0/11.3.4?slim=true)
|

---

### Release Notes

<details>
<summary>jprichardson/node-fs-extra (fs-extra)</summary>

###
[`v11.3.4`](https://redirect.github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1134--2026-03-03)

[Compare
Source](https://redirect.github.com/jprichardson/node-fs-extra/compare/11.3.3...11.3.4)

- Fix bug where calling `ensureSymlink`/`ensureSymlinkSync` with a
relative `srcPath` would fail if the symlink already existed
([#&TryGhost#8203;1038](https://redirect.github.com/jprichardson/node-fs-extra/issues/1038),
[#&TryGhost#8203;1064](https://redirect.github.com/jprichardson/node-fs-extra/pull/1064))

###
[`v11.3.3`](https://redirect.github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1133--2025-12-18)

[Compare
Source](https://redirect.github.com/jprichardson/node-fs-extra/compare/11.3.2...11.3.3)

- Fix copying symlink when destination is a symlink to the same target
([#&TryGhost#8203;1019](https://redirect.github.com/jprichardson/node-fs-extra/issues/1019),
[#&TryGhost#8203;1060](https://redirect.github.com/jprichardson/node-fs-extra/pull/1060))

###
[`v11.3.2`](https://redirect.github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1132--2025-09-15)

[Compare
Source](https://redirect.github.com/jprichardson/node-fs-extra/compare/11.3.1...11.3.2)

- Fix spurrious `UnhandledPromiseRejectionWarning` that could occur when
calling `.copy()` in some cases
([#&TryGhost#8203;1056](https://redirect.github.com/jprichardson/node-fs-extra/issues/1056),
[#&TryGhost#8203;1058](https://redirect.github.com/jprichardson/node-fs-extra/pull/1058))

###
[`v11.3.1`](https://redirect.github.com/jprichardson/node-fs-extra/blob/HEAD/CHANGELOG.md#1131--2025-08-05)

[Compare
Source](https://redirect.github.com/jprichardson/node-fs-extra/compare/11.3.0...11.3.1)

- Fix case where `move`/`moveSync` could incorrectly think files are
identical on Windows
([#&TryGhost#8203;1050](https://redirect.github.com/jprichardson/node-fs-extra/pull/1050))

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 these
updates again.

---

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

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [gscan](https://ghost.org/)
([source](https://redirect.github.com/TryGhost/gscan)) | [`5.4.0` →
`5.4.1`](https://renovatebot.com/diffs/npm/gscan/5.4.0/5.4.1) |
![age](https://developer.mend.io/api/mc/badges/age/npm/gscan/5.4.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/gscan/5.4.0/5.4.1?slim=true)
|

---

### Release Notes

<details>
<summary>TryGhost/gscan (gscan)</summary>

###
[`v5.4.1`](https://redirect.github.com/TryGhost/gscan/compare/v5.4.0...v5.4.1)

[Compare
Source](https://redirect.github.com/TryGhost/gscan/compare/v5.4.0...v5.4.1)

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [nwsapi](https://javascript.nwbox.com/nwsapi/)
([source](https://redirect.github.com/dperini/nwsapi)) | [`2.2.12` →
`2.2.23`](https://renovatebot.com/diffs/npm/nwsapi/2.2.12/2.2.23) |
![age](https://developer.mend.io/api/mc/badges/age/npm/nwsapi/2.2.23?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nwsapi/2.2.12/2.2.23?slim=true)
|

---

### Release Notes

<details>
<summary>dperini/nwsapi (nwsapi)</summary>

###
[`v2.2.23`](https://redirect.github.com/dperini/nwsapi/compare/4b06175e2c209b8c137f3dc1ed1b4748278b97f0...f1664d8d43e036e7d2bd1d179a5599863e25945d)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/4b06175e2c209b8c137f3dc1ed1b4748278b97f0...f1664d8d43e036e7d2bd1d179a5599863e25945d)

###
[`v2.2.22`](https://redirect.github.com/dperini/nwsapi/compare/47b31b7c559b3a1598a1584c8a57cf730d2ff88c...4b06175e2c209b8c137f3dc1ed1b4748278b97f0)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/47b31b7c559b3a1598a1584c8a57cf730d2ff88c...4b06175e2c209b8c137f3dc1ed1b4748278b97f0)

###
[`v2.2.21`](https://redirect.github.com/dperini/nwsapi/compare/10076e3987f7d754e5d694efd31ec713583827ef...47b31b7c559b3a1598a1584c8a57cf730d2ff88c)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/10076e3987f7d754e5d694efd31ec713583827ef...47b31b7c559b3a1598a1584c8a57cf730d2ff88c)

###
[`v2.2.20`](https://redirect.github.com/dperini/nwsapi/compare/300cbe2f625ef2217059e0d3df04dc6649a52037...10076e3987f7d754e5d694efd31ec713583827ef)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/300cbe2f625ef2217059e0d3df04dc6649a52037...10076e3987f7d754e5d694efd31ec713583827ef)

###
[`v2.2.19`](https://redirect.github.com/dperini/nwsapi/compare/f6f79df62eccece06c2ad0ac29d486e65c7e3bcc...300cbe2f625ef2217059e0d3df04dc6649a52037)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/f6f79df62eccece06c2ad0ac29d486e65c7e3bcc...300cbe2f625ef2217059e0d3df04dc6649a52037)

###
[`v2.2.18`](https://redirect.github.com/dperini/nwsapi/compare/37ad99b62941cc8421e682786a6118d774c2bfec...f6f79df62eccece06c2ad0ac29d486e65c7e3bcc)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/37ad99b62941cc8421e682786a6118d774c2bfec...f6f79df62eccece06c2ad0ac29d486e65c7e3bcc)

###
[`v2.2.16`](https://redirect.github.com/dperini/nwsapi/compare/ce1089c21c6c206b4951626ea5599f5ccece20a8...37ad99b62941cc8421e682786a6118d774c2bfec)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/ce1089c21c6c206b4951626ea5599f5ccece20a8...37ad99b62941cc8421e682786a6118d774c2bfec)

###
[`v2.2.15`](https://redirect.github.com/dperini/nwsapi/compare/3eedbf2dc3d0cd63a31962f18c76edebdb551c09...ce1089c21c6c206b4951626ea5599f5ccece20a8)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/3eedbf2dc3d0cd63a31962f18c76edebdb551c09...ce1089c21c6c206b4951626ea5599f5ccece20a8)

###
[`v2.2.14`](https://redirect.github.com/dperini/nwsapi/compare/ee69b43bfe979552161c4e4b7e73c7c70d2efc2b...3eedbf2dc3d0cd63a31962f18c76edebdb551c09)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/ee69b43bfe979552161c4e4b7e73c7c70d2efc2b...3eedbf2dc3d0cd63a31962f18c76edebdb551c09)

###
[`v2.2.13`](https://redirect.github.com/dperini/nwsapi/compare/088475fbbdefc9d10fbdd7f914d92bce96aa9d0f...ee69b43bfe979552161c4e4b7e73c7c70d2efc2b)

[Compare
Source](https://redirect.github.com/dperini/nwsapi/compare/088475fbbdefc9d10fbdd7f914d92bce96aa9d0f...ee69b43bfe979552161c4e4b7e73c7c70d2efc2b)

</details>

---

### Configuration

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

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, 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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [globals](https://redirect.github.com/sindresorhus/globals) |
[`16.5.0` →
`17.4.0`](https://renovatebot.com/diffs/npm/globals/16.5.0/17.4.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/globals/17.4.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/globals/16.5.0/17.4.0?slim=true)
|

---

### Release Notes

<details>
<summary>sindresorhus/globals (globals)</summary>

###
[`v17.4.0`](https://redirect.github.com/sindresorhus/globals/compare/v17.3.0...a9cfd7493fb701474d4dc946283c7b9d63d64134)

[Compare
Source](https://redirect.github.com/sindresorhus/globals/compare/v17.3.0...v17.4.0)

###
[`v17.3.0`](https://redirect.github.com/sindresorhus/globals/releases/tag/v17.3.0)

[Compare
Source](https://redirect.github.com/sindresorhus/globals/compare/v17.2.0...v17.3.0)

- Update globals (2026-02-01)
([#&TryGhost#8203;336](https://redirect.github.com/sindresorhus/globals/issues/336))
[`295fba9`](https://redirect.github.com/sindresorhus/globals/commit/295fba9)

***

###
[`v17.2.0`](https://redirect.github.com/sindresorhus/globals/releases/tag/v17.2.0)

[Compare
Source](https://redirect.github.com/sindresorhus/globals/compare/v17.1.0...v17.2.0)

- `jasmine`: Add `throwUnless` and `throwUnlessAsync` globals
([#&TryGhost#8203;335](https://redirect.github.com/sindresorhus/globals/issues/335))
[`97f23a7`](https://redirect.github.com/sindresorhus/globals/commit/97f23a7)

***

###
[`v17.1.0`](https://redirect.github.com/sindresorhus/globals/releases/tag/v17.1.0)

[Compare
Source](https://redirect.github.com/sindresorhus/globals/compare/v17.0.0...v17.1.0)

- Add `webpack` and `rspack` globals
([#&TryGhost#8203;333](https://redirect.github.com/sindresorhus/globals/issues/333))
[`65cae73`](https://redirect.github.com/sindresorhus/globals/commit/65cae73)

***

###
[`v17.0.0`](https://redirect.github.com/sindresorhus/globals/releases/tag/v17.0.0)

[Compare
Source](https://redirect.github.com/sindresorhus/globals/compare/v16.5.0...v17.0.0)

##### Breaking

- Split `audioWorklet` environment from `browser`
([#&TryGhost#8203;320](https://redirect.github.com/sindresorhus/globals/issues/320))
[`7bc293e`](https://redirect.github.com/sindresorhus/globals/commit/7bc293e)

##### Improvements

- Update globals
([#&TryGhost#8203;329](https://redirect.github.com/sindresorhus/globals/issues/329))
[`ebe1063`](https://redirect.github.com/sindresorhus/globals/commit/ebe1063)
- Get all browser globals from both `chrome` and `firefox`
([#&TryGhost#8203;321](https://redirect.github.com/sindresorhus/globals/issues/321))
[`59ceff8`](https://redirect.github.com/sindresorhus/globals/commit/59ceff8)
- Add `bunBuiltin` environment
([#&TryGhost#8203;324](https://redirect.github.com/sindresorhus/globals/issues/324))
[`1bc6e3b`](https://redirect.github.com/sindresorhus/globals/commit/1bc6e3b)
- Add `denoBuiltin` environment
([#&TryGhost#8203;324](https://redirect.github.com/sindresorhus/globals/issues/324))
[`1bc6e3b`](https://redirect.github.com/sindresorhus/globals/commit/1bc6e3b)
- Add `paintWorklet` environment
([#&TryGhost#8203;323](https://redirect.github.com/sindresorhus/globals/issues/323))
[`4b78f56`](https://redirect.github.com/sindresorhus/globals/commit/4b78f56)
- Add `sharedWorker` environment
([#&TryGhost#8203;322](https://redirect.github.com/sindresorhus/globals/issues/322))
[`4a02a85`](https://redirect.github.com/sindresorhus/globals/commit/4a02a85)

***

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
ref
https://linear.app/ghost/issue/FEA-480/native-share-buttons-with-link-based-referral-param-for-attribution

Adds the newsletter email Share action link (opens the Portal share
modal in browser) and related template/tests updates.

A follow-up PR will add the ability to toggle this setting on in
newsletters from the admin area (defaults to false)
TryGhost#27237

---------

Co-authored-by: Troy Ciesco <tmciesco@gmail.com>
…ost#27249)

closes  https://linear.app/tryghost/issue/NY-1213/

This field was overlooked in the initial implementation, but we do want
to include it as a customizable option for welcome emails. This PR is
just the minimal change to add the column to the `email_design_settings`
table; other changes to the frontend modal and the rendering are
forthcoming.
ref https://linear.app/ghost/issue/BER-3528

`gifts.expires_at` should always have a value set and never be `null`
…host#27253)

ref 25e1433

I found that my agent wouldn't use these utility functions by default. I
tweaked the instructions to better highlight that.
…#27304)

ref https://linear.app/ghost/issue/BER-3523

Added gift subscription notification columns to the `users` table so a
user can configure if they want to receive notifications for gift
subscription related actions (purchase, redemption)
…yGhost#27268)

closes https://linear.app/ghost/issue/NY-1214/

This wires up the welcome email renderer to conditionally include the
site's publication icon in the header. If the publication icon exists,
and the `show_header_icon` email design setting is enabled, it will
render the publication icon in the welcome emails.

This PR originally focused on updates to the renderer; for easier shipping, another PR was merged into it to add the toggle to the customize modal.
closes https://linear.app/ghost/issue/NY-1210/

- enabling design customization at GA would otherwise add publication
title and icon to existing welcome emails without user action
- limiting the data backfill to sites that already have welcome email
automations preserves current output for existing installs
- leaving new and not-yet-enabled sites on the default values keeps the
intended first-run behavior intact
…Ghost#27315)

closes https://linear.app/ghost/issue/NY-1218/

## What this changes

- fixed the welcome email customization modal so `Escape` no longer
bypasses the dirty-state flow
- kept Escape handling local to the welcome email UI instead of changing
shared Shade overlay behavior globally
- fixed nested color picker popovers so the first `Escape` closes the
picker without also opening the unsaved-changes dialog
- fixed nested font select menus so the first `Escape` closes the menu
without also opening the unsaved-changes dialog
- kept the confirmation dialog scoped so its own `Escape` handling does
not cascade back into the parent modal

## Why

The original bug was not limited to the top-level customize modal. The
same Escape propagation issue also showed up in nested portalled
controls inside the modal, which could still skip straight to the save
warning flow. This PR now covers the full interaction stack so `Escape`
always closes the topmost UI first.

## Testing

- added E2E coverage for the customize modal dirty-state Escape flow
- added E2E coverage for the color picker Escape flow
- added E2E coverage for the font select Escape flow
- ran `PLAYWRIGHT_HTML_OPEN=never yarn workspace @tryghost/e2e test
e2e/tests/admin/settings/member-welcome-emails.test.ts`
- ran `PLAYWRIGHT_HTML_OPEN=never yarn workspace @tryghost/e2e
test:single "Escape closes welcome email"`
closes https://linear.app/ghost/issue/ONC-1623/

When deep-linking to an admin route (e.g. `/ghost/#/tags`) while logged
out, the page rendered blank instead of showing the signin screen. This
was caused by the `react-fallback` catch-all route lacking the
authentication check that was previously on the now-removed Ember route
files.

- Added `react-fallback` route extending `AuthenticatedRoute` to enforce
signin for all React-rendered routes
- Persisted intended URL in `sessionStorage` before the auth redirect so
the user is returned to their original destination after signing in
(works for both React and Ember routes)
- Made `LoginPage.logout()` wait for the signin page to fully load
before resolving to avoid race conditions with subsequent navigations in
e2e tests
- Added e2e tests covering signin redirect for both React (`/tags`) and
Ember (`/posts`) routes
…ryGhost#27319)

When running e2e tests locally, the test report server runs
automatically if there were any failures instead of exiting cleanly.
This is especially annoying when agents run the e2e tests themselves, as
they will hang indefinitely on the command, not realizing that the tests
have already run.

This disables this behavior, so the e2e tests will exit cleanly even if
tests fail. The html report is still generated and can be opened
manually.
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [human-number](https://redirect.github.com/Kikobeats/human-number) |
[`2.0.9` →
`2.0.10`](https://renovatebot.com/diffs/npm/human-number/2.0.9/2.0.10) |
![age](https://developer.mend.io/api/mc/badges/age/npm/human-number/2.0.10?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/human-number/2.0.9/2.0.10?slim=true)
|

---

### Release Notes

<details>
<summary>Kikobeats/human-number (human-number)</summary>

###
[`v2.0.10`](https://redirect.github.com/Kikobeats/human-number/blob/HEAD/CHANGELOG.md#2010-2026-04-06)

[Compare
Source](https://redirect.github.com/Kikobeats/human-number/compare/v2.0.9...v2.0.10)

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
no refs

This is a test only change; there are no user-facing changes here.

## Summary

Consolidates welcome email E2E tests into a single file
(`member-welcome-emails.test.ts`) and rewrites the free welcome email
test suite as a 4-test sequential story, down from 7 redundant tests
plus 1 in `member-signup.test.ts`.

- **Moved** the welcome email delivery test from `member-signup.test.ts`
into `member-welcome-emails.test.ts`
- **Removed factory usage** — the welcome email record is now created by
the UI toggle, not seeded via API factory
- **Removed per-test isolation** in favor of per-file isolation, with
tests that build on shared state
- **Consolidated** 7 overlapping tests into 4 that cover the full
lifecycle: default off → enable and verify delivery → customize
subject/body and verify delivery → disable and verify no delivery
- **Removed** tests that were strictly weaker duplicates (API-only
assertions, separate reload-persistence checks)
- **Fixed** `EmailSearchOptions.timeoutMs` type to accept `null` for
non-waiting searches

### Tests removed and why

| Removed test | Reason |
|---|---|
| `received welcome email` (member-signup.test.ts) | Moved to welcome
emails test file |
| `can enable free welcome emails` | Subsumed by "sends welcome email
after enabling it" |
| `can edit free welcome email subject` | Subsumed by "delivers edited
subject and body" |
| `can disable free welcome emails` | Replaced by "disabling free
welcome email stops delivery" |
| `edited welcome email content persists after reload` | Email delivery
already proves persistence |
| `edited welcome email subject persists after reload` | Email delivery
already proves persistence |

## Test plan

- [x] All 13 tests in `member-welcome-emails.test.ts` pass
- [x] `yarn lint` passes (0 errors)
- [x] `yarn test:types` passes
## Summary
- add a narrow Renovate package rule for the `tinybirdco/tinybird-local`
Docker image
- allow those Docker digest PRs to use PR automerge once CI has passed
- keep the rule scoped to this single image rather than enabling Docker
automerge broadly

## Why this change
The `tinybirdco/tinybird-local` digest PR in TryGhost#27228 updates Ghost's
local analytics service image in CI and compose files. Like
`ghost/traffic-analytics`, it is an internal operational image update
that can safely use PR automerge once CI has passed.

---------

Co-authored-by: Chris Raible <chris@ghost.org>
…st#27329)

These tests have failed randomly a few times in PRs and on main - skipping them for now while working on a permanent fix.
…Ghost#27323)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| tinybirdco/tinybird-local | service | digest | `3bbfa58` → `2a8a6a3` |
| tinybirdco/tinybird-local |  | digest | `3bbfa58` → `2a8a6a3` |

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 these
updates again.

---

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

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [gscan](https://ghost.org/)
([source](https://redirect.github.com/TryGhost/gscan)) | [`5.4.1` →
`5.4.3`](https://renovatebot.com/diffs/npm/gscan/5.4.1/5.4.3) |
![age](https://developer.mend.io/api/mc/badges/age/npm/gscan/5.4.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/gscan/5.4.1/5.4.3?slim=true)
|

---

### Release Notes

<details>
<summary>TryGhost/gscan (gscan)</summary>

###
[`v5.4.3`](https://redirect.github.com/TryGhost/gscan/compare/v5.4.2...v5.4.3)

[Compare
Source](https://redirect.github.com/TryGhost/gscan/compare/v5.4.2...v5.4.3)

###
[`v5.4.2`](https://redirect.github.com/TryGhost/gscan/compare/v5.4.1...v5.4.2)

[Compare
Source](https://redirect.github.com/TryGhost/gscan/compare/v5.4.1...v5.4.2)

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[@aws-sdk/client-s3](https://redirect.github.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3)
([source](https://redirect.github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3))
| [`3.1024.0` →
`3.1025.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.1024.0/3.1025.0)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@aws-sdk%2fclient-s3/3.1025.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@aws-sdk%2fclient-s3/3.1024.0/3.1025.0?slim=true)
|

---

### Release Notes

<details>
<summary>aws/aws-sdk-js-v3 (@&TryGhost#8203;aws-sdk/client-s3)</summary>

###
[`v3.1025.0`](https://redirect.github.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#310250-2026-04-06)

[Compare
Source](https://redirect.github.com/aws/aws-sdk-js-v3/compare/v3.1024.0...v3.1025.0)

**Note:** Version bump only for package
[@&TryGhost#8203;aws-sdk/client-s3](https://redirect.github.com/aws-sdk/client-s3)

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
ref
https://linear.app/ghost/issue/BER-3489/ghost-admin-add-gifting-url-to-the-button-card-in-the-editor
ref
https://linear.app/ghost/issue/BER-3488/ghost-admin-add-gifting-url-to-the-cta-card-in-the-editor

- lets publishers promote the new gift subscription flow from posts and
emails via Button or CTA cards
- adds #/portal/gift to the link autocomplete alongside the other portal
links
- picked up automatically by all cards using the shared InputUrlSetting
(Button, CTA, Email CTA, Header, Product)
- gated behind the giftSubscriptions lab flag
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ghcr.io/astral-sh/uv](https://redirect.github.com/astral-sh/uv) |
final | patch | `0.11.5` → `0.11.6` |

---

### Release Notes

<details>
<summary>astral-sh/uv (ghcr.io/astral-sh/uv)</summary>

###
[`v0.11.6`](https://redirect.github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0116)

[Compare
Source](https://redirect.github.com/astral-sh/uv/compare/0.11.5...0.11.6)

Released on 2026-04-09.

##### Bug fixes

- Do not remove files outside the venv on uninstall
([#&TryGhost#8203;18942](https://redirect.github.com/astral-sh/uv/pull/18942))
- Validate and heal wheel `RECORD` during installation
([#&TryGhost#8203;18943](https://redirect.github.com/astral-sh/uv/pull/18943))
- Avoid `uv cache clean` errors due to Win32 path normalization
([#&TryGhost#8203;18856](https://redirect.github.com/astral-sh/uv/pull/18856))

</details>

---

### Configuration

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

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, 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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| python | stage | digest | `32919c1` → `eefe082` |

---

### Configuration

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

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, 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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://redirect.github.com/actions/checkout) |
action | pinDigest | → `de0fac2` |
| [node](https://redirect.github.com/nodejs/node) | final | pinDigest |
→ `8b1d14e` |
| [node](https://redirect.github.com/nodejs/node) | final | pinDigest |
→ `752ea8a` |

---

### Configuration

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

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

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

---

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

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@eslint/js](https://eslint.org)
([source](https://redirect.github.com/eslint/eslint/tree/HEAD/packages/js))
| [`9.37.0` →
`9.39.4`](https://renovatebot.com/diffs/npm/@eslint%2fjs/9.37.0/9.39.4)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@eslint%2fjs/9.39.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@eslint%2fjs/9.37.0/9.39.4?slim=true)
|
| [eslint](https://eslint.org)
([source](https://redirect.github.com/eslint/eslint)) | [`9.37.0` →
`9.39.4`](https://renovatebot.com/diffs/npm/eslint/9.37.0/9.39.4) |
![age](https://developer.mend.io/api/mc/badges/age/npm/eslint/9.39.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint/9.37.0/9.39.4?slim=true)
|

---

### Release Notes

<details>
<summary>eslint/eslint (@&TryGhost#8203;eslint/js)</summary>

###
[`v9.39.4`](https://redirect.github.com/eslint/eslint/compare/v9.39.3...71b2f6b628b76157b4a2a296cb969dc56abb296c)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.3...v9.39.4)

###
[`v9.39.3`](https://redirect.github.com/eslint/eslint/releases/tag/v9.39.3)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.2...v9.39.3)

#### Bug Fixes

-
[`791bf8d`](https://redirect.github.com/eslint/eslint/commit/791bf8d7e76ce7ab8c88cb8982658823da4eff27)
fix: restore TypeScript 4.0 compatibility in types
([#&TryGhost#8203;20504](https://redirect.github.com/eslint/eslint/issues/20504))
(sethamus)

#### Chores

-
[`8594a43`](https://redirect.github.com/eslint/eslint/commit/8594a436c22a0167fe3c2c4109bbdb04e519a014)
chore: upgrade
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js)@&#8203;9.39.3
([#&TryGhost#8203;20529](https://redirect.github.com/eslint/eslint/issues/20529))
(Milos Djermanovic)
-
[`9ceef92`](https://redirect.github.com/eslint/eslint/commit/9ceef92fbd3d1298d9a00483f86897834b88acac)
chore: package.json update for
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js) release
(Jenkins)
-
[`af498c6`](https://redirect.github.com/eslint/eslint/commit/af498c63b9ca065223a425a85afabdcc8451e69b)
chore: ignore `/docs/v9.x` in link checker
([#&TryGhost#8203;20453](https://redirect.github.com/eslint/eslint/issues/20453))
(Milos Djermanovic)

###
[`v9.39.2`](https://redirect.github.com/eslint/eslint/compare/v9.39.1...c43ce24ff0ce073ec4ad691cd5a50171dfe6cf1e)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.1...v9.39.2)

###
[`v9.39.1`](https://redirect.github.com/eslint/eslint/compare/v9.39.0...c7ebefc9eaf99b76b30b0d3cf9960807a47367c4)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.0...v9.39.1)

###
[`v9.39.0`](https://redirect.github.com/eslint/eslint/compare/v9.38.0...2375a6de8263393c129d41cac1b407b40111a73c)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.38.0...v9.39.0)

###
[`v9.38.0`](https://redirect.github.com/eslint/eslint/releases/tag/v9.38.0)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.37.0...v9.38.0)

##### Features

-
[`ce40f74`](https://redirect.github.com/eslint/eslint/commit/ce40f74efd45f66d9fbfc6f78ce622ee72008485)
feat: update `complexity` rule to only highlight function header
([#&TryGhost#8203;20048](https://redirect.github.com/eslint/eslint/issues/20048))
(Atul Nair)
-
[`e37e590`](https://redirect.github.com/eslint/eslint/commit/e37e590aae2a7fcca4d3a9adc1379ad466e5c5d1)
feat: correct `no-loss-of-precision` false positives with `e` notation
([#&TryGhost#8203;20187](https://redirect.github.com/eslint/eslint/issues/20187))
(Francesco Trotta)

##### Bug Fixes

-
[`50c3dfd`](https://redirect.github.com/eslint/eslint/commit/50c3dfd98065622765a51a8ddb1e70c44fc5a4cb)
fix: improve type support for isolated dependencies in pnpm
([#&TryGhost#8203;20201](https://redirect.github.com/eslint/eslint/issues/20201))
(Francesco Trotta)
-
[`a1f06a3`](https://redirect.github.com/eslint/eslint/commit/a1f06a350c4155c4dbf39bf932a38d71d70f1b65)
fix: correct SourceCode typings
([#&TryGhost#8203;20114](https://redirect.github.com/eslint/eslint/issues/20114))
(Pixel998)

##### Documentation

-
[`462675a`](https://redirect.github.com/eslint/eslint/commit/462675af8a811f9ca984efaedbdc5b46b13ced7a)
docs: improve web accessibility by hiding non-semantic character
([#&TryGhost#8203;20205](https://redirect.github.com/eslint/eslint/issues/20205))
(루밀LuMir)
-
[`c070e65`](https://redirect.github.com/eslint/eslint/commit/c070e65f6bb9e38d06a89ba2b3261781bec3d397)
docs: correct formatting in `no-irregular-whitespace` rule documentation
([#&TryGhost#8203;20203](https://redirect.github.com/eslint/eslint/issues/20203))
(루밀LuMir)
-
[`b39e71a`](https://redirect.github.com/eslint/eslint/commit/b39e71a2130ae1ea3fbc19b19f5b951eb625722a)
docs: Update README (GitHub Actions Bot)
-
[`cd39983`](https://redirect.github.com/eslint/eslint/commit/cd3998314876a4fad6463d9011bc73778ccc1fd9)
docs: move `custom-formatters` type descriptions to `nodejs-api`
([#&TryGhost#8203;20190](https://redirect.github.com/eslint/eslint/issues/20190))
(Percy Ma)

##### Chores

-
[`d17c795`](https://redirect.github.com/eslint/eslint/commit/d17c795bf1624e0604998482b98e6bb6bff39045)
chore: upgrade
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js)[@&#8203;9](https://redirect.github.com/9).38.0
([#&TryGhost#8203;20221](https://redirect.github.com/eslint/eslint/issues/20221))
(Milos Djermanovic)
-
[`25d0e33`](https://redirect.github.com/eslint/eslint/commit/25d0e33270e08baed09dbee2cdd56a8e5cd9da0f)
chore: package.json update for
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js) release
(Jenkins)
-
[`c82b5ef`](https://redirect.github.com/eslint/eslint/commit/c82b5efa1fc91900e029efa23e688fad67fc17fa)
refactor: Use types from
[@&TryGhost#8203;eslint/core](https://redirect.github.com/eslint/core)
([#&TryGhost#8203;20168](https://redirect.github.com/eslint/eslint/issues/20168))
(Nicholas C. Zakas)
-
[`ff31609`](https://redirect.github.com/eslint/eslint/commit/ff31609f195654d448954210ba4d31e921d463e8)
ci: add Node.js 25 to `ci.yml`
([#&TryGhost#8203;20220](https://redirect.github.com/eslint/eslint/issues/20220))
(루밀LuMir)
-
[`004577e`](https://redirect.github.com/eslint/eslint/commit/004577eda2f2f4b2829e0364f8b41893cebfc859)
ci: bump github/codeql-action from 3 to 4
([#&TryGhost#8203;20211](https://redirect.github.com/eslint/eslint/issues/20211))
(dependabot\[bot])
-
[`eac71fb`](https://redirect.github.com/eslint/eslint/commit/eac71fb77113de7bf199ff20c6ee44cefcb59848)
test: remove use of `nodejsScope` option of eslint-scope from tests
([#&TryGhost#8203;20206](https://redirect.github.com/eslint/eslint/issues/20206))
(Milos Djermanovic)
-
[`4168a18`](https://redirect.github.com/eslint/eslint/commit/4168a18b7efd8facbbd71cd44a62942a9f656a30)
chore: fix typo in legacy-eslint.js
([#&TryGhost#8203;20202](https://redirect.github.com/eslint/eslint/issues/20202))
(Sweta Tanwar)
-
[`205dbd2`](https://redirect.github.com/eslint/eslint/commit/205dbd2d9272e761574c478e3b0181f7b89ed0f6)
chore: fix typos
([#&TryGhost#8203;20200](https://redirect.github.com/eslint/eslint/issues/20200))
(ntnyq)
-
[`dbb200e`](https://redirect.github.com/eslint/eslint/commit/dbb200e3604e63bba23a18d40089ca44604835ed)
chore: use team member's username when name is not available in data
([#&TryGhost#8203;20194](https://redirect.github.com/eslint/eslint/issues/20194))
(Milos Djermanovic)
-
[`8962089`](https://redirect.github.com/eslint/eslint/commit/8962089edbd978b43513576387a134036b8e2d36)
chore: mark deprecated rules as available until v11.0.0
([#&TryGhost#8203;20184](https://redirect.github.com/eslint/eslint/issues/20184))
(Pixel998)

</details>

<details>
<summary>eslint/eslint (eslint)</summary>

###
[`v9.39.4`](https://redirect.github.com/eslint/eslint/releases/tag/v9.39.4)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.3...v9.39.4)

#### Bug Fixes

-
[`f18f6c8`](https://redirect.github.com/eslint/eslint/commit/f18f6c8ae92a1bcfc558f48c0bd863ea94067459)
fix: update dependency minimatch to ^3.1.5
([#&TryGhost#8203;20564](https://redirect.github.com/eslint/eslint/issues/20564))
(Milos Djermanovic)
-
[`a3c868f`](https://redirect.github.com/eslint/eslint/commit/a3c868f6ef103c1caff9d15f744f9ebd995e872f)
fix: update dependency
[@&TryGhost#8203;eslint/eslintrc](https://redirect.github.com/eslint/eslintrc)
to ^3.3.4
([#&TryGhost#8203;20554](https://redirect.github.com/eslint/eslint/issues/20554))
(Milos Djermanovic)
-
[`234d005`](https://redirect.github.com/eslint/eslint/commit/234d005da6cd3c924f359e3783fbf565a3c047c3)
fix: minimatch security vulnerability patch for v9.x
([#&TryGhost#8203;20549](https://redirect.github.com/eslint/eslint/issues/20549))
(Andrej Beles)
-
[`b1b37ee`](https://redirect.github.com/eslint/eslint/commit/b1b37eecaa033d2e390e1d8f1d6e68d0f5ff3a6a)
fix: update `ajv` to `6.14.0` to address security vulnerabilities
([#&TryGhost#8203;20538](https://redirect.github.com/eslint/eslint/issues/20538))
(루밀LuMir)

#### Documentation

-
[`4675152`](https://redirect.github.com/eslint/eslint/commit/46751526037682f8b42abcfb3e06d19213719347)
docs: add deprecation notice partial
([#&TryGhost#8203;20520](https://redirect.github.com/eslint/eslint/issues/20520))
(Milos Djermanovic)

#### Chores

-
[`b8b4eb1`](https://redirect.github.com/eslint/eslint/commit/b8b4eb15901c1bd6ef40d2589da4ae75795c0f6e)
chore: update dependencies for ESLint v9.39.4
([#&TryGhost#8203;20596](https://redirect.github.com/eslint/eslint/issues/20596))
(Francesco Trotta)
-
[`71b2f6b`](https://redirect.github.com/eslint/eslint/commit/71b2f6b628b76157b4a2a296cb969dc56abb296c)
chore: package.json update for
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js) release
(Jenkins)
-
[`1d16c2f`](https://redirect.github.com/eslint/eslint/commit/1d16c2fa3998440ae7b0f6e2612935bd6b0ded1d)
ci: pin Node.js 25.6.1
([#&TryGhost#8203;20563](https://redirect.github.com/eslint/eslint/issues/20563))
(Milos Djermanovic)

###
[`v9.39.3`](https://redirect.github.com/eslint/eslint/releases/tag/v9.39.3)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.2...v9.39.3)

#### Bug Fixes

-
[`791bf8d`](https://redirect.github.com/eslint/eslint/commit/791bf8d7e76ce7ab8c88cb8982658823da4eff27)
fix: restore TypeScript 4.0 compatibility in types
([#&TryGhost#8203;20504](https://redirect.github.com/eslint/eslint/issues/20504))
(sethamus)

#### Chores

-
[`8594a43`](https://redirect.github.com/eslint/eslint/commit/8594a436c22a0167fe3c2c4109bbdb04e519a014)
chore: upgrade
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js)@&#8203;9.39.3
([#&TryGhost#8203;20529](https://redirect.github.com/eslint/eslint/issues/20529))
(Milos Djermanovic)
-
[`9ceef92`](https://redirect.github.com/eslint/eslint/commit/9ceef92fbd3d1298d9a00483f86897834b88acac)
chore: package.json update for
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js) release
(Jenkins)
-
[`af498c6`](https://redirect.github.com/eslint/eslint/commit/af498c63b9ca065223a425a85afabdcc8451e69b)
chore: ignore `/docs/v9.x` in link checker
([#&TryGhost#8203;20453](https://redirect.github.com/eslint/eslint/issues/20453))
(Milos Djermanovic)

###
[`v9.39.2`](https://redirect.github.com/eslint/eslint/compare/v9.39.1...9278324aa0023d223874825b0d4b6ac75783096a)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.1...v9.39.2)

###
[`v9.39.1`](https://redirect.github.com/eslint/eslint/compare/v9.39.0...e2772811a8595d161870835ff04822b25a2cdf45)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.39.0...v9.39.1)

###
[`v9.39.0`](https://redirect.github.com/eslint/eslint/compare/v9.38.0...ac3a60dffc29d8d4d5031621bc062e77f891532a)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.38.0...v9.39.0)

###
[`v9.38.0`](https://redirect.github.com/eslint/eslint/releases/tag/v9.38.0)

[Compare
Source](https://redirect.github.com/eslint/eslint/compare/v9.37.0...v9.38.0)

#### Features

-
[`ce40f74`](https://redirect.github.com/eslint/eslint/commit/ce40f74efd45f66d9fbfc6f78ce622ee72008485)
feat: update `complexity` rule to only highlight function header
([#&TryGhost#8203;20048](https://redirect.github.com/eslint/eslint/issues/20048))
(Atul Nair)
-
[`e37e590`](https://redirect.github.com/eslint/eslint/commit/e37e590aae2a7fcca4d3a9adc1379ad466e5c5d1)
feat: correct `no-loss-of-precision` false positives with `e` notation
([#&TryGhost#8203;20187](https://redirect.github.com/eslint/eslint/issues/20187))
(Francesco Trotta)

#### Bug Fixes

-
[`50c3dfd`](https://redirect.github.com/eslint/eslint/commit/50c3dfd98065622765a51a8ddb1e70c44fc5a4cb)
fix: improve type support for isolated dependencies in pnpm
([#&TryGhost#8203;20201](https://redirect.github.com/eslint/eslint/issues/20201))
(Francesco Trotta)
-
[`a1f06a3`](https://redirect.github.com/eslint/eslint/commit/a1f06a350c4155c4dbf39bf932a38d71d70f1b65)
fix: correct SourceCode typings
([#&TryGhost#8203;20114](https://redirect.github.com/eslint/eslint/issues/20114))
(Pixel998)

#### Documentation

-
[`462675a`](https://redirect.github.com/eslint/eslint/commit/462675af8a811f9ca984efaedbdc5b46b13ced7a)
docs: improve web accessibility by hiding non-semantic character
([#&TryGhost#8203;20205](https://redirect.github.com/eslint/eslint/issues/20205))
(루밀LuMir)
-
[`c070e65`](https://redirect.github.com/eslint/eslint/commit/c070e65f6bb9e38d06a89ba2b3261781bec3d397)
docs: correct formatting in `no-irregular-whitespace` rule documentation
([#&TryGhost#8203;20203](https://redirect.github.com/eslint/eslint/issues/20203))
(루밀LuMir)
-
[`b39e71a`](https://redirect.github.com/eslint/eslint/commit/b39e71a2130ae1ea3fbc19b19f5b951eb625722a)
docs: Update README (GitHub Actions Bot)
-
[`cd39983`](https://redirect.github.com/eslint/eslint/commit/cd3998314876a4fad6463d9011bc73778ccc1fd9)
docs: move `custom-formatters` type descriptions to `nodejs-api`
([#&TryGhost#8203;20190](https://redirect.github.com/eslint/eslint/issues/20190))
(Percy Ma)

#### Chores

-
[`d17c795`](https://redirect.github.com/eslint/eslint/commit/d17c795bf1624e0604998482b98e6bb6bff39045)
chore: upgrade
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js)@&#8203;9.38.0
([#&TryGhost#8203;20221](https://redirect.github.com/eslint/eslint/issues/20221))
(Milos Djermanovic)
-
[`25d0e33`](https://redirect.github.com/eslint/eslint/commit/25d0e33270e08baed09dbee2cdd56a8e5cd9da0f)
chore: package.json update for
[@&TryGhost#8203;eslint/js](https://redirect.github.com/eslint/js) release
(Jenkins)
-
[`c82b5ef`](https://redirect.github.com/eslint/eslint/commit/c82b5efa1fc91900e029efa23e688fad67fc17fa)
refactor: Use types from
[@&TryGhost#8203;eslint/core](https://redirect.github.com/eslint/core)
([#&TryGhost#8203;20168](https://redirect.github.com/eslint/eslint/issues/20168))
(Nicholas C. Zakas)
-
[`ff31609`](https://redirect.github.com/eslint/eslint/commit/ff31609f195654d448954210ba4d31e921d463e8)
ci: add Node.js 25 to `ci.yml`
([#&TryGhost#8203;20220](https://redirect.github.com/eslint/eslint/issues/20220))
(루밀LuMir)
-
[`004577e`](https://redirect.github.com/eslint/eslint/commit/004577eda2f2f4b2829e0364f8b41893cebfc859)
ci: bump github/codeql-action from 3 to 4
([#&TryGhost#8203;20211](https://redirect.github.com/eslint/eslint/issues/20211))
(dependabot\[bot])
-
[`eac71fb`](https://redirect.github.com/eslint/eslint/commit/eac71fb77113de7bf199ff20c6ee44cefcb59848)
test: remove use of `nodejsScope` option of eslint-scope from tests
([#&TryGhost#8203;20206](https://redirect.github.com/eslint/eslint/issues/20206))
(Milos Djermanovic)
-
[`4168a18`](https://redirect.github.com/eslint/eslint/commit/4168a18b7efd8facbbd71cd44a62942a9f656a30)
chore: fix typo in legacy-eslint.js
([#&TryGhost#8203;20202](https://redirect.github.com/eslint/eslint/issues/20202))
(Sweta Tanwar)
-
[`205dbd2`](https://redirect.github.com/eslint/eslint/commit/205dbd2d9272e761574c478e3b0181f7b89ed0f6)
chore: fix typos
([#&TryGhost#8203;20200](https://redirect.github.com/eslint/eslint/issues/20200))
(ntnyq)
-
[`dbb200e`](https://redirect.github.com/eslint/eslint/commit/dbb200e3604e63bba23a18d40089ca44604835ed)
chore: use team member's username when name is not available in data
([#&TryGhost#8203;20194](https://redirect.github.com/eslint/eslint/issues/20194))
(Milos Djermanovic)
-
[`8962089`](https://redirect.github.com/eslint/eslint/commit/8962089edbd978b43513576387a134036b8e2d36)
chore: mark deprecated rules as available until v11.0.0
([#&TryGhost#8203;20184](https://redirect.github.com/eslint/eslint/issues/20184))
(Pixel998)

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 these
updates again.

---

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

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [husky](https://redirect.github.com/typicode/husky) | [`8.0.3` →
`9.1.7`](https://renovatebot.com/diffs/npm/husky/8.0.3/9.1.7) |
![age](https://developer.mend.io/api/mc/badges/age/npm/husky/9.1.7?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/husky/8.0.3/9.1.7?slim=true)
|

---

### Release Notes

<details>
<summary>typicode/husky (husky)</summary>

###
[`v9.1.7`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.7)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.6...v9.1.7)

#### What's Changed

- fix: add husky label to deprecated warning by
[@&TryGhost#8203;smackfu](https://redirect.github.com/smackfu) in
[#&TryGhost#8203;1538](https://redirect.github.com/typicode/husky/pull/1538)

#### New Contributors

- [@&TryGhost#8203;smackfu](https://redirect.github.com/smackfu) made their
first contribution in
[#&TryGhost#8203;1538](https://redirect.github.com/typicode/husky/pull/1538)

**Full Changelog**:
<typicode/husky@v9.1.6...v9.1.7>

###
[`v9.1.6`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.6)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.5...v9.1.6)

#### What's Changed

- Fix issue where example pre-commit file is generated incorrectly by
[@&TryGhost#8203;dexmlee](https://redirect.github.com/dexmlee) in
[#&TryGhost#8203;1519](https://redirect.github.com/typicode/husky/pull/1519)

#### New Contributors

- [@&TryGhost#8203;OlegKipchatov](https://redirect.github.com/OlegKipchatov)
made their first contribution in
[#&TryGhost#8203;1495](https://redirect.github.com/typicode/husky/pull/1495)
- [@&TryGhost#8203;Byron2016](https://redirect.github.com/Byron2016) made their
first contribution in
[#&TryGhost#8203;1499](https://redirect.github.com/typicode/husky/pull/1499)
- [@&TryGhost#8203;dexmlee](https://redirect.github.com/dexmlee) made their
first contribution in
[#&TryGhost#8203;1519](https://redirect.github.com/typicode/husky/pull/1519)

**Full Changelog**:
<typicode/husky@v9.1.5...v9.1.6>

###
[`v9.1.5`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.5)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.4...v9.1.5)

#### What's Changed

- fixes
[#&TryGhost#8203;1494](https://redirect.github.com/typicode/husky/issues/1494),
support `pre-merge-commit` hook by
[@&TryGhost#8203;RainMeoCat](https://redirect.github.com/RainMeoCat) in
[#&TryGhost#8203;1497](https://redirect.github.com/typicode/husky/pull/1497)

#### New Contributors

- [@&TryGhost#8203;RainMeoCat](https://redirect.github.com/RainMeoCat) made
their first contribution in
[#&TryGhost#8203;1497](https://redirect.github.com/typicode/husky/pull/1497)

**Full Changelog**:
<typicode/husky@v9.1.4...v9.1.5>

###
[`v9.1.4`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.4)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.3...v9.1.4)

- Improve deprecation notice

###
[`v9.1.3`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.3)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.2...v9.1.3)

- fix: better handle space in `PATH`

###
[`v9.1.2`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.2)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.1...v9.1.2)

Show a message instead of automatically removing deprecated code.

This only concerns projects that still have the following code in their
hooks:

```diff
- #!/usr/bin/env sh # <- This is deprecated, remove it
- . "$(dirname -- "$0")/_/husky.sh"  # <- This is deprecated, remove it

### Rest of your hook code
```

**Hooks with these lines will fail in `v10.0.0`**

###
[`v9.1.1`](https://redirect.github.com/typicode/husky/releases/tag/v9.1.1)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.1.0...v9.1.1)

<p>
<img
src="https://github.com/user-attachments/assets/72a03e68-e9c3-4644-94f9-d5ceb343aca5"
height="500px" alt="" />
</p>

*Super saiyan ~~god~~ dog! It's over 9.0.0!*

### What's new

You can now run package commands directly, no need for `npx` or
equivalents.
It makes writing hooks more intuitive and is also slightly faster 🐺⚡️

```diff

### .husky/pre-commit
- npx jest
+ jest # ~0.2s faster
```

A new recipe has been added to the docs. Lint staged files without
external dependencies (inspired by Prettier docs). Feel free to modify
it.

```shell

### .husky/pre-commit
prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown
git update-index --again
```

For more advanced use cases, see
[lint-staged](https://redirect.github.com/lint-staged/lint-staged).

### Fixes

- `bunx husky init` command
- Workaround for some hooks implementation on Windows

### Deprecations

- `#!/usr/bin/env sh` and `. "$(dirname -- "$0")/_/husky.sh"` are
deprecated. **`husky` command will automatically remove them, no action
required.**
- If you're having code in `~/.huskyrc` please move it to
`.config/husky/init.sh`

Support for these will be removed in v10.

### Friendly reminder

If Git hooks don't fit your workflow, you can disable Husky globally.
Just add `export HUSKY=0` to `.config/husky/init.sh`.

I've seen some confusion about this on X, so just a heads-up!

### Sponsoring

Husky is downloaded over 45M times per month and used by \~1.5M
projects. If your company wants to sponsor, you can do so here: [GitHub
Sponsors](https://redirect.github.com/sponsors/typicode).

**Have a nice summer ☀️ I'm open to new opportunities/consulting so feel
free to drop me a message 😉**

###
[`v9.1.0`](https://redirect.github.com/typicode/husky/compare/v9.0.11...v9.1.0)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.11...v9.1.0)

###
[`v9.0.11`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.11)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.10...v9.0.11)

- chore: update `package-lock.json` by
[@&TryGhost#8203;btea](https://redirect.github.com/btea) in
[#&TryGhost#8203;1383](https://redirect.github.com/typicode/husky/pull/1383)
- fix: `export HUSKY=0` in init (fixes
[#&TryGhost#8203;1393](https://redirect.github.com/typicode/husky/issues/1393))
by [@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1395](https://redirect.github.com/typicode/husky/pull/1395)

###
[`v9.0.10`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.10)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.9...v9.0.10)

- fix: rename index.d.ts to index.d.mts by
[@&TryGhost#8203;mrkjdy](https://redirect.github.com/mrkjdy) in
[#&TryGhost#8203;1379](https://redirect.github.com/typicode/husky/pull/1379)

###
[`v9.0.9`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.9)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.8...v9.0.9)

- refactor: rename files by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1378](https://redirect.github.com/typicode/husky/pull/1378)

###
[`v9.0.8`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.8)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.7...v9.0.8)

- docs: update index.md by
[@&TryGhost#8203;khaledYS](https://redirect.github.com/khaledYS) in
[#&TryGhost#8203;1369](https://redirect.github.com/typicode/husky/pull/1369)
- Fix tab detection on install command by
[@&TryGhost#8203;glensc](https://redirect.github.com/glensc) in
[#&TryGhost#8203;1376](https://redirect.github.com/typicode/husky/pull/1376)
- refactor: reduce file size by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1377](https://redirect.github.com/typicode/husky/pull/1377)

###
[`v9.0.7`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.7)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.6...v9.0.7)

- fix: typo and source `~/.huskyrc` correctly (compatibility with v8)
- docs: fix example by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1363](https://redirect.github.com/typicode/husky/pull/1363)

###
[`v9.0.6`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.6)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.5...v9.0.6)

- docs: add favicon by
[@&TryGhost#8203;rakleed](https://redirect.github.com/rakleed) in
[#&TryGhost#8203;1354](https://redirect.github.com/typicode/husky/pull/1354)
- chore: apply editorconfig to code only by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1355](https://redirect.github.com/typicode/husky/pull/1355)
- docs: update install script to mjs and fix CI checks by
[@&TryGhost#8203;starnayuta](https://redirect.github.com/starnayuta) in
[#&TryGhost#8203;1357](https://redirect.github.com/typicode/husky/pull/1357)
- Fix unbound variable by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1359](https://redirect.github.com/typicode/husky/pull/1359)

###
[`v9.0.5`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.5)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.4...v9.0.5)

- docs: update path to startup files by
[@&TryGhost#8203;ManuelRauber](https://redirect.github.com/ManuelRauber) in
[#&TryGhost#8203;1350](https://redirect.github.com/typicode/husky/pull/1350)
- fix: init error by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1353](https://redirect.github.com/typicode/husky/pull/1353)

###
[`v9.0.4`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.4)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.3...v9.0.4)

- fix: init create dir before by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1348](https://redirect.github.com/typicode/husky/pull/1348)
- refactor: simplify by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1349](https://redirect.github.com/typicode/husky/pull/1349)
- fix: init not working on pnpm
[#&TryGhost#8203;1334](https://redirect.github.com/typicode/husky/issues/1334)
by [@&TryGhost#8203;rozbo](https://redirect.github.com/rozbo) in
[#&TryGhost#8203;1347](https://redirect.github.com/typicode/husky/pull/1347)

###
[`v9.0.3`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.3)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.2...v9.0.3)

- docs: fix link by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1340](https://redirect.github.com/typicode/husky/pull/1340)
- chore: fix links in issue template by
[@&TryGhost#8203;julien-f](https://redirect.github.com/julien-f) in
[#&TryGhost#8203;1341](https://redirect.github.com/typicode/husky/pull/1341)
- fix: add scripts field if not present by
[@&TryGhost#8203;chalkygames123](https://redirect.github.com/chalkygames123) in
[#&TryGhost#8203;1338](https://redirect.github.com/typicode/husky/pull/1338)
- docs: changelog link by
[@&TryGhost#8203;typicode](https://redirect.github.com/typicode) in
[#&TryGhost#8203;1343](https://redirect.github.com/typicode/husky/pull/1343)
- fix: insert final newline by
[@&TryGhost#8203;chalkygames123](https://redirect.github.com/chalkygames123) in
[#&TryGhost#8203;1339](https://redirect.github.com/typicode/husky/pull/1339)
- fix: fix git hooks path on windows by
[@&TryGhost#8203;rozbo](https://redirect.github.com/rozbo) in
[#&TryGhost#8203;1346](https://redirect.github.com/typicode/husky/pull/1346)

###
[`v9.0.2`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.2)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v9.0.1...v9.0.2)

- fix: exit code by
[@&TryGhost#8203;gergelypap](https://redirect.github.com/gergelypap) in
[#&TryGhost#8203;1336](https://redirect.github.com/typicode/husky/pull/1336)
- docs: typo by
[@&TryGhost#8203;chalkygames123](https://redirect.github.com/chalkygames123) in
[#&TryGhost#8203;1337](https://redirect.github.com/typicode/husky/pull/1337)

###
[`v9.0.1`](https://redirect.github.com/typicode/husky/releases/tag/v9.0.1)

[Compare
Source](https://redirect.github.com/typicode/husky/compare/v8.0.3...v9.0.1)

<p align="center">
Kicking off the year with an exciting update!
</p>

<p align="center">
<img
src="https://github.com/typicode/husky/assets/5502029/457ab087-e935-4196-b99f-601ecf37f263"
height="400px" alt="" />
</p>

*Note: install using `husky@latest` to get the bug fixes that were
released after.*

#### Introducing `husky init`

##### v8

```shell
npm pkg set scripts.prepare="husky install"
npm run prepare
npx husky add .husky/pre-commit "npm test"
```

##### v9

Adding husky to a project is now easier than ever. It's just a single
line that does the same as above. No need to read the docs to get
started anymore.

```shell
npx husky init
```

#### Adding a New Hook

##### v8

```shell
npx husky add  .husky/pre-commit "npm test"
git add --chmod=+x .husky/pre-commit # On Windows
```

##### v9

Adding a hook is as simple as creating a file. This can be accomplished
using your favorite editor, a script or a basic `echo` command. For
example, on Linux/macOS:

```shell
echo "npm test" > .husky/pre-commit
```

#### Further Size Reduction

`v8` was already the most compact Git hooks manager at approximately
`6kB`.

`v9` takes this a step further, reducing the size to just `3kB`, likely
making it the smallest devDependency in your toolkit.

**To give you an idea of how small it is, the biggest file in the
project is the MIT license 😄**

#### More to Come

Additional features are in the pipeline for `v9`. Stay tuned
:raised\_hands:

#### Other Changes

- **Enhanced security** with CI and npm `--provenance` for safer
publishing.
- Added **`$XDG_CONFIG_HOME`** support. Move `~/.huskyrc` to
`~/.config/husky/init.sh` for centralized configuration.
- **Fixed permission issue for Windows-created hooks**; they no longer
need to be executable.
- Removed `husky install`. Use `husky` or `husky some/dir` for the same
functionality (deprecation notice to be added).
- Modified behavior when `.git` is missing; it now triggers a warning
instead of failure.
- Replaced `HUSKY_DEBUG=1` with `HUSKY=2` for debugging.
- Updated the Husky API for module usage.
- Transitioned to `ESM` for module usage.
- Dropped support for Node 14 and 16.
- Revamped docs.

#### How to Migrate

`v9` is backward compatible with `v8`, allowing you to freely upgrade
and migrate your hooks later.

Here are the steps to migrate:

`package.json`

```diff
{
  "scripts": {
-   "prepare": "husky install"
+   "prepare": "husky"
  }
}
```

`.husky/pre-commit`

```diff
- #!/usr/bin/env sh
- . "$(dirname -- "$0")/_/husky.sh"
npm test 
```

*Note: `sh` will be used to run hooks, even if a shebang is set.*

If you were using `husky` as a module:

```diff
- const husky = require('husky')
- // ...
+ import husky from 'husky'
+ console.log(husky())
```

</details>

---

### Configuration

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

- Branch creation
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 09:00 PM and 11:59 PM, Monday through Friday (`* 21-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-6`)
- Automerge
  - Only on Sunday and Saturday (`* * * * 0,6`)
  - Between 12:00 AM and 12:59 PM, only on Monday (`* 0-12 * * 1`)
- Between 10:00 PM and 11:59 PM, Monday through Friday (`* 22-23 * *
1-5`)
- Between 12:00 AM and 04:59 AM, Tuesday through Saturday (`* 0-4 * *
2-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 was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/TryGhost/Ghost).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.