From 91781e3c7aac55b149a57016f7ef261e6ea127c8 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Tue, 23 Apr 2024 11:19:21 +0800 Subject: [PATCH 01/20] add code --- eng/pipelines/armstrong-validation.yml | 40 ++++++ eng/scripts/Armstrong-Validation.ps1 | 185 +++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 eng/pipelines/armstrong-validation.yml create mode 100644 eng/scripts/Armstrong-Validation.ps1 diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml new file mode 100644 index 000000000000..932ee47aa966 --- /dev/null +++ b/eng/pipelines/armstrong-validation.yml @@ -0,0 +1,40 @@ +trigger: none + +jobs: +- job: + pool: + name: azsdk-pool-mms-ubuntu-2204-general + vmImage: ubuntu-22.04 + + # refer to https://github.com/MicrosoftDocs/pipelines-go/blob/main/azure-pipelines.yml + variables: + GOBIN: '$(GOPATH)/bin' # Go binaries path + GOROOT: '/usr/local/go1.22.2' # Go installation path + GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path + modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code + + steps: + - task: GoTool@0 + inputs: + version: '1.22.2' + + - script: | + mkdir -p '$(GOBIN)' + mkdir -p '$(GOPATH)/pkg' + mkdir -p '$(modulePath)' + shopt -s extglob + shopt -s dotglob + mv !(gopath) '$(modulePath)' + echo '##vso[task.prependpath]$(GOBIN)' + echo '##vso[task.prependpath]$(GOROOT)/bin' + displayName: 'Set up the Go workspace' + + - script: | + go version + go install github.com/azure/armstrong@109e9a46faa57c2c5af762019342dff3030f7d79 + displayName: 'Install go dependencies' + + - pwsh: | + $(Build.SourcesDirectory)/eng/scripts/Armstrong-Validation.ps1 -Verbose + displayName: Armstrong Validation + ignoreLASTEXITCODE: true diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 new file mode 100644 index 000000000000..f0fbf1c06624 --- /dev/null +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -0,0 +1,185 @@ +[CmdletBinding()] +param ( + [Parameter(Position = 0)] + [string] $BaseCommitish = "HEAD^", + [Parameter(Position = 1)] + [string] $TargetCommitish = "HEAD" +) +Set-StrictMode -Version 3 + +. $PSScriptRoot/ChangedFiles-Functions.ps1 +. $PSScriptRoot/Logging-Functions.ps1 + +$script:psYamlInstalled = $false +function Ensure-PowerShell-Yaml-Installed { + if ($script:psYamlInstalled) { + # If already checked once in this script, don't log anything further + return; + } + + $script:psYamlInstalled = [bool] (Get-Module -ListAvailable -Name powershell-yaml | Where-Object { $_.Version -eq "0.4.7" }) + + if ($script:psYamlInstalled) { + LogInfo "Module powershell-yaml@0.4.7 already installed" + } + else { + LogInfo "Installing module powershell-yaml@0.4.7" + Install-Module -Name powershell-yaml -RequiredVersion 0.4.7 -Force -Scope CurrentUser + $script:psYamlInstalled = $true + } +} + +function Find-Suppressions-Yaml { + param ( + [string]$fileInSpecFolder + ) + + $currentDirectory = Get-Item (Split-Path -Path $fileInSpecFolder) + + while ($currentDirectory) { + $suppressionsFile = Join-Path -Path $currentDirectory.FullName -ChildPath "suppressions.yaml" + + if (Test-Path $suppressionsFile) { + return $suppressionsFile + } + else { + $currentDirectory = $currentDirectory.Parent + } + } + + return $null +} + +function Get-Suppression { + param ( + [string]$fileInSpecFolder + ) + + $suppressionsFile = Find-Suppressions-Yaml $fileInSpecFolder + if ($suppressionsFile) { + Ensure-PowerShell-Yaml-Installed + + $suppressions = Get-Content -Path $suppressionsFile -Raw | ConvertFrom-Yaml + foreach ($suppression in $suppressions) { + $tool = $suppression["tool"] + $path = $suppression["path"] + + if ($tool -eq "ArmstrongValidation") { + # Paths in suppressions.yml are relative to the file itself + $fullPath = Join-Path -Path (Split-Path -Path $suppressionsFile) -ChildPath $path + + # If path is not specified, suppression applies to all files + if (!$path -or ($fileInSpecFolder -like $fullPath)) { + return $suppression + } + } + } + } + + return $null +} + +function Get-ChangedTerraformFiles($changedFiles = (Get-ChangedFiles)) { + $changedFiles = Get-ChangedFilesUnderSpecification $changedFiles + + $changedSwaggerFiles = $changedFiles.Where({ + $_.EndsWith("/main.tf") + }) + + return $changedSwaggerFiles +} + +$script:armstrongInstalled = $false +function Ensure-Armstrong-Installed { + if ($script:armstrongInstalled) { + # If already checked once in this script, don't log anything further + return; + } + + $script:armstrongInstalled = $true + + # install golang + if (!(Get-Command "go" -ErrorAction SilentlyContinue)) { + LogError "Golang is not installed" + exit 1 + } + + # install armstrong + if (!(Get-Command "armstrong" -ErrorAction SilentlyContinue)) { + LogError "Armstrong is not installed" + exit 1 + } +} + +function Validate-Terraform-Error($repoPath, $filePath) { + $fileDirectory = (Split-Path -Parent $filePath) + + $outputDirectory = Join-Path -Path $fileDirectory -ChildPath "58d50903-36e9-4f57-a1e5-f246d7ecdec0" + + if (!(Test-Path -Path $outputDirectory)) { + New-Item -Path $outputDirectory -ItemType Directory + # run armstrong credscan + $specPath = Join-Path -Path $repoPath -ChildPath "specification" + LogInfo "armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory" + armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory + } + + $result = @() + # error reports are stored in a directory named armstrong_credscan_ + Get-ChildItem -Path $outputDirectory -Directory -Filter "armstrong_credscan_*" | ForEach-Object { + $errorJsonPath = Join-Path -Path $_.FullName -ChildPath "errors.json" + if (Test-Path -Path $errorJsonPath) { + Get-Content -Path $errorJsonPath -Raw | ConvertFrom-Json | ForEach-Object { + $result += "$_" + } + } + } + + return $result +} + +$repoPath = Resolve-Path "$PSScriptRoot/../.." + +$terraformErrors = @() + +$filesToCheck = (Get-ChangedTerraformFiles (Get-ChangedFiles $BaseCommitish $TargetCommitish)) + +if (!$filesToCheck) { + LogInfo "No Terraform files found to check" +} +else { + foreach ($file in $filesToCheck) { + LogInfo "Checking $file" + + $fullPath = (Join-Path $repoPath $file) + + $suppression = Get-Suppression $fullPath + if ($suppression) { + $reason = $suppression["reason"] ?? "" + + LogInfo " Suppressed: $reason" + # Skip further checks, to avoid potential errors on files already suppressed + continue + } + + try { + Ensure-Armstrong-Installed + LogInfo " Validating errors from Terraform file: $fullPath" + $terraformErrors += (Validate-Terraform-Error $repoPath $fullPath) + } + catch { + $terraformErrors += " failed to validate errors from Terraform file: $file`n $_" + } + } +} + +if ($terraformErrors.Count -gt 0) { + $errorString = "Armstrong Validation failed for some files. To fix, address the following errors: `n" + $errorString += $terraformErrors -join "`n" + LogError $errorString + + LogJobFailure + exit 1 +} + +exit 0 From da9dda0f2f02a685126063e09e3264980ac623ab Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Fri, 26 Apr 2024 13:28:09 +0800 Subject: [PATCH 02/20] fix yml --- eng/pipelines/armstrong-validation.yml | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml index 932ee47aa966..484e2a696533 100644 --- a/eng/pipelines/armstrong-validation.yml +++ b/eng/pipelines/armstrong-validation.yml @@ -5,13 +5,6 @@ jobs: pool: name: azsdk-pool-mms-ubuntu-2204-general vmImage: ubuntu-22.04 - - # refer to https://github.com/MicrosoftDocs/pipelines-go/blob/main/azure-pipelines.yml - variables: - GOBIN: '$(GOPATH)/bin' # Go binaries path - GOROOT: '/usr/local/go1.22.2' # Go installation path - GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path - modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code steps: - task: GoTool@0 @@ -19,15 +12,8 @@ jobs: version: '1.22.2' - script: | - mkdir -p '$(GOBIN)' - mkdir -p '$(GOPATH)/pkg' - mkdir -p '$(modulePath)' - shopt -s extglob - shopt -s dotglob - mv !(gopath) '$(modulePath)' - echo '##vso[task.prependpath]$(GOBIN)' - echo '##vso[task.prependpath]$(GOROOT)/bin' - displayName: 'Set up the Go workspace' + echo '##vso[task.prependpath]$(HOME)/go/bin' + displayName: 'Set Environment Variables' - script: | go version From 0755ad3201f6377bb90cee44b7d59400a49f8bbe Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Fri, 26 Apr 2024 13:52:39 +0800 Subject: [PATCH 03/20] fix yml --- eng/pipelines/armstrong-validation.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml index 484e2a696533..1c618675f1e9 100644 --- a/eng/pipelines/armstrong-validation.yml +++ b/eng/pipelines/armstrong-validation.yml @@ -11,14 +11,11 @@ jobs: inputs: version: '1.22.2' - - script: | - echo '##vso[task.prependpath]$(HOME)/go/bin' - displayName: 'Set Environment Variables' - - script: | go version go install github.com/azure/armstrong@109e9a46faa57c2c5af762019342dff3030f7d79 - displayName: 'Install go dependencies' + echo '##vso[task.prependpath]$(HOME)/go/bin' + displayName: 'Setup dependencies' - pwsh: | $(Build.SourcesDirectory)/eng/scripts/Armstrong-Validation.ps1 -Verbose From 62347fa235d995f51d399b58e6538f77f8cc0e2f Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Sun, 28 Apr 2024 11:01:22 +0800 Subject: [PATCH 04/20] update --- eng/pipelines/armstrong-validation.yml | 2 +- eng/scripts/Armstrong-Validation.ps1 | 41 +++++++++++++++----------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml index 1c618675f1e9..e87761c3e5d9 100644 --- a/eng/pipelines/armstrong-validation.yml +++ b/eng/pipelines/armstrong-validation.yml @@ -13,7 +13,7 @@ jobs: - script: | go version - go install github.com/azure/armstrong@109e9a46faa57c2c5af762019342dff3030f7d79 + go install github.com/azure/armstrong@67fe406e78e3b94075932add869f8b11fb4dd0a6 echo '##vso[task.prependpath]$(HOME)/go/bin' displayName: 'Setup dependencies' diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index f0fbf1c06624..7358cf05330b 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -83,6 +83,7 @@ function Get-ChangedTerraformFiles($changedFiles = (Get-ChangedFiles)) { $changedFiles = Get-ChangedFilesUnderSpecification $changedFiles $changedSwaggerFiles = $changedFiles.Where({ + # since `git diff` returns paths with `/`, use the following code to match the `main.tf` $_.EndsWith("/main.tf") }) @@ -113,27 +114,31 @@ function Ensure-Armstrong-Installed { function Validate-Terraform-Error($repoPath, $filePath) { $fileDirectory = (Split-Path -Parent $filePath) - - $outputDirectory = Join-Path -Path $fileDirectory -ChildPath "58d50903-36e9-4f57-a1e5-f246d7ecdec0" - - if (!(Test-Path -Path $outputDirectory)) { - New-Item -Path $outputDirectory -ItemType Directory - # run armstrong credscan - $specPath = Join-Path -Path $repoPath -ChildPath "specification" - LogInfo "armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory" - armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory - } - - $result = @() - # error reports are stored in a directory named armstrong_credscan_ - Get-ChildItem -Path $outputDirectory -Directory -Filter "armstrong_credscan_*" | ForEach-Object { - $errorJsonPath = Join-Path -Path $_.FullName -ChildPath "errors.json" - if (Test-Path -Path $errorJsonPath) { - Get-Content -Path $errorJsonPath -Raw | ConvertFrom-Json | ForEach-Object { - $result += "$_" + $outputDirectory = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) + + try { + if (!(Test-Path -Path $outputDirectory)) { + New-Item -Path $outputDirectory -ItemType Directory + # run armstrong credscan + $specPath = Join-Path -Path $repoPath -ChildPath "specification" + LogInfo "armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory" + armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory + } + + $result = @() + # error reports are stored in a directory named armstrong_credscan_ + Get-ChildItem -Path $outputDirectory -Directory -Filter "armstrong_credscan_*" | ForEach-Object { + $errorJsonPath = Join-Path -Path $_.FullName -ChildPath "errors.json" + if (Test-Path -Path $errorJsonPath) { + Get-Content -Path $errorJsonPath -Raw | ConvertFrom-Json | ForEach-Object { + $result += "$_" + } } } } + finally { + Remove-Item -Path $outputDirectory -Recurse -Force + } return $result } From bae3d8d46d02c687b57aec0c04256abb8e60d3cc Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Sun, 28 Apr 2024 15:40:57 +0800 Subject: [PATCH 05/20] update --- eng/scripts/Armstrong-Validation.ps1 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 7358cf05330b..63f97b5fd690 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -115,23 +115,29 @@ function Ensure-Armstrong-Installed { function Validate-Terraform-Error($repoPath, $filePath) { $fileDirectory = (Split-Path -Parent $filePath) $outputDirectory = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) + $result = @() try { if (!(Test-Path -Path $outputDirectory)) { - New-Item -Path $outputDirectory -ItemType Directory + New-Item -Path $outputDirectory -ItemType Directory *> $null # run armstrong credscan $specPath = Join-Path -Path $repoPath -ChildPath "specification" LogInfo "armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory" armstrong credscan -working-dir $fileDirectory -swagger-repo $specPath -output-dir $outputDirectory } - $result = @() # error reports are stored in a directory named armstrong_credscan_ Get-ChildItem -Path $outputDirectory -Directory -Filter "armstrong_credscan_*" | ForEach-Object { $errorJsonPath = Join-Path -Path $_.FullName -ChildPath "errors.json" if (Test-Path -Path $errorJsonPath) { Get-Content -Path $errorJsonPath -Raw | ConvertFrom-Json | ForEach-Object { - $result += "$_" + $properties = $_.PSObject.Properties + $item = "Error Item:" + foreach ($property in $properties) { + $item += "`n $($property.Name): $($property.Value)" + } + + $result += $item } } } @@ -181,7 +187,7 @@ else { if ($terraformErrors.Count -gt 0) { $errorString = "Armstrong Validation failed for some files. To fix, address the following errors: `n" $errorString += $terraformErrors -join "`n" - LogError $errorString + Write-Error $errorString LogJobFailure exit 1 From 440c6316d95c5eef131f98f63a7d8f3b0d2ef185 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 29 Apr 2024 07:15:38 +0800 Subject: [PATCH 06/20] debug --- eng/scripts/Armstrong-Validation.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 63f97b5fd690..f77abaed2b05 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -149,6 +149,15 @@ function Validate-Terraform-Error($repoPath, $filePath) { return $result } +# DEBUG +Get-ChildItem Env: | ForEach-Object { + LogInfo "$($_.Name): $($_.Value)" +} + +LogWarning "Warning Test" +LogError "Error Test" +# DEBUG end + $repoPath = Resolve-Path "$PSScriptRoot/../.." $terraformErrors = @() From 7ae49e2beaf7a65f81204b8307a1e192646d3c53 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 29 Apr 2024 07:50:33 +0800 Subject: [PATCH 07/20] update --- eng/scripts/Armstrong-Validation.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index f77abaed2b05..f4449f815c4d 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -149,15 +149,15 @@ function Validate-Terraform-Error($repoPath, $filePath) { return $result } -# DEBUG -Get-ChildItem Env: | ForEach-Object { - LogInfo "$($_.Name): $($_.Value)" +# Check if the repository and target branch are the ones that need to do API Testing +$repositoryName = [Environment]::GetEnvironmentVariable("BUILD_REPOSITORY_NAME", [EnvironmentVariableTarget]::Process) +$targetBranchName = [Environment]::GetEnvironmentVariable("SYSTEM_PULLREQUEST_TARGETBRANCH", [EnvironmentVariableTarget]::Process) +LogInfo "Repository: $repositoryName" +LogInfo "Target branch: $targetBranchName" +if ($repositoryName -eq "Azure/azure-rest-api-specs" -and $targetBranchName -eq "ms-zhenhua/armstrong-validation") { + LogError "The Pull Request against main branch needs to provide API Testing results" } -LogWarning "Warning Test" -LogError "Error Test" -# DEBUG end - $repoPath = Resolve-Path "$PSScriptRoot/../.." $terraformErrors = @() @@ -196,7 +196,7 @@ else { if ($terraformErrors.Count -gt 0) { $errorString = "Armstrong Validation failed for some files. To fix, address the following errors: `n" $errorString += $terraformErrors -join "`n" - Write-Error $errorString + LogError $errorString LogJobFailure exit 1 From ca8ee984c5e366332d5fc346a3b04bd7ff8f9269 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 29 Apr 2024 08:23:52 +0800 Subject: [PATCH 08/20] update --- eng/scripts/Armstrong-Validation.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index f4449f815c4d..98da92a55359 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -132,7 +132,7 @@ function Validate-Terraform-Error($repoPath, $filePath) { if (Test-Path -Path $errorJsonPath) { Get-Content -Path $errorJsonPath -Raw | ConvertFrom-Json | ForEach-Object { $properties = $_.PSObject.Properties - $item = "Error Item:" + $item = "Credential Error:" foreach ($property in $properties) { $item += "`n $($property.Name): $($property.Value)" } @@ -155,7 +155,9 @@ $targetBranchName = [Environment]::GetEnvironmentVariable("SYSTEM_PULLREQUEST_TA LogInfo "Repository: $repositoryName" LogInfo "Target branch: $targetBranchName" if ($repositoryName -eq "Azure/azure-rest-api-specs" -and $targetBranchName -eq "ms-zhenhua/armstrong-validation") { - LogError "The Pull Request against main branch needs to provide API Testing results" + $apiTestingError = "API Testing Error:" + $apiTestingError += "`n The Pull Request against main branch may need to provide API Testing results. Please follow https://github.com/Azure/armstrong/blob/main/docs/guidance-for-api-test.md to complete the API Testing" + LogError $apiTestingError } $repoPath = Resolve-Path "$PSScriptRoot/../.." @@ -194,7 +196,7 @@ else { } if ($terraformErrors.Count -gt 0) { - $errorString = "Armstrong Validation failed for some files. To fix, address the following errors: `n" + $errorString = "Armstrong Validation failed for some files. To fix, address the following errors. For false positive errors, please follow https://eng.ms/docs/products/azure-developer-experience/design/specs-pr-guides/pr-suppressions to suppress 'ArmstrongValidation'`n" $errorString += $terraformErrors -join "`n" LogError $errorString From 63a6f5eae7b1f92579e2190041e148067431a2e9 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 29 Apr 2024 08:56:50 +0800 Subject: [PATCH 09/20] update --- eng/scripts/Armstrong-Validation.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 98da92a55359..d1266f9dbb82 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -155,8 +155,9 @@ $targetBranchName = [Environment]::GetEnvironmentVariable("SYSTEM_PULLREQUEST_TA LogInfo "Repository: $repositoryName" LogInfo "Target branch: $targetBranchName" if ($repositoryName -eq "Azure/azure-rest-api-specs" -and $targetBranchName -eq "ms-zhenhua/armstrong-validation") { - $apiTestingError = "API Testing Error:" + $apiTestingError = "API Testing Warning:" $apiTestingError += "`n The Pull Request against main branch may need to provide API Testing results. Please follow https://github.com/Azure/armstrong/blob/main/docs/guidance-for-api-test.md to complete the API Testing" + # Though it is a warning, we still log it as error because warning log won't be shown in GitHub LogError $apiTestingError } From dd48b66a06e0d8a4e959ff55cbd13d09a7f248e0 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Tue, 7 May 2024 01:28:35 +0000 Subject: [PATCH 10/20] Use shared component get-suppressions - Aligns with #28927 --- eng/scripts/Armstrong-Validation.ps1 | 65 ++-------------------------- 1 file changed, 4 insertions(+), 61 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index d1266f9dbb82..35cda2eb0c20 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -10,73 +10,16 @@ Set-StrictMode -Version 3 . $PSScriptRoot/ChangedFiles-Functions.ps1 . $PSScriptRoot/Logging-Functions.ps1 -$script:psYamlInstalled = $false -function Ensure-PowerShell-Yaml-Installed { - if ($script:psYamlInstalled) { - # If already checked once in this script, don't log anything further - return; - } - - $script:psYamlInstalled = [bool] (Get-Module -ListAvailable -Name powershell-yaml | Where-Object { $_.Version -eq "0.4.7" }) - - if ($script:psYamlInstalled) { - LogInfo "Module powershell-yaml@0.4.7 already installed" - } - else { - LogInfo "Installing module powershell-yaml@0.4.7" - Install-Module -Name powershell-yaml -RequiredVersion 0.4.7 -Force -Scope CurrentUser - $script:psYamlInstalled = $true - } -} - -function Find-Suppressions-Yaml { - param ( - [string]$fileInSpecFolder - ) - - $currentDirectory = Get-Item (Split-Path -Path $fileInSpecFolder) - - while ($currentDirectory) { - $suppressionsFile = Join-Path -Path $currentDirectory.FullName -ChildPath "suppressions.yaml" - - if (Test-Path $suppressionsFile) { - return $suppressionsFile - } - else { - $currentDirectory = $currentDirectory.Parent - } - } - - return $null -} - function Get-Suppression { param ( [string]$fileInSpecFolder ) - $suppressionsFile = Find-Suppressions-Yaml $fileInSpecFolder - if ($suppressionsFile) { - Ensure-PowerShell-Yaml-Installed - - $suppressions = Get-Content -Path $suppressionsFile -Raw | ConvertFrom-Yaml - foreach ($suppression in $suppressions) { - $tool = $suppression["tool"] - $path = $suppression["path"] - - if ($tool -eq "ArmstrongValidation") { - # Paths in suppressions.yml are relative to the file itself - $fullPath = Join-Path -Path (Split-Path -Path $suppressionsFile) -ChildPath $path - - # If path is not specified, suppression applies to all files - if (!$path -or ($fileInSpecFolder -like $fullPath)) { - return $suppression - } - } - } - } + # -NoEnumerate to prevent single-element arrays from being collapsed to a single object + # -AsHashtable is closer to raw JSON than PSCustomObject + $suppressions = npx get-suppressions ArmstrongValidation $fileInSpecFolder | ConvertFrom-Json -NoEnumerate -AsHashtable - return $null + return $suppressions ? $suppressions[0] : $null } function Get-ChangedTerraformFiles($changedFiles = (Get-ChangedFiles)) { From 722f3f4a53d2118d93f256b09331f149a6f9a3cc Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Tue, 7 May 2024 21:33:18 +0000 Subject: [PATCH 11/20] Install Node and deps before calling get-suppressions --- eng/pipelines/armstrong-validation.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml index e87761c3e5d9..5ed1436ef89e 100644 --- a/eng/pipelines/armstrong-validation.yml +++ b/eng/pipelines/armstrong-validation.yml @@ -7,6 +7,8 @@ jobs: vmImage: ubuntu-22.04 steps: + - template: /eng/pipelines/templates/steps/npm-install.yml + - task: GoTool@0 inputs: version: '1.22.2' From b7baad1b6e80a541f0184e10ad7b423455210ab9 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Tue, 7 May 2024 21:33:49 +0000 Subject: [PATCH 12/20] Check for errors after "npx get-suppressions" --- eng/scripts/Armstrong-Validation.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 35cda2eb0c20..63cabf01ce33 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -19,6 +19,12 @@ function Get-Suppression { # -AsHashtable is closer to raw JSON than PSCustomObject $suppressions = npx get-suppressions ArmstrongValidation $fileInSpecFolder | ConvertFrom-Json -NoEnumerate -AsHashtable + if ($LASTEXITCODE -ne 0) { + LogError "Failure running 'npm exec get-suppressions'" + LogJobFailure + exit 1 + } + return $suppressions ? $suppressions[0] : $null } From c27030532b7ae4183cdf36a5f777548262597ee7 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Thu, 7 Nov 2024 23:57:33 +0000 Subject: [PATCH 13/20] Convert "Armstrong Validation" to GitHub Action --- .github/workflows/armstrong-validation.yaml | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/armstrong-validation.yaml diff --git a/.github/workflows/armstrong-validation.yaml b/.github/workflows/armstrong-validation.yaml new file mode 100644 index 000000000000..7bcf491891d9 --- /dev/null +++ b/.github/workflows/armstrong-validation.yaml @@ -0,0 +1,36 @@ +name: Armstrong Validation + +on: pull_request + +jobs: + armstrong-validation: + name: Armstrong Validation + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.2 + + - name: Install Go Dependencies + run: | + go version + go install github.com/azure/armstrong@67fe406e78e3b94075932add869f8b11fb4dd0a6 + echo '##vso[task.prependpath]$(HOME)/go/bin' + + - name: Setup Node and run `npm ci` + uses: ./.github/actions/setup-node-npm-ci + + - name: Armstrong Validation + run: | + # Keep processing when errors are written. Nonzero exit will mark the + # step as failed. + $ErrorActionPreference = 'Continue' + + ./eng/scripts/Armstrong-Validation.ps1 -Verbose + shell: pwsh From c1a948c24d157c79022f8e4c9c05111d0a534edd Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Thu, 7 Nov 2024 23:59:30 +0000 Subject: [PATCH 14/20] Update GITHUB_PATH --- .github/workflows/armstrong-validation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/armstrong-validation.yaml b/.github/workflows/armstrong-validation.yaml index 7bcf491891d9..e3add6c0d667 100644 --- a/.github/workflows/armstrong-validation.yaml +++ b/.github/workflows/armstrong-validation.yaml @@ -21,7 +21,7 @@ jobs: run: | go version go install github.com/azure/armstrong@67fe406e78e3b94075932add869f8b11fb4dd0a6 - echo '##vso[task.prependpath]$(HOME)/go/bin' + echo "$(HOME)/go/bin" >> $GITHUB_PATH - name: Setup Node and run `npm ci` uses: ./.github/actions/setup-node-npm-ci From 68326bff20f9759e7e2dd38531cabc57408e0f37 Mon Sep 17 00:00:00 2001 From: Mike Harder Date: Fri, 8 Nov 2024 00:15:50 +0000 Subject: [PATCH 15/20] Update path to logging helpers --- eng/scripts/Armstrong-Validation.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 63cabf01ce33..6ad48a72d44e 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -7,8 +7,8 @@ param ( ) Set-StrictMode -Version 3 +. $PSScriptRoot/../common/scripts/logging.ps1 . $PSScriptRoot/ChangedFiles-Functions.ps1 -. $PSScriptRoot/Logging-Functions.ps1 function Get-Suppression { param ( From 3acdffeea0aeab649600802bd5a66cf01d65fd6d Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Mon, 11 Nov 2024 16:42:50 +0800 Subject: [PATCH 16/20] remove pipeline task --- .github/workflows/armstrong-validation.yaml | 5 ++--- eng/pipelines/armstrong-validation.yml | 25 --------------------- 2 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 eng/pipelines/armstrong-validation.yml diff --git a/.github/workflows/armstrong-validation.yaml b/.github/workflows/armstrong-validation.yaml index e3add6c0d667..fbc7d19736d7 100644 --- a/.github/workflows/armstrong-validation.yaml +++ b/.github/workflows/armstrong-validation.yaml @@ -20,7 +20,7 @@ jobs: - name: Install Go Dependencies run: | go version - go install github.com/azure/armstrong@67fe406e78e3b94075932add869f8b11fb4dd0a6 + go install github.com/azure/armstrong@latest echo "$(HOME)/go/bin" >> $GITHUB_PATH - name: Setup Node and run `npm ci` @@ -30,7 +30,6 @@ jobs: run: | # Keep processing when errors are written. Nonzero exit will mark the # step as failed. - $ErrorActionPreference = 'Continue' - + ./eng/scripts/Armstrong-Validation.ps1 -Verbose shell: pwsh diff --git a/eng/pipelines/armstrong-validation.yml b/eng/pipelines/armstrong-validation.yml deleted file mode 100644 index 5ed1436ef89e..000000000000 --- a/eng/pipelines/armstrong-validation.yml +++ /dev/null @@ -1,25 +0,0 @@ -trigger: none - -jobs: -- job: - pool: - name: azsdk-pool-mms-ubuntu-2204-general - vmImage: ubuntu-22.04 - - steps: - - template: /eng/pipelines/templates/steps/npm-install.yml - - - task: GoTool@0 - inputs: - version: '1.22.2' - - - script: | - go version - go install github.com/azure/armstrong@67fe406e78e3b94075932add869f8b11fb4dd0a6 - echo '##vso[task.prependpath]$(HOME)/go/bin' - displayName: 'Setup dependencies' - - - pwsh: | - $(Build.SourcesDirectory)/eng/scripts/Armstrong-Validation.ps1 -Verbose - displayName: Armstrong Validation - ignoreLASTEXITCODE: true From 5ffc3e450f36b0c304c131430c5b4ac8e5de710c Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Tue, 12 Nov 2024 10:01:42 +0800 Subject: [PATCH 17/20] fix armstrong cred scan error --- .github/workflows/armstrong-validation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/armstrong-validation.yaml b/.github/workflows/armstrong-validation.yaml index fbc7d19736d7..3397cd63b4bf 100644 --- a/.github/workflows/armstrong-validation.yaml +++ b/.github/workflows/armstrong-validation.yaml @@ -20,7 +20,7 @@ jobs: - name: Install Go Dependencies run: | go version - go install github.com/azure/armstrong@latest + go install github.com/azure/armstrong@c27cb68ad5d83f254f921d594f02b618deb4ad7e echo "$(HOME)/go/bin" >> $GITHUB_PATH - name: Setup Node and run `npm ci` From f02698790d2a36c828eeabbc6beb3e476643f40d Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Sun, 17 Nov 2024 07:55:25 +0800 Subject: [PATCH 18/20] update armstrong pipeline task --- .github/workflows/armstrong-validation.yaml | 18 ++- eng/common/scripts/Invoke-GitHubAPI.ps1 | 21 +++ eng/scripts/Armstrong-Validation.ps1 | 136 ++++++++++++++------ 3 files changed, 132 insertions(+), 43 deletions(-) diff --git a/.github/workflows/armstrong-validation.yaml b/.github/workflows/armstrong-validation.yaml index 3397cd63b4bf..c2d7ba4f5d1d 100644 --- a/.github/workflows/armstrong-validation.yaml +++ b/.github/workflows/armstrong-validation.yaml @@ -1,7 +1,16 @@ name: Armstrong Validation -on: pull_request - +on: + pull_request: + types: + - opened + - reopened + - edited + - ready_for_review + - labeled + - unlabeled + - synchronize + jobs: armstrong-validation: name: Armstrong Validation @@ -25,7 +34,7 @@ jobs: - name: Setup Node and run `npm ci` uses: ./.github/actions/setup-node-npm-ci - + - name: Armstrong Validation run: | # Keep processing when errors are written. Nonzero exit will mark the @@ -33,3 +42,6 @@ jobs: ./eng/scripts/Armstrong-Validation.ps1 -Verbose shell: pwsh + env: + GH_PR_NUMBER: ${{ github.event.number }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/eng/common/scripts/Invoke-GitHubAPI.ps1 b/eng/common/scripts/Invoke-GitHubAPI.ps1 index c4a9fa5bb11e..0dce19de7c69 100644 --- a/eng/common/scripts/Invoke-GitHubAPI.ps1 +++ b/eng/common/scripts/Invoke-GitHubAPI.ps1 @@ -258,6 +258,27 @@ function Add-GitHubIssueComment { -MaximumRetryCount 3 } +function Get-GitHubIssueComments { + param ( + [Parameter(Mandatory = $true)] + $RepoOwner, + [Parameter(Mandatory = $true)] + $RepoName, + [Parameter(Mandatory = $true)] + $IssueNumber, + [Parameter(Mandatory = $true)] + $AuthToken + ) + + $uri = "$GithubAPIBaseURI/$RepoOwner/$RepoName/issues/$IssueNumber/comments" + + return Invoke-RestMethod ` + -Method GET ` + -Uri $uri ` + -Headers (Get-GitHubApiHeaders -token $AuthToken) ` + -MaximumRetryCount 3 +} + # Will add labels to existing labels on the issue function Add-GitHubIssueLabels { param ( diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index 6ad48a72d44e..f928d0172bdd 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -2,31 +2,16 @@ param ( [Parameter(Position = 0)] [string] $BaseCommitish = "HEAD^", + [Parameter(Position = 1)] [string] $TargetCommitish = "HEAD" ) Set-StrictMode -Version 3 +. $PSScriptRoot/../common/scripts/Invoke-GitHubAPI.ps1 . $PSScriptRoot/../common/scripts/logging.ps1 . $PSScriptRoot/ChangedFiles-Functions.ps1 - -function Get-Suppression { - param ( - [string]$fileInSpecFolder - ) - - # -NoEnumerate to prevent single-element arrays from being collapsed to a single object - # -AsHashtable is closer to raw JSON than PSCustomObject - $suppressions = npx get-suppressions ArmstrongValidation $fileInSpecFolder | ConvertFrom-Json -NoEnumerate -AsHashtable - - if ($LASTEXITCODE -ne 0) { - LogError "Failure running 'npm exec get-suppressions'" - LogJobFailure - exit 1 - } - - return $suppressions ? $suppressions[0] : $null -} +. $PSScriptRoot/Suppressions-Functions.ps1 function Get-ChangedTerraformFiles($changedFiles = (Get-ChangedFiles)) { $changedFiles = Get-ChangedFilesUnderSpecification $changedFiles @@ -98,23 +83,44 @@ function Validate-Terraform-Error($repoPath, $filePath) { return $result } -# Check if the repository and target branch are the ones that need to do API Testing -$repositoryName = [Environment]::GetEnvironmentVariable("BUILD_REPOSITORY_NAME", [EnvironmentVariableTarget]::Process) -$targetBranchName = [Environment]::GetEnvironmentVariable("SYSTEM_PULLREQUEST_TARGETBRANCH", [EnvironmentVariableTarget]::Process) -LogInfo "Repository: $repositoryName" -LogInfo "Target branch: $targetBranchName" -if ($repositoryName -eq "Azure/azure-rest-api-specs" -and $targetBranchName -eq "ms-zhenhua/armstrong-validation") { - $apiTestingError = "API Testing Warning:" - $apiTestingError += "`n The Pull Request against main branch may need to provide API Testing results. Please follow https://github.com/Azure/armstrong/blob/main/docs/guidance-for-api-test.md to complete the API Testing" - # Though it is a warning, we still log it as error because warning log won't be shown in GitHub - LogError $apiTestingError +function Get-AddedSwaggerFiles() { + $addedFiles = git -c core.quotepath=off diff --name-status --diff-filter=d $BaseCommitish $TargetCommitish | Where-Object { $_ -match 'A\s' } | ForEach-Object { $_.Substring(2).Trim() } + $addedSwaggerFiles = $addedFiles.Where({ + $_.EndsWith(".json") + }) + + return $addedSwaggerFiles } $repoPath = Resolve-Path "$PSScriptRoot/../.." +$filesToCheck = (Get-ChangedTerraformFiles (Get-ChangedFiles $BaseCommitish $TargetCommitish)) -$terraformErrors = @() +# Check whether new swagger files have Armstrong Configurations +$addedFiles = Get-AddedSwaggerFiles +foreach ($file in $addedFiles) { + $directory = Split-Path -Path $file -Parent + $filePath = Join-Path $repoPath $file + LogInfo $filePath + $suppression = Get-Suppression ArmstrongValidation $filePath + if ($suppression) { + $reason = $suppression["reason"] ?? "" + LogInfo "$file suppressed Armstrong Test: $reason" + continue + } -$filesToCheck = (Get-ChangedTerraformFiles (Get-ChangedFiles $BaseCommitish $TargetCommitish)) + $terraformFiles = $filesToCheck.Where({ + # since `git diff` returns paths with `/`, use the following code to match the `main.tf` + $_.StartsWith($directory) + }) + + if ($terraformFiles.Count -eq 0) { + LogError "The new swagger file $file does not have Armstrong Configurations" + exit 1 + } +} + +# Check Armstrong Configurations +$terraformErrors = @() if (!$filesToCheck) { LogInfo "No Terraform files found to check" @@ -123,24 +129,23 @@ else { foreach ($file in $filesToCheck) { LogInfo "Checking $file" - $fullPath = (Join-Path $repoPath $file) + $filePath = (Join-Path $repoPath $file) - $suppression = Get-Suppression $fullPath + $suppression = Get-Suppression ArmstrongValidation $filePath if ($suppression) { $reason = $suppression["reason"] ?? "" - LogInfo " Suppressed: $reason" - # Skip further checks, to avoid potential errors on files already suppressed + LogInfo "$file suppressed Armstrong configuration validation: $reason" continue } try { Ensure-Armstrong-Installed - LogInfo " Validating errors from Terraform file: $fullPath" - $terraformErrors += (Validate-Terraform-Error $repoPath $fullPath) + LogInfo " Validating errors from Terraform file: $filePath" + $terraformErrors += (Validate-Terraform-Error $repoPath $filePath) } catch { - $terraformErrors += " failed to validate errors from Terraform file: $file`n $_" + $terraformErrors += "failed to validate errors from Terraform file $file : $_" } } } @@ -148,10 +153,61 @@ else { if ($terraformErrors.Count -gt 0) { $errorString = "Armstrong Validation failed for some files. To fix, address the following errors. For false positive errors, please follow https://eng.ms/docs/products/azure-developer-experience/design/specs-pr-guides/pr-suppressions to suppress 'ArmstrongValidation'`n" $errorString += $terraformErrors -join "`n" - LogError $errorString + LogInfo $errorString + exit 1 +} + +# Check the Armstrong Test Result +$repositoryId = [Environment]::GetEnvironmentVariable("GITHUB_REPOSITORY", [EnvironmentVariableTarget]::Process) +LogInfo "Repository ID: $repositoryId" +$repoOwner = $repositoryId.Split("/")[0] +$repoName = $repositoryId.Split("/")[1] +LogInfo "Repository Owner: $repoOwner" +LogInfo "Repository Name: $repoName" +$pullRequestNumber = [Environment]::GetEnvironmentVariable("GH_PR_NUMBER", [EnvironmentVariableTarget]::Process) +$authToken = [Environment]::GetEnvironmentVariable("GH_TOKEN", [EnvironmentVariableTarget]::Process) +LogInfo "Repository ID: $repositoryId" +LogInfo "Pull Request Number: $pullRequestNumber" + +$hasArmstrongTestResult = $false +try { + $response = Get-GitHubIssueComments -RepoOwner $repoOwner -RepoName $repoName -IssueNumber $pullRequestNumber -AuthToken $AuthToken + for ($i = $response.Length - 1; $i -ge 0; $i--) { + $responseObject = $response[$i] + if ($responseObject.body.Contains("API TEST ERROR REPORT")) { + LogInfo $responseObject.body + $hasArmstrongTestResult = $true + + if ($responseObject.body.Contains("Approved-Suppression")) { + LogInfo "The API TEST ERROR REPORT is tagged Approved-Suppression" + continue + } + + if ($responseObject.body.Contains("**message**:")) { + LogError "Please fix all errors in API TEST ERROR REPORT: $($responseObject.html_url)" + } + + $coverages = [regex]::Matches($responseObject.body, '(\d+(\.\d+)?)(?=%)') + # Output the matches + foreach ($coverage in $coverages) { + if ($coverage.Value + "%" -ne "100.0%") { + LogError "Properties of some APIs are not 100% covered in API TEST ERROR REPORT: $($responseObject.html_url)" + } + } + + LogInfo "Armstrong Test result is submitted in PR comments: $($responseObject.html_url)" + break + } + } +} +catch { + LogError "Failed with exception: $_" + exit 1 +} - LogJobFailure +if (!$hasArmstrongTestResult) { + LogError "Armstrong Test result is not submitted in PR comments." exit 1 } -exit 0 +exit 0 \ No newline at end of file From 2ae09aefab593f5d8e254bbfa785d42434de1358 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Sun, 17 Nov 2024 08:24:48 +0800 Subject: [PATCH 19/20] update Armstrong-Validation.ps1 --- eng/scripts/Armstrong-Validation.ps1 | 93 +++++++++++++++------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index f928d0172bdd..fff30d68b624 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -96,8 +96,9 @@ $repoPath = Resolve-Path "$PSScriptRoot/../.." $filesToCheck = (Get-ChangedTerraformFiles (Get-ChangedFiles $BaseCommitish $TargetCommitish)) # Check whether new swagger files have Armstrong Configurations -$addedFiles = Get-AddedSwaggerFiles -foreach ($file in $addedFiles) { +$addedSwaggerFiles = Get-AddedSwaggerFiles +$swaggerFilesToBeTest = @() +foreach ($file in $addedSwaggerFiles) { $directory = Split-Path -Path $file -Parent $filePath = Join-Path $repoPath $file LogInfo $filePath @@ -108,6 +109,8 @@ foreach ($file in $addedFiles) { continue } + $swaggerFilesToBeTest += $file + $terraformFiles = $filesToCheck.Where({ # since `git diff` returns paths with `/`, use the following code to match the `main.tf` $_.StartsWith($directory) @@ -158,56 +161,60 @@ if ($terraformErrors.Count -gt 0) { } # Check the Armstrong Test Result -$repositoryId = [Environment]::GetEnvironmentVariable("GITHUB_REPOSITORY", [EnvironmentVariableTarget]::Process) -LogInfo "Repository ID: $repositoryId" -$repoOwner = $repositoryId.Split("/")[0] -$repoName = $repositoryId.Split("/")[1] -LogInfo "Repository Owner: $repoOwner" -LogInfo "Repository Name: $repoName" -$pullRequestNumber = [Environment]::GetEnvironmentVariable("GH_PR_NUMBER", [EnvironmentVariableTarget]::Process) -$authToken = [Environment]::GetEnvironmentVariable("GH_TOKEN", [EnvironmentVariableTarget]::Process) -LogInfo "Repository ID: $repositoryId" -LogInfo "Pull Request Number: $pullRequestNumber" - -$hasArmstrongTestResult = $false -try { - $response = Get-GitHubIssueComments -RepoOwner $repoOwner -RepoName $repoName -IssueNumber $pullRequestNumber -AuthToken $AuthToken - for ($i = $response.Length - 1; $i -ge 0; $i--) { - $responseObject = $response[$i] - if ($responseObject.body.Contains("API TEST ERROR REPORT")) { - LogInfo $responseObject.body - $hasArmstrongTestResult = $true - - if ($responseObject.body.Contains("Approved-Suppression")) { +if ($swaggerFilesToBeTest.Count -ne 0) { + $repositoryId = [Environment]::GetEnvironmentVariable("GITHUB_REPOSITORY", [EnvironmentVariableTarget]::Process) + LogInfo "Repository ID: $repositoryId" + $repoOwner = $repositoryId.Split("/")[0] + $repoName = $repositoryId.Split("/")[1] + LogInfo "Repository Owner: $repoOwner" + LogInfo "Repository Name: $repoName" + $pullRequestNumber = [Environment]::GetEnvironmentVariable("GH_PR_NUMBER", [EnvironmentVariableTarget]::Process) + $authToken = [Environment]::GetEnvironmentVariable("GH_TOKEN", [EnvironmentVariableTarget]::Process) + LogInfo "Repository ID: $repositoryId" + LogInfo "Pull Request Number: $pullRequestNumber" + + $hasArmstrongTestResult = $false + try { + $response = Get-GitHubIssueComments -RepoOwner $repoOwner -RepoName $repoName -IssueNumber $pullRequestNumber -AuthToken $AuthToken + for ($i = $response.Length - 1; $i -ge 0; $i--) { + $responseObject = $response[$i] + + if ($responseObject.body.Contains("API TEST ERROR REPORT Approved-Suppression")) { + $hasArmstrongTestResult = $true LogInfo "The API TEST ERROR REPORT is tagged Approved-Suppression" - continue + break } - if ($responseObject.body.Contains("**message**:")) { - LogError "Please fix all errors in API TEST ERROR REPORT: $($responseObject.html_url)" - } + if ($responseObject.body.Contains("API TEST ERROR REPORT")) { + LogInfo $responseObject.body + $hasArmstrongTestResult = $true - $coverages = [regex]::Matches($responseObject.body, '(\d+(\.\d+)?)(?=%)') - # Output the matches - foreach ($coverage in $coverages) { - if ($coverage.Value + "%" -ne "100.0%") { - LogError "Properties of some APIs are not 100% covered in API TEST ERROR REPORT: $($responseObject.html_url)" + if ($responseObject.body.Contains("**message**:")) { + LogError "Please fix all errors in API TEST ERROR REPORT: $($responseObject.html_url)" } - } - LogInfo "Armstrong Test result is submitted in PR comments: $($responseObject.html_url)" - break + $coverages = [regex]::Matches($responseObject.body, '(\d+(\.\d+)?)(?=%)') + # Output the matches + foreach ($coverage in $coverages) { + if ($coverage.Value + "%" -ne "100.0%") { + LogError "Properties of some APIs are not 100% covered in API TEST ERROR REPORT: $($responseObject.html_url)" + } + } + + LogInfo "Armstrong Test result is submitted in PR comments: $($responseObject.html_url)" + break + } } } -} -catch { - LogError "Failed with exception: $_" - exit 1 -} + catch { + LogError "Failed with exception: $_" + exit 1 + } -if (!$hasArmstrongTestResult) { - LogError "Armstrong Test result is not submitted in PR comments." - exit 1 + if (!$hasArmstrongTestResult) { + LogError "Armstrong Test result is not submitted in PR comments." + exit 1 + } } exit 0 \ No newline at end of file From 26726e3f12dc156273705914dc235738cd3612b9 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Fri, 29 Nov 2024 19:47:52 +0800 Subject: [PATCH 20/20] bug fix --- eng/scripts/Armstrong-Validation.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/scripts/Armstrong-Validation.ps1 b/eng/scripts/Armstrong-Validation.ps1 index fff30d68b624..b3d7599c2e24 100644 --- a/eng/scripts/Armstrong-Validation.ps1 +++ b/eng/scripts/Armstrong-Validation.ps1 @@ -86,8 +86,8 @@ function Validate-Terraform-Error($repoPath, $filePath) { function Get-AddedSwaggerFiles() { $addedFiles = git -c core.quotepath=off diff --name-status --diff-filter=d $BaseCommitish $TargetCommitish | Where-Object { $_ -match 'A\s' } | ForEach-Object { $_.Substring(2).Trim() } $addedSwaggerFiles = $addedFiles.Where({ - $_.EndsWith(".json") - }) + $_ -match "\d{4}-\d{2}-\d{2}(-preview)?/[^/]*\.json$" + }) return $addedSwaggerFiles } @@ -112,9 +112,9 @@ foreach ($file in $addedSwaggerFiles) { $swaggerFilesToBeTest += $file $terraformFiles = $filesToCheck.Where({ - # since `git diff` returns paths with `/`, use the following code to match the `main.tf` - $_.StartsWith($directory) - }) + # since `git diff` returns paths with `/`, use the following code to match the `main.tf` + $_.StartsWith($directory) + }) if ($terraformFiles.Count -eq 0) { LogError "The new swagger file $file does not have Armstrong Configurations"