Problem/Motivation

Recipes are conceived as composable, with any given recipe often requiring a chain of other recipes. But there's little practical sense as yet of just how this would work, or of what recommended patterns might be.

Proposed resolution

Currently core's standard install profile provides both required (config/install) and optional (config/optional) configuration. It also does something that could potentially be modelled as a config action - sets the site email address as a recipient of the feedback contact form. To get a sense of how recipes might work, a useful exercise would be to look at different models of how the standard install profile might be divided up into recipes.

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nedjo created an issue. See original summary.

alexpott’s picture

This is a fantastic idea.

thejimbirch’s picture

I am thinking a suite of basic recipes could be created and then combined into a Standard recipe.

Custom block basics
Contact form basics
Comment basics
Editor basics
Content type basics (Article, Page, Tags, layout blocks)
System basics
User basics
Media basics
Responsive image basics
Workflow basics

My only thinking was regarding the optional config. If I wanted to install the responsive image basics recipe, I would assume that I would want to enable the responsive image module. But in the greater Standard recipe could it (or should it) still be optional?

alexpott’s picture

I think that the great Standard recipe could suggest the responsive image basics recipe

alexpott’s picture

We're now at a point where I think this effort will be informative and help shape the direction. I think rather than doing this myself it'd be really great if other people involve in the initiative could have a go. I think we'd learn a lot from the process.

I've created an issue fork we we can all work on this and review it together. I suggest that we place the recipes in core/recipes to start with as that is the likely location that core recipes are going to ship.

alexpott’s picture

I've added an issue to list and eventually make config entity methods into actions - see #3303127: Determine which core config entity methods should be config actions

nedjo’s picture

Some initial thoughts here.

One issue is standard takes advantage of core's ability to re-provide config that an extension has already provided. Examples are system.site and user.settings. In a recipe, these should be modelled as config actions, making only the specific changes. For example, to determine what config actions we need, we can diff standard's system.site with the original version as provided by the System module. In this case, the only difference is in the page.front setting, so that's all that needs to go into a config action. This exercise will help clarify what config actions we need.

At the lowest level, we'll have a set of base recipes that have no config dependencies. Then we'll build up from there. The config dependencies in the config as provided in standard will serve as a guide, but only after we decide: what are we going to pull out into config actions? The big one here is, again, user roles and their permissions. The standard roles currently as provided are weighed down by a bunch of module and config dependencies. Probably we want to remove all those permissions and their dependencies. The permissions will be added in as config actions provided by higher level recipes.

So user.role.content_editor.yml would become:

langcode: en
status: true
dependencies: {  }
id: content_editor
label: 'Content editor'
weight: 2
is_admin: false
permissions: {  }

The next decision is: does that role go into its own recipe, or is it bundled into a recipe with other roles?

Meantime, the list of permissions pulled from content_editor gives us a useful guide on how the rest of the recipes are going to divide up. They all have to go somewhere. For example, the 'create terms in tags' and 'edit terms in tags' permissions suggest a tags recipe.

A basic aim to keep in mind here is what recipes are for--enabling much more nuanced and selective approaches. Beyond the very limited flexibility provided by optional config, standard is monolithic. Here, we want choices. For example, on a given site you might want pages but not articles, or vice-versa. So the two should go in separate recipes, which will probably be the highest-level recipes in standard.

kerrymick made their first commit to this issue’s fork.

thejimbirch’s picture

Status: Active » Needs work

Thanks for the great explanation nedjo!

Kerry and I worked on this today. We added simple recipes for Basic HTML Editor, Full HTML Editor, and Standard Users in the standard_profile_recipes folder. The latter is a work in progress as we need to understand what config actions are available. I couldn't grok that by looking at the code and may need more examples/documentation.

Building these was a great exercise, though. Instead of just building, I may try to take an ERD approach next week to see what is the best way to break the monolith into pebbles.

nedjo’s picture

@thejimbirch thx for this, it's good to see some initial ideas taking shape.

I've been looking at using Features to package core's standard config into recipes, like it currently packages it into modules. I applied some D10 compatibility fixes and opened #3303481: Support generating recipes and child issues.

