Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Armstrong Validation into the spec PR check. #28829

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
91781e3
add code
ms-zhenhua Apr 23, 2024
da9dda0
fix yml
ms-zhenhua Apr 26, 2024
0755ad3
fix yml
ms-zhenhua Apr 26, 2024
62347fa
update
ms-zhenhua Apr 28, 2024
bae3d8d
update
ms-zhenhua Apr 28, 2024
440c631
debug
ms-zhenhua Apr 28, 2024
7ae49e2
update
ms-zhenhua Apr 28, 2024
ca8ee98
update
ms-zhenhua Apr 29, 2024
63a6f5e
update
ms-zhenhua Apr 29, 2024
0a5623c
Merge branch 'main' into ms-zhenhua/armstrong-validation
mikeharder May 7, 2024
dd48b66
Use shared component get-suppressions
mikeharder May 7, 2024
0e38c65
Merge branch 'main' into ms-zhenhua/armstrong-validation
mikeharder May 7, 2024
66fed05
Merge branch 'main' into ms-zhenhua/armstrong-validation
mikeharder May 7, 2024
722f3f4
Install Node and deps before calling get-suppressions
mikeharder May 7, 2024
b7baad1
Check for errors after "npx get-suppressions"
mikeharder May 7, 2024
babe855
Merge branch 'main' of https://github.com/Azure/azure-rest-api-specs …
ms-zhenhua Nov 7, 2024
c270305
Convert "Armstrong Validation" to GitHub Action
mikeharder Nov 7, 2024
c1a948c
Update GITHUB_PATH
mikeharder Nov 7, 2024
68326bf
Update path to logging helpers
mikeharder Nov 8, 2024
dbf48ca
Merge branch 'main' into ms-zhenhua/armstrong-validation
ms-zhenhua Nov 8, 2024
eaa05ea
Merge branch 'main' into ms-zhenhua/armstrong-validation
ms-zhenhua Nov 11, 2024
3acdffe
remove pipeline task
ms-zhenhua Nov 11, 2024
5ffc3e4
fix armstrong cred scan error
ms-zhenhua Nov 12, 2024
f026987
update armstrong pipeline task
ms-zhenhua Nov 16, 2024
2ae09ae
update Armstrong-Validation.ps1
ms-zhenhua Nov 17, 2024
3775e7e
Merge branch 'main' into ms-zhenhua/armstrong-validation
ms-zhenhua Nov 29, 2024
26726e3
bug fix
ms-zhenhua Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions eng/pipelines/armstrong-validation.yml
Original file line number Diff line number Diff line change
@@ -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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the pipeline work without setting these vars? Because these would also need to be different on Windows vs Linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

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
185 changes: 185 additions & 0 deletions eng/scripts/Armstrong-Validation.ps1
Original file line number Diff line number Diff line change
@@ -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 [email protected] already installed"
}
else {
LogInfo "Installing module [email protected]"
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"
Copy link
Member

@mikeharder mikeharder Apr 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should create a unique temp directory using code like this:

Suggested change
$outputDirectory = Join-Path -Path $fileDirectory -ChildPath "58d50903-36e9-4f57-a1e5-f246d7ecdec0"
$outputDirectory= [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
try {
New-Item -Path $outputDirectory -ItemType Directory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code updated. Thanks.


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_<timestamp>
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"] ?? "<no reason specified>"

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