A run started with exactly the variables its caller passed to WorkflowEngine::start(), so a workflow that needed an input depended on whichever code started it. Two of the shipped starters pass none at all, and a workflow exported as configuration arrived with nothing to run on.

A definition may now declare the instance variables its runs start with. The engine seeds them at instance scope when the run starts, before its first step.

A value the caller passes wins over a declared one of the same name, including one passed explicitly as NULL: the caller knows the facts of the particular run, while the definition knows only its own defaults. A subprocess child is a caller like any other, so its parent's mapped input wins and the child's own declarations fill in the rest.

The declarations are read off the version the instance pinned, and they are part of the executable shape, so editing them cuts a new version and a run already going keeps what it started with.

A declared name must start with a letter, which keeps it out of the engine's reserved namespace of names beginning with two underscores. Pre-seeding a node's timeout anchor would start a run with a deadline the engine never set, invisible in the variable view and in the audit trail. The API layer already refused such a name from a remote caller; a Regex constraint now refuses it in configuration, and the entity drops it on the storage path that an import bypasses the constraint on.

Authors edit the declarations from a workflow's Variables operation on the model list: a name and a value per row, opening with one empty row and a control that appends the next without saving, so declaring several does not mean a save between each. Clearing a name stops declaring it. The form writes each value as text, which is what a routing condition compares against; a value that text cannot carry, brought in by imported configuration, is shown and left alone rather than flattened.

The page also declares a tab beside Retention, Execution and Reading, but a workflow's canonical page is the modeler view and renders no tabs, which is why the model list carries an operation per per-workflow page. Variables is listed there now, and so is Reading, which was missing for the same reason and was reachable only by typing its path.

The same branch also spells every Choice constraint in the module's configuration schema the way symfony/validator 7.4 expects, with the choices under a choices key. Nothing had noticed the deprecated spelling, because nothing validated configuration until the tests added here did. Sixteen constraints across four schema files, spelling only: each file was compared before and after to prove the choices are unchanged.

Came up while designing #3614495: Make taking the holds off the clock an explicit workflow step, instead of imposing it on every workflow from the starter, which no longer needs it, so this stands on its own merits.

AI-Generated: Yes (Claude Code was used to help draft this issue summary and to write the code and tests on the merge request. I reviewed and ran the work myself before posting it.)

Issue fork orchestra-3614496

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

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review
mably’s picture

Title: Let a workflow definition declare the instance variables its runs start with » Let a workflow definition declare the instance variables its runs start with, so a run does not depend on whichever code starts it
Issue summary: View changes
mably’s picture

Issue summary: View changes

  • mably committed 037a5586 on 1.x
    feat: #3614496 Let a workflow definition declare the instance variables...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.