utilities/pipelines/resourcePublish/Get-ModulesMissingFromUniversalArtifactsFeed.ps1 (112 lines of code) (raw):

<# .SYNOPSIS Get a list of all modules (path & version) in the given TemplatePath that do not exist as an Universal Package in the given Azure DevOps project & artifacts feed .DESCRIPTION Get a list of all modules (path & version) in the given TemplatePath that do not exist as an Universal Package in the given Azure DevOps project & artifacts feed .PARAMETER TemplateFilePath Mandatory. The Template File Path to process .PARAMETER VstsOrganizationUri Mandatory. Azure DevOps organization URL hosting the artifacts feed. Example: 'https://dev.azure.com/fabrikam/'. .PARAMETER VstsFeedProject Optional. Name of the project hosting the artifacts feed. May be empty. Example: 'IaC'. .PARAMETER VstsFeedName Mandatory. Name to the feed to publish to. Example: 'Artifacts'. .PARAMETER UseApiSpecsAlignedName Optional. If set to true, the module name looked for is aligned with the Azure API naming. If not, it's one aligned with the module's folder path. See the following examples: - True: microsoft.keyvault.vaults.secrets - False: key-vault.vault.secret .PARAMETER BearerToken Optional. The bearer token to use to authenticate the request. If not provided it MUST be existing in your environment as `$env:TOKEN` .EXAMPLE Get-ModulesMissingFromUniversalArtifactsFeed -TemplateFilePath 'C:\modules\key-vault\vault\main.bicep' -vstsOrganizationUri 'https://dev.azure.com/fabrikam' -VstsProject 'IaC' -VstsFeedName 'Artifacts' Check if either the Key Vault module or any of its children (e.g. 'secret') is missing in artifacts feed 'Artifacts' of Azure DevOps project 'https://dev.azure.com/fabrikam/IaC' Returns for example: Name Value ---- ----- Version 0.4.0 TemplateFilePath C:\ResourceModules\modules\key-vault\vault\access-policy\main.bicep Version 0.4.0 TemplateFilePath C:\ResourceModules\modules\key-vault\vault\key\main.bicep Version 0.4.0 TemplateFilePath C:\ResourceModules\modules\key-vault\vault\secret\main.bicep Version 0.5.0 TemplateFilePath C:\ResourceModules\modules\key-vault\vault\main.bicep #> function Get-ModulesMissingFromUniversalArtifactsFeed { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $TemplateFilePath, [Parameter(Mandatory = $true)] [string] $VstsFeedName, [Parameter(Mandatory = $true)] [string] $VstsOrganizationUri, [Parameter(Mandatory = $false)] [string] $VstsFeedProject = '', [Parameter(Mandatory = $false)] [bool] $UseApiSpecsAlignedName = $false, [Parameter(Mandatory = $false)] [string] $BearerToken = $env:TOKEN ) begin { Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) # Load used functions . (Join-Path $PSScriptRoot 'Get-UniversalArtifactsName.ps1') } process { # Get all children, bicep templates only $availableModuleTemplatePaths = (Get-ChildItem -Path (Split-Path $TemplateFilePath) -Recurse -Include @('main.bicep')).FullName # Get all children, ARM templates only $availableModuleTemplatePathsARM = (Get-ChildItem -Path (Split-Path $TemplateFilePath) -Recurse -Include @('main.json')).FullName # Add ARM templates to the list of available modules only if there is no bicep template for the same module foreach ($path in $availableModuleTemplatePathsARM) { if ($availableModuleTemplatePaths -contains $path.Replace('.json', '.bicep')) { continue } $availableModuleTemplatePaths += $path } $availableModuleTemplatePaths = $availableModuleTemplatePaths | Sort-Object # Get artifacts if ($VstsOrganizationUri -like '*/') { $VstsOrganizationUri = $VstsOrganizationUri.Substring(0, ($VstsOrganizationUri.length - 1)) # Remove tailing slash if any } $VstsOrganization = Split-Path $VstsOrganizationUri -Leaf # Extract only organization name $modulesInputObject = @{ Method = 'Get' Headers = @{ # Authorization = "Basic $BearerToken" # For custom PAT Authorization = "Bearer $BearerToken" # For pipeline PAT } Uri = "https://feeds.dev.azure.com/$VstsOrganization/$VstsFeedProject/_apis/packaging/Feeds/$VstsFeedName/Packages?api-version=6.0-preview" } $publishedModules = Invoke-RestMethod @modulesInputObject $publishedModules = $publishedModules.value.name # Reduce down to the name # Test all children against Universal Artifacts feed $missingTemplatePaths = @() foreach ($templatePath in $availableModuleTemplatePaths) { # Get a valid Universal Artifact name $artifactsIdentifier = Get-UniversalArtifactsName -TemplateFilePath $templatePath -UseApiSpecsAlignedName $UseApiSpecsAlignedName if ($publishedModules -notcontains $artifactsIdentifier) { $missingTemplatePaths += $templatePath } } # Collect any that are not part of the ACR, fetch their version and return the result array $modulesToPublish = @() foreach ($missingTemplatePath in $missingTemplatePaths) { $moduleVersionToPublish = @{ TemplateFilePath = $missingTemplatePath Version = '{0}.0' -f (Get-Content (Join-Path (Split-Path $missingTemplatePath) 'version.json') -Raw | ConvertFrom-Json).version } $modulesToPublish += $moduleVersionToPublish Write-Verbose ('Missing module [{0}] will be considered for publishing with version [{1}]' -f $moduleVersionToPublish.TemplateFilePath, $moduleVersionToPublish.Version) -Verbose } if ($modulesToPublish.count -eq 0) { Write-Verbose 'No modules missing in the target environment' -Verbose } return $modulesToPublish } end { Write-Debug ('{0} exited' -f $MyInvocation.MyCommand) } }