Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
efe4a69
core: extend When condition schema validation - remove legacy schema …
blindzero Dec 30, 2025
e3efcf2
core: extend When condition schema validation - remove legacy schema …
blindzero Dec 30, 2025
bddf2dd
Merge branch 'issues/8-Workflow-conditionsguards-evaluate-`when`-duri…
blindzero Dec 30, 2025
75b2112
core: evaluate new When condition DSL
blindzero Dec 30, 2025
4b4321d
core: rename When to Condition (schema validation)
blindzero Dec 30, 2025
a94ef17
core: evaluate Condition DSL (All/Any/None + Path/Value(s))
blindzero Dec 30, 2025
8b5610a
core: add unit tests for Condition schema and evaluator
blindzero Dec 30, 2025
b2c6fb2
tests: rename When tests to Condition
blindzero Dec 30, 2025
91fa5b9
tests: migrate Invoke-IdlePlan condition tests to new Condition DSL
blindzero Dec 30, 2025
c931566
core: evaluate step conditions during planning (NotApplicable)
blindzero Dec 30, 2025
8fc6a96
a
blindzero Dec 30, 2025
235cf77
core: skip NotApplicable steps during execution
blindzero Dec 30, 2025
b824b1e
core: evaluate new When condition DSL
blindzero Dec 30, 2025
b5e4c53
core: rename When to Condition (schema validation)
blindzero Dec 30, 2025
8bddc85
core: evaluate Condition DSL (All/Any/None + Path/Value(s))
blindzero Dec 30, 2025
1b862fc
core: add unit tests for Condition schema and evaluator
blindzero Dec 30, 2025
aacecd9
tests: rename When tests to Condition
blindzero Dec 30, 2025
4940240
tests: migrate Invoke-IdlePlan condition tests to new Condition DSL
blindzero Dec 30, 2025
b6670df
core: evaluate step conditions during planning (NotApplicable)
blindzero Dec 30, 2025
99a62d3
a
blindzero Dec 30, 2025
1170ec5
core: skip NotApplicable steps during execution
blindzero Dec 30, 2025
ff406dd
core: rename When to Condition in workflow schema validation
blindzero Dec 31, 2025
9d30941
fix(core): harden Condition DSL validation and planning
blindzero Dec 31, 2025
e311834
test(core): stabilize Condition DSL tests
blindzero Dec 31, 2025
26074f6
docs(examples): migrate workflow samples from When to Condition
blindzero Dec 31, 2025
bbfb026
Workflow conditions/guards: evaluate `when` during planning
blindzero Dec 31, 2025
5959c95
docs: updated Cmldlet reference
blindzero Dec 31, 2025
21c4c67
ändern auf BeforeDiscovery für Import
blindzero Dec 31, 2025
9b3358f
test: add centralized module import helpers
blindzero Dec 31, 2025
8cbc470
test: normalize module import across tests
blindzero Dec 31, 2025
1922a48
core: fix resolve step handlers via Get-IdleStepRegistry
blindzero Dec 31, 2025
f907b96
test(core): prevent regression for built-in step discovery without St…
blindzero Dec 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/reference/cmdlets/Invoke-IdlePlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Executes an IdLE plan.
## SYNTAX

```
Invoke-IdlePlan [-Plan] <Object> [[-Providers] <Object>] [[-EventSink] <Object>]
Invoke-IdlePlan [-Plan] <Object> [[-Providers] <Hashtable>] [[-EventSink] <Object>]
[-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

Expand Down Expand Up @@ -41,15 +41,15 @@ Aliases:
Required: True
Position: 1
Default value: None
Accept pipeline input: False
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```

### -Providers
Provider registry/collection passed through to execution.

