Problem/Motivation

Talks about #2628144: Ensure that ConfigImport is taking place against the same code base making config import more reliable. There is some contention because it reduces some of the abilities of developers to do what they please. This issue is going to do something simpler. Ensure that when running configuration import there are no outstanding database updates to run.

Proposed resolution

Add validator to ensure that no outstanding updates need running.

Remaining tasks

User interface changes

Additional configuration import validation messages

API changes

None

For kernel tests we have added \Drupal\KernelTests\KernelTestBase::installUpdateRegistryState() to set the state for modules so that config imports are easy to test.

Data model changes

None

Release notes snippet

Config imports are prevented if there are outstanding database updates. In order to import Configuration, all available updates must have been run. This change helps users follow best practices around configuration management, drupal updates and deployments.

CommentFileSizeAuthor
#74 interdiff_72-74.txt8.15 KBpooja saraah
#74 2762235-74.patch24 KBpooja saraah
#72 2762235-2-72.patch23.41 KBalexpott
#72 68-72-interdiff.txt2.54 KBalexpott
#68 2762235-2-68.patch23.57 KBalexpott
#68 67-68-interdiff.txt7.95 KBalexpott
#67 2762235-2-67.patch15.63 KBalexpott
#67 64-67-interdiff.txt10.19 KBalexpott
#64 2762235-2-64.patch12.86 KBalexpott
#64 63-64-interdiff.txt2.21 KBalexpott
#63 2762235-2-63.patch13.23 KBalexpott
#58 interdiff_34_54.txt12.47 KBKapilV
#56 interdiff_34_54.patch12.47 KBKapilV
#56 2762235-54.patch5.83 KBKapilV
#34 interdiff-2762235-30-34.txt1.2 KBbircher
#34 2762235-34.patch12.47 KBbircher
#30 2762235-30.patch12.49 KBalexpott
#30 28-30-interdiff.txt3.4 KBalexpott
#28 2762235-28.patch12.16 KBalexpott
#28 26-28-interdiff.txt503 bytesalexpott
#26 2762235-26.patch12.07 KBalexpott
#26 23-26-interdiff.txt3.66 KBalexpott
#7 2762235-7.patch1.79 KBvijaycs85
#11 2762235-11.patch7.3 KBswentel
#14 2762235-14.patch7.99 KBswentel
#15 2762235-15.patch7.98 KBswentel
#17 2762235-17.patch9.22 KBswentel
#18 2762235-18.patch9.17 KBswentel
#21 2762235-21.patch9.72 KBswentel
#23 interdiff-2762235-23.txt3.81 KBswentel
#23 2762235-23.patch11.75 KBswentel
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alexpott created an issue. See original summary.

dawehner’s picture

+1 for the general approach. Updates are designed to be executed before anything else. On the other hand we should maybe consider to allow config imports as part of post update, otherwise post update config changes would be overridden by deployment scripts.

alexpott’s picture

@dawehner this is why #2628144: Ensure that ConfigImport is taking place against the same code base - I think that that is the only real way to deal with this - but this is a first and less controversial step.

alexpott’s picture

Status: Needs review » Needs work
moshe weitzman’s picture

I was never totally clear on the right order between these two steps so IMO this explicit ordering is helpful.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

vijaycs85’s picture

Status: Needs work » Needs review
FileSize
1.79 KB

Initial patch...

alexpott’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
+++ b/core/modules/system/src/SystemConfigSubscriber.php
@@ -78,6 +78,40 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
+    $updates = update_get_update_list();

There are also post updates to check for. This is the code from system_requirements()...

    // Check installed modules.
    $has_pending_updates = FALSE;
    foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
      $updates = drupal_get_schema_versions($module);
      if ($updates !== FALSE) {
        $default = drupal_get_installed_schema_version($module);
        if (max($updates) > $default) {
          $has_pending_updates = TRUE;
          break;
        }
      }
    }
    if (!$has_pending_updates) {
      /** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */
      $post_update_registry = \Drupal::service('update.post_update_registry');
      $missing_post_update_functions = $post_update_registry->getPendingUpdateFunctions();
      if (!empty($missing_post_update_functions)) {
        $has_pending_updates = TRUE;
      }
    }
vijaycs85’s picture

Thanks @alexpott. I have added tests #1970534-108: Patch testing issue and working on test failures (ref: https://www.drupal.org/pift-ci-job/568413)

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

