Automation-Pipeline-Examples/update-module-and-pipelines.ps1
|
#Requires -Version 5.1 # AZLOCAL-UPDATER-VERSION: 1.2.0 <# .SYNOPSIS Refresh the AzLocal.UpdateManagement CI/CD pipeline files in THIS repository to match the latest published module version, then commit and push. .DESCRIPTION This script was dropped into your repository root by Copy-AzLocalPipelineExample. Run it whenever a new AzLocal.UpdateManagement version is published to PowerShell Gallery to: 1. Install/upgrade the module to the latest published version (only when the gallery is newer than what is already installed), then import it. 2. Refresh the bundled pipeline YAMLs via Update-AzLocalPipelineExample - a MARKER-AWARE merge that preserves any operator customisations you placed inside the AZLOCAL-CUSTOMIZE marker regions (schedule CRONs, service-connection names, runner labels, ITSM secret bindings, etc.). 3. Stage ONLY the workflow folder, the repo-root config\ folder, the managed README.md (when module-managed), and THIS script itself (both of which Update-AzLocalPipelineExample may have refreshed in place when the module shipped a newer template), then commit and push when (and only when) something actually changed. The target platform and workflow folder were baked in at drop time by Copy-AzLocalPipelineExample, so the script is turnkey for this repo. You can still override them via parameters. .PARAMETER RepoRoot Repository root. Defaults to the folder this script lives in (the repo root, where Copy-AzLocalPipelineExample dropped it). .PARAMETER Platform Pipeline platform this repo uses ('GitHub' or 'AzureDevOps'). Baked in at drop time. .PARAMETER WorkflowSubPath Workflow / pipeline folder, RELATIVE to the repo root (for example '.github/workflows' on GitHub, or 'pipelines' on Azure DevOps). Baked in at drop time. .PARAMETER Scope Install scope passed to Install-Module when an upgrade is required. 'CurrentUser' (default) needs no elevation; 'AllUsers' requires an elevated session. .PARAMETER NoPush Refresh the YAMLs only - skip the git add / commit / push. Review the result yourself with 'git status' / 'git diff'. .EXAMPLE .\Update-Module-And-Pipelines.ps1 Upgrade the module if needed, refresh the pipelines, then commit and push any changes. .EXAMPLE .\Update-Module-And-Pipelines.ps1 -NoPush Refresh the pipelines but leave the commit/push to you. .NOTES Platform : __PLATFORM__ Workflow folder : __WORKFLOW_SUBPATH__ Module : AzLocal.UpdateManagement Generated by : Copy-AzLocalPipelineExample Template version: 1.2.0 (managed file - Copy/Update-AzLocalPipelineExample auto-refresh this script in place when the module ships a newer template version. Tune behaviour via PARAMETERS, not by editing the body; edits to the body are replaced on refresh. Pass -SkipStarterUpdater to freeze it.) #> [CmdletBinding(SupportsShouldProcess = $true)] param( [string]$RepoRoot = $PSScriptRoot, [ValidateSet('GitHub', 'AzureDevOps')] [string]$Platform = '__PLATFORM__', [string]$WorkflowSubPath = '__WORKFLOW_SUBPATH__', [ValidateSet('CurrentUser', 'AllUsers')] [string]$Scope = 'CurrentUser', [switch]$NoPush ) $ErrorActionPreference = 'Stop' $moduleName = 'AzLocal.UpdateManagement' # --------------------------------------------------------------------------- # 1. Ensure the latest published module version is installed and imported. # We deliberately do NOT Uninstall-Module first - that needs elevation for # AllUsers installs and would needlessly remove a pinned/side-by-side # version. Install-Module -Force lays the new version down alongside. # --------------------------------------------------------------------------- $installed = Get-Module -ListAvailable -Name $moduleName | Sort-Object Version -Descending | Select-Object -First 1 $latest = $null try { $latest = (Find-Module -Name $moduleName -ErrorAction Stop).Version } catch { Write-Warning "Could not query PowerShell Gallery for '$moduleName' ($($_.Exception.Message)). Falling back to the installed version." } if ($latest -and (-not $installed -or [version]$latest -gt [version]$installed.Version)) { $fromText = if ($installed) { $installed.Version } else { '(not installed)' } Write-Host "Installing $moduleName $latest (was $fromText)..." -ForegroundColor Cyan Install-Module -Name $moduleName -Scope $Scope -RequiredVersion $latest -Force -AllowClobber } elseif ($installed) { Write-Host "$moduleName is already up to date ($($installed.Version))." -ForegroundColor Green } else { throw "$moduleName is not installed and PowerShell Gallery could not be reached. Install it manually, then re-run." } Get-Module -Name $moduleName | Remove-Module -Force -ErrorAction SilentlyContinue Import-Module -Name $moduleName -Force $version = (Get-Module -Name $moduleName | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString() Write-Host "Using $moduleName $version." -ForegroundColor Green # --------------------------------------------------------------------------- # 2. Refresh the pipeline YAMLs (marker-aware merge; preserves customisations). # --------------------------------------------------------------------------- $workflowFull = Join-Path -Path $RepoRoot -ChildPath $WorkflowSubPath if (-not (Test-Path -LiteralPath $workflowFull)) { throw "Workflow folder not found: '$workflowFull'. Pass -RepoRoot / -WorkflowSubPath to override." } Write-Host "Refreshing $Platform pipelines under '$workflowFull'..." -ForegroundColor Cyan Update-AzLocalPipelineExample -Destination $workflowFull -Platform $Platform # --------------------------------------------------------------------------- # 3. Stage ONLY the workflow folder, the repo-root config\, the managed # README.md, and THIS script, then commit and push when there is something # to commit. Scoping the 'git add' keeps unrelated working-tree changes out # of this automated commit. '-A -- <path>' also captures the canonical-name # renames/deletes that Update may perform. # --------------------------------------------------------------------------- if ($NoPush) { Write-Host "-NoPush set; skipping git commit/push. Review with 'git status' / 'git diff'." -ForegroundColor Yellow return } # Include THIS script too: Update-AzLocalPipelineExample may have refreshed it # in place (version-gated self-update) when the module shipped a newer # template. Staging it commits/pushes that improvement instead of leaving it as # a dirty working-tree change. Only added when the script actually lives inside # the repo (the normal dropped-at-repo-root case); resolved to a repo-relative, # forward-slashed path so it survives the Test-Path filter below. $selfRel = $null if ($PSCommandPath) { try { $selfFull = (Resolve-Path -LiteralPath $PSCommandPath).ProviderPath $repoFull = (Resolve-Path -LiteralPath $RepoRoot).ProviderPath.TrimEnd('\', '/') if ($selfFull.StartsWith($repoFull, [System.StringComparison]::OrdinalIgnoreCase)) { $selfRel = $selfFull.Substring($repoFull.Length).TrimStart('\', '/') -replace '\\', '/' } } catch { $selfRel = $null } } $candidatePaths = @($WorkflowSubPath, 'config') if ($selfRel) { $candidatePaths += $selfRel } # Include the managed repo README too, but ONLY when it is module-managed # (carries the hidden AZLOCAL-README-VERSION marker). An operator-owned README - # one without the marker - is deliberately left out so unrelated README edits # are never swept into this automated commit. $readmeFull = Join-Path -Path $RepoRoot -ChildPath 'README.md' if ((Test-Path -LiteralPath $readmeFull -PathType Leaf) -and ((Get-Content -LiteralPath $readmeFull -Raw) -match 'AZLOCAL-README-VERSION')) { $candidatePaths += 'README.md' } $gitPaths = $candidatePaths | Where-Object { Test-Path -LiteralPath (Join-Path -Path $RepoRoot -ChildPath $_) } if ($gitPaths.Count -eq 0) { Write-Warning "Neither '$WorkflowSubPath' nor 'config' exists under '$RepoRoot'; nothing to stage." return } & git -C $RepoRoot add -A -- $gitPaths if ($LASTEXITCODE -ne 0) { throw "git add failed (exit code $LASTEXITCODE)." } & git -C $RepoRoot diff --cached --quiet if ($LASTEXITCODE -eq 0) { Write-Host "No changes to commit - pipelines already match $moduleName $version." -ForegroundColor Green return } if ($PSCmdlet.ShouldProcess($RepoRoot, "git commit and push AzLocal pipeline refresh ($moduleName $version)")) { & git -C $RepoRoot commit -m "Refresh AzLocal update pipelines for $moduleName $version" if ($LASTEXITCODE -ne 0) { throw "git commit failed (exit code $LASTEXITCODE)." } & git -C $RepoRoot push if ($LASTEXITCODE -ne 0) { throw "git push failed (exit code $LASTEXITCODE)." } Write-Host "Pushed pipeline refresh for $moduleName $version." -ForegroundColor Green } |