```yaml
Type: Object
Type: Hashtable
Parameter Sets: (All)
Aliases:

Expand Down Expand Up @@ -129,7 +129,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable

## OUTPUTS

### System.Object
### PSCustomObject (PSTypeName: IdLE.ExecutionResult)
## NOTES

## RELATED LINKS
4 changes: 2 additions & 2 deletions docs/usage/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ The host maps step types to step implementations via a step registry.

## Conditional steps

Steps can be skipped using declarative `When` conditions.
Steps can be skipped using declarative `Condition` key.

Example:

```powershell
When = @{
Condition = @{
Path = 'Plan.LifecycleEvent'
Equals = 'Joiner'
}
Expand Down
32 changes: 32 additions & 0 deletions examples/workflows/joiner-with-condition.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@{
Name = 'Joiner - Condition Demo'
LifecycleEvent = 'Joiner'
Steps = @(
@{
Name = 'EmitOnlyForJoiner'
Type = 'IdLE.Step.EmitEvent'
Condition = @{
Equals = @{
Path = 'Plan.LifecycleEvent'
Value = 'Joiner'
}
}
With = @{
Message = 'This step runs only if Plan.LifecycleEvent == Joiner.'
}
}
@{
Name = 'SkipForJoiner'
Type = 'IdLE.Step.EmitEvent'
Condition = @{
Equals = @{
Path = 'Plan.LifecycleEvent'
Value = 'Leaver'
}
}
With = @{
Message = 'You should never see this in a Joiner run.'
}
}
)
}
28 changes: 0 additions & 28 deletions examples/workflows/joiner-with-when.psd1

This file was deleted.

146 changes: 146 additions & 0 deletions src/IdLE.Core/Private/Test-IdleCondition.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
function Test-IdleCondition {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidateNotNull()]
[hashtable] $Condition,

[Parameter(Mandatory)]
[ValidateNotNull()]
[object] $Context
)

# Evaluates a declarative Condition (data-only) against the provided context.
#
# Supported schema (validated by Test-IdleConditionSchema):
# - Groups: All | Any | None (each contains an array/list of condition nodes)
# - Operators:
# - Equals = @{ Path = '<path>'; Value = <value> }
# - NotEquals = @{ Path = '<path>'; Value = <value> }
# - Exists = '<path>' OR @{ Path = '<path>' }
# - In = @{ Path = '<path>'; Values = <array|scalar> }
#
# Paths are resolved via Get-IdleValueByPath against the provided $Context.
# For readability in configuration, a leading "context." prefix is ignored.

$schemaErrors = Test-IdleConditionSchema -Condition $Condition -StepName $null
if (@($schemaErrors).Count -gt 0) {
$msg = "Condition schema validation failed: {0}" -f ([string]::Join(' ', @($schemaErrors)))
throw [System.ArgumentException]::new($msg, 'Condition')
}

function Resolve-IdleConditionPathValue {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Path
)

# Allow "context." prefix for readability in config files.
$effectivePath = if ($Path.StartsWith('context.')) { $Path.Substring(8) } else { $Path }

return Get-IdleValueByPath -Object $Context -Path $effectivePath
}

function Test-IdleConditionNode {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidateNotNull()]
[System.Collections.IDictionary] $Node
)

# GROUPS
if ($Node.Contains('All')) {
foreach ($child in @($Node.All)) {
if (-not (Test-IdleConditionNode -Node ([System.Collections.IDictionary]$child))) {
return $false
}
}
return $true
}

if ($Node.Contains('Any')) {
foreach ($child in @($Node.Any)) {
if (Test-IdleConditionNode -Node ([System.Collections.IDictionary]$child)) {
return $true
}
}
return $false
}

if ($Node.Contains('None')) {
foreach ($child in @($Node.None)) {
if (Test-IdleConditionNode -Node ([System.Collections.IDictionary]$child)) {
return $false
}
}
return $true
}

# OPERATORS
if ($Node.Contains('Equals')) {
$op = $Node.Equals

$actual = Resolve-IdleConditionPathValue -Path ([string]$op.Path)
$expected = $op.Value

# Stable semantics: compare as strings (keeps config predictable across providers/types).
return ([string]$actual -eq [string]$expected)
}

if ($Node.Contains('NotEquals')) {
$op = $Node.NotEquals

$actual = Resolve-IdleConditionPathValue -Path ([string]$op.Path)
$expected = $op.Value

return ([string]$actual -ne [string]$expected)
}

if ($Node.Contains('Exists')) {
$existsVal = $Node.Exists

$path = if ($existsVal -is [string]) {
[string]$existsVal
} else {
[string]$existsVal.Path
}

$value = Resolve-IdleConditionPathValue -Path $path
return ($null -ne $value)
}

if ($Node.Contains('In')) {
$op = $Node.In

$actual = Resolve-IdleConditionPathValue -Path ([string]$op.Path)
$values = $op.Values

if ($null -eq $values) {
return $false
}

# Treat scalar and array uniformly.
$candidates = if ($values -is [System.Collections.IEnumerable] -and -not ($values -is [string])) {
@($values)
} else {
@($values)
}

foreach ($candidate in $candidates) {
if ([string]$actual -eq [string]$candidate) {
return $true
}
}

return $false
}

# Should never happen due to schema validation.
return $false
}

return (Test-IdleConditionNode -Node $Condition)
}
Loading