Problem/Motivation

Workflow config entities are partially validatable using the typed config system, but not quite. There are several properties that are not yet validatable:

$ ./vendor/bin/drush config:inspect --filter-keys=workflows.workflow.editorial --detail --list-constraints  --fields=key,validatability,constraints
➜  🤖 Analyzing…

 ------------------------------------------ ------------- --------------------------------------------------------------------------------- 
  Key                                        Validatable   Validation constraints                                                           
 ------------------------------------------ ------------- --------------------------------------------------------------------------------- 
  workflows.workflow.editorial               53%           ValidKeys: '<infer>'                                                             
   workflows.workflow.editorial:             Validatable   ValidKeys: '<infer>'                                                             
   workflows.workflow.editorial:_core        Validatable   ValidKeys:                                                                       
                                                             - default_config_hash                                                          
   workflows.workflow.editorial:_core.defa   Validatable   NotNull: {  }                                                                    
  ult_config_hash                                          Regex: '/^[a-zA-Z0-9\-_]+$/'                                                     
                                                           Length: 43                                                                       
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:dependenci   Validatable   ValidKeys: '<infer>'                                                             
  es                                                                                                                                        
   workflows.workflow.editorial:dependenci   NOT           ❌ @todo Add validation constraints to ancestor type: config_dependencies        
  es.module                                                                                                                                 
   workflows.workflow.editorial:dependenci   Validatable   NotBlank: {  }                                                                   
  es.module.0                                              ExtensionName: {  }                                                              
                                                           ExtensionExists: module                                                          
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:id           Validatable   Regex:                                                                           
                                                             pattern: '/^[a-z0-9_]+$/'                                                      
                                                             message: 'The %value machine name is not valid.'                               
                                                           Length:                                                                          
                                                             max: 166                                                                       
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:label        Validatable   Regex:                                                                           
                                                             pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           NotBlank: {  }                                                                   
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:langcode     Validatable   NotNull: {  }                                                                    
                                                           Choice:                                                                          
                                                             callback:                                                                      
                                                           'Drupal\Core\TypedData\Plugin\DataType\LanguageReference::getAllValidLangcodes'  
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:status       Validatable   ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type         Validatable   PluginExists:                                                                    
                                                             manager: plugin.manager.workflows.type                                         
                                                             interface: Drupal\workflows\WorkflowTypeInterface                              
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs                                                                                                                                       
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type:                            
  ngs.default_moderation_state                             workflow.type_settings.content_moderation                                        
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type:                            
  ngs.entity_types                                         workflow.type_settings.content_moderation                                        
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type:                            
  ngs.states                                               workflow.type_settings.content_moderation                                        
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.states.archived                                                                                                                       
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.archived.default_revision                                                                                                      
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.states.archived.label                                  pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.archived.published                                                                                                             
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: content_moderation.state   
  ngs.states.archived.weight                                                                                                                
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.states.draft                                                                                                                          
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.draft.default_revision                                                                                                         
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.states.draft.label                                     pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.draft.published                                                                                                                
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: content_moderation.state   
  ngs.states.draft.weight                                                                                                                   
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.states.published                                                                                                                      
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.published.default_revision                                                                                                     
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.states.published.label                                 pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   Validatable   ↣ PrimitiveType: {  }                                                            
  ngs.states.published.published                                                                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: content_moderation.state   
  ngs.states.published.weight                                                                                                               
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type:                            
  ngs.transitions                                          workflow.type_settings.content_moderation                                        
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.transitions.archive                                                                                                                   
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archive.from                                                                                                              
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archive.from.0                                                                                                            
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.transitions.archive.label                              pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archive.to                                                                                                                
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archive.weight                                                                                                            
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.transitions.archived_draft                                                                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_draft.from                                                                                                       
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_draft.from.0                                                                                                     
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.transitions.archived_draft.label                       pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_draft.to                                                                                                         
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_draft.weight                                                                                                     
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.transitions.archived_published                                                                                                        
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_published.from                                                                                                   
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_published.from.                                                                                                  
  0                                                                                                                                         
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.transitions.archived_published.label                   pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_published.to                                                                                                     
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.archived_published.weigh                                                                                                  
  t                                                                                                                                         
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.transitions.create_new_draft                                                                                                          
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.create_new_draft.from                                                                                                     
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.create_new_draft.from.0                                                                                                   
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.create_new_draft.from.1                                                                                                   
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.transitions.create_new_draft.label                     pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.create_new_draft.to                                                                                                       
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.create_new_draft.weight                                                                                                   
   workflows.workflow.editorial:type_setti   Validatable   ValidKeys: '<infer>'                                                             
  ngs.transitions.publish                                                                                                                   
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.publish.from                                                                                                              
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.publish.from.0                                                                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.publish.from.1                                                                                                            
   workflows.workflow.editorial:type_setti   Validatable   Regex:                                                                           
  ngs.transitions.publish.label                              pattern: '/([^\PC])/u'                                                         
                                                             match: false                                                                   
                                                             message: 'Labels are not allowed to span multiple lines or contain control     
                                                           characters.'                                                                     
                                                           ↣ PrimitiveType: {  }                                                            
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.publish.to                                                                                                                
   workflows.workflow.editorial:type_setti   NOT           ❌ @todo Add validation constraints to ancestor type: workflows.transition       
  ngs.transitions.publish.weight                                                                                                            
   workflows.workflow.editorial:uuid         Validatable   Uuid: {  }                                                                       
                                                           ↣ PrimitiveType: {  }                                                            
 ------------------------------------------ ------------- --------------------------------------------------------------------------------- 

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector — or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. Install the Standard install profile + content_moderation
  5. vendor/bin/drush config:inspect --filter-keys=workflows.workflow.editorial --detail --list-constraints

