Private/Invoke-WorkflowCompilerPack.ps1
|
function Invoke-WorkflowCompilerPack { <# .SYNOPSIS Packs a UiPath project by invoking UiPath.WorkflowCompiler `build` directly. .DESCRIPTION This is the same engine uipcli and `uip rpa pack` both drive internally, invoked without either wrapper in between. Driving it directly is what makes --include-sources controllable: the compiler's own default is true, uipcli hardcodes true and exposes no flag for it, so any package packed through uipcli ships every .cs file in plaintext under content/. Package identity travels in a pack-options JSON file rather than on the command line, so values containing spaces or quotes survive the process boundary intact. Boolean flags take a separate 'true'/'false' argument — '--flag=true' is a parse error for this tool. Returns the process exit code. Stream discipline matches Invoke-UipcliPack: output goes to Verbose on success and to Warning on failure. .PARAMETER WorkflowCompiler Hashtable from Resolve-CpmfUipsWorkflowCompiler (FilePath, ArgumentPrefix). .PARAMETER ProjectDir Project directory containing project.json. .PARAMETER OutputDir Directory the compiler writes the package into. .PARAMETER PackOptions Package identity fields written to the pack-options JSON file. .PARAMETER PackSettings Pack-time policy: IncludeSources, SkipAnalyze, SkipValidate, NoOptimizeDeps, SplitPackages, ExcludeConfiguredSources, LogLevel, PolicyFileType, PolicyFilePath. .PARAMETER ExtraArgs Additional arguments appended verbatim. #> [CmdletBinding()] [OutputType([int])] param( [Parameter(Mandatory)] [hashtable]$WorkflowCompiler, [Parameter(Mandatory)] [string] $ProjectDir, [Parameter(Mandatory)] [string] $OutputDir, [hashtable]$PackOptions = @{}, [hashtable]$PackSettings = @{}, [string[]] $ExtraArgs = @() ) function ConvertTo-CompilerBool { param([object]$Value) if ($null -eq $Value) { return 'false' } if ([bool]$Value) { return 'true' } else { return 'false' } } $packOptionsFile = Join-Path ([System.IO.Path]::GetTempPath()) "cpmf-packoptions-$([System.Guid]::NewGuid()).json" try { # Only non-empty fields are written; the compiler treats an empty string # as a real value and would stamp it into the nuspec. $payload = [ordered]@{} foreach ($key in @('id', 'version', 'author', 'description', 'releaseNotes', 'tags', 'iconUrl', 'projectUrl', 'repositoryType', 'repositoryUrl', 'repositoryBranch', 'repositoryCommit')) { if ($PackOptions.ContainsKey($key) -and -not [string]::IsNullOrWhiteSpace([string]$PackOptions[$key])) { $payload[$key] = [string]$PackOptions[$key] } } $json = $payload | ConvertTo-Json -Compress -Depth 4 [System.IO.File]::WriteAllText($packOptionsFile, $json, (New-Object System.Text.UTF8Encoding $false)) Write-Verbose "[workflowcompiler] pack-options: $json" $logLevel = if ($PackSettings.ContainsKey('LogLevel') -and -not [string]::IsNullOrWhiteSpace([string]$PackSettings['LogLevel'])) { [string]$PackSettings['LogLevel'] } else { 'Warning' } $buildArgs = @($WorkflowCompiler.ArgumentPrefix) + @( 'build' '-p', $ProjectDir '-o', $OutputDir '--log-level', $logLevel '--format-logs', 'true' '--skip-analyze', (ConvertTo-CompilerBool $PackSettings['SkipAnalyze']) '--skip-validate', (ConvertTo-CompilerBool $PackSettings['SkipValidate']) '--no-optimize-deps', (ConvertTo-CompilerBool $PackSettings['NoOptimizeDeps']) '--include-sources', (ConvertTo-CompilerBool $PackSettings['IncludeSources']) '--split-packages', (ConvertTo-CompilerBool $PackSettings['SplitPackages']) '--exclude-configured-sources', (ConvertTo-CompilerBool $PackSettings['ExcludeConfiguredSources']) '--pack-options-file', $packOptionsFile ) if ($PackOptions.ContainsKey('version') -and -not [string]::IsNullOrWhiteSpace([string]$PackOptions['version'])) { $buildArgs += @('--build-version', [string]$PackOptions['version']) } if ($PackOptions.ContainsKey('id') -and -not [string]::IsNullOrWhiteSpace([string]$PackOptions['id'])) { $buildArgs += @('--package-name', [string]$PackOptions['id']) } if ($PackSettings.ContainsKey('PolicyFileType') -and -not [string]::IsNullOrWhiteSpace([string]$PackSettings['PolicyFileType'])) { $buildArgs += @('--policy-file-type', [string]$PackSettings['PolicyFileType']) } if ($PackSettings.ContainsKey('PolicyFilePath') -and -not [string]::IsNullOrWhiteSpace([string]$PackSettings['PolicyFilePath'])) { $buildArgs += @('--policy-file', [string]$PackSettings['PolicyFilePath']) } if ($ExtraArgs.Count -gt 0) { $buildArgs += $ExtraArgs } Write-Verbose "[workflowcompiler] $($WorkflowCompiler.FilePath) $($buildArgs -join ' ')" $capture = Invoke-NativeCommandCapture -FilePath $WorkflowCompiler.FilePath -ArgumentList $buildArgs $output = @($capture.StdOutLines) + @($capture.StdErrLines) $exitCode = $capture.ExitCode # The compiler emits a JSON result envelope as its last stdout line. $summary = $null foreach ($line in @($capture.StdOutLines)) { $str = "$line".Trim() if ($str.StartsWith('{') -and $str.EndsWith('}')) { try { $parsed = $str | ConvertFrom-Json if ($parsed.PSObject.Properties.Name -contains 'Type' -or $parsed.PSObject.Properties.Name -contains 'Success') { $summary = $parsed } } catch { Write-Verbose "[workflowcompiler] Unparsed JSON-looking line: $str" } } } if ($exitCode -ne 0) { foreach ($line in $output) { Write-Warning "[workflowcompiler] $line" } if ($summary -and $summary.PSObject.Properties.Name -contains 'Summary') { Write-Warning "[workflowcompiler] $($summary.Summary)" } } else { foreach ($line in $output) { Write-Verbose "[workflowcompiler] $line" } } return $exitCode } finally { Remove-Item -LiteralPath $packOptionsFile -Force -ErrorAction SilentlyContinue } } |