Wagtail 7.4 LTS maintenance - #921
Conversation
- Raise minimum Wagtail to 7.0 (6.3 LTS reached EOL 2026-05-01). - Add Wagtail 7.1, 7.3 and 7.4 (LTS) to the tox matrix; add Django 5.1. - Update classifiers: drop "Framework :: Wagtail :: 6", add "Framework :: Django :: 6.0". - Remove stale WAGTAIL_VERSION / DJANGO_VERSION compatibility guards that targeted versions outside the supported range. - Update README "Requirements" section and add a CHANGELOG entry under Unreleased. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wagtail 7.1 is not in the Wagtail support window (only 7.0 LTS, 7.2, 7.3 and 7.4 LTS are currently supported). 7.2 has just exited active support but remains kept for the current release cycle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- mkdocs: pin 1.4.3 -> >=1.6,<2 (current series). - mkdocs-material: minimum bumped to 9.5. - mkdocstrings[python]: 0.22.0 -> >=0.26 (1.x now available). - mkdocs-autorefs: 0.4.x -> >=1.0,<2. - mkdocs-include-markdown-plugin: 4.x -> >=7.0,<8. - pygments: drop unnecessary <2.16 cap. - dj-database-url: allow <4 (currently 3.x). - django-rq: allow <5 (currently 4.x). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- pre-commit-hooks: v5.0.0 -> v6.0.0. - ruff-pre-commit: v0.11.8 -> v0.15.12; rename the `ruff` hook to `ruff-check` (the new canonical id; `ruff` is now a legacy alias). - mirrors-eslint: v8.1.0 -> v10.3.0. Additional dependencies are kept pinned to the existing versions because they track the Node admin bundle, which will be updated separately. - Sync `.github/workflows/ruff.yml` to ruff 0.15.12. `mirrors-prettier` is left at v2.7.1: the upstream mirror is archived and the only newer rev is `v4.0.0-alpha.8`, which would reformat the codebase wholesale and pull in a Prettier alpha. The prettier migration will be handled in a dedicated commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- actions/checkout: v4 -> v6 - actions/setup-python: v5 -> v6 - actions/setup-node: v4 -> v6 - actions/upload-artifact: v4 -> v7 - actions/download-artifact: v4 -> v8 - codecov/codecov-action: v4 -> v6 The artifact action major bumps change the underlying Node runtime required on self-hosted runners; GitHub-hosted runners pick this up automatically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- webpack: 4 -> 5; webpack-cli: 3 -> 5.
- typescript: 3.9 -> 5; tsconfig adds target/module/moduleResolution
('bundler') / skipLibCheck for TS 5 compatibility.
- ts-loader: 6 -> 9.
- css-loader: 2 -> 7; style-loader: 0.23 -> 4.
- copy-webpack-plugin: 6 -> 13.
- @svgr/webpack: 5 -> 8.
- gettext-extractor: 3.5 -> 3.8.
- Drop `file-loader`; replace with webpack 5 native `asset/resource`
module type in webpack.config.js.
- @types/react / @types/react-dom: bump to latest 16.x patch.
- .nvmrc: 14 -> 22.
- Regenerate package-lock.json (lockfileVersion 1 -> 3).
React / react-dom / styled-components are intentionally left at 16.x /
5.x: bumping React types to 18 surfaces a known incompatibility with
@types/styled-components 5, which in turn requires a styled-components
6 migration. That migration is deferred to a dedicated change.
Verified `npm run build` produces the expected bundles
(wagtail-localize.js, wagtail-localize-component-form.js, CSS files
copied).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The envlist uses the factor `postgres15` (matching the postgres version in CI), but `[gh-actions:env]` mapped `DATABASE=postgres` to the non-existent factor `postgres`. As a result every postgres job in GitHub Actions fell back to tox's default `py` env, which neither pins Django nor Wagtail, instead of running the intended matrix entries. Map `postgres` to `postgres15` so the matrix entries are selected as designed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`Translation.save_target()` was raising `IntegrityError` on the `(translation_key, locale_id)` unique constraint whenever a snippet being translated contained a `ClusterableModel` child whose own children were also `TranslatableMixin` (e.g. a `Header` snippet with `NavigationLink` children that each have `SubNavigationLink` grandchildren). Wagtail's `CopyForTranslationAction._copy_for_translation` only sets the target locale on the entries it sees in the top-level `child_object_map`. When a direct child is itself a `ClusterableModel`, modelcluster recursively copies the cluster via `copy_cluster()` and the inner `child_object_map` is discarded. The grandchildren therefore keep the source locale; on save, modelcluster commits them with the source `translation_key` paired with the source locale, colliding with the existing source rows. Walk the cluster after `copy_for_translation` returns and re-assign `.locale` on every nested `TranslatableMixin` descendant. The fixup is local to `create_or_update_translation` so it doesn't require changes in Wagtail core. The bug was not visible on the previous test matrix because the `SubNavigationLink` exercise only began to fail on Wagtail 7.3+; the matrix stopped at Wagtail 7.2 before this branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Django 4.2 LTS reached end of life in April 2026, so the matrix entry is now testing an unsupported runtime. Dropping it also removes the fallout from a regression in wagtail-modeladmin 2.3.0, which only breaks on Django <5.0 (`self.params = request.GET.dict()` followed by `params.lists()`), letting us keep `wagtail-modeladmin>=2.0,<3.0` without pinning. Changes: - pyproject.toml: bump `Django>=4.2` to `Django>=5.1`; drop the `Framework :: Django :: 4.2` classifier. - tox.ini: remove all `django4.2-*` envs from the matrix and the `django4.2: Django>=4.2,<5.0` factor dep. `[testenv:migrations]` now floors at `Django>=5.1,<5.2`. - wagtail_localize/modeladmin/views.py: inline the `DJANGO_VERSION >= (5, 0)` guard in `TranslatableIndexView.get_filters` (always-true under the new floor); drop the now-unused `DJANGO_VERSION` import. - README.md: drop `4.2` from the Django requirements line. - CHANGELOG.md (Unreleased): note the dropped Django 4.2 support and the new minimum Django version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| super().__init__() | ||
|
|
||
|
|
||
| def _set_locale_on_nested_translatable_children(instance, locale): |
There was a problem hiding this comment.
Just highlighting:
Upstream Wagtail fix for nested-cluster locale assignment in CopyForTranslationAction — should be filed against wagtail/wagtail so the workaround in models.py can eventually be retired.
In the PR summary above. Could it be related to wagtail/wagtail#14084
There was a problem hiding this comment.
@nickmoreton this should be a separate PR please. Has nothing to do with Wagtail 7.4 maintenance work
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #921 +/- ##
==========================================
+ Coverage 93.02% 93.04% +0.01%
==========================================
Files 47 47
Lines 4245 4242 -3
Branches 551 552 +1
==========================================
- Hits 3949 3947 -2
+ Misses 177 176 -1
Partials 119 119 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| ### Added | ||
|
|
||
| - Wagtail 7.3 and 7.4 (LTS) to the test matrix. | ||
| - Django 5.1 to the test matrix. | ||
|
|
||
| ### Changed | ||
|
|
||
| - Minimum supported Wagtail is now 7.0. | ||
| - Minimum supported Django is now 5.1. | ||
|
|
||
| ### Fixed | ||
|
|
||
| - `Translation.save_target()` no longer raises an `IntegrityError` on the `(translation_key, locale_id)` unique constraint when translating a snippet whose cluster contains nested `TranslatableMixin` grandchildren. Wagtail's `copy_for_translation` only re-locales the top level of the returned cluster, so the fixup is applied here as well. | ||
|
|
||
| ### Removed | ||
|
|
||
| - Support for Wagtail 6.3 (reached end of life on 2026-05-01). | ||
| - Support for Django 4.2 (reached end of life in April 2026). | ||
| - Stale `WAGTAIL_VERSION` and `DJANGO_VERSION` compatibility guards for versions outside the supported range. | ||
|
|
There was a problem hiding this comment.
Please reword in line with other comments on other repositories. tl;dr merge and make it human written
| dependencies = [ | ||
| "Django>=4.2", | ||
| "Wagtail>=6.3", | ||
| "Django>=5.1", |
There was a problem hiding this comment.
| "Django>=5.1", | |
| "Django>=5.2", |
| python{3.10,3.11,3.12,3.13}-django5.1-wagtail{7.0,7.2}-postgres15 | ||
| python{3.12,3.13,3.14}-django5.2-wagtail{7.2,7.3,7.4}-postgres15 | ||
| python{3.12,3.13,3.14}-django6.0-wagtail{7.2,7.3,7.4}-postgres15 | ||
| # note: we're running a subset of the test with sqlite | ||
| python3.11-django4.2-wagtail{6.3}-sqlite | ||
| python3.13-django5.2-wagtail{7.0}-sqlite | ||
| python3.14-django5.2-wagtail{7.2}-sqlite | ||
| python3.14-django6.0-wagtail{7.2}-sqlite | ||
| python3.11-django5.1-wagtail{7.0}-sqlite | ||
| python3.13-django5.2-wagtail{7.3}-sqlite | ||
| python3.14-django6.0-wagtail{7.4}-sqlite |
There was a problem hiding this comment.
Needs to be a bit simpler please.
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| # keep in sync with .github/workflows/ruff.yml | ||
| rev: 'v0.11.8' | ||
| rev: 'v0.15.12' |
Summary
WAGTAIL_VERSION/DJANGO_VERSIONcompatibility guards that no longer cover any supported version.Translation.save_target()that raisedIntegrityErroron(translation_key, locale_id)when translating snippets with nestedTranslatableMixincluster grandchildren. Wagtail'sCopyForTranslationActiononly re-locales the top tier of the returned cluster; the workaround walks the cluster aftercopy_for_translationand re-assigns the target locale on every nested descendant.ruff-checkid), GitHub Actions majors, and the Node build stack (webpack 5, TypeScript 5, dropfile-loaderin favour of webpack 5 asset modules).postgres → postgres15) so the matrix entries actually run instead of falling back to the defaultpyenv.Commits, in order:
dc3b7ccAdd Wagtail 7.4 LTS support, drop Wagtail 6.3f32bcd0Remove Wagtail 7.1 from the supported version range725ea4aUpdate Python documentation and testing dev dependenciesc24eb4fBump pre-commit hook versionsf17ed81Bump GitHub Actions to current majorsb5d5541Bump Node build tooling to webpack 5 / TypeScript 5410ff23Fix tox-gh-actions postgres env factor mapping5947e94Fix nested-cluster locale on snippet translation saveac77fdfDrop Django 4.2 supportDeliberately deferred
mirrors-prettierrev bump — the only newer rev isv4.0.0-alpha.8on an archived mirror; will be handled separately by switching torbubley/mirrors-prettier.@types/reactto 18 surfaces a known incompatibility with@types/styled-components@5; needs a dedicated styled-components 6 migration.additional_dependenciesare still pinned to ancient versions; tied to the React/styled-components migration above.CopyForTranslationAction— should be filed againstwagtail/wagtailso the workaround inmodels.pycan eventually be retired.Test plan
tox -e python3.13-django5.2-wagtail7.4-postgres15(primary new combination)tox -e python3.10-django5.1-wagtail7.0-postgres15(lower bound)tox -e python3.14-django6.0-wagtail7.4-postgres15(upper bound)tox -e wagtailmainpre-commit run --all-filesnpm ci && npm run build(webpack 5 bundle output sanity-checked)mkdocs build --strict(docs extras had several major bumps)🤖 Generated with Claude Code