microsoft/hve-core

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/add-pester-code-coverage

Branches

Tags

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

Clone

HTTPS

Download ZIP

scripts/linting/Invoke-YamlLint.ps1

173lines Ā· modecode

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