feat(drupal): upgrade stuar.tc from Drupal 9.4 to Drupal 11#115
feat(drupal): upgrade stuar.tc from Drupal 9.4 to Drupal 11#115Decipher wants to merge 3 commits into
Conversation
📝 WalkthroughWalkthroughTargets Drupal 11 and PHP 8.3: DDEV and Composer configs updated, many Drupal config sync files revised (modules, fields, views, editor, sitemaps), ChangesDrupal 9 → 11 upgrade and config migration
sequenceDiagram
actor Dev as Developer
participant Composer as Composer
participant DDEV as DDEV
participant Drupal as Drupal
participant DB as Database
participant Config as Config Sync
Dev->>Composer: update composer.json (PHP ≥ 8.3, repos, patches)
Composer-->>Dev: install updated vendors
Dev->>DDEV: apply .ddev config (drupal11, php 8.3) and start
DDEV->>DB: provision MariaDB / run migrations
Dev->>Drupal: enable modules, run update.php
Dev->>Config: import config sync changes
Config->>Drupal: apply entity/display/form/view updates (remove field_display_title)
Drupal->>DB: schema updates and uninstall hooks
Drupal-->>Dev: run tests (Kernel + JSON:API) and verification
Estimated code review effort 🎯 4 (Complex) | ⏱️ ~65 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
drupal/config/sync/views.view.taxonomy_term.yml (1)
280-284:⚠️ Potential issue | 🔴 CriticalThe
rssview mode must be enabled and display configurations must be created for all node types.The RSS view mode definition exists but is disabled (status: false) and has no entity display configurations for article, event, or page node types. This breaks both the taxonomy term feed and frontpage feed displays. Either enable the view mode and configure displays for each node type that appears in feeds, or revert to using a functional view mode like
teaser.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@drupal/config/sync/views.view.taxonomy_term.yml` around lines 280 - 284, The RSS view mode referenced by row.type: node_rss and view_mode: rss is currently disabled and missing entity display configs; enable the rss view mode (set status: true for the rss view mode config) and create entity view displays for each node bundle used in feeds (article, event, page) by adding/creating the corresponding entity_view_display configs (e.g. entity_view_display.node.article.rss, entity_view_display.node.event.rss, entity_view_display.node.page.rss) with the desired field visibility/formatters; alternatively, if you prefer not to support a dedicated rss mode, change the view row.view_mode from rss to a functional mode like teaser and remove the missing rss display configs.
🧹 Nitpick comments (4)
drupal/config/sync/core.base_field_override.node.article.promote.yml (1)
12-12: ⚡ Quick winConsider adding a description for content editors.
The description field is empty. Adding a brief description would help content editors understand when to use the "Promoted to front page" option.
📝 Suggested description
-description: '' +description: 'Check this box to feature this article on the front page.'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@drupal/config/sync/core.base_field_override.node.article.promote.yml` at line 12, The YAML field "description" in core.base_field_override.node.article.promote.yml is empty; add a concise description for content editors explaining the "Promoted to front page" flag (e.g., when to toggle it and its effect) by editing the description key in that file (core.base_field_override.node.article.promote.yml -> description) to a short human-readable sentence so editors understand when to use this option.drupal/config/sync/core.base_field_override.node.event.promote.yml (1)
12-12: ⚡ Quick winConsider adding a description for content editors.
The description field is empty. Adding a brief description would help content editors understand when to use the "Promoted to front page" option for events.
📝 Suggested description
-description: '' +description: 'Check this box to feature this event on the front page.'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@drupal/config/sync/core.base_field_override.node.event.promote.yml` at line 12, Add a concise description to the empty description field for the "Promoted to front page" override so content editors know when to use it: update the description key in core.base_field_override.node.event.promote.yml (the YAML entry for the "Promoted to front page" field) with a short explanatory sentence such as when the option should be checked and its effect on event visibility.drupal/config/sync/views.settings.yml (1)
5-5: ⚡ Quick winUse an explicit plugin-id key for
jsonapi_viewsindisplay_extenders.Line 5 uses a numeric key (
0) while the existing entry is keyed by plugin id. Prefer a consistent keyed mapping to avoid config normalization drift.Proposed fix
display_extenders: simple_sitemap_display_extender: simple_sitemap_display_extender - 0: jsonapi_views + jsonapi_views: jsonapi_views🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@drupal/config/sync/views.settings.yml` at line 5, The display_extenders mapping uses a numeric key "0" for the jsonapi_views entry which breaks consistency; replace the numeric key with an explicit plugin-id key by changing the mapping to use "jsonapi_views:" (i.e., move the value under a key named jsonapi_views) so the display_extenders section lists entries by plugin id rather than numeric indices and avoid config normalization drift.nuxt/tests/jsonapi/article.test.js (1)
4-4: ⚡ Quick winConsider making certificate validation conditional on environment.
The HTTPS agent disables certificate validation, which is flagged by CodeQL as a security risk. While this is acceptable for local development with DDev's self-signed certificates, consider making it conditional:
🔒 Suggested improvement
-const agent = new https.Agent({ rejectUnauthorized: false }) +const agent = new https.Agent({ + rejectUnauthorized: process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0' +})This allows disabling validation explicitly via environment variable while defaulting to secure validation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@nuxt/tests/jsonapi/article.test.js` at line 4, The test currently creates an HTTPS agent with certificate validation disabled via "const agent = new https.Agent({ rejectUnauthorized: false })"; change this so rejectUnauthorized is conditional on an environment flag (e.g., process.env.DISABLE_CERT_VALIDATION === 'true' or NODE_ENV === 'test' && process.env.DISABLE_CERT_VALIDATION), defaulting to true (secure) otherwise; update the creation of the agent in the test to compute a boolean like disableValidationFromEnv and pass it as the rejectUnauthorized option so local dev can opt-out while CI and production remain secure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@drupal/config/sync/core.base_field_override.node.article.promote.yml`:
- Around line 15-17: The promote field for articles currently has default_value:
value: 1 but an empty description; update the core.base_field_override for the
"promote" field on node.article by either (A) leaving default_value as 1 and
adding a clear description like "When checked, this article is auto-promoted to
the front page by default" to the description key so editors understand the
behavior, or (B) if auto-promotion was unintentional, change default_value:
value from 1 to 0 and update the description accordingly; target the "promote"
field, the "default_value" key and the "description" key in the YAML.
In `@drupal/config/sync/editor.editor.formatted.yml`:
- Around line 19-21: The CKEditor5 plugin key is incorrect: replace the plugin
key "source_editing" with the CKEditor5 config schema key
"ckeditor5_sourceEditing" so the "allowed_tags" setting is applied; update the
plugins map entry (the "plugins" → "source_editing" node) to use
"ckeditor5_sourceEditing" while keeping "allowed_tags: ''" intact so the
configuration is recognized by Drupal.
In `@nuxt/jest.config.js`:
- Around line 23-24: The testPathIgnorePatterns override removed Jest's default
node_modules ignore and causes tests in dependencies to run; update the
testPathIgnorePatterns setting (near the testMatch configuration) to include the
default ignore (e.g., '/node_modules/') along with any custom patterns rather
than an empty array so Jest will skip node_modules while still applying your
custom patterns.
In `@wiki/upgrade-notes/drupal-11.md`:
- Around line 16-19: The markdown tables (e.g., the header row starting with "|
Module | From | To |" and the subsequent row containing "admin_toolbar") need
blank lines before and after them to satisfy MD058 linting; update the document
around each table (including the other table at the block around lines 46–49) by
inserting a single blank line immediately above the table header and one blank
line immediately after the table end so each table is separated from surrounding
text.
---
Outside diff comments:
In `@drupal/config/sync/views.view.taxonomy_term.yml`:
- Around line 280-284: The RSS view mode referenced by row.type: node_rss and
view_mode: rss is currently disabled and missing entity display configs; enable
the rss view mode (set status: true for the rss view mode config) and create
entity view displays for each node bundle used in feeds (article, event, page)
by adding/creating the corresponding entity_view_display configs (e.g.
entity_view_display.node.article.rss, entity_view_display.node.event.rss,
entity_view_display.node.page.rss) with the desired field visibility/formatters;
alternatively, if you prefer not to support a dedicated rss mode, change the
view row.view_mode from rss to a functional mode like teaser and remove the
missing rss display configs.
---
Nitpick comments:
In `@drupal/config/sync/core.base_field_override.node.article.promote.yml`:
- Line 12: The YAML field "description" in
core.base_field_override.node.article.promote.yml is empty; add a concise
description for content editors explaining the "Promoted to front page" flag
(e.g., when to toggle it and its effect) by editing the description key in that
file (core.base_field_override.node.article.promote.yml -> description) to a
short human-readable sentence so editors understand when to use this option.
In `@drupal/config/sync/core.base_field_override.node.event.promote.yml`:
- Line 12: Add a concise description to the empty description field for the
"Promoted to front page" override so content editors know when to use it: update
the description key in core.base_field_override.node.event.promote.yml (the YAML
entry for the "Promoted to front page" field) with a short explanatory sentence
such as when the option should be checked and its effect on event visibility.
In `@drupal/config/sync/views.settings.yml`:
- Line 5: The display_extenders mapping uses a numeric key "0" for the
jsonapi_views entry which breaks consistency; replace the numeric key with an
explicit plugin-id key by changing the mapping to use "jsonapi_views:" (i.e.,
move the value under a key named jsonapi_views) so the display_extenders section
lists entries by plugin id rather than numeric indices and avoid config
normalization drift.
In `@nuxt/tests/jsonapi/article.test.js`:
- Line 4: The test currently creates an HTTPS agent with certificate validation
disabled via "const agent = new https.Agent({ rejectUnauthorized: false })";
change this so rejectUnauthorized is conditional on an environment flag (e.g.,
process.env.DISABLE_CERT_VALIDATION === 'true' or NODE_ENV === 'test' &&
process.env.DISABLE_CERT_VALIDATION), defaulting to true (secure) otherwise;
update the creation of the agent in the test to compute a boolean like
disableValidationFromEnv and pass it as the rejectUnauthorized option so local
dev can opt-out while CI and production remain secure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3cfdf572-2ec7-477e-a0c2-2d95a0dfc867
⛔ Files ignored due to path filters (1)
drupal/composer.lockis excluded by!**/*.lock
📒 Files selected for processing (140)
AGENTS.mddrupal/.ddev/config.yamldrupal/composer.jsondrupal/config/sync/admin_toolbar.settings.ymldrupal/config/sync/admin_toolbar_tools.settings.ymldrupal/config/sync/block.block.mainnavigation.ymldrupal/config/sync/config_ignore.settings.ymldrupal/config/sync/config_pages.type.druxt_settings.ymldrupal/config/sync/content_lock.settings.ymldrupal/config/sync/content_lock_timeout.settings.ymldrupal/config/sync/core.base_field_override.node.article.promote.ymldrupal/config/sync/core.base_field_override.node.event.promote.ymldrupal/config/sync/core.entity_form_display.block_content.basic_block.default.ymldrupal/config/sync/core.entity_form_display.config_pages.druxt_settings.default.ymldrupal/config/sync/core.entity_form_display.node.article.default.ymldrupal/config/sync/core.entity_form_display.node.event.default.ymldrupal/config/sync/core.entity_form_display.node.page.default.ymldrupal/config/sync/core.entity_form_display.paragraph.from_library.default.ymldrupal/config/sync/core.entity_form_display.paragraph.repository.default.ymldrupal/config/sync/core.entity_view_display.block_content.basic_block.default.ymldrupal/config/sync/core.entity_view_display.config_pages.druxt_settings.default.ymldrupal/config/sync/core.entity_view_display.node.article.card.ymldrupal/config/sync/core.entity_view_display.node.article.default.ymldrupal/config/sync/core.entity_view_display.node.article.full.ymldrupal/config/sync/core.entity_view_display.node.article.teaser.ymldrupal/config/sync/core.entity_view_display.node.event.card.ymldrupal/config/sync/core.entity_view_display.node.event.default.ymldrupal/config/sync/core.entity_view_display.node.event.full.ymldrupal/config/sync/core.entity_view_display.node.event.teaser.ymldrupal/config/sync/core.entity_view_display.node.page.card.ymldrupal/config/sync/core.entity_view_display.node.page.default.ymldrupal/config/sync/core.entity_view_display.node.page.full.ymldrupal/config/sync/core.entity_view_display.node.page.landing.ymldrupal/config/sync/core.entity_view_display.node.page.teaser.ymldrupal/config/sync/core.entity_view_display.paragraph.from_library.default.ymldrupal/config/sync/core.entity_view_display.paragraph.repository.default.ymldrupal/config/sync/core.entity_view_display.paragraphs_library_item.paragraphs_library_item.summary.ymldrupal/config/sync/core.extension.ymldrupal/config/sync/decoupled_router.settings.ymldrupal/config/sync/diff.settings.ymldrupal/config/sync/editor.editor.formatted.ymldrupal/config/sync/entity_clone.cloneable_entities.ymldrupal/config/sync/entity_usage.settings.ymldrupal/config/sync/environment_indicator.settings.ymldrupal/config/sync/exclude_node_title.settings.ymldrupal/config/sync/field.field.media.image.field_media_caption.ymldrupal/config/sync/field.field.node.article.field_display_title.ymldrupal/config/sync/field.field.node.event.field_display_title.ymldrupal/config/sync/field.field.node.page.field_display_title.ymldrupal/config/sync/field.field.paragraph.card.field_link.ymldrupal/config/sync/field.field.paragraph.code.field_description.ymldrupal/config/sync/field.field.paragraph.link.field_link.ymldrupal/config/sync/field.field.paragraph.repository.field_description.ymldrupal/config/sync/field.field.paragraph.repository.field_url.ymldrupal/config/sync/field.field.paragraph.text_formatted.field_text_formatted.ymldrupal/config/sync/field.storage.block_content.field_display_title.ymldrupal/config/sync/field.storage.config_pages.field_site_name.ymldrupal/config/sync/field.storage.config_pages.field_social_drupal.ymldrupal/config/sync/field.storage.config_pages.field_social_github.ymldrupal/config/sync/field.storage.config_pages.field_social_gravatar.ymldrupal/config/sync/field.storage.config_pages.field_social_twitter.ymldrupal/config/sync/field.storage.node.field_display_title.ymldrupal/config/sync/linkyreplacer.settings.ymldrupal/config/sync/m4032404.settings.ymldrupal/config/sync/masquerade.settings.ymldrupal/config/sync/media_file_delete.settings.ymldrupal/config/sync/metatag.settings.ymldrupal/config/sync/paragraphs.paragraphs_type.card.ymldrupal/config/sync/paragraphs.paragraphs_type.code.ymldrupal/config/sync/paragraphs.paragraphs_type.from_library.ymldrupal/config/sync/paragraphs.paragraphs_type.jumbotron.ymldrupal/config/sync/paragraphs.paragraphs_type.link.ymldrupal/config/sync/paragraphs.paragraphs_type.repository.ymldrupal/config/sync/paragraphs.paragraphs_type.section.ymldrupal/config/sync/paragraphs.paragraphs_type.text_formatted.ymldrupal/config/sync/paragraphs_ee.paragraphs_category.basics.ymldrupal/config/sync/paragraphs_ee.paragraphs_category.wrappers.ymldrupal/config/sync/pathauto.pattern.menu_path_title.ymldrupal/config/sync/pathauto.pattern.type_title_date.ymldrupal/config/sync/simple_oauth.settings.ymldrupal/config/sync/simple_sitemap.sitemap.index.ymldrupal/config/sync/simple_sitemap.type.index.ymldrupal/config/sync/simple_sitemap_engines.simple_sitemap_engine.google.ymldrupal/config/sync/simple_sitemap_engines.simple_sitemap_engine.naver.ymldrupal/config/sync/simple_sitemap_engines.simple_sitemap_engine.seznam.ymldrupal/config/sync/simple_sitemap_engines.simple_sitemap_engine.yep.ymldrupal/config/sync/system.action.user_add_role_action.admin_content.ymldrupal/config/sync/system.action.user_add_role_action.author.ymldrupal/config/sync/system.action.user_remove_role_action.admin_content.ymldrupal/config/sync/system.action.user_remove_role_action.author.ymldrupal/config/sync/system.date.ymldrupal/config/sync/system.rss.ymldrupal/config/sync/user.role.admin_content.ymldrupal/config/sync/user.role.admin_developer.ymldrupal/config/sync/user.role.admin_users.ymldrupal/config/sync/user.role.anonymous.ymldrupal/config/sync/user.role.api_frontend.ymldrupal/config/sync/user.role.authenticated.ymldrupal/config/sync/user.role.author.ymldrupal/config/sync/views.settings.ymldrupal/config/sync/views.view.block_content.ymldrupal/config/sync/views.view.content.ymldrupal/config/sync/views.view.files.ymldrupal/config/sync/views.view.glossary.ymldrupal/config/sync/views.view.locked_content.ymldrupal/config/sync/views.view.managed_links.ymldrupal/config/sync/views.view.media.ymldrupal/config/sync/views.view.media_library.ymldrupal/config/sync/views.view.paragraphs_library.ymldrupal/config/sync/views.view.redirect.ymldrupal/config/sync/views.view.taxonomy_term.ymldrupal/config/sync/views.view.user_admin_people.ymldrupal/config/sync/views.view.watchdog.ymldrupal/config/sync/views.view.who_s_new.ymldrupal/config/sync/views.view.who_s_online.ymldrupal/content/meta/index.jsondrupal/content/node.3b8ab24d-8ebc-46f1-a1c1-f680fb9ee52f.jsondrupal/content/node.5e5812bb-7afe-4f4d-a2ac-c0c35115a96c.jsondrupal/content/node.642863be-342d-4467-acdf-2339f2fbfdd5.jsondrupal/content/node.bd41aa4c-8749-4634-aa1e-e65572a2b8f7.jsondrupal/content/path_alias.d396c674-d135-4a32-bd01-8b6600814919.jsondrupal/recipes/README.txtdrupal/web/.ht.router.phpdrupal/web/.htaccessdrupal/web/INSTALL.txtdrupal/web/autoload.phpdrupal/web/example.gitignoredrupal/web/modules/README.txtdrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/UriNormalizerKernelTest.phpdrupal/web/profiles/README.txtdrupal/web/sites/default/default.services.ymldrupal/web/sites/default/default.settings.phpdrupal/web/sites/development.services.ymldrupal/web/sites/example.settings.local.phpdrupal/web/sites/example.sites.phpdrupal/web/themes/README.txtnuxt/jest.config.jsnuxt/tests/jsonapi/article.test.jswiki/upgrade-notes/drupal-10.mdwiki/upgrade-notes/drupal-11.md
💤 Files with no reviewable changes (44)
- drupal/config/sync/core.entity_view_display.node.page.card.yml
- drupal/config/sync/paragraphs.paragraphs_type.card.yml
- drupal/config/sync/user.role.admin_content.yml
- drupal/config/sync/content_lock_timeout.settings.yml
- drupal/config/sync/system.rss.yml
- drupal/config/sync/user.role.author.yml
- drupal/config/sync/field.field.node.page.field_display_title.yml
- drupal/config/sync/system.action.user_add_role_action.author.yml
- drupal/config/sync/paragraphs.paragraphs_type.section.yml
- drupal/config/sync/paragraphs.paragraphs_type.repository.yml
- drupal/content/node.bd41aa4c-8749-4634-aa1e-e65572a2b8f7.json
- drupal/config/sync/system.action.user_remove_role_action.author.yml
- drupal/config/sync/system.action.user_remove_role_action.admin_content.yml
- drupal/config/sync/field.field.node.event.field_display_title.yml
- drupal/config/sync/field.field.node.article.field_display_title.yml
- drupal/config/sync/paragraphs.paragraphs_type.jumbotron.yml
- drupal/config/sync/core.entity_view_display.node.page.landing.yml
- drupal/config/sync/admin_toolbar_tools.settings.yml
- drupal/config/sync/core.entity_view_display.node.event.teaser.yml
- drupal/content/node.642863be-342d-4467-acdf-2339f2fbfdd5.json
- drupal/web/autoload.php
- drupal/config/sync/simple_sitemap_engines.simple_sitemap_engine.google.yml
- drupal/config/sync/user.role.authenticated.yml
- drupal/config/sync/exclude_node_title.settings.yml
- drupal/content/node.5e5812bb-7afe-4f4d-a2ac-c0c35115a96c.json
- drupal/config/sync/core.entity_view_display.node.article.full.yml
- drupal/config/sync/system.action.user_add_role_action.admin_content.yml
- drupal/config/sync/core.entity_view_display.node.page.default.yml
- drupal/config/sync/core.entity_view_display.node.page.teaser.yml
- drupal/config/sync/paragraphs.paragraphs_type.text_formatted.yml
- drupal/config/sync/field.storage.node.field_display_title.yml
- drupal/config/sync/paragraphs.paragraphs_type.link.yml
- drupal/config/sync/paragraphs.paragraphs_type.code.yml
- drupal/config/sync/user.role.api_frontend.yml
- drupal/config/sync/core.entity_view_display.node.event.card.yml
- drupal/config/sync/core.entity_view_display.node.page.full.yml
- drupal/config/sync/core.entity_view_display.node.event.default.yml
- drupal/content/node.3b8ab24d-8ebc-46f1-a1c1-f680fb9ee52f.json
- drupal/config/sync/user.role.admin_developer.yml
- drupal/config/sync/core.entity_view_display.node.article.card.yml
- drupal/config/sync/core.entity_view_display.node.article.teaser.yml
- drupal/config/sync/core.entity_view_display.node.event.full.yml
- drupal/config/sync/user.role.anonymous.yml
- drupal/config/sync/core.entity_view_display.node.article.default.yml
| plugins: | ||
| source_editing: | ||
| allowed_tags: '' |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For Drupal 11 editor.editor.*.ymlconfig, what is the correctsettings.pluginskey for Source Editing:source_editingorckeditor5_sourceEditing?
💡 Result:
Correct key: ckeditor5_sourceEditing. In Drupal’s CKEditor 5 editor settings, the “Source editing” plugin configuration is stored under the Drupal plugin settings entry name ckeditor5_sourceEditing (not settings.plugins.source_editing). This is reflected by the CKEditor 5 module’s configuration file for the Source Editing feature, where the editor’s ckeditor5_sourceEditing configuration is defined, including the plugin list under drupal: label/class/library/toolbar items, and the settings schema uses the ckeditor5_sourceEditing plugin id mapping. [1][2] So in Drupal 11 editor.editor.*.yml, under settings.plugins you should use: - settings: plugins: ckeditor5_sourceEditing: … (If you instead use source_editing, it will not match the CKEditor 5 module’s defined configurable plugin id for source editing.) [2][3]
Citations:
- 1: https://api.druphelp.com/api/drupal/core%21modules%21ckeditor5%21ckeditor5.ckeditor5.yml/10
- 2: https://api.druphelp.com/api/drupal/core%21modules%21ckeditor5%21config%21schema%21ckeditor5.schema.yml/10
- 3: https://api.drupal.org/api/drupal/core%21modules%21ckeditor5%21tests%21src%21FunctionalJavascript%21SourceEditingTest.php/11.x
Use the Drupal CKEditor5 plugin key expected by config schema.
Line 20 uses source_editing, but Drupal CKEditor5 config expects the Source Editing plugin under ckeditor5_sourceEditing. With the current key, allowed_tags will not be applied and the configuration will be ignored.
Suggested fix
plugins:
- source_editing:
+ ckeditor5_sourceEditing:
allowed_tags: ''🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@drupal/config/sync/editor.editor.formatted.yml` around lines 19 - 21, The
CKEditor5 plugin key is incorrect: replace the plugin key "source_editing" with
the CKEditor5 config schema key "ckeditor5_sourceEditing" so the "allowed_tags"
setting is applied; update the plugins map entry (the "plugins" →
"source_editing" node) to use "ckeditor5_sourceEditing" while keeping
"allowed_tags: ''" intact so the configuration is recognized by Drupal.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@nuxt/tests/jsonapi/article.test.js`:
- Line 1: The test imports fetch via require('node-fetch') in
nuxt/tests/jsonapi/article.test.js which isn't declared in package.json; either
add node-fetch as a devDependency in nuxt/package.json (so the
require('node-fetch') works), or remove the import and switch the tests to use
globalThis.fetch (update package.json engines to "node": ">=18.0.0" if choosing
globalThis); update the test file to stop requiring node-fetch if you add the
engines change, or add node-fetch to devDependencies if you keep the require.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: adcb5890-a324-419d-823d-e04c0b66d5d1
📒 Files selected for processing (3)
drupal/.ddev/commands/web/phpunitdrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/UriNormalizerKernelTest.phpnuxt/tests/jsonapi/article.test.js
✅ Files skipped from review due to trivial changes (1)
- drupal/.ddev/commands/web/phpunit
🚧 Files skipped from review as they are similar to previous changes (1)
- drupal/web/modules/custom/stuartc_tests/tests/src/Kernel/UriNormalizerKernelTest.php
| @@ -0,0 +1,40 @@ | |||
| const fetch = require('node-fetch') | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package manifests: node-fetch / engines / jest =="
fd -i 'package.json' | while read -r f; do
echo "-- $f"
rg -n '"node-fetch"|"engines"|"node"|\"jest\"' "$f" || true
done
echo
echo "== CI Node version configuration =="
rg -n --iglob '*.yml' 'setup-node|node-version'Repository: Decipher/stuar.tc
Length of output: 325
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== nuxt/package.json content =="
cat nuxt/package.json
echo
echo "== Test file: article.test.js (lines 1-20) =="
head -20 nuxt/tests/jsonapi/article.test.js
echo
echo "== Check if node-fetch is used elsewhere =="
rg 'node-fetch|fetch' nuxt/ --type js --type ts -n | head -20Repository: Decipher/stuar.tc
Length of output: 4466
node-fetch dependency is missing and will cause test failure.
Line 1 uses require('node-fetch'), but the dependency is not declared in nuxt/package.json. Tests will fail with MODULE_NOT_FOUND at runtime. Either add node-fetch as a devDependency or replace with globalThis.fetch (requires Node 18+ in engines field).
Suggested patch using globalThis.fetch (Node 18+ required)
-const fetch = require('node-fetch')
-
const BASE_URL = process.env.BASE_URL || 'http://stuartclark.ddev.site'
@@ fetchJsonApi @@
- const res = await fetch(url.toString())
+ const res = await globalThis.fetch(url.toString())Also requires adding or updating engines in package.json:
"engines": {
"node": ">=18.0.0"
}Also applies to: 10-10
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@nuxt/tests/jsonapi/article.test.js` at line 1, The test imports fetch via
require('node-fetch') in nuxt/tests/jsonapi/article.test.js which isn't declared
in package.json; either add node-fetch as a devDependency in nuxt/package.json
(so the require('node-fetch') works), or remove the import and switch the tests
to use globalThis.fetch (update package.json engines to "node": ">=18.0.0" if
choosing globalThis); update the test file to stop requiring node-fetch if you
add the engines change, or add node-fetch to devDependencies if you keep the
require.
5b8e022 to
060c957
Compare
060c957 to
811e536
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@wiki/testing-guide.md`:
- Around line 228-231: Remove the duplicated note block that repeats the
test-module sentence and the `tests/src/Kernel/JsonApiEndpointTest.php` file
listing; keep only one instance and delete the redundant block so the
documentation references the test file once.
- Around line 209-212: The fenced code block containing
"drupal/web/modules/custom/stuartc_tests/" is missing a language tag (MD040);
update that fence in wiki/testing-guide.md by adding a language specifier (e.g.,
"text") after the opening ``` so the block becomes ```text followed by the path
and closing ```, ensuring the linter no longer flags the missing language.
- Line 254: The plain-text CI command "ddev phpunit --group stuartc_tests
web/modules/custom/stuartc_tests/" should be formatted as a fenced code block
for clarity; wrap that exact command with triple backticks and include the
language tag (bash) on the opening fence and the closing triple backticks after
the command so it renders as a code snippet.
In `@wiki/upgrade-notes/drupal-11.md`:
- Around line 168-173: Update the paragraph that currently reads "Cypress E2E
tests cannot run due to Node.js 24 incompatibility..." to scope the issue to
local Node 24 only by rephrasing it to something like: "Cypress E2E tests cannot
run locally under Node.js 24 due to Nuxt 2's webpack 4
(ERR_OSSL_EVP_UNSUPPORTED); CI runs Cypress under Node 16." Keep the three fix
options (NODE_OPTIONS=--openssl-legacy-provider, use Node 16 via nvm for Cypress
runs, upgrade to Nuxt 3/4) but explicitly note that CI in this PR uses Node 16
so this is not a CI blocker.
- Around line 93-102: This block runs DDEV commands without ensuring the reader
is in the Drupal project directory; prepend an explicit directory change (e.g.,
add a line with cd drupal) immediately before the sequence of DDEV commands (the
lines containing ddev config --database=..., ddev start, and ddev utility
migrate-database ...) so the example clearly runs from the drupal working
directory and avoids user errors.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 113b0283-cc74-48ef-af4a-3cd00d6a761d
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (24)
.github/workflows/ci.yml.markdownlintignore.markdownlintrcAGENTS.mdREADME.mddrupal/.ddev/commands/web/phpunitdrupal/config/sync/core.base_field_override.node.article.promote.ymldrupal/config/sync/core.base_field_override.node.event.promote.ymldrupal/config/sync/core.extension.ymldrupal/config/sync/file.settings.ymldrupal/config/sync/views.settings.ymldrupal/phpstan.neondrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiArticleTest.phpdrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiFieldTest.phpdrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiRouteTest.phpdrupal/web/modules/custom/stuartc_tests/tests/src/Kernel/UriNormalizerKernelTest.phpnuxt/jest.config.jsnuxt/tests/jsonapi/article.test.jspackage.jsonwiki/architecture.mdwiki/development-setup.mdwiki/testing-guide.mdwiki/troubleshooting.mdwiki/upgrade-notes/drupal-11.md
💤 Files with no reviewable changes (2)
- drupal/phpstan.neon
- README.md
✅ Files skipped from review due to trivial changes (11)
- .markdownlintignore
- .markdownlintrc
- drupal/config/sync/core.base_field_override.node.event.promote.yml
- drupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiArticleTest.php
- wiki/architecture.md
- drupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiRouteTest.php
- drupal/config/sync/file.settings.yml
- package.json
- drupal/web/modules/custom/stuartc_tests/tests/src/Kernel/JsonApiFieldTest.php
- wiki/development-setup.md
- wiki/troubleshooting.md
🚧 Files skipped from review as they are similar to previous changes (5)
- drupal/.ddev/commands/web/phpunit
- drupal/config/sync/views.settings.yml
- drupal/config/sync/core.base_field_override.node.article.promote.yml
- drupal/web/modules/custom/stuartc_tests/tests/src/Kernel/UriNormalizerKernelTest.php
- nuxt/tests/jsonapi/article.test.js
|
|
||
| ``` | ||
| drupal/web/modules/custom/stuartc_tests/ | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced code block.
The fence starting at Line 210 is missing a language specifier, which triggers MD040.
Suggested fix
-```
+```text
drupal/web/modules/custom/stuartc_tests/</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 210-210: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wiki/testing-guide.md` around lines 209 - 212, The fenced code block
containing "drupal/web/modules/custom/stuartc_tests/" is missing a language tag
(MD040); update that fence in wiki/testing-guide.md by adding a language
specifier (e.g., "text") after the opening ``` so the block becomes ```text
followed by the path and closing ```, ensuring the linter no longer flags the
missing language.
| It contains kernel tests that verify route availability and content field definitions: | ||
|
|
||
| - `tests/src/Kernel/JsonApiEndpointTest.php` | ||
|
|
There was a problem hiding this comment.
Remove duplicated test-module note block.
The sentence and file path list here duplicate the block already documented at Line 214–Line 217.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wiki/testing-guide.md` around lines 228 - 231, Remove the duplicated note
block that repeats the test-module sentence and the
`tests/src/Kernel/JsonApiEndpointTest.php` file listing; keep only one instance
and delete the redundant block so the documentation references the test file
once.
|
|
||
| To run in CI (GitHub Actions), verify JSON:API endpoint manually or fix PHPUnit configuration: | ||
| ddev phpunit --group stuartc_tests web/modules/custom/stuartc_tests/ No newline at end of file | ||
| ddev phpunit --group stuartc_tests web/modules/custom/stuartc_tests/ |
There was a problem hiding this comment.
Format the CI command as a fenced code snippet.
Line 254 is presented as plain text under a heading; rendering it as code improves clarity and consistency.
Suggested fix
-To run in CI (GitHub Actions), verify JSON:API endpoint manually or fix PHPUnit configuration:
-ddev phpunit --group stuartc_tests web/modules/custom/stuartc_tests/
+To run in CI (GitHub Actions), verify JSON:API endpoint manually or fix PHPUnit configuration:
+
+```bash
+ddev phpunit --group stuartc_tests web/modules/custom/stuartc_tests/
+```🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wiki/testing-guide.md` at line 254, The plain-text CI command "ddev phpunit
--group stuartc_tests web/modules/custom/stuartc_tests/" should be formatted as
a fenced code block for clarity; wrap that exact command with triple backticks
and include the language tag (bash) on the opening fence and the closing triple
backticks after the command so it renders as a code snippet.
| ```bash | ||
| php -v | ||
| # Should show 8.3.x | ||
| # Updated .ddev/config.yaml | ||
| # type: drupal9 → drupal11 | ||
| # php_version: "8.1" → "8.3" | ||
| # mariadb_version: "10.3" → "10.6" | ||
|
|
||
| ddev config --database=mariadb:10.3 # revert for migration | ||
| ddev start | ||
| ddev utility migrate-database mariadb:10.6 # migrate data | ||
| ``` |
There was a problem hiding this comment.
Add explicit cd drupal context before DDEV commands.
In this block, readers can run these commands from the wrong directory. Please make the Drupal working directory explicit to avoid setup failures.
Suggested fix
```bash
+cd drupal
+
# Updated .ddev/config.yaml
# type: drupal9 → drupal11
# php_version: "8.1" → "8.3"Based on learnings: "DDev commands must be run from the drupal directory".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wiki/upgrade-notes/drupal-11.md` around lines 93 - 102, This block runs DDEV
commands without ensuring the reader is in the Drupal project directory; prepend
an explicit directory change (e.g., add a line with cd drupal) immediately
before the sequence of DDEV commands (the lines containing ddev config
--database=..., ddev start, and ddev utility migrate-database ...) so the
example clearly runs from the drupal working directory and avoids user errors.
| Cypress E2E tests cannot run due to Node.js 24 incompatibility with Nuxt 2's webpack 4 (ERR_OSSL_EVP_UNSUPPORTED). This is a frontend tooling issue, not related to the Drupal upgrade. Fix options: | ||
|
|
||
| The Gin theme needs to be updated to 4.x for D11: | ||
| ```bash | ||
| composer require drupal/gin:^4.0 drupal/gin_login:^2.0 drupal/gin_toolbar:^2.0 | ||
| ``` | ||
| - Use `NODE_OPTIONS=--openssl-legacy-provider` | ||
| - Use Node 16 via nvm for Cypress runs | ||
| - Upgrade to Nuxt 3/4 (separate future change) | ||
|
|
There was a problem hiding this comment.
Scope the Cypress limitation to local Node 24 only.
This wording says Cypress “cannot run,” but CI in this PR runs Cypress under Node 16. Narrow this note so it doesn't read like a global blocker.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wiki/upgrade-notes/drupal-11.md` around lines 168 - 173, Update the paragraph
that currently reads "Cypress E2E tests cannot run due to Node.js 24
incompatibility..." to scope the issue to local Node 24 only by rephrasing it to
something like: "Cypress E2E tests cannot run locally under Node.js 24 due to
Nuxt 2's webpack 4 (ERR_OSSL_EVP_UNSUPPORTED); CI runs Cypress under Node 16."
Keep the three fix options (NODE_OPTIONS=--openssl-legacy-provider, use Node 16
via nvm for Cypress runs, upgrade to Nuxt 3/4) but explicitly note that CI in
this PR uses Node 16 so this is not a CI blocker.
Types of changes
Description
Upgrades the stuar.tc site (Nuxt + Drupal/DruxtJS) from Drupal 9.4 to Drupal 11, including supporting infrastructure and tooling changes.
Key changes:
field_display_title,field_content_supplementary), removed obsolete roles (admin_content,author), and added new modules (entity_clone, new sitemap engines).Summary by CodeRabbit
Updates
Documentation
Tests