From 1608bd5c871f02dd7f138dd1ada935b9addace9d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 12:45:03 +0000 Subject: [PATCH 1/7] Initial plan From 2c9c03a3e840e6e0a8ee9ee4b069765d56101be8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 12:48:37 +0000 Subject: [PATCH 2/7] Restructure examples: separate Mock/Live/Templates workflows and update demo script Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- README.md | 6 +- examples/Invoke-IdleDemo.ps1 | 49 ++++++-- examples/README.md | 105 +++++++++++++++--- .../{ => live}/ad-joiner-complete.psd1 | 0 .../{ => live}/ad-leaver-offboarding.psd1 | 0 .../ad-mover-department-change.psd1 | 0 .../{ => live}/entraid-joiner-complete.psd1 | 0 .../entraid-leaver-offboarding.psd1 | 0 .../entraid-mover-department-change.psd1 | 0 .../{ => live}/joiner-with-entraid-sync.psd1 | 0 .../{ => mock}/joiner-ensureentitlement.psd1 | 0 .../joiner-minimal-ensureattribute.psd1 | 0 .../workflows/{ => mock}/joiner-minimal.psd1 | 0 .../{ => mock}/joiner-with-condition.psd1 | 0 .../{ => mock}/joiner-with-onfailure.psd1 | 0 tests/WorkflowSamples.Tests.ps1 | 93 +++++++++++++++- 16 files changed, 221 insertions(+), 32 deletions(-) rename examples/workflows/{ => live}/ad-joiner-complete.psd1 (100%) rename examples/workflows/{ => live}/ad-leaver-offboarding.psd1 (100%) rename examples/workflows/{ => live}/ad-mover-department-change.psd1 (100%) rename examples/workflows/{ => live}/entraid-joiner-complete.psd1 (100%) rename examples/workflows/{ => live}/entraid-leaver-offboarding.psd1 (100%) rename examples/workflows/{ => live}/entraid-mover-department-change.psd1 (100%) rename examples/workflows/{ => live}/joiner-with-entraid-sync.psd1 (100%) rename examples/workflows/{ => mock}/joiner-ensureentitlement.psd1 (100%) rename examples/workflows/{ => mock}/joiner-minimal-ensureattribute.psd1 (100%) rename examples/workflows/{ => mock}/joiner-minimal.psd1 (100%) rename examples/workflows/{ => mock}/joiner-with-condition.psd1 (100%) rename examples/workflows/{ => mock}/joiner-with-onfailure.psd1 (100%) diff --git a/README.md b/README.md index 09647513..6afcdef1 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,9 @@ The demo shows: - creating a lifecycle request - building a deterministic plan from a workflow definition (`.psd1`) -- executing the plan using built-in steps (and optionally a host-provided step registry for extensions) +- executing the plan using built-in steps and a mock provider + +By default, the demo runs **Mock workflows** that work out-of-the-box without external systems. The examples folder also includes **Live workflows** that demonstrate real-world scenarios with Active Directory and Entra ID, but these require the corresponding infrastructure and provider modules. The execution result buffers all emitted events in `result.Events`. Hosts can optionally stream events live by providing `-EventSink` as an object implementing `WriteEvent(event)`. @@ -123,7 +125,7 @@ by providing `-EventSink` as an object implementing `WriteEvent(event)`. Next steps: - Documentation entry point: `docs/index.md` -- Workflow samples: `examples/workflows/` +- Workflow samples: `examples/workflows/` (organized by category: mock, live, templates) - Repository demo: `examples/Invoke-IdleDemo.ps1` - Pester tests: `tests/` diff --git a/examples/Invoke-IdleDemo.ps1 b/examples/Invoke-IdleDemo.ps1 index c24d2f3a..bc48b080 100644 --- a/examples/Invoke-IdleDemo.ps1 +++ b/examples/Invoke-IdleDemo.ps1 @@ -11,6 +11,11 @@ param( [Parameter(ParameterSetName = 'Run')] [switch]$All, + [Parameter(ParameterSetName = 'List')] + [Parameter(ParameterSetName = 'Run')] + [ValidateSet('Mock', 'Live', 'Templates', 'All')] + [string]$Category = 'Mock', + [Parameter(ParameterSetName = 'Run')] [ValidateRange(1, 50)] [int]$Repeat = 1, @@ -125,21 +130,41 @@ function Get-IdleLifecycleEventFromWorkflowName { } function Get-DemoWorkflows { + param( + [Parameter()] + [ValidateSet('Mock', 'Live', 'Templates', 'All')] + [string]$Category = 'Mock' + ) + $workflowDir = Join-Path -Path $PSScriptRoot -ChildPath 'workflows' if (-not (Test-Path -Path $workflowDir)) { throw "Workflow directory not found: $workflowDir" } - Get-ChildItem -Path $workflowDir -Filter '*.psd1' -File | - Sort-Object Name | - ForEach-Object { - [pscustomobject]@{ - Name = $_.BaseName - Path = $_.FullName - File = $_.Name - } + $categories = if ($Category -eq 'All') { + @('mock', 'live', 'templates') + } else { + @($Category.ToLowerInvariant()) + } + + $workflows = foreach ($cat in $categories) { + $catDir = Join-Path -Path $workflowDir -ChildPath $cat + if (Test-Path -Path $catDir) { + Get-ChildItem -Path $catDir -Filter '*.psd1' -File | + Sort-Object Name | + ForEach-Object { + [pscustomobject]@{ + Name = $_.BaseName + Path = $_.FullName + File = $_.Name + Category = $cat + } + } } + } + + return $workflows } function Select-DemoWorkflows { @@ -204,15 +229,15 @@ Import-Module (Join-Path $PSScriptRoot '..\src\IdLE\IdLE.psd1') -Force -ErrorAct Import-Module (Join-Path $PSScriptRoot '..\src\IdLE.Steps.Common\IdLE.Steps.Common.psd1') -Force -ErrorAction Stop Import-Module (Join-Path $PSScriptRoot '..\src\IdLE.Provider.Mock\IdLE.Provider.Mock.psd1') -Force -ErrorAction Stop -$available = @(Get-DemoWorkflows) +$available = @(Get-DemoWorkflows -Category $Category) if ($available.Count -eq 0) { - throw "No workflows found in 'examples/workflows'." + throw "No workflows found in 'examples/workflows' for category '$Category'." } if ($List) { - Write-DemoHeader "IdLE Demo – Available Examples" - $available | Select-Object Name, File | Format-Table -AutoSize + Write-DemoHeader "IdLE Demo – Available Examples (Category: $Category)" + $available | Select-Object Name, Category, File | Format-Table -AutoSize return } diff --git a/examples/README.md b/examples/README.md index 7557a0ff..c6b3957d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,44 @@ # Examples -This folder contains runnable examples for IdLE. +This folder contains runnable examples for IdLE, organized into categories based on their requirements and intended use. + +## Workflow Categories + +### Mock +Workflows that run out-of-the-box with `IdLE.Provider.Mock`. These are fully functional demonstrations requiring no external systems. + +**Prerequisites:** +- `IdLE` + `IdLE.Steps.Common` +- `IdLE.Provider.Mock` + +**Workflows:** +- `joiner-minimal.psd1` — minimal workflow with a single EmitEvent step +- `joiner-minimal-ensureattribute.psd1` — demonstrates EnsureAttribute step +- `joiner-ensureentitlement.psd1` — demonstrates EnsureEntitlement step for group assignment +- `joiner-with-condition.psd1` — demonstrates conditional step execution +- `joiner-with-onfailure.psd1` — demonstrates OnFailureSteps for cleanup and notifications + +### Live +Example workflows that require real providers and external systems (Active Directory, Entra ID, Entra Connect). These are intended as templates for production scenarios but cannot run without the necessary infrastructure. + +**Prerequisites:** +- Real AD/Entra ID environment +- Provider modules: `IdLE.Provider.ActiveDirectory`, `IdLE.Provider.EntraID`, `IdLE.Provider.DirectorySync.EntraConnect` +- Appropriate authentication/credentials + +**Workflows:** +- `ad-joiner-complete.psd1` — complete Active Directory joiner workflow +- `ad-mover-department-change.psd1` — Active Directory department change workflow +- `ad-leaver-offboarding.psd1` — Active Directory leaver offboarding workflow +- `entraid-joiner-complete.psd1` — complete Entra ID joiner workflow +- `entraid-mover-department-change.psd1` — Entra ID department change workflow +- `entraid-leaver-offboarding.psd1` — Entra ID leaver offboarding workflow +- `joiner-with-entraid-sync.psd1` — demonstrates cross-system workflow with AD and Entra ID sync + +### Templates +Generic starting points for building custom workflows. These are structurally valid but not executed in CI. + +(Currently empty - reserved for future templates) ## Run the demo @@ -10,24 +48,48 @@ From the repository root: pwsh -File .\examples\Invoke-IdleDemo.ps1 ``` -The demo: +By default, the demo runs **Mock** workflows only (deterministic, no external dependencies). -- builds a plan from a workflow (`.psd1`) -- executes the plan using mock providers -- prints step results and buffered events +### List available workflows + +```powershell +# List Mock workflows (default) +.\examples\Invoke-IdleDemo.ps1 -List -## Workflow samples +# List Live workflows +.\examples\Invoke-IdleDemo.ps1 -List -Category Live -Workflow samples are located in: +# List all workflows +.\examples\Invoke-IdleDemo.ps1 -List -Category All +``` -- `examples/workflows/` +### Run specific workflows -Highlighted samples: +```powershell +# Run specific Mock workflow by name +.\examples\Invoke-IdleDemo.ps1 -Example joiner-minimal -- `joiner-minimal.psd1` — minimal workflow with a single EmitEvent step -- `joiner-with-condition.psd1` — demonstrates conditional step execution -- `joiner-ensureentitlement.psd1` — ensures a demo group assignment via the built-in EnsureEntitlement step -- `joiner-with-onfailure.psd1` — demonstrates OnFailureSteps for cleanup and notifications +# Run all Mock workflows +.\examples\Invoke-IdleDemo.ps1 -All + +# Run all Live workflows (requires infrastructure) +.\examples\Invoke-IdleDemo.ps1 -All -Category Live +``` + +### Interactive selection + +If you run the script without parameters, it will interactively prompt you to select from available Mock workflows. + +## How it works + +The demo: + +- validates the workflow using `Test-IdleWorkflow` +- builds a plan from the workflow (`.psd1`) using `New-IdlePlan` +- executes the plan using `Invoke-IdlePlan` with mock or real providers +- prints step results and buffered events + +## Workflow structure Workflows are **data-only** PSD1 files. A minimal workflow looks like: @@ -56,3 +118,20 @@ $result.Events | Select-Object Type, StepName, Message ``` Hosts can optionally stream events live by providing `-EventSink` as an object implementing `WriteEvent(event)`. + +## Workflow Matrix + +| Workflow File | Category | Runnable with Mock | Required Providers | External Prerequisites | +|---------------|----------|--------------------|--------------------|------------------------| +| joiner-minimal.psd1 | Mock | ✅ Yes | Identity (Mock) | None | +| joiner-minimal-ensureattribute.psd1 | Mock | ✅ Yes | Identity (Mock) | None | +| joiner-ensureentitlement.psd1 | Mock | ✅ Yes | Identity (Mock) | None | +| joiner-with-condition.psd1 | Mock | ✅ Yes | Identity (Mock) | None | +| joiner-with-onfailure.psd1 | Mock | ✅ Yes | Identity (Mock) | None | +| ad-joiner-complete.psd1 | Live | ❌ No | Identity (AD) | Active Directory, credentials | +| ad-mover-department-change.psd1 | Live | ❌ No | Identity (AD) | Active Directory, credentials | +| ad-leaver-offboarding.psd1 | Live | ❌ No | Identity (AD) | Active Directory, credentials | +| entraid-joiner-complete.psd1 | Live | ❌ No | Identity (Entra ID) | Entra ID, credentials | +| entraid-mover-department-change.psd1 | Live | ❌ No | Identity (Entra ID) | Entra ID, credentials | +| entraid-leaver-offboarding.psd1 | Live | ❌ No | Identity (Entra ID) | Entra ID, credentials | +| joiner-with-entraid-sync.psd1 | Live | ❌ No | Identity (AD), Cloud (Entra ID), DirectorySync | AD, Entra ID, Entra Connect, credentials | diff --git a/examples/workflows/ad-joiner-complete.psd1 b/examples/workflows/live/ad-joiner-complete.psd1 similarity index 100% rename from examples/workflows/ad-joiner-complete.psd1 rename to examples/workflows/live/ad-joiner-complete.psd1 diff --git a/examples/workflows/ad-leaver-offboarding.psd1 b/examples/workflows/live/ad-leaver-offboarding.psd1 similarity index 100% rename from examples/workflows/ad-leaver-offboarding.psd1 rename to examples/workflows/live/ad-leaver-offboarding.psd1 diff --git a/examples/workflows/ad-mover-department-change.psd1 b/examples/workflows/live/ad-mover-department-change.psd1 similarity index 100% rename from examples/workflows/ad-mover-department-change.psd1 rename to examples/workflows/live/ad-mover-department-change.psd1 diff --git a/examples/workflows/entraid-joiner-complete.psd1 b/examples/workflows/live/entraid-joiner-complete.psd1 similarity index 100% rename from examples/workflows/entraid-joiner-complete.psd1 rename to examples/workflows/live/entraid-joiner-complete.psd1 diff --git a/examples/workflows/entraid-leaver-offboarding.psd1 b/examples/workflows/live/entraid-leaver-offboarding.psd1 similarity index 100% rename from examples/workflows/entraid-leaver-offboarding.psd1 rename to examples/workflows/live/entraid-leaver-offboarding.psd1 diff --git a/examples/workflows/entraid-mover-department-change.psd1 b/examples/workflows/live/entraid-mover-department-change.psd1 similarity index 100% rename from examples/workflows/entraid-mover-department-change.psd1 rename to examples/workflows/live/entraid-mover-department-change.psd1 diff --git a/examples/workflows/joiner-with-entraid-sync.psd1 b/examples/workflows/live/joiner-with-entraid-sync.psd1 similarity index 100% rename from examples/workflows/joiner-with-entraid-sync.psd1 rename to examples/workflows/live/joiner-with-entraid-sync.psd1 diff --git a/examples/workflows/joiner-ensureentitlement.psd1 b/examples/workflows/mock/joiner-ensureentitlement.psd1 similarity index 100% rename from examples/workflows/joiner-ensureentitlement.psd1 rename to examples/workflows/mock/joiner-ensureentitlement.psd1 diff --git a/examples/workflows/joiner-minimal-ensureattribute.psd1 b/examples/workflows/mock/joiner-minimal-ensureattribute.psd1 similarity index 100% rename from examples/workflows/joiner-minimal-ensureattribute.psd1 rename to examples/workflows/mock/joiner-minimal-ensureattribute.psd1 diff --git a/examples/workflows/joiner-minimal.psd1 b/examples/workflows/mock/joiner-minimal.psd1 similarity index 100% rename from examples/workflows/joiner-minimal.psd1 rename to examples/workflows/mock/joiner-minimal.psd1 diff --git a/examples/workflows/joiner-with-condition.psd1 b/examples/workflows/mock/joiner-with-condition.psd1 similarity index 100% rename from examples/workflows/joiner-with-condition.psd1 rename to examples/workflows/mock/joiner-with-condition.psd1 diff --git a/examples/workflows/joiner-with-onfailure.psd1 b/examples/workflows/mock/joiner-with-onfailure.psd1 similarity index 100% rename from examples/workflows/joiner-with-onfailure.psd1 rename to examples/workflows/mock/joiner-with-onfailure.psd1 diff --git a/tests/WorkflowSamples.Tests.ps1 b/tests/WorkflowSamples.Tests.ps1 index 6431712c..24f7eec8 100644 --- a/tests/WorkflowSamples.Tests.ps1 +++ b/tests/WorkflowSamples.Tests.ps1 @@ -7,13 +7,96 @@ BeforeAll { $workflowsPath = Join-Path -Path (Get-RepoRootPath) -ChildPath 'examples/workflows' } -Describe 'Example workflows' { - It 'All workflow PSD1 files validate' { - $files = Get-ChildItem -Path $workflowsPath -Filter '*.psd1' -File - $files | Should -Not -BeNullOrEmpty +Describe 'Mock example workflows' { + BeforeAll { + $mockWorkflowsPath = Join-Path -Path $workflowsPath -ChildPath 'mock' + $mockWorkflows = Get-ChildItem -Path $mockWorkflowsPath -Filter '*.psd1' -File -ErrorAction SilentlyContinue + } + + It 'Mock workflow directory exists' { + $mockWorkflowsPath | Should -Exist + } + + It 'Mock workflows exist' { + $mockWorkflows | Should -Not -BeNullOrEmpty + } + + It 'All mock workflows validate with Test-IdleWorkflow' { + foreach ($file in $mockWorkflows) { + { Test-IdleWorkflow -WorkflowPath $file.FullName } | Should -Not -Throw + } + } + + It 'All mock workflows can create a plan with Mock provider' { + $providers = @{ + Identity = New-IdleMockIdentityProvider + } + + foreach ($file in $mockWorkflows) { + $workflow = Import-PowerShellDataFile -Path $file.FullName + $lifecycleEvent = if ($workflow.ContainsKey('LifecycleEvent')) { $workflow.LifecycleEvent } else { 'Joiner' } + $request = New-IdleLifecycleRequest -LifecycleEvent $lifecycleEvent -Actor 'test-user' + + { New-IdlePlan -WorkflowPath $file.FullName -Request $request -Providers $providers } | Should -Not -Throw + } + } + + It 'All mock workflows execute successfully with Mock provider' { + $providers = @{ + Identity = New-IdleMockIdentityProvider + } + + foreach ($file in $mockWorkflows) { + $workflow = Import-PowerShellDataFile -Path $file.FullName + $lifecycleEvent = if ($workflow.ContainsKey('LifecycleEvent')) { $workflow.LifecycleEvent } else { 'Joiner' } + $request = New-IdleLifecycleRequest -LifecycleEvent $lifecycleEvent -Actor 'test-user' + + $plan = New-IdlePlan -WorkflowPath $file.FullName -Request $request -Providers $providers + $result = Invoke-IdlePlan -Plan $plan -Providers $providers + + $result.Status | Should -Be 'Completed' -Because "Mock workflow '$($file.Name)' should complete successfully" + } + } +} + +Describe 'Live example workflows' { + BeforeAll { + $liveWorkflowsPath = Join-Path -Path $workflowsPath -ChildPath 'live' + $liveWorkflows = Get-ChildItem -Path $liveWorkflowsPath -Filter '*.psd1' -File -ErrorAction SilentlyContinue + } + + It 'Live workflow directory exists' { + $liveWorkflowsPath | Should -Exist + } + + It 'Live workflows exist' { + $liveWorkflows | Should -Not -BeNullOrEmpty + } - foreach ($file in $files) { + It 'All live workflows validate with Test-IdleWorkflow' { + foreach ($file in $liveWorkflows) { { Test-IdleWorkflow -WorkflowPath $file.FullName } | Should -Not -Throw } } } + +Describe 'Template example workflows' { + BeforeAll { + $templatesWorkflowsPath = Join-Path -Path $workflowsPath -ChildPath 'templates' + $templateWorkflows = Get-ChildItem -Path $templatesWorkflowsPath -Filter '*.psd1' -File -ErrorAction SilentlyContinue + } + + It 'Templates workflow directory exists' { + $templatesWorkflowsPath | Should -Exist + } + + It 'All template workflows validate with Test-IdleWorkflow (if any exist)' { + if ($templateWorkflows) { + foreach ($file in $templateWorkflows) { + { Test-IdleWorkflow -WorkflowPath $file.FullName } | Should -Not -Throw + } + } else { + Set-ItResult -Skipped -Because 'No template workflows exist yet' + } + } +} From 1b3ba901fa48decc11dad94676799264732ab1de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 13:25:45 +0000 Subject: [PATCH 3/7] Fix: Add templates directory with .gitkeep to resolve test failure Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- examples/workflows/templates/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/workflows/templates/.gitkeep diff --git a/examples/workflows/templates/.gitkeep b/examples/workflows/templates/.gitkeep new file mode 100644 index 00000000..c4f88305 --- /dev/null +++ b/examples/workflows/templates/.gitkeep @@ -0,0 +1 @@ +# Templates directory From 903c6a2a9002c49eb63a21c4bc378c4652b5f12d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:37:51 +0000 Subject: [PATCH 4/7] Restrict demo script execution to Mock workflows only - Add validation to prevent execution of Live/Templates workflows - Live workflows require real providers (DirectorySync, Cloud) which are not available in the demo script - Users can still list Live workflows with -List -Category Live - Update README to remove misleading instruction about running Live workflows - Provide clear error message when attempting to run non-Mock workflows Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- examples/Invoke-IdleDemo.ps1 | 7 +++++++ examples/README.md | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/Invoke-IdleDemo.ps1 b/examples/Invoke-IdleDemo.ps1 index bc48b080..c2982ee5 100644 --- a/examples/Invoke-IdleDemo.ps1 +++ b/examples/Invoke-IdleDemo.ps1 @@ -243,6 +243,13 @@ if ($List) { $selected = @(Select-DemoWorkflows -AvailableWorkflows $available -ExampleNames $Example -AllWorkflows:$All) +# Validate that execution is only attempted with Mock workflows +# Live and Templates workflows are for reference/validation only and require real providers +if ($selected | Where-Object { $_.Category -ne 'mock' }) { + $nonMockWorkflows = $selected | Where-Object { $_.Category -ne 'mock' } | Select-Object -ExpandProperty Name + throw "Cannot execute non-Mock workflows: $($nonMockWorkflows -join ', '). Live and Templates workflows require real providers and infrastructure. Use '-Category Mock' (default) or '-List -Category Live' to view Live workflows without executing them." +} + $providers = @{ Identity = New-IdleMockIdentityProvider } diff --git a/examples/README.md b/examples/README.md index c6b3957d..33e2dddb 100644 --- a/examples/README.md +++ b/examples/README.md @@ -71,11 +71,10 @@ By default, the demo runs **Mock** workflows only (deterministic, no external de # Run all Mock workflows .\examples\Invoke-IdleDemo.ps1 -All - -# Run all Live workflows (requires infrastructure) -.\examples\Invoke-IdleDemo.ps1 -All -Category Live ``` +**Note:** Only Mock workflows can be executed via the demo script. Live workflows require real providers and infrastructure, and cannot be run through this demo. Use `-List -Category Live` to view Live workflows for reference. + ### Interactive selection If you run the script without parameters, it will interactively prompt you to select from available Mock workflows. From b7ab2a28ab6a9dea404e021c21bc43736d0821a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 15:07:41 +0000 Subject: [PATCH 5/7] Remove restrictive validation - allow Live workflow execution attempts - Remove validation that blocked Live/Templates workflow execution - Live workflows can now be attempted but will fail naturally if providers are missing - This preserves the distinction: Mock (works out-of-the-box), Live (requires real providers), Templates (starting points) - Engine provides clear error messages about missing provider capabilities - Update README to clarify behavior and how to run Live workflows - Default remains Mock for safe out-of-the-box experience Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- examples/Invoke-IdleDemo.ps1 | 10 +++------- examples/README.md | 7 +++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/Invoke-IdleDemo.ps1 b/examples/Invoke-IdleDemo.ps1 index c2982ee5..9e2e11b4 100644 --- a/examples/Invoke-IdleDemo.ps1 +++ b/examples/Invoke-IdleDemo.ps1 @@ -243,13 +243,9 @@ if ($List) { $selected = @(Select-DemoWorkflows -AvailableWorkflows $available -ExampleNames $Example -AllWorkflows:$All) -# Validate that execution is only attempted with Mock workflows -# Live and Templates workflows are for reference/validation only and require real providers -if ($selected | Where-Object { $_.Category -ne 'mock' }) { - $nonMockWorkflows = $selected | Where-Object { $_.Category -ne 'mock' } | Select-Object -ExpandProperty Name - throw "Cannot execute non-Mock workflows: $($nonMockWorkflows -join ', '). Live and Templates workflows require real providers and infrastructure. Use '-Category Mock' (default) or '-List -Category Live' to view Live workflows without executing them." -} - +# Note: Mock workflows use New-IdleMockIdentityProvider which works out-of-the-box. +# Live workflows require real providers and will fail if those providers are not available. +# To run Live workflows, users should modify this script to provide the necessary providers. $providers = @{ Identity = New-IdleMockIdentityProvider } diff --git a/examples/README.md b/examples/README.md index 33e2dddb..79a91f66 100644 --- a/examples/README.md +++ b/examples/README.md @@ -69,11 +69,14 @@ By default, the demo runs **Mock** workflows only (deterministic, no external de # Run specific Mock workflow by name .\examples\Invoke-IdleDemo.ps1 -Example joiner-minimal -# Run all Mock workflows +# Run all Mock workflows (default category) .\examples\Invoke-IdleDemo.ps1 -All + +# Run all workflows in a specific category +.\examples\Invoke-IdleDemo.ps1 -All -Category Live ``` -**Note:** Only Mock workflows can be executed via the demo script. Live workflows require real providers and infrastructure, and cannot be run through this demo. Use `-List -Category Live` to view Live workflows for reference. +**Note:** The demo script defaults to Mock workflows which work out-of-the-box. Live workflows can be executed via the demo script, but will fail if the required providers and infrastructure are not available. To run Live workflows, you must modify the demo script to provide the necessary real providers (see lines 246-248 in `Invoke-IdleDemo.ps1`). ### Interactive selection From 3543bf98979864988e59fcddb9f7293e3f38b49a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 24 Jan 2026 15:14:14 +0000 Subject: [PATCH 6/7] Fix import-idle.ps1 to work with restructured workflow directories - Update workflow discovery to recursively search subdirectories - Change from specific glob pattern to directory-based recursive search - Add test coverage for import-idle.ps1 to prevent future regressions - New test validates workflow discovery and script execution - All tests pass (251 passed, 1 skipped) Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- tests/ImportIdLE.Tests.ps1 | 38 ++++++++++++++++++++++++++++++++++++++ tools/import-idle.ps1 | 8 ++++---- 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 tests/ImportIdLE.Tests.ps1 diff --git a/tests/ImportIdLE.Tests.ps1 b/tests/ImportIdLE.Tests.ps1 new file mode 100644 index 00000000..510dc625 --- /dev/null +++ b/tests/ImportIdLE.Tests.ps1 @@ -0,0 +1,38 @@ +Set-StrictMode -Version Latest + +BeforeAll { + . (Join-Path $PSScriptRoot '_testHelpers.ps1') + $repoRoot = Get-RepoRootPath + $importScript = Join-Path -Path $repoRoot -ChildPath 'tools/import-idle.ps1' +} + +Describe 'Import-IdLE helper script' { + It 'import-idle.ps1 script exists' { + $importScript | Should -Exist + } + + It 'import-idle.ps1 finds workflows in subdirectories' { + # The script should find workflows in examples/workflows/mock, live, and templates subdirectories + # This test validates that the script can discover workflows after the directory restructuring + + $repoRoot = Get-RepoRootPath + $workflowDir = Join-Path -Path $repoRoot -ChildPath 'examples/workflows' + + # Verify workflows exist in subdirectories + $mockWorkflows = Get-ChildItem -Path (Join-Path $workflowDir 'mock') -Filter '*.psd1' -File -ErrorAction SilentlyContinue + $liveWorkflows = Get-ChildItem -Path (Join-Path $workflowDir 'live') -Filter '*.psd1' -File -ErrorAction SilentlyContinue + + $mockWorkflows | Should -Not -BeNullOrEmpty + $liveWorkflows | Should -Not -BeNullOrEmpty + + # Verify the script logic for finding workflows recursively + $allWorkflows = Get-ChildItem -Path $workflowDir -Filter '*.psd1' -File -Recurse + $allWorkflows | Should -Not -BeNullOrEmpty + $allWorkflows.Count | Should -BeGreaterThan 5 + } + + It 'import-idle.ps1 executes without errors' { + # Execute the import script and verify it completes successfully + { & $importScript -ErrorAction Stop } | Should -Not -Throw + } +} diff --git a/tools/import-idle.ps1 b/tools/import-idle.ps1 index fca151f5..c8e1c8e8 100644 --- a/tools/import-idle.ps1 +++ b/tools/import-idle.ps1 @@ -5,7 +5,7 @@ param() $repoRoot = Split-Path -Path $PSScriptRoot -Parent $idleManifest = Join-Path -Path $repoRoot -ChildPath 'src/IdLE/IdLE.psd1' -$workflowGlob = Join-Path -Path $repoRoot -ChildPath 'examples/workflows/*.psd1' +$workflowDir = Join-Path -Path $repoRoot -ChildPath 'examples/workflows' Remove-Module -Name IdLE, IdLE.Core -Force -ErrorAction SilentlyContinue @@ -35,10 +35,10 @@ if ($missing) { Write-Host "IdLE public API is available." -ForegroundColor Green -# Validate all example workflows strictly -$workflowPaths = Get-ChildItem -Path $workflowGlob -File -ErrorAction Stop | Select-Object -ExpandProperty FullName +# Validate all example workflows strictly (recursively search subdirectories) +$workflowPaths = Get-ChildItem -Path $workflowDir -Filter '*.psd1' -File -Recurse -ErrorAction Stop | Select-Object -ExpandProperty FullName if (-not $workflowPaths) { - throw "No workflow definition files found at: $workflowGlob" + throw "No workflow definition files found in: $workflowDir" } foreach ($wf in $workflowPaths) { From d9babb9f0ec592b082e0fcc48b54a2f073e36e14 Mon Sep 17 00:00:00 2001 From: Matthias Fleschuetz <13959569+blindzero@users.noreply.github.com> Date: Sat, 24 Jan 2026 16:37:08 +0100 Subject: [PATCH 7/7] fix redundant variable assignment repoRoot --- tests/ImportIdLE.Tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ImportIdLE.Tests.ps1 b/tests/ImportIdLE.Tests.ps1 index 510dc625..ae6439e8 100644 --- a/tests/ImportIdLE.Tests.ps1 +++ b/tests/ImportIdLE.Tests.ps1 @@ -15,7 +15,6 @@ Describe 'Import-IdLE helper script' { # The script should find workflows in examples/workflows/mock, live, and templates subdirectories # This test validates that the script can discover workflows after the directory restructuring - $repoRoot = Get-RepoRootPath $workflowDir = Join-Path -Path $repoRoot -ChildPath 'examples/workflows' # Verify workflows exist in subdirectories