Proposed resolution

  1. Add validation constraints.
  2. Mark FullyValidatable.

Remaining tasks

Review.

User interface changes

None.

API changes

TBD

Data model changes

None.

Release notes snippet

N/A

Issue fork drupal-2920441

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

Sam152 created an issue. See original summary.

sam152’s picture

wim leers’s picture

Would be cool to have the Workflow config entity type be the very first entity type with full config entity validation. Because it is the youngest config entity type addition to core. And imagine a drag-and-drop, snazzy decoupled JS configuration UI for it! With this implemented, that'd actually be possible :)

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

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.

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

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.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.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). 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.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now 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.

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

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now 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.

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

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now 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.

Version: 10.1.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, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

wim leers’s picture

See the parent issue — several config entity types in Drupal core are now fully validatable! 🚀

wim leers’s picture

Assigned: Unassigned » wim leers
Issue summary: View changes

I'll get this going…

wim leers’s picture

Title: Add config validation for workflow entities. » Add config validation for workflow entities
Assigned: wim leers » Unassigned
Status: Active » Needs review
Related issues: +#2871746: Sequences of mappings cannot merge keys from a subsequent definition of mapping keys

This MR gets us to 100% validatability, but at the last moment I discovered there was a whole new edge case: predefined_states_workflow_test_type — where possible states are NOT defined in the config 😬

Anyway, this should still serve as a good starting point 👍

P.S.: this might be blocked on #2871746: Sequences of mappings cannot merge keys from a subsequent definition of mapping keys?

wim leers’s picture

The test failures seem to have revealed a long-standing bug in how %parent.%key works for a nested sequence item 😬 We'll need to fix that first.

wim leers’s picture

The ExistsIn constraint I wrote for this MR is already useful in another: see #3422862-4: Add validation constraints to book.settings.

smustgrave’s picture

Status: Needs review » Postponed

Seems this is postponed on #2871746: Sequences of mappings cannot merge keys from a subsequent definition of mapping keys

Also left a comment in [#15456258] about breaking that up.

wim leers’s picture

Status: Postponed » Needs work

That's not yet certain. 😅 Plus, we can continue here regardless of that.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.