As discussed in Slack, drawing on your start and beginning with what I could get out of Features and then manually editing for the rest, I've committed an initial rough cut at dividing up the standard config and pushed it to a new branch on this issue's fork, 3301370-atomic-standard. Note that when you view changes on that branch you need to set the target branch from 1.0.x to 10.0.x.

I've put in all the time I had for this exercise, so it's over to you (and others who show up or who you can recruit!). Even if you decide to work from the start I've made, there's still a tonne to do here.

Here's some of the precepts I used plus related notes:

  • Assume that practically all Drupal sites will be built using the recipes here. Contributed recipes will be built on the basis of these core ones. What we're rebuilding here is not "standard". Instead we're creating the basis of everything--including all of what are now the core install profiles. For example, there will be "minimal" and "demo_umami" recipes well as a "standard" one, all built on a common set of recipes.
  • Where a config entity is applicable to many different use cases, it should go in its own recipe. For example, a given recipe may call for both, neither, or one of the roles "administrator" and "content editor", so they should each go in separate recipes. Similarly, any field storage that's applicable to multiple content types goes in its own recipe.
  • Use selective enhancement for maximum flexibility. For example, not all recipes that require an article content type will also require tags. So the tags vocabulary goes into its own recipe
  • , an article recipe doesn't require tags, and there's a bridging recipe that selectively enhances article with tags.
  • Anywhere that core re-provides a config entity that's already provided by a module, that's a use case for config actions. Since we don't have those actions yet, we (a) add them as needed as a child issue of #3303127: Determine which core config entity methods should be config actions and (b) rough them in for now in the appropriate recipes, pending finalization.
  • As we rebuild, we can add recipes purely composed of other recipes when doing so meets what we anticipate to be common needs. For example, a standard_roles
  • We'll need to standardize as we go. For example, currently core's standard profile provides a "content editor" role while umami_demo provides an "editor" role. We probably don't need both, and so likely will need to rename one or the other.

Suggested next steps include:

  • Determine if we need composer files for these core recipes. If so, add them. Pay special attention to the question of what to put for "suggest". For example, the article_content_type recipe might suggest article_comment and article_tags.
  • Convert what's left in the profiles/standard/config/install directory into config actions, adding them to existing or new recipes as appropriate. When committing, remove the bits you're converting from config into config actions. For example, if you convert a permission into a config action, delete it from the source role. That way, we know exactly what's left to convert.
  • Have a go at another core profile, like minimal. Can we compose it from what we have for standard? Do we need to split off some of the standard recipes into smaller ones so that they work for both minimal and standard?

Happy to answer further questions as they come up. Meantime, over to you--thanks!

nedjo’s picture

@thejimbirch: some more notes:

  • I've left some @todo comments in recipe and config files. These are further areas to dig in.
  • I worked with the assumption the best default approach to extension-provided config is: default to the * wildcard. We should cherry-pick config only when there's a compelling use case to install an extension without all of its config. If we want to exclude some extension-provided config, that's a hint the config may better be provided by a recipe rather than by the extension. See #3304892: Determine which core module-provided config should be moved into recipes.
  • Per #3267267: [Meta] Tasks to deprecate RDF, I've left RDF configuration out of recipes.
kerrymick’s picture

Jim and I worked on this today. @nedjo thanks so much for your direction on this. Below are the changes we made:

  • Changed article content type to standard article content type instead of plus.
  • Added standard media types and standard responsive images as suggested recipes for the standard drupal install.
  • Renamed the standard installation profile.
  • Added suggestions for article comments and article tags for article content types.
nedjo’s picture

@kerrymick: Nice!

Drawing on our work here, I've written some additional detailed documentation, see the links at #3284777-7: Produce guidelines and/or a standard/spec for interoperable recipes. Please review if/when you get a chance. I'm hoping that provides a lot more to go on as you continue the work of converting the install profiles into recipes. See in particular the documentation on converting install profiles into recipes.

Re this change, it turns out there's already a recommended type here. Per the recipe documentation:

The type 'Site' is a special
case that allows such Drupal recipes to be listed on the installer.

So the type for the standard recipe should be "Site".

Please let me know if there's further help or support you could use at this point as you continue the work.

Thanks!

thejimbirch’s picture

