diff --git a/.azuredevops/pipelineTemplates/jobs.publishModule.yml b/.azuredevops/pipelineTemplates/jobs.publishModule.yml index 8ce5ad76f0..cb62982445 100644 --- a/.azuredevops/pipelineTemplates/jobs.publishModule.yml +++ b/.azuredevops/pipelineTemplates/jobs.publishModule.yml @@ -155,7 +155,7 @@ jobs: pwsh: true script: | # Load used functions - . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToUpdate.ps1') + . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1') . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToUniversalArtifactFeed.ps1') #Prioritizing the bicep file @@ -168,20 +168,23 @@ jobs: TemplateFilePath = $TemplateFilePath } - Write-Verbose "Invoke Get-ModulesToUpdate with" -Verbose + Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose # Get the modified child resources - $ModulesToUpdate = Get-ModulesToUpdate @functionInput -Verbose + $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose # Publish the modified child resources - foreach ($ModuleToUpdate in $ModulesToUpdate) { + foreach ($ModuleToPublish in $ModulesToPublish) { + $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0] + Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)" + $functionInput = @{ - TemplateFilePath = $ModuleToUpdate.TemplateFilePath + TemplateFilePath = $ModuleToPublish.TemplateFilePath VstsOrganizationUri = '${{ parameters.vstsOrganizationUri }}' VstsFeedProject = '${{ parameters.vstsFeedProject }}' VstsFeedName = '${{ parameters.vstsFeedName }}' - ModuleVersion = $ModuleToUpdate.Version + ModuleVersion = $ModuleToPublish.Version BearerToken = $env:TOKEN } @@ -189,6 +192,7 @@ jobs: Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose Publish-ModuleToUniversalArtifactFeed @functionInput -Verbose + Write-Host "##[endgroup]" } env: TOKEN: $(vstsFeedToken) @@ -210,7 +214,7 @@ jobs: ScriptType: InlineScript inline: | # Load used functions - . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToUpdate.ps1') + . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1') . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToTemplateSpec.ps1') #Prioritizing the bicep file @@ -223,26 +227,30 @@ jobs: TemplateFilePath = $TemplateFilePath } - Write-Verbose "Invoke Get-ModulesToUpdate with" -Verbose + Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose # Get the modified child resources - $ModulesToUpdate = Get-ModulesToUpdate @functionInput -Verbose + $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose # Publish the modified child resources - foreach ($ModuleToUpdate in $ModulesToUpdate) { + foreach ($ModuleToPublish in $ModulesToPublish) { + $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0] + Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)" + $functionInput = @{ - TemplateFilePath = $ModuleToUpdate.TemplateFilePath + TemplateFilePath = $ModuleToPublish.TemplateFilePath TemplateSpecsRgName = '${{ parameters.templateSpecsRgName }}' TemplateSpecsRgLocation = '${{ parameters.templateSpecsRgLocation }}' TemplateSpecsDescription = '${{ parameters.templateSpecsDescription }}' - ModuleVersion = $ModuleToUpdate.Version + ModuleVersion = $ModuleToPublish.Version } Write-Verbose "Invoke Publish-ModuleToTemplateSpec with" -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose Publish-ModuleToTemplateSpec @functionInput -Verbose + Write-Host "##[endgroup]" } # [private bicep registry publish] task(s) @@ -262,7 +270,7 @@ jobs: ScriptType: InlineScript inline: | # Load used functions - . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToUpdate.ps1') + . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1') . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToPrivateBicepRegistry.ps1') #Prioritizing the bicep file @@ -275,24 +283,28 @@ jobs: TemplateFilePath = $TemplateFilePath } - Write-Verbose "Invoke Get-ModulesToUpdate with" -Verbose + Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose # Get the modified child resources - $ModulesToUpdate = Get-ModulesToUpdate @functionInput -Verbose + $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose # Publish the modified child resources - foreach ($ModuleToUpdate in $ModulesToUpdate) { + foreach ($ModuleToPublish in $ModulesToPublish) { + $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0] + Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)" + $functionInput = @{ - TemplateFilePath = $ModuleToUpdate.TemplateFilePath + TemplateFilePath = $ModuleToPublish.TemplateFilePath BicepRegistryName = '${{ parameters.bicepRegistryName }}' BicepRegistryRgName = '${{ parameters.bicepRegistryRgName }}' BicepRegistryRgLocation = '${{ parameters.bicepRegistryRgLocation }}' - ModuleVersion = $ModuleToUpdate.Version + ModuleVersion = $ModuleToPublish.Version } Write-Verbose "Invoke Publish-ModuleToPrivateBicepRegistry with" -Verbose Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose Publish-ModuleToPrivateBicepRegistry @functionInput -Verbose + Write-Host "##[endgroup]" } diff --git a/.github/actions/templates/publishModule/action.yml b/.github/actions/templates/publishModule/action.yml index 8ee6cc8d23..5e41ce9f59 100644 --- a/.github/actions/templates/publishModule/action.yml +++ b/.github/actions/templates/publishModule/action.yml @@ -70,7 +70,7 @@ runs: Write-Output "::group::Publish module to template specs" # Load used functions - . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Get-ModulesToUpdate.ps1') + . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Get-ModulesToPublish.ps1') . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Publish-ModuleToTemplateSpec.ps1') $functionInput = @{ @@ -81,16 +81,19 @@ runs: Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose # Get the modified child resources - $ModulesToUpdate = Get-ModulesToUpdate @functionInput -Verbose + $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose # Publish the modified child resources - foreach ($ModuleToUpdate in $ModulesToUpdate) { + foreach ($ModuleToPublish in $ModulesToPublish) { + $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0] + Write-Output "::group::$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)" + $functionInput = @{ - TemplateFilePath = $ModuleToUpdate.TemplateFilePath + TemplateFilePath = $ModuleToPublish.TemplateFilePath TemplateSpecsRgName = '${{ inputs.templateSpecsRgName }}' TemplateSpecsRgLocation = '${{ inputs.templateSpecsRgLocation }}' TemplateSpecsDescription = '${{ inputs.templateSpecsDescription }}' - ModuleVersion = $ModuleToUpdate.Version + ModuleVersion = $ModuleToPublish.Version } Write-Verbose "Invoke task with" -Verbose @@ -109,7 +112,7 @@ runs: Write-Output "::group::Publish module to private bicep registry" # Load used functions - . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Get-ModulesToUpdate.ps1') + . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Get-ModulesToPublish.ps1') . (Join-Path $env:GITHUB_WORKSPACE 'utilities' 'pipelines' 'resourcePublish' 'Publish-ModuleToPrivateBicepRegistry.ps1') $functionInput = @{ @@ -120,16 +123,19 @@ runs: Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose # Get the modified child resources - $ModulesToUpdate = Get-ModulesToUpdate @functionInput -Verbose + $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose # Publish the modified child resources - foreach ($ModuleToUpdate in $ModulesToUpdate) { + foreach ($ModuleToPublish in $ModulesToPublish) { + $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0] + Write-Output "::group::$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)" + $functionInput = @{ - TemplateFilePath = $ModuleToUpdate.TemplateFilePath + TemplateFilePath = $ModuleToPublish.TemplateFilePath BicepRegistryName = '${{ inputs.bicepRegistryName }}' BicepRegistryRgName = '${{ inputs.bicepRegistryRgName }}' BicepRegistryRgLocation = '${{ inputs.bicepRegistryRgLocation }}' - ModuleVersion = $ModuleToUpdate.Version + ModuleVersion = $ModuleToPublish.Version } Write-Verbose "Invoke task with" -Verbose diff --git a/docs/wiki/PipelinesDesign.md b/docs/wiki/PipelinesDesign.md index e96b22dd63..57559f0c6f 100644 --- a/docs/wiki/PipelinesDesign.md +++ b/docs/wiki/PipelinesDesign.md @@ -114,9 +114,13 @@ Besides the execution of a publish, there is also the possibility to set the swi The publishing works as follows: -1. The script `utilities/pipelines/resourcePublish/Get-ModulesToUpdate.ps1` gets all changed module files including child modules and handles the logic of propagating the appropriate module version to be used: +1. The script `utilities/pipelines/resourcePublish/Get-ModulesToPublish.ps1` gets all changed module files including child modules and handles the logic of propagating the appropriate module version to be used: 1. The major (`x.0`) and minor (`0.x`) version are set based on the file `version.json` in the module folder. - 1. The patch (`0.0.x`) version is calculated based on the number of commits on the `HEAD` ref. This will cause the patch version to never reset to 0 with major and/or minor increment, as specified for [semver](https://semver.org/). + 2. The patch (`0.0.x`) version is calculated based on the number of commits on the `HEAD` ref (aka. git height). This will cause the patch version to never reset to 0 with major and/or minor increment, as specified for [semver](https://semver.org/). + 3. The module is published with a patch specific version (`x.y.z`). For Template Specs and Bicep Registry a major (`x`) and minor (`x.x`) version is also updated, allowing a consumer to use the latest version of any major or minor version. + 1. For a changed child module, the direct parent hierarchy is also registered for an update, following the same procedure as above. + 1. The list of module files paths and their versions are passed on as a array list. +2. The different publishing scripts run (Artifact, Template Spec or Bicep Registry) and publish the module to the respective target location for each item on the list. **Example scenario** @@ -139,7 +143,9 @@ Lets look at an example run where we would do a patch change on the `fileShares` - Assuming the development branch started from commit 500 on the default branch, and the author added 6 commits on the development branch, the prerelease versions will reach `0.3.506-prerelease`. - Meanwhile, there can be changes (let's say 2 squashed PR merges) on the default branch that is pushing its number of commits in history further. - If the PR for the changes to `fileShare` is squash merged as commit number 503, the patch version on the child and parent module is then `503`, resulting in a version `0.3.503` being published. - +7. The merge triggers cascading updates in the following way: + - The module is published with a `major.minor.patch` version as well as a `major.minor` and `major` version updates, allowing consumers to target the latest major or minor version with ease. + - All parent module are published following the steps mentioned above. ``` \ \ C499 -> C500 ---> C501 ---> C502 ---> C503 (503) diff --git a/utilities/pipelines/resourcePublish/Get-ModulesToUpdate.ps1 b/utilities/pipelines/resourcePublish/Get-ModulesToPublish.ps1 similarity index 72% rename from utilities/pipelines/resourcePublish/Get-ModulesToUpdate.ps1 rename to utilities/pipelines/resourcePublish/Get-ModulesToPublish.ps1 index 7740aaf3c1..f0dfed8001 100644 --- a/utilities/pipelines/resourcePublish/Get-ModulesToUpdate.ps1 +++ b/utilities/pipelines/resourcePublish/Get-ModulesToPublish.ps1 @@ -31,13 +31,9 @@ function Get-ModifiedFileList { [string] $CompareCommit = 'HEAD^' ) - Write-Verbose "Gathering modified files between [$Commit] and [$CompareCommit]" -Verbose + Write-Verbose "Gathering modified files between [$CompareCommit] and [$Commit]" -Verbose $Diff = git diff --name-only --diff-filter=AM $CompareCommit $Commit - $ModifiedFiles = $Diff | Get-Item - Write-Verbose 'The following files have been added or modified:' -Verbose - $ModifiedFiles | ForEach-Object { - Write-Verbose (' - [{0}]' -f $_.FullName) -Verbose - } + $ModifiedFiles = $Diff | Get-Item -Force return $ModifiedFiles } @@ -62,22 +58,15 @@ function Get-GitBranchName { param () # Get branch name from Git - try { - Write-Verbose "Git: Using git command 'git branch --show-current'" -Verbose - $BranchName = git branch --show-current - } catch { - Write-Verbose 'Git: No name found.' -Verbose - } + $BranchName = git branch --show-current # If git could not get name, try GitHub variable if ([string]::IsNullOrEmpty($BranchName) -and (Test-Path env:GITHUB_REF_NAME)) { - Write-Verbose "GitHub: Using environment variable 'GITHUB_REF_NAME': [$env:GITHUB_REF_NAME]" -Verbose $BranchName = $env:GITHUB_REF_NAME } # If git could not get name, try Azure DevOps variable if ([string]::IsNullOrEmpty($BranchName) -and (Test-Path env:BUILD_SOURCEBRANCHNAME)) { - Write-Verbose "Azure DevOps: Using environment variable 'BUILD_SOURCEBRANCHNAME': [$env:BUILD_SOURCEBRANCHNAME]" -Verbose $BranchName = $env:BUILD_SOURCEBRANCHNAME } @@ -142,7 +131,7 @@ Find the closest deploy.bicep/json file to the changed files in the module folde Mandatory. Path to the main/parent module folder. .EXAMPLE -Get-TemplateFileToUpdate -ModuleFolderPath "C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\" +Get-TemplateFileToPublish -ModuleFolderPath "C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\" C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\tableServices\tables\deploy.bicep @@ -151,32 +140,34 @@ Assuming there is a changed file in 'Microsoft.Storage\storageAccounts\tableServ the function would return the deploy.bicep file in the same folder. #> -function Get-TemplateFileToUpdate { +function Get-TemplateFileToPublish { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $ModuleFolderPath ) - + $ModuleFolderRelPath = $ModuleFolderPath.Split('/arm/')[-1] $ModifiedFiles = Get-ModifiedFileList -Verbose - Write-Verbose "Looking for modified files under: [$ModuleFolderPath]" -Verbose + Write-Verbose "Looking for modified files under: [$ModuleFolderRelPath]" -Verbose $ModifiedModuleFiles = $ModifiedFiles | Where-Object { $_.FullName -like "*$ModuleFolderPath*" } - $TemplateFilesToUpdate = $ModifiedModuleFiles | ForEach-Object { + $TemplateFilesToPublish = $ModifiedModuleFiles | ForEach-Object { Find-TemplateFile -Path $_.FullName -Verbose } | Sort-Object -Property FullName -Unique -Descending - if ($TemplateFilesToUpdate.Count -eq 0) { + if ($TemplateFilesToPublish.Count -eq 0) { Write-Verbose 'No template file found in the modified module.' -Verbose } - Write-Verbose ('Modified modules found: [{0}]' -f $TemplateFilesToUpdate.count) -Verbose - $TemplateFilesToUpdate | ForEach-Object { - Write-Verbose " - $($_.FullName)" -Verbose + Write-Verbose ('Modified modules found: [{0}]' -f $TemplateFilesToPublish.count) -Verbose + $TemplateFilesToPublish | ForEach-Object { + $RelPath = ($_.FullName).Split('/arm/')[-1] + $RelPath = $RelPath.Split('/deploy.')[0] + Write-Verbose " - [$RelPath]" -Verbose } - return $TemplateFilesToUpdate + return $TemplateFilesToPublish } <# @@ -231,19 +222,17 @@ function Get-ParentModuleTemplateFile { } if (-not (Test-Path -Path $ParentTemplateFilePath)) { - Write-Verbose "No parent template file found at: [$ParentTemplateFilePath]" -Verbose return } - Write-Verbose "Parent template file found at: [$ParentTemplateFilePath]" -Verbose - $ParentTemplateFilesToUpdate = [System.Collections.ArrayList]@() - $ParentTemplateFilesToUpdate += $ParentTemplateFilePath | Get-Item + $ParentTemplateFilesToPublish = [System.Collections.ArrayList]@() + $ParentTemplateFilesToPublish += $ParentTemplateFilePath | Get-Item if ($Recurse) { - $ParentTemplateFilesToUpdate += Get-ParentModuleTemplateFile $ParentTemplateFilePath -Recurse + $ParentTemplateFilesToPublish += Get-ParentModuleTemplateFile $ParentTemplateFilePath -Recurse } - return $ParentTemplateFilesToUpdate + return $ParentTemplateFilesToPublish } <# @@ -302,7 +291,7 @@ function Get-ModuleVersionFromFile { $VersionFilePath = Join-Path -Path $ModuleFolder -ChildPath 'version.json' if (-not (Test-Path -Path $VersionFilePath)) { - throw "No version file found at: $VersionFilePath" + throw "No version file found at: [$VersionFilePath]" } $VersionFileContent = Get-Content $VersionFilePath | ConvertFrom-Json @@ -343,14 +332,10 @@ function Get-NewModuleVersion { $BranchName = Get-GitBranchName -Verbose - Write-Verbose "Current branch: [$BranchName]" -Verbose if ($BranchName -ne 'main' -and $BranchName -ne 'master') { - Write-Verbose "PreRelease: [$PreRelease]" -Verbose $NewVersion = "$NewVersion-prerelease".ToLower() } - Write-Verbose "New version: [$NewVersion]" -Verbose - return $NewVersion } @@ -358,16 +343,16 @@ function Get-NewModuleVersion { <# .SYNOPSIS -Generates a hashtable with template file paths to update with a new version. +Generates a hashtable with template file paths to publish with a new version. .DESCRIPTION -Generates a hashtable with template file paths to update with a new version. +Generates a hashtable with template file paths to publish with a new version. .PARAMETER TemplateFilePath Mandatory. Path to a deploy.bicep/json file. .EXAMPLE -Get-ModulesToUpdate -TemplateFilePath 'C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\deploy.bicep' +Get-ModulesToPublish -TemplateFilePath 'C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\deploy.bicep' Name Value @@ -379,11 +364,11 @@ Version 0.3.848-prerelease TemplateFilePath C:\Repos\Azure\ResourceModules\arm\Microsoft.Storage\storageAccounts\deploy.bicep Version 0.3.848-prerelease -Generates a hashtable with template file paths to update and their new versions. +Generates a hashtable with template file paths to publish and their new versions. #># -function Get-ModulesToUpdate { +function Get-ModulesToPublish { [CmdletBinding()] param ( @@ -392,34 +377,70 @@ function Get-ModulesToUpdate { ) $ModuleFolderPath = Split-Path $TemplateFilePath -Parent - $TemplateFilesToUpdate = Get-TemplateFileToUpdate -ModuleFolderPath $ModuleFolderPath | Sort-Object FullName -Descending + $TemplateFilesToPublish = Get-TemplateFileToPublish -ModuleFolderPath $ModuleFolderPath | Sort-Object FullName -Descending - $ModulesToUpdate = [System.Collections.ArrayList]@() - foreach ($TemplateFileToUpdate in $TemplateFilesToUpdate) { - $ModuleVersion = Get-NewModuleVersion -TemplateFilePath $TemplateFileToUpdate.FullName -Verbose - $ModulesToUpdate += @{ + $ModulesToPublish = [System.Collections.ArrayList]@() + foreach ($TemplateFileToPublish in $TemplateFilesToPublish) { + $ModuleVersion = Get-NewModuleVersion -TemplateFilePath $TemplateFileToPublish.FullName -Verbose + + $ModulesToPublish += @{ Version = $ModuleVersion - TemplateFilePath = $TemplateFileToUpdate.FullName + TemplateFilePath = $TemplateFileToPublish.FullName + } + + if ($ModuleVersion -notmatch 'prerelease') { + + # Latest Major,Minor + $ModulesToPublish += @{ + Version = ($ModuleVersion.Split('.')[0..1] -join '.') + TemplateFilePath = $TemplateFileToPublish.FullName + } + + # Latest Major + $ModulesToPublish += @{ + Version = ($ModuleVersion.Split('.')[0]) + TemplateFilePath = $TemplateFileToPublish.FullName + } } - $ParentTemplateFilesToUpdate = Get-ParentModuleTemplateFile -TemplateFilePath $TemplateFileToUpdate.FullName -Recurse - Write-Verbose "Found [$($ParentTemplateFilesToUpdate.count)] parent template files to update" -Verbose - foreach ($ParentTemplateFileToUpdate in $ParentTemplateFilesToUpdate) { - $ParentModuleVersion = Get-NewModuleVersion -TemplateFilePath $ParentTemplateFileToUpdate.FullName + $ParentTemplateFilesToPublish = Get-ParentModuleTemplateFile -TemplateFilePath $TemplateFileToPublish.FullName -Recurse + foreach ($ParentTemplateFileToPublish in $ParentTemplateFilesToPublish) { + $ParentModuleVersion = Get-NewModuleVersion -TemplateFilePath $ParentTemplateFileToPublish.FullName - $ModulesToUpdate += @{ + $ModulesToPublish += @{ Version = $ParentModuleVersion - TemplateFilePath = $ParentTemplateFileToUpdate.FullName + TemplateFilePath = $ParentTemplateFileToPublish.FullName + } + + if ($ModuleVersion -notmatch 'prerelease') { + + # Latest Major,Minor + $ModulesToPublish += @{ + Version = ($ParentModuleVersion.Split('.')[0..1] -join '.') + TemplateFilePath = $ParentTemplateFileToPublish.FullName + } + + # Latest Major + $ModulesToPublish += @{ + Version = ($ParentModuleVersion.Split('.')[0]) + TemplateFilePath = $ParentTemplateFileToPublish.FullName + } } } } - $ModulesToUpdate = $ModulesToUpdate | Sort-Object TemplateFilePath -Descending -Unique + $ModulesToPublish = $ModulesToPublish | Sort-Object TemplateFilePath, Version -Descending -Unique - Write-Verbose 'Update the following modules:'-Verbose - $ModulesToUpdate | ForEach-Object { - Write-Verbose (' - [{0}] [{1}] ' -f $_.Version, $_.TemplateFilePath) -Verbose + if ($ModulesToPublish.count -gt 0) { + Write-Verbose 'Publish the following modules:'-Verbose + $ModulesToPublish | ForEach-Object { + $RelPath = ($_.TemplateFilePath).Split('/arm/')[-1] + $RelPath = $RelPath.Split('/deploy.')[0] + Write-Verbose (' - [{0}] [{1}] ' -f $RelPath, $_.Version) -Verbose + } + } else { + Write-Verbose 'No modules to publish.'-Verbose } - return $ModulesToUpdate + return $ModulesToPublish } diff --git a/utilities/pipelines/resourcePublish/Publish-ModuleToUniversalArtifactFeed.ps1 b/utilities/pipelines/resourcePublish/Publish-ModuleToUniversalArtifactFeed.ps1 index 21d792f3c4..7868fe45fa 100644 --- a/utilities/pipelines/resourcePublish/Publish-ModuleToUniversalArtifactFeed.ps1 +++ b/utilities/pipelines/resourcePublish/Publish-ModuleToUniversalArtifactFeed.ps1 @@ -1,3 +1,34 @@ +#region Helper +<# +.SYNOPSIS +Asserts that the given version string it semver 2.0 compatible + +.DESCRIPTION +Asserts that the given version string it semver 2.0 compatible + +.PARAMETER Version +The version to check + +.EXAMPLE +Assert-SemVerCompatability -Version '1.0.0' + +True + +Checks if the version '1.0.0' is semver 2.0 compatible + +#> +function Assert-SemVerCompatability { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $Version + ) + + return $Version -match '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' +} +#endregion + <# .SYNOPSIS Publish a new version of a given module to an Azure DevOps artifact feed as a universal package. @@ -61,6 +92,10 @@ function Publish-ModuleToUniversalArtifactFeed { } process { + if (-not (Assert-SemVerCompatability -Version $ModuleVersion)) { + Write-Warning "Invalid module version: [$ModuleVersion] - Skipping" + return + } ################################# ## Generate package name ## @@ -103,7 +138,12 @@ function Publish-ModuleToUniversalArtifactFeed { $inputObject += @('--project', "$VstsFeedProject") } - az artifacts universal publish @inputObject + try { + az artifacts universal publish @inputObject + } catch { + Write-Warning "Failed to publish module to Universal Package Feed [$VstsOrganizationUri/$VstsFeedProject/$VstsFeedName]" + Write-Warning $_ + } } Write-Verbose 'Publish complete'