diff --git a/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 b/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 index f176c4a707..5788e5b557 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 +++ b/avm/utilities/pipelines/staticValidation/compliance/helper/helper.psm1 @@ -176,4 +176,52 @@ function Remove-JSONMetadata { } return $TemplateObject +} + +<# +.SYNOPSIS +Get a hashtable of all environment variables in the given GitHub workflow + +.DESCRIPTION +Get a hashtable of all environment variables in the given GitHub workflow + +.PARAMETER WorkflowPath +Mandatory. The path of the workflow to get the environment variables from + +.EXAMPLE +Get-WorkflowEnvVariablesAsObject -WorkflowPath 'C:/bicep-registry-modules/.github/workflows/test.yml' + +Get the environment variables from the given workflow +#> +function Get-WorkflowEnvVariablesAsObject { + + [CmdletBinding()] + param ( + [Parameter(Mandatory)] + [string] $WorkflowPath + ) + + $contentFileContent = Get-Content -Path $workflowPath + + $envStartIndex = $contentFileContent.IndexOf('env:') + + if (-not $envStartIndex) { + # No env variables defined in the given workflow + return @{} + } + + $searchIndex = $envStartIndex + 1 + $envVars = @{} + + while ($searchIndex -lt $contentFileContent.Count) { + $line = $contentFileContent[$searchIndex] + if ($line -match "^\s+(\w+): (?:`"|')*([^`"'\s]+)(?:`"|')*$") { + $envVars[($Matches[1])] = $Matches[2] + } else { + break + } + $searchIndex++ + } + + return $envVars } \ No newline at end of file diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 5a007c118a..9686ea9fc1 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -219,29 +219,53 @@ Describe 'File/folder tests' -Tag 'Modules' { Describe 'Pipeline tests' -Tag 'Pipeline' { - $moduleFolderTestCases = [System.Collections.ArrayList] @() + $pipelineTestCases = [System.Collections.ArrayList] @() foreach ($moduleFolderPath in $moduleFolderPaths) { $resourceTypeIdentifier = ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}(res|ptn)[\/|\\]{1}')[2] -replace '\\', '/' # avm/res// $relativeModulePath = Join-Path 'avm' ($moduleFolderPath -split '[\/|\\]{1}avm[\/|\\]{1}')[1] - $moduleFolderTestCases += @{ - moduleFolderName = $resourceTypeIdentifier - relativeModulePath = $relativeModulePath - isTopLevelModule = ($resourceTypeIdentifier -split '[\/|\\]').Count -eq 2 + $isTopLevelModule = ($resourceTypeIdentifier -split '[\/|\\]').Count -eq 2 + if ($isTopLevelModule) { + + $workflowsFolderName = Join-Path $repoRootPath '.github' 'workflows' + $workflowFileName = Get-PipelineFileName -ResourceIdentifier $relativeModulePath + $workflowPath = Join-Path $workflowsFolderName $workflowFileName + + $pipelineTestCases += @{ + relativeModulePath = $relativeModulePath + moduleFolderName = $resourceTypeIdentifier + workflowFileName = $workflowFileName + workflowPath = $workflowPath + } } } - It '[] Module should have a GitHub workflow.' -TestCases ($moduleFolderTestCases | Where-Object { $_.isTopLevelModule }) { + It '[] Module should have a GitHub workflow in path [.github/workflows/].' -TestCases $pipelineTestCases { param( - [string] $relativeModulePath + [string] $WorkflowPath ) - $workflowsFolderName = Join-Path $repoRootPath '.github' 'workflows' - $workflowFileName = Get-PipelineFileName -ResourceIdentifier $relativeModulePath - $workflowPath = Join-Path $workflowsFolderName $workflowFileName - Test-Path $workflowPath | Should -Be $true -Because "path [$workflowPath] should exist." + Test-Path $WorkflowPath | Should -Be $true -Because "path [$WorkflowPath] should exist." + } + + It '[] GitHub workflow [] should have [workflowPath] environment variable with value [.github/workflows/].' -TestCases $pipelineTestCases { + + param( + [string] $WorkflowPath, + [string] $WorkflowFileName + ) + + if (-not (Test-Path $WorkflowPath)) { + Set-ItResult -Skipped -Because "Cannot test content of file in path [$WorkflowPath] as it does not exist." + return + } + + $environmentVariables = Get-WorkflowEnvVariablesAsObject -WorkflowPath $WorkflowPath + + $environmentVariables.Keys | Should -Contain 'workflowPath' + $environmentVariables['workflowPath'] | Should -Be ".github/workflows/$workflowFileName" } } diff --git a/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 b/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 index 40736d1696..8777654978 100644 --- a/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 +++ b/avm/utilities/tools/Invoke-WorkflowsForBranch.ps1 @@ -172,6 +172,11 @@ Optional. The GitHub repository to run the workfows in. Invoke-WorkflowsForBranch -PersonalAccessToken '' -TargetBranch 'feature/branch' -PipelineFilter 'avm.res.*' -WorkflowInputs @{ staticValidation = 'true'; deploymentValidation = 'true'; removeDeployment = 'true' } Run all GitHub workflows that start with'avm.res.*' using branch 'feature/branch'. Also returns all GitHub status badges. + +.EXAMPLE +Invoke-WorkflowsForBranch -PersonalAccessToken '' -TargetBranch 'feature/branch' -PipelineFilter 'avm.res.*' -WorkflowInputs @{ staticValidation = 'true'; deploymentValidation = 'true'; removeDeployment = 'true' } -WhatIf + +Only simulate the triggering of all GitHub workflows that start with'avm.res.*' using branch 'feature/branch'. Hence ONLY returns all GitHub status badges. #> function Invoke-WorkflowsForBranch { @@ -224,10 +229,10 @@ function Invoke-WorkflowsForBranch { } # Generate pipeline badges - if ($SkipPipelineBadges) { + if (-not $SkipPipelineBadges) { $encodedBranch = [uri]::EscapeDataString($TargetBranch) - $workflowUrl = "https://github.com/$RepositoryOwner/$RepositoryName/actions/workflows/$workflowFileName&event=workflow_dispatch" - $gitHubWorkflowBadges += "[![$($workflow.name)]($workflowUrl/badge.svg?branch=$encodedBranch)]($workflowUrl)" + $workflowUrl = "https://github.com/$RepositoryOwner/$RepositoryName/actions/workflows/$workflowFileName" + $gitHubWorkflowBadges += "[![$($workflow.name)]($workflowUrl/badge.svg?branch=$encodedBranch&event=workflow_dispatch)]($workflowUrl)" } }