Synchronize config on recipe apply

Created on 23 May 2025, 14 days ago

Problem/Motivation

As outlined in 🌱 Support synchronizing config from recipes Active , when a given recipe-provided config item already exists on a given site in a state that differs from that in the recipe, depending on whether and how an optional "strict" setting is set, the recipe will either:

  1. fail to apply, throwing a RecipePreExistingConfigException exception (this is the default behaviour) or
  2. skip the given item.

In strict</strict> mode, many recipes may fail to apply; see #3307647: Support option of reverting to config as provided when (re)applying a recipe . Even when a recipe declares <code>strict: false, a given site will miss out on upstream configuration changes introduced for a given item in the interim between the initial and any subsequent application of the recipe.

Steps to reproduce

Proposed resolution

In Configuration Synchronizer, conditionally take over config handling on recipe apply such that any config updates are merged in. In strict mode, this approach would prevent the RecipePreExistingConfigException exception and allow recipe application to proceed. In so-called lenient mode, this approach will allow a site owner to receive upstream changes. In either case, a site administrator will have several update options, based on the selected update mode.

Configuration Synchronizer has several update modes as defined in ConfigSyncListerInterface:


  /**
   * Mode in which available updates are merged into the active configuration.
   */
  const UPDATE_MODE_MERGE = 1;

  /**
   * Mode in which available updates reset the active configuration.
   *
   * An available update is a difference between the Any customizations of these
   * items in the active configuration are discarded.
   */
  const UPDATE_MODE_PARTIAL_RESET = 2;

  /**
   * Mode in which the active configuration is reset to the provided state.
   *
   * Unlike ::UPDATE_MODE_PARTIAL_RESET, this mode applies to all provided
   * configuration--not only what has available updates. Any customizations in
   * the active configuration are discarded.
   */
  const UPDATE_MODE_FULL_RESET = 3;

As an experimental API, recipes in core are not - yet - extendible. For example:

  • There are no interfaces in the Drupal\Core\Recipe namespace and all classes are final.
  • There are no services.

In addition, there is, as yet, only a single custom event dispatched: RecipeAppliedEvent.

We can't, for example, decorate a service to make our changes, meaning that, in the interim until the APIs mature, the only viable approach is patching. Whether to resort to patching core is, obviously, a decision for the maintainers to take. The initial aim in this ticket is to outline what would be needed.

By way of context, a search of drupalcode identifies some 130 contrib projects that include at least one patch on Drupal core.

Fortunately, it appears the changes needed may be fairly minimal. Most of the code we'll need to alter seems to be confined to the Drupal\Core\Recipe\ConfigConfigurator, which is used in Drupal\Core\Recipe\Recipe. Assuming enabling work in other child issues of 🌱 Support synchronizing config from recipes Active , at a very high level, the needed work looks to be:

  1. Write a new class wrapping Drupal\Core\Recipe\ConfigConfigurator (we can't extend because it's final).
  2. Patch Drupal\Core\Recipe\Recipe to swap in our config configurator class for core's.

Remaining tasks

User interface changes

API changes

Data model changes

Feature request
Status

Active

Version

3.0

Component

Code

Created by

🇨🇦Canada nedjo

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024