-
Notifications
You must be signed in to change notification settings - Fork 4
111 lines (96 loc) · 5.01 KB
/
Copy patharchitecture-check.yml
File metadata and controls
111 lines (96 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
name: Architecture guardrails
# Manual only, deliberately kept separate from the build/release pipeline (dotnet.yml).
# Trigger from the Actions tab ("Run workflow") once you want to check the current
# state of main (or any branch) against architecture.rules.txt.
on:
workflow_dispatch:
jobs:
validate:
runs-on: windows-latest
permissions:
security-events: write # Required to upload the SARIF report
contents: read
# Single definition of the output directory: the validation step writes into it and the
# two upload steps read from it. Kept in one place so the sides cannot drift apart - a
# mismatch here looks exactly like a missing result file.
env:
OUT_DIR: artifacts/codeanalyst
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Restore
run: dotnet restore CSharpCodeAnalyst.sln
# Restore alone is not enough: MSBuildWorkspace's design-time build for the WPF
# projects needs referenced projects' DLLs to physically exist (e.g.
# ThirdParty/DsmSuite/DsmSuite.DsmViewer.View). Without a real build first, -validate
# logs "Parser failures" for those projects but still exits 0 on an incomplete graph -
# confirmed by reproducing it locally.
- name: Build
run: dotnet build CSharpCodeAnalyst.sln --no-restore -c Debug
- name: Download C# Code Analyst (latest release)
shell: pwsh
run: |
$url = "https://github.com/ATrefzer/CSharpCodeAnalyst/releases/latest/download/latest-release.zip"
Invoke-WebRequest $url -OutFile codeanalyst.zip
Expand-Archive codeanalyst.zip -DestinationPath tools/codeanalyst -Force
- name: Validate architecture
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path $env:OUT_DIR | Out-Null
$exe = Get-ChildItem tools/codeanalyst -Filter CSharpCodeAnalyst.exe -Recurse | Select-Object -First 1
$argList = @(
"-validate",
"-sln:$env:GITHUB_WORKSPACE\CSharpCodeAnalyst.sln",
"-rules:$env:GITHUB_WORKSPACE\architecture.rules.txt",
"-log-console",
"-log-file:$env:GITHUB_WORKSPACE\$env:OUT_DIR\validation-log.txt",
"-out:$env:GITHUB_WORKSPACE\$env:OUT_DIR\validation-result.txt",
# SARIF is what turns findings into annotations on the pull request. -source-root
# is the directory the paths inside the report are made relative to, which for a
# checkout is always the workspace - without it, absolute runner paths would match
# no file in the repository and the alerts would be dropped silently.
"-source-root:$env:GITHUB_WORKSPACE",
"-sarif:$env:GITHUB_WORKSPACE\$env:OUT_DIR\architecture.sarif"
)
# CSharpCodeAnalyst.exe is a WinExe (GUI subsystem). The plain `& $exe args` call
# operator does not reliably wait or propagate the exit code when no console is
# attached (the normal case on a CI runner). Start-Process -Wait -PassThru is the
# reliable way to invoke it headlessly.
$proc = Start-Process -FilePath $exe.FullName -ArgumentList $argList -WorkingDirectory $exe.DirectoryName -NoNewWindow -Wait -PassThru `
-RedirectStandardOutput "$env:OUT_DIR\console-stdout.txt" `
-RedirectStandardError "$env:OUT_DIR\console-stderr.txt"
Get-Content "$env:OUT_DIR\console-stdout.txt" | Write-Host
if ((Get-Item "$env:OUT_DIR\console-stderr.txt").Length -gt 0) {
Get-Content "$env:OUT_DIR\console-stderr.txt" | Write-Host
}
# -validate exit codes: 0 = clean, 1 = violations, 2 = validation failed
# (load/parse error).
$code = $proc.ExitCode
Write-Host "CSharpCodeAnalyst -validate exit code: $code"
# Only a broken analysis fails the run. Violations are the finding, not a failure of
# this workflow: they are uploaded as code scanning alerts, and that list is the signal
# to read. Failing the run on them would also leave a permanent "tool is reporting
# errors" banner on the code scanning page, where nothing is actually wrong with the
# tool. To block a pull request on violations, use the "Code scanning results" check
# in branch protection rather than this exit code.
if ($code -eq 2) {
exit 2
}
if ($code -eq 1) {
Write-Host "::warning::Architecture violations found - see the code scanning alerts for details."
}
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: architecture-validation
path: ${{ env.OUT_DIR }}/
- name: Upload SARIF results
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ env.OUT_DIR }}/architecture.sarif
category: architecture-guardrails