Version: 1.0.x-dev » 10.0.x-dev
thejimbirch’s picture

Just noting that work should continue on the 3301370-atomic-standard branch.

thejimbirch’s picture

Issue tags: +DrupalCon Pittsburgh 2023

joegraduate made their first commit to this issue’s fork.

thejimbirch’s picture

Issue tags: -
StatusFileSize
new186.43 KB

Pushed a couple more recipes.

Started creating an ERD for what was updated. I think I may continue this as it helps my brain understand it all.

Only local images are allowed.

Some things that are in the Standard profiles module that adds additional functionality that may not be configuration.
* Assign user 1 the "administrator" role.
* Populate the default shortcut set.
* * Add content - internal:/node/add
* * All content - internal:/admin/content
* Sync the contact.form.feedback recipient to `site_mail`

I believe this is the big list of modules and themes that will need to verify are installed after the standard profiles are installed.

Verify these modules are installed:

- node
- history
- block
- breakpoint
- ckeditor
- config
- comment
- contextual
- contact
- menu_link_content
- datetime
- block_content
- editor
- help
- image
- menu_ui
- options
- path
- page_cache
- dynamic_page_cache
- big_pipe
- taxonomy
- dblog
- search
- shortcut
- toolbar
- field_ui
- file
- rdf
- views
- views_ui
- tour
- automated_cron
themes:
- olivero
- claro

thejimbirch’s picture

standard.links.menu.yml

standard.front_page:
title: 'Home'
route_name: ''
menu_name: main

1. This assumes there is a main menu right? Or would this create it also?
2. I don't think we can do this in config. Content maybe?

thejimbirch’s picture

StatusFileSize
new372.04 KB

Made some more commits this morning. Getting closer.

Need to add comments and tags into Article as that is how Standard has it.

Here is an updated (not complete) ERD.

ERD of the recipes

thejimbirch’s picture

Component: Documentation » Code
narendrar’s picture

Hi, how can I test what has been implemented in the branch 3301370-atomic-standard?
I want to move this issue forward but am unsure where to start exactly.

thejimbirch’s picture

Hi Narendra!

The recipes that replace the Standard profile are located in /core/recipes/ on the 3301370-atomic-standard branch.

https://git.drupalcode.org/issue/distributions_recipes-3301370/-/tree/33...

The primary recipe being the /core/recipes/standard/
https://git.drupalcode.org/issue/distributions_recipes-3301370/-/tree/33...

If you look at that recipe.yml you can see the dependencies, then their dependencies...

All of the recipes could use testing of being applied, together and separate. This should be done on Drupal installed with the minimal profile.

To apply a recipe, run:
php core/scripts/drupal recipe core/recipes/standard

After each test, be sure to reset your database by reinstalling Drupal with the minimal profile.

Please let me know if you have any questions.

Thanks!

thejimbirch changed the visibility of the branch 3301370-model-cores-standard to hidden.

thejimbirch’s picture

Version: 10.0.x-dev » 11.x-dev
thejimbirch’s picture

StatusFileSize
new101.49 KB

ok, I couldn't get the Gitlab branch to update and it it months behind, so I made a patch. There are some differences to the MR.

1. I added a profile called Empty. Since minimal still has opinions, I tried to get Drupal to the barest minimum I could. With installing this profile, we are left with 4 modules and config that comes from system and user modules.

mysql
system
update (can be uninstalled)
user
- anonymous role
- authenticated role

2. I worked on applying a couple of the recipes, but overall, most fail, and they need a lot of work. I have learned a lot on how to crafter recipes in the last year, and some of the recipes are just plain wrong.

Here is the short list on what I worked on this evening.

standard - Segmentation fault (what is that?)
administrator_role - applies
content_editor_role - applies

3. Next steps
Test and fix every recipe starting with the smallest pieces and working up. This is going to quickly expose a few issues we know about, especially Error when installing a recipe that has configuration files already in the system. as we have different configs that need the same modules.

4. My workflow was:

Apply the recipes patch, and the patch in this issue to a fresh Drupal installation
drush si empty to install Drupal with the new empty profile.
cd /web (if needed)
php core/scripts/drupal recipe core/recipes/{recipe_name}

