scripts/workflow-run.ps1
|
#!/usr/bin/env pwsh <# .SYNOPSIS Run (or rerun) an installed workflow. .DESCRIPTION Reads the workflow.yaml tasks section, creates task JSONs in the shared queue with the workflow field set, runs preflight checks, and spawns a workflow process filtered to this workflow's tasks. .PARAMETER WorkflowName Name of the installed workflow (e.g., "iwg-bs-scoring"). #> param( [Parameter(Mandatory, Position = 0)] [string]$WorkflowName ) $ErrorActionPreference = "Stop" $DotbotBase = Join-Path $HOME "dotbot" $ProjectDir = Get-Location $BotDir = Join-Path $ProjectDir ".bot" Import-Module (Join-Path $DotbotBase "scripts\Platform-Functions.psm1") -Force if (-not (Test-Path $BotDir)) { Write-DotbotError "No .bot directory found. Run 'dotbot init' first." exit 1 } # Import manifest utilities . (Join-Path $BotDir "systems\runtime\modules\workflow-manifest.ps1") $wfDir = Join-Path $BotDir "workflows\$WorkflowName" # Default workflow lives at .bot/ root; installed workflows at .bot/workflows/{name}/ if (-not (Test-Path $wfDir)) { # Check if this is the default workflow (manifest at .bot/workflow.yaml) $defaultYaml = Join-Path $BotDir "workflow.yaml" if ((Test-Path $defaultYaml)) { $defaultManifest = Read-WorkflowManifest -WorkflowDir $BotDir $defaultName = if ($defaultManifest -and $defaultManifest.name) { $defaultManifest.name } else { 'default' } if ($WorkflowName -eq $defaultName -or $WorkflowName -eq 'default') { $wfDir = $BotDir $WorkflowName = $defaultName } } } if (-not (Test-Path (Join-Path $wfDir "workflow.yaml"))) { Write-DotbotError "Workflow '$WorkflowName' is not installed." Write-DotbotWarning "Installed workflows:" $wfBaseDir = Join-Path $BotDir "workflows" if (Test-Path $wfBaseDir) { Get-ChildItem $wfBaseDir -Directory | ForEach-Object { Write-Status "- $($_.Name)" } } exit 1 } # Parse manifest $manifest = Read-WorkflowManifest -WorkflowDir $wfDir Write-DotbotBanner -Title "D O T B O T v3.5" -Subtitle "Run Workflow: $WorkflowName" # --- Preflight checks --- $envLocalPath = Join-Path $ProjectDir ".env.local" if ($manifest.requires -and $manifest.requires.env_vars) { # Load .env.local $envValues = @{} if (Test-Path $envLocalPath) { Get-Content $envLocalPath | ForEach-Object { if ($_ -match '^\s*([^#][^=]+)=(.+)$') { $envValues[$matches[1].Trim()] = $matches[2].Trim() } } } $missing = @() foreach ($ev in $manifest.requires.env_vars) { $varName = if ($ev.var) { $ev.var } elseif ($ev['var']) { $ev['var'] } else { continue } if (-not $envValues[$varName]) { $missing += $varName } } if ($missing.Count -gt 0) { Write-DotbotError "Missing required environment variables: $($missing -join ', ')" Write-DotbotWarning "Set them in .env.local" exit 1 } Write-Success "Preflight: all required env vars present" } # --- Handle rerun --- $tasksDir = Join-Path $BotDir "workspace\tasks" $rerunMode = if ($manifest.rerun) { $manifest.rerun } else { "fresh" } # Check for existing tasks $existingCount = 0 foreach ($status in @('todo', 'analysing', 'analysed', 'in-progress', 'done', 'skipped')) { $dir = Join-Path $tasksDir $status if (Test-Path $dir) { Get-ChildItem $dir -Filter "*.json" -File | ForEach-Object { try { $content = Get-Content $_.FullName -Raw | ConvertFrom-Json if ($content.workflow -eq $WorkflowName) { $existingCount++ } } catch { Write-DotbotCommand "Parse skipped: $_" } } } } if ($existingCount -gt 0) { if ($rerunMode -eq "fresh") { Write-Status "Clearing $existingCount existing tasks (rerun: fresh)" Clear-WorkflowTasks -TasksBaseDir $tasksDir -WorkflowName $WorkflowName | Out-Null } else { Write-Status "Keeping $existingCount existing tasks (rerun: append)" } } # --- Create tasks from manifest --- $tasks = @() if ($manifest.tasks) { $tasks = @($manifest.tasks) } if ($tasks.Count -eq 0) { Write-DotbotWarning "No tasks defined in workflow.yaml" exit 0 } Write-Status "Creating $($tasks.Count) task(s) from manifest..." foreach ($taskDef in $tasks) { # Convert PSCustomObject to hashtable if needed $td = @{} if ($taskDef -is [PSCustomObject]) { foreach ($p in $taskDef.PSObject.Properties) { $td[$p.Name] = $p.Value } } elseif ($taskDef -is [System.Collections.IDictionary]) { $td = $taskDef } $result = New-WorkflowTask -ProjectBotDir $BotDir -WorkflowName $WorkflowName -TaskDef $td Write-DotbotCommand "+ $($result.name)" } Write-Success "Created $($tasks.Count) task(s) for $WorkflowName" # --- Spawn workflow process --- $lpPath = Join-Path $BotDir "systems\runtime\launch-process.ps1" Write-Status "Launching workflow process..." $wfArgs = @( "-NoProfile", "-File", $lpPath, "-Type", "task-runner", "-Continue", "-Workflow", $WorkflowName, "-Description", "Run: $WorkflowName" ) Start-Process pwsh -ArgumentList $wfArgs -WorkingDirectory $ProjectDir Write-BlankLine Write-Success "Workflow '$WorkflowName' started. Use .bot/go.ps1 to monitor progress." Write-BlankLine |