swentel’s picture

Status: Needs work » Needs review
FileSize
7.3 KB

Rerolled the patch from the test patch issue.

Made the specific added test work - except for the post update check, but I think there's some static caching going on there.
Note also the irony of running the import before 'profile' is set, throws notices in the test, bitter irony :)

Status: Needs review » Needs work

The last submitted patch, 11: 2762235-11.patch, failed testing.

swentel’s picture

So the remaining failures are due to pending post updates. Checked whether I could replace the post update registry in the kerneltest, but seem to fail so far .. will look further this evening.

swentel’s picture

Status: Needs work » Needs review
FileSize
7.99 KB

Ok, I was focusing on the wrong thing, thanks for berdir for pointing me to drupal_set_installed_schema_version() ...

swentel’s picture

Bring back the post updates, will trigger fails,

- either because of static values in update path tests (at least, that's my suspicion)
- in kerneltestbase because the registry finds the post update functions from system (so either we swap that service or we run them in kerneltestbase - first one seems more appropriate)

Status: Needs review » Needs work

The last submitted patch, 15: 2762235-15.patch, failed testing.

swentel’s picture

Status: Needs work » Needs review
FileSize
9.22 KB

This should fix the fails for classes using kernelTestBase.

swentel’s picture

stupid file_put_contents left over

The last submitted patch, 17: 2762235-17.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 18: 2762235-18.patch, failed testing.

swentel’s picture

Status: Needs work » Needs review
FileSize
9.72 KB

This should be green

alexpott’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -78,6 +78,53 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
    +  protected function hasModuleUpdates() {
    

    Given that most of the code in this method is a copy of system_requirements() we might want to open a follow up to create an update list service or something similar.

  2. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -78,6 +78,53 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
    +    foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
    ...
    +        if (max($updates) > $default) {
    ...
    +      $post_update_registry = \Drupal::service('update.post_update_registry');
    

    let's inject these things

  3. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -78,6 +78,53 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
    +      $updates = drupal_get_schema_versions($module);
    ...
    +        $default = drupal_get_installed_schema_version($module);
    

    There's nothing else to do other than call these procedural methods :(

  4. +++ b/core/modules/system/src/Tests/Update/UpdatePendingConfigImportTest.php
    @@ -0,0 +1,79 @@
    +class UpdatePendingConfigImportTest extends UpdatePathTestBase {
    +
    +
    +
    +  /**
    

    Lots of space :)

  5. +++ b/core/modules/system/src/Tests/Update/UpdatePendingConfigImportTest.php
    @@ -0,0 +1,79 @@
    +    // Use the UI to import (for some reason I can't get the config importer to
    +    // get rid of it's error log of pending database updates, and that error log
    +    // is probably stuck somewhere deeper).
    

    Static hmmm.... services are static. But after running updates we could rebuild the container and the config importer as before. I think to keep us sane do everything via the UI and assert on the error messages that would appear to a user. The test should have a comment that nothing should be done of the parent site and everything should be done on the system-under-test to test what a user would see.

swentel’s picture

Status: Needs work » Needs review
FileSize
11.75 KB
3.81 KB

1. good idea
2. done : UpdateRegistry doesn't have an interface though, introduce one as UpdateRegistryTest is a bit lying of course in it's comments :) Also, is that the right place for that class to be ? Maybe rename to UpdateRegistryNull ?
3. sad schema ..
4. fixed
5. ugh, so I can't login first to try and run an initial sync because system_update_8400() hasn't run yet .. the irony ... I've been thinking whether we should not rely on UpdatePathTestBase(), but being able to run updates is nice .. let me think about it some more .. suggestions welcome of course.

The last submitted patch, 23: 2762235-23.patch, failed testing.

swentel’s picture

UpdateRegistry doesn't have an interface though

And hence all the fails when injecting, the fun!

alexpott’s picture

So the question is do we want people to override the UpdateRegistry - I'm not sure about that. The simple thing is to make the test class extend the real class.

Status: Needs review » Needs work

The last submitted patch, 26: 2762235-26.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
FileSize
503 bytes
12.16 KB

Shouldn't post a patch without running a couple of tests first...

zaporylie’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests

+1 to general concept because developers are still confused what should goes first - updb or cim. Adding such a check will keep developers happy.

  1. +++ b/core/lib/Drupal/Core/Test/TestUpdateRegistry.php
    @@ -0,0 +1,52 @@
    + * UpdateRegistryTest used for tests.
    ...
    +class TestUpdateRegistry extends UpdateRegistry {
    

    docblock and class name doesn't match

  2. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -23,13 +25,32 @@ class SystemConfigSubscriber implements EventSubscriberInterface {
    +   * The update registry
    

    Missing full stop.

  3. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -78,6 +99,52 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
    +    foreach ($this->moduleHandler->getModuleList() as $module => $filename) {
    +      $updates = drupal_get_schema_versions($module);
    +      if ($updates !== FALSE) {
    +        $default = drupal_get_installed_schema_version($module);
    +        if (max($updates) > $default) {
    +          $has_pending_updates = TRUE;
    +          break;
    +        }
    +      }
    +    }
    +    if (!$has_pending_updates) {
    +      $missing_post_update_functions = $this->postUpdateRegistry->getPendingUpdateFunctions();
    +      if (!empty($missing_post_update_functions)) {
    +        $has_pending_updates = TRUE;
    +      }
    +    }
    +
    

    Can we change the order? First check for missing post update functions and then, if needed, iterate over module list? That will, potentially, make it faster(?).

    Instead of setting value for $has_pending_updates we could just return TRUE. There's no need to continue.

alexpott’s picture

Status: Needs work » Needs review
FileSize
3.4 KB
12.49 KB

Thanks for the review @zaporylie.

  1. fixed
  2. fixed
  3. The early returns are a good idea. The loops around modules exist inside $this->postUpdateRegistry->getPendingUpdateFunctions() so there is no performance benefit to switching the order - especially now we're doing early returns.
zaporylie’s picture

+++ b/core/modules/system/src/SystemConfigSubscriber.php
@@ -78,6 +100,53 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
+    $has_pending_updates = FALSE;
...
+    if (!$has_pending_updates) {
...
+    }
...
+    return $has_pending_updates;

I think we can remove $has_pending_updates variable and condition wrapping $missing_post_update_functions and return FALSE in last line of hasModuleUpdates()

Status: Needs review » Needs work

The last submitted patch, 30: 2762235-30.patch, failed testing.

fago’s picture

I don't think that the patch follow the right approach regarding post updates.

Post update hooks are for applying content changes. However, content changes might require config changes to work, e.g. having a new field added. Thus, imo the right order of things would be
1. updates
2. config import
3. post updates

There is also a PR to drush what the above that approach possible using drush commands: https://github.com/drush-ops/drush/pull/2740

That said, I think the patch should check for all updates being applied, but not for all post-updates being applied.

bircher’s picture

#31: I agree, attached the patch. Also I tested the failing test on 8.4.x and it worked there, so lets see if the CI likes it better now.

#33: Well, this is a very common problem when building sites indeed.
But I think the workflow you propose is flawed because hook_post_update_NAME is for fixing content you broke in a hook_update_N function since in those functions you can not assume to have the API available. So post_update hooks should always follow the update hooks immediately.
On the other hand what you describe is a hook that should be run after configuration deployment to fix content that had been broken due to configuration changes. It is natural to turn to the hook that is already there, and we had a couple of projects that manually adjusted the configuration in the hook so that the content could be fixed in that hook. But then I discovered that such a post_config_import hook is not difficult to do. Here is the code we use to this effect: https://github.com/bircher/drupal-config_import_n I would have to add some more automated tests and create a project on d.o, but maybe instead we would want to have that as part of drupal core directly.

fago’s picture

But I think the workflow you propose is flawed because hook_post_update_NAME is for fixing content you broke in a hook_update_N function since in those functions you can not assume to have the API available.

I can't see why post-update should be only valid for this case. The documentation says:

Executes an update which is intended to update data, like entities.

This is exactly what I'm trying to do in #33 - so the hook seems to be fine?

Adding a separate post-config-import update would be an option, but I'm not convinced we need pre + post config import updates. After running updates, the system should be in a working state and it should be able to process config imports, no? I don't see data migrations would have to be run before config import when we have it afterwards?

bircher’s picture

You are right, there is a perfectly valid use case for updating entities in a post_update hook and the documentation is not wrong.

But I think it makes sense to distinguish between an update to an entity because of configuration changes due to schema changes in a (contrib) module, and due to configuration change as part of the site building process. Because in the first one the configuration changes in the update hook and hence the post_update hook is the perfect place to change the content entity. But the second changes the configuration as part of the configuration import and in my opinion the content should change in the post_config_import hook.

Of course since we currently only have the post_update hook it seems natural to use it for both cases and not differentiate between the two. But that leads to the problem that sometimes you want to import the configuration before the update. And that is because (as of now) both drush and the drupal UI do hook updates and post_updates at the same time (one after the other). And in my opinion that is a good thing.
"Sometimes" is very bad for repeatable scripts, and ergo I am suggesting to use a different hook in those times.

You are right that we don't necessarily need a pre and post config import hook since the post_update hook *is* also the pre config import hook. But I added both to my proof of concept to differentiate what kind of changes we are talking about. And as such a pre import hook would save the data of a field to be removed and the post import hook would add it to the new field. This is for the use case of site building where in the site development process you remove a field and add a new one (of say a new type with the same name).
So the argument is more for DX that you can say these two pre and post import hooks go together and this post_update goes with that update hook.

Right now without this patch there is:

  1. config import
  2. update hooks
  3. post_update hooks

(bad) and (good)

  1. update hooks
  2. post_update hooks
  3. config import

With the patch there is only:

  1. update hooks
  2. post_update hooks
  3. config import

You would like:

  1. update hooks
  2.  
  3. config import
  4. post_update hooks

And I propose as a follow up:

  1. update hooks
  2. post_update hooks
  3. config import
  4. post_config_import hooks

or possibly:

  1. update hooks
  2. post_update hooks
  3. pre_config_import hooks
  4. config import
  5. post_config_import hooks

But I think that should be a follow-up and not block the issue at hand.

moshe weitzman’s picture

update hooks
post_update hooks
pre_config_import hooks
config import
post_config_import hooks

That gets my vote. The pre_config_import hook is a great place to pull out config before it gets changed. It would naturally get used by the post_config_import hook.

fago’s picture

ok, I can follow the reasoning outlined by bircher - I agree it makes to have a post update hook + a post config import hook.

That gets my vote. The pre_config_import hook is a great place to pull out config before it gets changed. It would naturally get used by the post_config_import hook.

I cannot follow that use case though, can you elaborate on this? What do you mean with pulling out config and how does that relate to post-config?

This makes total sense to me, but I'm wondering whether we need the pre-config hook:

update hooks
post_update hooks
pre_config_import hooks ??
config import
post_config_import hooks

Still, of course this would need a documentation update to clarify when to use what.

moshe weitzman’s picture

Sorry, "pull out config" is a vague term. I think whats desired is a way to store in memory relevant config values in a pre_config_import hook and then use those values in a post_config_import hook

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

I guess we should get this in, and work on pre/post_config_import hooks in a new issue. Maybe @bircher is up for creating it?

I did a code review of this patch and it LGTM. Further, I retested and bot is happy.

catch’s picture

Status: Reviewed & tested by the community » Needs work

I have at least one concern with this issue in its current state.

Especially on custom projects, let's say you have a configuration change that adds a field, then a post update hook that populates the field for some entities. This patch would require you to write a hook_update_N() for the configuration change instead of being able to do a drush cim -y && drush updb. Sometimes field content is set dynamically, say if data is being denormalized, so the hook_update_N() exists purely to load and save affected entities with no other logic.

In this case you may very well have zero hook_update_N() to run at all - you're deploying one changeset which you control entirely. You might not even be deploying the change to production but only to dev/staging during medium stages of a project.

If we shut that workflow off (which I've used personally, why write a hook_update_N() unless you have to), it undoes some of the convenience of configuration management.

Also missing a change record and the issue summary isn't clear, but I think we probably need to either add the new hooks here rather than in a follow-up.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

bircher’s picture

Hmm

I see your concern. However, I do not really understand the difference between writing a `hook_update_N` and a `hook_post_config_import_NAME` for a one-off hook that doesn't do anything dangerous and is meant to run after configuration imports.

The above mentioned hook exists in https://github.com/bircher/drupal-config_import_n which I can make into either a contrib project or a core patch #2901418: Add hook_post_config_import_NAME after config import if we decide to block this issue on having the hooks in core.

fago’s picture

We had a production discussion on this topic during Drupalcon Vienna sprints. We being: alex pott, bircher, jibran, mbm80 and me.

Here is a short summary of our conclusions:

  • post-update hooks cannot be reliable for content imports for projects as content imports may rely on the (field) config changes, which are done during config import.
  • content imports relying on config could be done with an event subscriber reacting on the config import and running the content import once the required config was imported. However this is not a nice DX as the developer would have to take care of the run-only-once update logic, plus the code would be in the code-base all the time vs only during running updates.
  • to improve DX for this content-import use-case a hook_post_config_import_NAME() receiving the config importer $event is the way to go -> let's do this in #2901418: Add hook_post_config_import_NAME after config import
  • given that we can require all updates to be run before config-import is run (this issue)
  • we also noted that hook-install() cannot be used for content imports in modules as module cannot rely on default config to be there then (it's not duing config import). But that's another topic.
jibran’s picture

we also noted that hook-install() cannot be used for content imports in modules as module cannot rely on default config to be there then (it's not duing config import). But that's another topic.

Created #2914213: Don't create content in install hooks if module is installed during config import for this.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mpp’s picture

Issue summary: View changes
claudiu.cristea’s picture

+++ b/core/modules/system/src/SystemConfigSubscriber.php
@@ -78,6 +100,52 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
+    // Check post update hooks.
+    $missing_post_update_functions = $this->postUpdateRegistry->getPendingUpdateFunctions();
+    if (!empty($missing_post_update_functions)) {
+      return TRUE;
+    }

I think we should only check for hook_update_N(). Those updates are supposed to repair the DB. If such updates are successful the config import should be safe.

As an alternative to #2901418: Add hook_post_config_import_NAME after config import, we're using this sequence, in order to run content manipulations with the new installed modules and updated configs:

drush updb --no-post-updates
drush config:import
drush updb

In this way we are able to run content manipulations, in hook_post_update_NAME(), that are relying on the updated configs and new modules installed by config:import.

EDIT: And this was supposed to be the initial scope of hook_post_update_NAME(), to run updates on top of the healed API. With config import, we're installing new modules & updating config, and that is part of “fixing the API”, in the same way as hook_update_N() is.

EDIT2: I've missed the @fago's comment from #33. It's exactly the same solution.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

bircher’s picture

Issue tags: +Needs reroll

Since I closed #2901418: Add hook_post_config_import_NAME after config import which was listed here as a solution for why some people were against this change I will also link the better way to handle this situation here: Drush deploy documentation

So there is nothing stopping us from doing this.

KapilV’s picture

Assigned: Unassigned » KapilV
kishor_kolekar’s picture

Status: Needs work » Needs review
FileSize
11.54 KB

Re-roll the patch for 8.9.x-dev

kishor_kolekar’s picture

opss sorry @kapilkumar0324, I haven't seen you assign this issue yourself

KapilV’s picture

Assigned: KapilV » Unassigned
Issue tags: -Needs reroll
FileSize
5.83 KB
12.47 KB

hear a reroll patch.

KapilV’s picture

KapilV’s picture

FileSize
12.47 KB

The last submitted patch, , failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 56: 2762235-54.patch, failed testing. View results

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
alexpott’s picture

Now that we have drush deploy and there's way more consensus about how updates and config imports are supposed to work together I think we can return to this. Especially as people experience things like #3241246: Missing schema: views.settings:ui.show.master_display

Here's a patch for D10 - I've used some PHP 8 features so we'll need a different patch for 9.4.x.

alexpott’s picture

Fixing the tests and some comments.

alexpott’s picture

Issue summary: View changes

Adding release note to the issue summary - we also need a change record. I've load to point to something like https://drupalize.me/topic/deployment-workflows which explains when to import and when to export.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

alexpott’s picture

After discussing this with @catch decided to add \Drupal\KernelTests\KernelTestBase::installUpdateRegistryState() to set the update registry state in kernel tests when necessary. I think this is the best way to support adding the validation. Module install in kernel tests is already very very odd and there can not be much in contrib or custom that is using the ConfigImporter during kernel tests so maybe doing this is okay.

Here are the options I considered:

  1. Update them in the same way the module install would. This has the downside of loading all .install and post_update.php code in KTBs and doing lot so inserts to state for every test.
  2. Fake it (PHP_INT_MAX) and mock the post update registry. This has the downside of faking it. It's what #64 does.
  3. Provide a trait/method that fixes the state for tests that need it in KTB. This is what this patch does. It has the downside that contrib / custom KTB tests might break if they are testing config import. However they can simply call $this->installUpdateRegistryState(static::$modules); in set up and things will work.
  4. Mocking the event so that it does not trigger in KTB unless you do something. Not explored - I think this would be very surprising.
alexpott’s picture

Fixing some more kernel tests...

Makes me less sure about adding the new method.

The last submitted patch, 67: 2762235-2-67.patch, failed testing. View results

alexpott’s picture

Issue summary: View changes
Issue tags: -Needs change record

Added CR and fixed up the release note a bit.

alexpott’s picture

Issue summary: View changes
alexpott’s picture

daffie’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/system/src/SystemConfigSubscriber.php
    @@ -81,6 +115,50 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
    +    foreach ($this->moduleHandler->getModuleList() as $module => $filename) {
    

    We are not using the $filename in the loop, than we therefor change it to: foreach (array_keys($this->moduleHandler->getModuleList()) as $module) {.

  2. +++ b/core/modules/system/tests/src/Functional/UpdateSystem/UpdatePendingConfigImportTest.php
    @@ -0,0 +1,102 @@
    +  /**
    +   * {@inheritdoc}
    +   */
    +  protected function doSelectionTest() {
    +    if ($this->getName() === 'testConfigImportWithHookUpdateN') {
    +      $this->assertSession()->pageTextContains('9001 - Pending update.');
    +      $this->assertSession()->pageTextNotContains('Pending post update.');
    +    }
    +    else {
    +      $this->assertSession()->pageTextContains('Pending post update.');
    +      $this->assertSession()->pageTextNotContains('9001 - Pending update.');
    +    }
    +  }
    

    I think that this method should be added to the method doTest().

  3. +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    @@ -739,6 +739,52 @@ protected function installSchema($module, $tables) {
    +   * Sets the update registry state for the provided modules.
    

    Nitpick: can we add "as fully updated"?

  4. +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    @@ -739,6 +739,52 @@ protected function installSchema($module, $tables) {
    +  protected function installUpdateRegistryState(string|array $modules): void {
    

    The testbot failing for PHP 7.4. Probably for string|array.

pooja saraah’s picture

Can't apply the Patch on #72 against Drupal 9.4.x

Thanks for your suggestions @daffie
I have addressed the point 1. and 3. on comment #73
Here, I have Attached patch against Drupal 9.4.x

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

maskedjellybean’s picture

There's a lot of references to hook_post_config_import_NAME in these comments and in related issues, but according to api.drupal.org, no such hook exists. I'd like to know what the solution to the problem posed in #41 will be. I've always run config import before database updates. That's because the primary purpose of database updates (in my opinion) is to modify content and the purpose of config is to modify structure. We need structure in place before we can create content that relies on that structure. Doing the opposite feels very counterintuitive to me but I can see that almost everyone disagrees with me. It's certainly got me scratching my head.

I'm not here to tell you not to add this requirement. I think the fact that there's confusion about which to run first is a problem. But I'd really like to know how you all would solve the issue of the hook_update creating content for a field that does not exist yet because config has not been imported. EDIT: Without deploying twice (one deploy with the config and the next with the hook_update).

bircher’s picture

The hook_post_config_import_NAME idea has been replaced with hook_deploy_NAME in drush.
https://www.drush.org/latest/deploycommand/

The deploy hooks are not supported by drupal (yet) but that is a different issue. Deploy hooks are not meant for contrib modules or core, since they are meant to be "owned" by the same git repository as the exported config. But if this is a need, then the UI for deploy hooks would be relatively easy to implement as a contrib module.

From my understanding update hooks are for fixing the database schema to work with the latest codebase, post update hooks are for fixing the data that the update hook broke. Config import changes the structure and deploy hooks can update content knowing the config has been imported.

maskedjellybean’s picture

Ah thank you for the info! So there is no working solution for my question yet, but eventually it will be to use hook_deploy_NAME and then modify my deploy script like this: drush updb -y; drush cim -y; drush deploy:hook -y? Does the "NAME" part of hook_deploy_NAME matter or does it just need to be unique?

bircher’s picture

Ah no! you misunderstood!
Drupal does not have a UI to run deploy hooks (yet). But deploy hooks are a thing already for a while and work in production with the stable drush version since two years.

So since you are using drush this is already available to you.
Deploy hooks work the same way as post update hooks.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.