narendrar’s picture

StatusFileSize
new99.47 KB
new5.54 KB

Attaching patch with some progress from #26

narendrar’s picture

StatusFileSize
new638 bytes
new99.6 KB

Working article_content_type recipe patch

narendrar’s picture

Status: Needs work » Needs review
StatusFileSize
new15.9 KB
new98.59 KB

All recipes can be imported now. I have commented out some config actions to do so. Some recipes can be further broken down in smaller recipes. But I think now this patch require further discussion before moving further.

phenaproxima’s picture

Nice work, @narendraR! I have added that patch to https://github.com/phenaproxima/recipe-test, which is my project to facilitate manual testing of recipes. (Feel free to clone that for your own use, and submit PRs. I can add you as a collaborator that that repo, if it will useful.)

I think a good next step here is to add test coverage that we can install the Empty profile and apply the Standard recipe. For now, we don't have to confirm that the site actually has all the stuff that Standard would provide; just that the drupal recipe command succeeds, with the Empty profile installed. Thoughts?

thejimbirch’s picture

thejimbirch changed the visibility of the branch 3301370-atomic-standard to hidden.

narendrar’s picture

StatusFileSize
new2.4 KB
new100.27 KB

Re #30, Test added, but it is giving schema error.

narendrar’s picture

StatusFileSize
new3.23 KB
new100.68 KB

Updated patch with working test.

phenaproxima’s picture

