microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/address-powershell-test-comments

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/linting/Invoke-YamlLint.ps1

186lines Ā· modecode

1#!/usr/bin/env pwsh
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4#Requires -Version 7.0
5<#
6.SYNOPSIS
7 Validates YAML files using actionlint for GitHub Actions workflows.
8
9.DESCRIPTION
10 Runs actionlint to validate GitHub Actions workflow files. Supports changed-files-only
11 mode for PR validation and exports JSON results for CI integration.
12
13.PARAMETER ChangedFilesOnly
14 Validate only changed YAML files.
15
16.PARAMETER BaseBranch
17 Base branch for detecting changed files (default: origin/main).
18
19.PARAMETER OutputPath
20 Path for JSON results output (default: logs/yaml-lint-results.json).
21
22.EXAMPLE
23 ./scripts/linting/Invoke-YamlLint.ps1 -Verbose
24
25.EXAMPLE
26 ./scripts/linting/Invoke-YamlLint.ps1 -ChangedFilesOnly
27
28.NOTES
29 Requires actionlint to be installed. Install via:
30 - Windows: choco install actionlint -or- scoop install actionlint -or- winget install actionlint
31 - macOS: brew install actionlint
32 - Linux: go install github.com/rhysd/actionlint/cmd/actionlint@latest
33#>
34
35[CmdletBinding()]
36param(
37 [Parameter(Mandatory = $false)]
38 [switch]$ChangedFilesOnly,
39
40 [Parameter(Mandatory = $false)]
41 [string]$BaseBranch = "origin/main",
42
43 [Parameter(Mandatory = $false)]
44 [string]$OutputPath = "logs/yaml-lint-results.json"
45)
46
47$ErrorActionPreference = 'Stop'
48
49# Import shared helpers
50Import-Module (Join-Path $PSScriptRoot "Modules/LintingHelpers.psm1") -Force
51Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force
52
53Write-Host "šŸ” Running YAML Lint (actionlint)..." -ForegroundColor Cyan
54
55# Check if actionlint is available
56$actionlintPath = Get-Command actionlint -ErrorAction SilentlyContinue
57if (-not $actionlintPath) {
58 Write-Error "actionlint is not installed. See script help for installation instructions."
59 exit 1
60}
61
62Write-Verbose "Using actionlint: $($actionlintPath.Source)"
63
64# Get files to analyze
65$workflowPath = ".github/workflows"
66$filesToAnalyze = @()
67
68if ($ChangedFilesOnly) {
69 Write-Host "Detecting changed workflow files..." -ForegroundColor Cyan
70 $changedFiles = @(Get-ChangedFilesFromGit -BaseBranch $BaseBranch -FileExtensions @('*.yml', '*.yaml'))
71 $filesToAnalyze = @($changedFiles | Where-Object { $_ -like "$workflowPath/*" })
72}
73else {
74 Write-Host "Analyzing all workflow files..." -ForegroundColor Cyan
75 if (Test-Path $workflowPath) {
76 $filesToAnalyze = @(Get-ChildItem -Path $workflowPath -File | Where-Object { $_.Extension -in '.yml', '.yaml' } | ForEach-Object { $_.FullName })
77 }
78}
79
80if (@($filesToAnalyze).Count -eq 0) {
81 Write-Host "āœ… No workflow files to analyze" -ForegroundColor Green
82 Set-CIOutput -Name "count" -Value "0"
83 Set-CIOutput -Name "issues" -Value "0"
84 exit 0
85}
86
87Write-Host "Analyzing $($filesToAnalyze.Count) workflow files..." -ForegroundColor Cyan
88Set-CIOutput -Name "count" -Value $filesToAnalyze.Count
89
90#region Main Execution
91try {
92 # Run actionlint with JSON output
93 $actionlintArgs = @('-format', '{{json .}}')
94 if ($ChangedFilesOnly -and $filesToAnalyze.Count -gt 0) {
95 $actionlintArgs += $filesToAnalyze
96 }
97
98 $rawOutput = & actionlint @actionlintArgs 2>&1
99 # actionlint exit code is not used; errors are parsed from JSON output
100
101 # Parse JSON output
102 $issues = @()
103 if ($rawOutput -and $rawOutput -ne "null") {
104 try {
105 $issues = $rawOutput | ConvertFrom-Json -ErrorAction Stop
106 if ($null -eq $issues) { $issues = @() }
107 if ($issues -isnot [array]) { $issues = @($issues) }
108 }
109 catch {
110 Write-Warning "Failed to parse actionlint output: $($_.Exception.Message)"
111 Write-Verbose "Raw output: $rawOutput"
112 }
113 }
114
115 # Process issues and create annotations
116 $hasErrors = $false
117 foreach ($issue in $issues) {
118 $hasErrors = $true
119
120 Write-CIAnnotation `
121 -Message $issue.message `
122 -Level Error `
123 -File $issue.filepath `
124 -Line $issue.line `
125 -Column $issue.column
126
127 Write-Host " āŒ $($issue.filepath):$($issue.line):$($issue.column): $($issue.message)" -ForegroundColor Red
128 }
129
130 # Export results
131 $summary = @{
132 TotalFiles = $filesToAnalyze.Count
133 TotalIssues = $issues.Count
134 Errors = $issues.Count
135 Warnings = 0
136 HasErrors = $hasErrors
137 Timestamp = (Get-Date -Format "o")
138 Tool = "actionlint"
139 }
140
141 # Ensure logs directory exists
142 $logsDir = Split-Path $OutputPath -Parent
143 if (-not (Test-Path $logsDir)) {
144 New-Item -ItemType Directory -Force -Path $logsDir | Out-Null
145 }
146
147 $issues | ConvertTo-Json -Depth 5 | Out-File $OutputPath
148 $summary | ConvertTo-Json | Out-File "logs/yaml-lint-summary.json"
149
150 # Set outputs
151 Set-CIOutput -Name "issues" -Value $summary.TotalIssues
152 Set-CIOutput -Name "errors" -Value $summary.Errors
153
154 if ($hasErrors) {
155 Set-CIEnv -Name "YAML_LINT_FAILED" -Value "true"
156 }
157
158 # Write summary
159 Write-CIStepSummary -Content "## YAML Lint Results`n"
160
161 if ($summary.TotalIssues -eq 0) {
162 Write-CIStepSummary -Content "āœ… **Status**: Passed`n`nAll $($summary.TotalFiles) workflow files passed validation."
163 Write-Host "`nāœ… All workflow files passed YAML linting!" -ForegroundColor Green
164 exit 0
165 }
166 else {
167 Write-CIStepSummary -Content @"
168āŒ **Status**: Failed
169
170| Metric | Count |
171|--------|-------|
172| Files Analyzed | $($summary.TotalFiles) |
173| Total Issues | $($summary.TotalIssues) |
174| Errors | $($summary.Errors) |
175"@
176
177 Write-Host "`nāŒ YAML Lint found $($summary.TotalIssues) issue(s)" -ForegroundColor Red
178 exit 1
179 }
180}
181catch {
182 Write-Error -ErrorAction Continue "YAML Lint failed: $($_.Exception.Message)"
183 Write-CIAnnotation -Message "YAML Lint failed: $($_.Exception.Message)" -Level Error
184 exit 1
185}
186#endregion
187