Functions/Build-Workflow.ps1
|
# Build Workflow Functions # Complete build, copy, and attach workflow for releases function Start-BuildWorkflow { <# .SYNOPSIS Executes a complete build workflow including building, copying files, and preparing for release. .DESCRIPTION This function provides a complete build workflow that: 1. Builds the project in specified configuration 2. Finds all built files (DLL, EXE, etc.) 3. Copies files to release locations 4. Optionally creates archives 5. Prepares files for GitHub release attachment .PARAMETER ProjectPath Path to the project file or directory. .PARAMETER Configuration Build configuration (Release, Debug, etc.). Default: Release .PARAMETER Architecture Target architecture (win-x64, win-x86, etc.). Default: win-x64 .PARAMETER Framework Target framework (net8.0, net6.0, etc.). Default: net8.0 .PARAMETER AssemblyName Name of the main assembly. If not specified, will be extracted from project file. .PARAMETER OutputDirectory Directory to copy built files to. Default: ./dist/ .PARAMETER CreateArchive Whether to create ZIP archives of the built files. .PARAMETER ArchiveName Name for the archive file (without extension). .PARAMETER IncludeDebugFiles Whether to include debug files (.pdb) in the output. .PARAMETER CleanOutput Whether to clean the output directory before copying files. .PARAMETER PublishMode Whether to use publish mode instead of regular build. .EXAMPLE Start-BuildWorkflow -ProjectPath "MyApp.csproj" -Configuration "Release" -Architecture "win-x64" .EXAMPLE Start-BuildWorkflow -ProjectPath "MyApp.csproj" -CreateArchive -ArchiveName "MyApp-v1.0" -PublishMode #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$ProjectPath, [Parameter(Mandatory = $false)] [string]$Configuration = "Release", [Parameter(Mandatory = $false)] [string]$Architecture = "win-x64", [Parameter(Mandatory = $false)] [string]$Framework = "net8.0", [Parameter(Mandatory = $false)] [string]$AssemblyName, [Parameter(Mandatory = $false)] [string]$OutputDirectory = "./dist/", [Parameter(Mandatory = $false)] [switch]$CreateArchive, [Parameter(Mandatory = $false)] [string]$ArchiveName, [Parameter(Mandatory = $false)] [switch]$IncludeDebugFiles, [Parameter(Mandatory = $false)] [switch]$CleanOutput, [Parameter(Mandatory = $false)] [switch]$PublishMode ) Write-Host "🚀 Starting Build Workflow" -ForegroundColor Cyan Write-Host "Project: $ProjectPath" -ForegroundColor Gray Write-Host "Configuration: $Configuration" -ForegroundColor Gray Write-Host "Architecture: $Architecture" -ForegroundColor Gray Write-Host "Framework: $Framework" -ForegroundColor Gray Write-Host "" # Step 1: Extract project information $projectInfo = Get-ProjectInfo -ProjectPath $ProjectPath if (-not $AssemblyName) { $AssemblyName = $projectInfo.AssemblyName } Write-Host "📋 Project Information:" -ForegroundColor Green Write-Host " Assembly Name: $AssemblyName" -ForegroundColor Gray Write-Host " Project Directory: $($projectInfo.ProjectDir)" -ForegroundColor Gray Write-Host "" # Step 2: Build the project Write-Host "🔨 Building project..." -ForegroundColor Green if ($PublishMode) { if (-not (Get-Command Dotnet-Publish -ErrorAction SilentlyContinue)) { throw "Dotnet-Publish command not found in Bluscream-BuildTools module" } $buildResult = Dotnet-Publish -ProjectPath $ProjectPath -Configuration $Configuration -Architecture $Architecture -Framework $Framework if (-not $buildResult) { throw "Publish build failed" } } else { if (-not (Get-Command Dotnet-Build -ErrorAction SilentlyContinue)) { throw "Dotnet-Build command not found in Bluscream-BuildTools module" } $buildResult = Dotnet-Build -ProjectPath $ProjectPath -Configuration $Configuration -Architecture $Architecture -Framework $Framework if (-not $buildResult) { throw "Build failed" } } Write-Host "✓ Build completed successfully" -ForegroundColor Green Write-Host "" # Step 3: Find all built files Write-Host "🔍 Finding built files..." -ForegroundColor Green $builtFiles = @() $fileTypes = @( @{ Extension = ".exe"; Type = "executable" }, @{ Extension = ".dll"; Type = "library" }, @{ Extension = ".pdb"; Type = "debug symbols" } ) foreach ($fileType in $fileTypes) { if ($fileType.Extension -eq ".pdb" -and -not $IncludeDebugFiles) { continue } $foundFile = Find-BuiltFile -Config $Configuration -Arch $Architecture -ProjectFramework $Framework -AssemblyName $AssemblyName -FileExtension $fileType.Extension -FileType $fileType.Type -IsPublish:$PublishMode -ProjectDir $projectInfo.ProjectDir if ($foundFile) { $builtFiles += $foundFile } } if ($builtFiles.Count -eq 0) { throw "No built files found" } Write-Host "✓ Found $($builtFiles.Count) built files" -ForegroundColor Green Write-Host "" # Step 4: Prepare output directory if ($CleanOutput -and (Test-Path $OutputDirectory)) { Write-Host "🧹 Cleaning output directory..." -ForegroundColor Yellow Remove-Item $OutputDirectory -Recurse -Force } if (-not (Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null Write-Host "✓ Created output directory: $OutputDirectory" -ForegroundColor Green } # Step 5: Copy files to output directory Write-Host "📋 Copying files to output directory..." -ForegroundColor Green $copiedFiles = @() foreach ($file in $builtFiles) { $destinationPath = Join-Path $OutputDirectory $file.Name Copy-Item $file.FullName $destinationPath -Force $copiedFiles += $destinationPath Write-Host " ✓ Copied: $($file.Name)" -ForegroundColor Gray } Write-Host "✓ Copied $($copiedFiles.Count) files to $OutputDirectory" -ForegroundColor Green Write-Host "" # Step 6: Create archive if requested $archivePath = $null if ($CreateArchive) { Write-Host "📦 Creating archive..." -ForegroundColor Green if (-not $ArchiveName) { $ArchiveName = "$AssemblyName-$Configuration-$Architecture" } $archivePath = "$OutputDirectory$ArchiveName.zip" if (Test-Path $archivePath) { Remove-Item $archivePath -Force } Compress-Archive -Path $copiedFiles -DestinationPath $archivePath -Force Write-Host "✓ Created archive: $archivePath" -ForegroundColor Green Write-Host "" } # Step 7: Prepare release information $releaseInfo = @{ ProjectPath = $ProjectPath Configuration = $Configuration Architecture = $Architecture Framework = $Framework AssemblyName = $AssemblyName OutputDirectory = $OutputDirectory BuiltFiles = $builtFiles CopiedFiles = $copiedFiles ArchivePath = $archivePath Success = $true } Write-Host "🎉 Build Workflow Completed Successfully!" -ForegroundColor Green Write-Host "Output Directory: $OutputDirectory" -ForegroundColor Cyan Write-Host "Files: $($copiedFiles.Count)" -ForegroundColor Cyan if ($archivePath) { Write-Host "Archive: $archivePath" -ForegroundColor Cyan } Write-Host "" return $releaseInfo } function Get-ProjectInfo { <# .SYNOPSIS Extracts project information from a .NET project file. .DESCRIPTION Parses a .NET project file to extract assembly name, project directory, and other relevant information. .PARAMETER ProjectPath Path to the project file. .EXAMPLE Get-ProjectInfo -ProjectPath "MyApp.csproj" #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$ProjectPath ) if (-not (Test-Path $ProjectPath)) { throw "Project file not found: $ProjectPath" } $projectDir = Split-Path $ProjectPath -Parent $projectContent = Get-Content $ProjectPath -Raw # Extract assembly name $assemblyName = $null if ($projectContent -match '<AssemblyName>([^<]+)</AssemblyName>') { $assemblyName = $Matches[1] } elseif ($projectContent -match '<AssemblyName>([^<]+)</AssemblyName>') { $assemblyName = $Matches[1] } else { # Fallback to project file name without extension $assemblyName = [System.IO.Path]::GetFileNameWithoutExtension($ProjectPath) } # Extract target framework $targetFramework = $null if ($projectContent -match '<TargetFramework>([^<]+)</TargetFramework>') { $targetFramework = $Matches[1] } elseif ($projectContent -match '<TargetFrameworks>([^<]+)</TargetFrameworks>') { $targetFramework = ($Matches[1] -split ';')[0] # Take first framework } return @{ ProjectPath = $ProjectPath ProjectDir = $projectDir AssemblyName = $assemblyName TargetFramework = $targetFramework } } function New-ReleasePackage { <# .SYNOPSIS Creates a complete release package with all necessary files and metadata. .DESCRIPTION Creates a release package that includes built files, metadata, and optionally archives for distribution. .PARAMETER ReleaseInfo Release information object from Start-BuildWorkflow. .PARAMETER Version Version number for the release. .PARAMETER ReleaseNotes Release notes for the release. .PARAMETER CreateArchives Whether to create ZIP archives for different architectures. .EXAMPLE New-ReleasePackage -ReleaseInfo $releaseInfo -Version "1.0.0" -CreateArchives #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [hashtable]$ReleaseInfo, [Parameter(Mandatory = $false)] [string]$Version = "1.0.0", [Parameter(Mandatory = $false)] [string]$ReleaseNotes = "", [Parameter(Mandatory = $false)] [switch]$CreateArchives ) Write-Host "📦 Creating Release Package" -ForegroundColor Cyan Write-Host "Version: $Version" -ForegroundColor Gray Write-Host "" $packageDir = Join-Path $ReleaseInfo.OutputDirectory "package" if (Test-Path $packageDir) { Remove-Item $packageDir -Recurse -Force } New-Item -ItemType Directory -Path $packageDir -Force | Out-Null # Copy all files to package directory foreach ($file in $ReleaseInfo.CopiedFiles) { $fileName = Split-Path $file -Leaf Copy-Item $file (Join-Path $packageDir $fileName) -Force } # Create metadata file $metadata = @{ Version = $Version AssemblyName = $ReleaseInfo.AssemblyName Configuration = $ReleaseInfo.Configuration Architecture = $ReleaseInfo.Architecture Framework = $ReleaseInfo.Framework BuildDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" ReleaseNotes = $ReleaseNotes } $metadataPath = Join-Path $packageDir "release-metadata.json" $metadata | ConvertTo-Json -Depth 3 | Set-Content $metadataPath -Encoding UTF8 # Create README for the release $readmeContent = @" # $($ReleaseInfo.AssemblyName) v$Version ## Release Information - **Version:** $Version - **Configuration:** $($ReleaseInfo.Configuration) - **Architecture:** $($ReleaseInfo.Architecture) - **Framework:** $($ReleaseInfo.Framework) - **Build Date:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss") ## Files Included $($ReleaseInfo.CopiedFiles | ForEach-Object { "- $(Split-Path $_ -Leaf)" } | Out-String) ## Installation 1. Extract all files to your desired location 2. Run the executable file 3. Ensure all dependencies are installed ## Release Notes $ReleaseNotes "@ $readmePath = Join-Path $packageDir "README.md" $readmeContent | Set-Content $readmePath -Encoding UTF8 Write-Host "✓ Created release package in: $packageDir" -ForegroundColor Green if ($CreateArchives) { $archiveName = "$($ReleaseInfo.AssemblyName)-v$Version-$($ReleaseInfo.Architecture)" $archivePath = "$($ReleaseInfo.OutputDirectory)$archiveName.zip" if (Test-Path $archivePath) { Remove-Item $archivePath -Force } Compress-Archive -Path "$packageDir\*" -DestinationPath $archivePath -Force Write-Host "✓ Created archive: $archivePath" -ForegroundColor Green } return @{ PackageDirectory = $packageDir MetadataPath = $metadataPath ReadmePath = $readmePath ArchivePath = if ($CreateArchives) { $archivePath } else { $null } Success = $true } } |