+++ b/core/lib/Drupal/Core/Recipe/ConfigConfigurator.php
@@ -30,11 +30,22 @@ public function __construct(public readonly array $config, string $recipe_direct
+          // Remove keys with empty values.
+          foreach ($active_data as $key => $value) {
+            if (empty($value)) {
+              unset($active_data[$key]);
+            }
+          }
+          // Remove keys with empty values.
+          foreach ($recipe_config as $key => $value) {
+            if (empty($value)) {
+              unset($recipe_config[$key]);
+            }
+          }

Why was this change necessary?

This is probably not good, because won't this kick out legitimate values that are, say, empty arrays, or FALSE, or 0?

narendrar’s picture

Re #35 I agree with your comment. This was done to avoid recipe fail while re-applying them due to empty `permissions` and `dependencies`.

phenaproxima’s picture

Ah, thanks for the explanation, @narendraR. What would happen, then, if we changed that code to specifically target empty permissions and dependencies arrays?

narendrar’s picture

wim leers’s picture

First: nice work getting it this far already! 😄

RE #36 + #38

  1. Why are you re-applying?
  2. What exact call sequence/recipe dependency tree triggers the RecipePreExistingConfigException exception in \Drupal\Core\Recipe\ConfigConfigurator::__construct()? (Can you please add that detailed info to #3390916: Error when installing a recipe that has configuration files already in the system, even if there is no difference? 🙏)
  3. Can you explain what the connection is to #3283900: Define recipe runtime configuration update requirements, because there is no update/drift in contents of depended upon recipes here? Unless that's what you mean by "re-applying": modifying the Standard recipe, re-applying it and then getting errors due to that? 🤔 As you can see: I'm clueless here, so I'd definitely appreciate it if you could explain this some more 🤓

Review

I also reviewed the recipe itself, to see if the patterns in there made sense to me. I have some questions and suggestions:

  1. +++ b/core/recipes/basic_html_editor/recipe.yml
    @@ -0,0 +1,22 @@
    +  import:
    +    ckeditor5: '*'
    +    editor: '*'
    

    There's nothing to import from these, so why are these listed? 🤔

  2. +++ b/core/recipes/basic_html_editor/recipe.yml
    @@ -0,0 +1,22 @@
    +#  actions:
    +#    filter.format.full_html:
    +#      setFilterConfig:
    +#        editor_file_reference:
    +#        -
    +#          id: editor_file_reference
    +#          provider: editor
    +#          status: true
    +#          weight: 11
    +#          settings: {  }
    

    Dead leftover? 😅

  3. +++ b/core/recipes/basic_html_editor/recipe.yml
    --- /dev/null
    +++ b/core/recipes/basic_html_format/config/filter.format.basic_html.yml
    

    🤔 Almost nobody will want to use only the "Basic HTML" text format without the editor. I think we should change this to a single basic_html_format_editor recipe.

  4. +++ b/core/recipes/standard/recipe.yml
    @@ -0,0 +1,67 @@
    +  - standard_editors
    ...
    +  - ckeditor5
    ...
    +  - editor
    

    🤔 I'd expect the Standard recipe to not explicitly list editor, filter or ckeditor5. I'd expect the recipes to handle that directly deal with those concepts (here right now: standard_editors) to install relevant modules for us.

  5. +++ b/core/recipes/standard/recipe.yml
    @@ -0,0 +1,67 @@
    +  - page_cache
    +  - dynamic_page_cache
    +  - big_pipe
    

    🤔 Similarly, I'd expect these modules to not be listed but instead be a core_recommended_performance recipe.

  6. +++ b/core/recipes/standard/recipe.yml
    @@ -0,0 +1,67 @@
    +  - automated_cron
    +  - announcements_feed
    

    🤔 Similarly, I'd expect these modules to not be listed but instead be a core_recommended_maintenance recipe.

narendrar’s picture

Thanks Wim for review 🙏
Re 39.1: All standard profile related recipes should be able to apply individually. So suppose if someone applies tags_taxonomy first and then try to apply article_tags recipe, tags_taxonomy will be re-applied as it is part of article_tags recipe.

39.2: If we revert the changes in ConfigConfigurator.php, RecipePreExistingConfigException will trigger. One of the reason for this is because of empty dependencies and permissions config keys.

39.3: I am not sure and hence asked at https://www.drupal.org/project/distributions_recipes/issues/3390916#comm...

Review explanation:
1. Thanks, I will remove this. I only tried to make all existing recipes run for now and will look into each recipe next.
2. I commented it intentionally to make recipe run. https://www.drupal.org/project/distributions_recipes/issues/3301370#comm...
3. 👍
4. 👍
5. Not sure if this should be clubbed into a single recipe or not. What if someone wants to only install big_pipe?
6. Same as point 5.

phenaproxima’s picture

Quoting #40:

So suppose if someone applies tags_taxonomy first and then try to apply article_tags recipe, tags_taxonomy will be re-applied as it is part of article_tags recipe.

This seems concerning.

Remember: as things currently stand, your site config can’t deviate from the recipe’s config, or you get PreExistingConfigException. Does this mean, effectively, that you’re locked in to the opinions of an entire recipe stack if you merely want to add some functionality?!

narendrar’s picture

StatusFileSize
new12.22 KB
new106.49 KB

Re:

Does this mean, effectively, that you’re locked in to the opinions of an entire recipe stack if you merely want to add some functionality?

This is what I believe.

After applying attached patch, I did below steps:

  1. Run drush si -y and drush cex -y and added config files in git.
  2. Run drush si -y empty && drush cex -y && php core/scripts/drupal recipe core/recipes/standard && drush -y cex && drush uli --uri=http://recipe.test/

After doing second step, only change in configuration is related to change in uuid and removal of

-_core:
-  default_config_hash

key from files. Also I am not sure how to add override core.menu.static_menu_link_overrides.yml standard config file.

After running second step, I am getting below error:
TypeError: Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}(): Argument #1 ($definition) must be of type Drupal\Core\Field\FieldStorageDefinitionInterface, __PHP_Incomplete_Class given in Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}() (line 175 of /core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php). which I am not sure how to solve.

If I remove config folder from user_user_type recipe, second step will work without error and I am not getting above error.

PS: Please do not review patch(how files are added or restructuring of recipes), as I have added all configs to match it similar to standard profile and it requires lots of refactoring. But to make it similar to standard profile and find out the issues I did it in this way.

narendrar’s picture

StatusFileSize
new270 bytes
new106.94 KB

To overcome core.menu.static_menu_link_overrides.yml issue, I added it in empty profile. Still getting the same error as above. Now configurations of of standard profile and standard recipe are exactly same except default_config_hash and default_config_hash

wim leers’s picture

#40

  1. Could you please add a comment to the commented out pieces? That'll make this easier to understand and evolve 😊
  1. … then they can create just a new recipe? Recipes are packaged opinions. Packaged recommendations. Drupal core's recommendation can be to install a bunch of performance-related modules together.
  2. See above.

#41 + #42:

Re:
Does this mean, effectively, that you’re locked in to the opinions of an entire recipe stack if you merely want to add some functionality?

This is what I believe.

That's also my impression of the status quo based on what I've seen. That's why issues like #3390916: Error when installing a recipe that has configuration files already in the system, even if there is no difference, #3283669: Review recipe implications for PreExistingConfigException, #3393086: Optional configuration is imported even when module dependencies aren't there. etc. are so important to solve prior to wide adoption.

AFAICT the reason this hasn't been considered a major problem so far is that Recipes has only been used for spinning up a new site, i.e. to reduce initial development time. The ability to apply recipes to an already existing site (and hence configured by a human) has AFAICT been considered something for a future iteration of recipes. But we are trying to change that from "distant future" to "near future" and ideally "now" 🤓

After doing second step, only change in configuration is related to change in uuid and removal of

-_core:
-  default_config_hash

key from files.

Why do you say this explicitly? As a statement of success or as a description of a bug? 😅 Because thanks to this:

        // @todo investigate if there is any generic code in core for this.
        unset($active_data['uuid'], $active_data['_core']);

in ConfigConfigurator changes in those aspects do not trigger RecipePreExistingConfigException 👍

Also I am not sure how to add override core.menu.static_menu_link_overrides.yml standard config file.

The purpose of this issue is to replace the Standard install profile with a recipe. A recipe cannot contain any configuration. Therefore AFAICT you can do what you already did for core/profiles/standard/config/install/node.settings.yml and all other Standard-owned config (i.e. everything added by #2990776: Remove config-editing parts from standard_install() in favor of exported configuration): use config actions. An empty core.menu.static_menu_link_overrides is created upon site install, see core/config/install/core.menu.static_menu_link_overrides.yml (TIL that exists!).

After running second step, I am getting below error:
TypeError: Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}(): Argument #1 ($definition) must be of type Drupal\Core\Field\FieldStorageDefinitionInterface, __PHP_Incomplete_Class given in Drupal\Core\Entity\Sql\DefaultTableMapping::Drupal\Core\Entity\Sql\{closure}() (line 175 of /core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php). which I am not sure how to solve.

Some quick searching yields https://stackoverflow.com/a/6575098 → it sounds like the autoloader does not have all the classes it should have. Either a composer install problem (i.e. it didn't create or failed to update the autoloader), or potentially a problem with a race condition between module installation and invoking logic in a freshly installed module? 🤔

If I remove config folder from user_user_type recipe, second step will work without error and I am not getting above error.

Hm that suggests my theory above is wrong. What's the full stack trace, i.e. what code is getting executed that makes it hit this point eventually?

narendrar’s picture

StatusFileSize
new1.46 KB
new108.41 KB

Re #44,
I will address the review points in upcoming patches. Thanks 🙏

Above error seems to be cache issue.
drush si -y empty && drush cex -y && php core/scripts/drupal recipe core/recipes/standard && drush -y cex && <strong>drush cr</strong> && ./vendor/bin/drush uli --uri=http://recipe.test/
Running drush cr before visiting website fixed the issue. See #3315694: Allow recipe command to write to the container - ensuring that cache does not be cleared after a recipe installs a module

wim leers’s picture

@narendraR I updated that issue: #3315694-7: Allow recipe command to write to the container - ensuring that cache does not be cleared after a recipe installs a module — can you help push that issue forward by providing exact steps to reproduce this today (it was created in late 2022, >1 year ago). 🙏

narendrar’s picture

StatusFileSize
new19.52 KB
new107.78 KB

Re #46, Added steps to reproduce the issue.

Re #40, Addressed all review points.

Some refactoring is done in attached patch with all recipes working individually and standard recipe having same configuration as standard profile. This patch still needs more refactoring from my end before asking for another review.

narendrar’s picture

Status: Needs work » Needs review
StatusFileSize
new10.45 KB
new109.65 KB

I have made changes in recipes and it is up for review. 🙏

phenaproxima’s picture

Nice work, @narendraR!

I added this patch to https://github.com/phenaproxima/recipe-test, then ran the custom script composer run install-from-recipe (which installs the Empty profile and applies the recipe). It worked!

Buuut...then I tried making some changes. I wanted to see what would happen if I excluded the Article content type, so I made the recipes section of web/core/recipes/standard/recipe.yml look like this:

  - basic_block_type
#  - article_comment
#  - article_tags
  - feedback_contact_form
  - page_content_type
#  - standard_content_types
  - standard_editors
  - standard_roles
  - user_user_type
  - restricted_html_format
  - core_recommended_performance
  - core_recommended_maintenance
  - core_recommended_themes

(Removed the Article stuff and standard_content_type; added page_content_type.)

And...got an error on my next run of composer run install-from-recipe:

In RecipeConfigInstaller.php line 53:
                                                                   
  The configuration 'views.view.frontpage' has unmet dependencies  

When I added a debug line, I discovered that the missing dependency is core.entity_view_mode.node.rss.

This points to some sort of bug, though I don't have time to dive into it. Why does removing the Article content type cause the RSS view mode to stop existing?

phenaproxima’s picture

Ah, I see why the problem in #49 happens -- it's because only the article_content_type recipe actually bothers to import that view mode.

thejimbirch’s picture

I believe dependent recipes are applied first.

While the standard/recipe.yml requires core's node module's config you need, the page_content_type/recipe.yml does not.

wim leers’s picture

#50 seems to imply that to achieve truly reliable and composable recipes, that we should have automatic test coverage for each recipe that verifies its installability.

#51 points out there is one missing dependency. Right now finding the culprit is a manual process (which @phenaproxima did in #50).

I propose that we do NOT fix this manually, and instead first write a test that is able to test all discovered recipes, and verifies they're all complete wrt config dependencies. That should result in @phenaproxima's finding being discovered automatically.

In other words: let's automate this once now to allow iterating faster on this patch! (Because the composition of each recipe is bound to change before this gets committed, and every such refactoring is likely to introduce new bugs due to oversights — which is normal for humans, so let's let the computers do it for us 🤓.)

phenaproxima’s picture

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

I kinda tend to agree with Wim here. Standard's dependency tree is very dense, and we will almost certainly miss things if we try to keep it in our brains.

thejimbirch’s picture

Would this be a test that is part of the Standard Profile, or of Recipes? If it the later, shouldn't that be another issue?

I don't do much with core tests. Would this be something a recipe creator could run on their local to validate their recipe dependencies?

wim leers’s picture

Issue tags: +Needs followup

#53: 👍 Adding one more tag: once the test exists and has proven to be helpful, we'll want to extract that test coverage into a separate issue, like @thejimbirch suggests in #54.

#54: The latter. But it should be developed here first, because this is by far the most complex set of recipes. Once the test has proven to be working (i.e. automatically identify what @phenaproxima identified in #50), then we should convert it to a separate issue + MR with explicit test coverage. That can then land first, and then this MR can be rebased (and be smaller again).

Would this be something a recipe creator could run on their local to validate their recipe dependencies?

Eventually, yes. It's related to #3400672: Robustly validate the structure of recipe.yml. #3400672 currently is scoped to only verify that the structure of a recipe.yml file is complete (all necessary key-value pairs defined) and consistent (for example: if a recipe installs module FOO, then it must also specify which config entities of FOO to install). What's being described here (#52) is going further: if we're talking about a BAR recipe that depends on FOO and BAZ, then it'd verify that for all config entities installed/modified by BAR, that their config dependencies are met thanks to FOO and BAZ.

phenaproxima’s picture

Status: Needs work » Closed (duplicate)
Related issues: +#3417835: Convert the Standard install profile into a set of recipes

Okay, we don't know how the hell this happened but the issue fork is all bungled up - possibly because it was opened before 11.x was branched.

At @alexpott's suggestion, I'm closing this issue out and we'll move over to a new issue -- #3417835: Convert the Standard install profile into a set of recipes -- and a new issue fork therein. All credit has been transferred.

See you there!

murz’s picture

As we now have the ability to install Drupal directly from a recipe, would be great to add this feature to the test-site.php to use recipes in tests too, linking a related issue about this: #3581540: Extend test-site.php to allow install sites from recipes