Skip to content

Commit 5d11302

Browse files
committed
Attempt to set up GitHub Actions (#13)
Update packages and add GitHub actions and a sandbox project
1 parent badc5d5 commit 5d11302

File tree

47 files changed

+1523
-58
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1523
-58
lines changed

.github/setup/action.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: setup
2+
description: Sets up the build environment
3+
4+
inputs:
5+
sln:
6+
default: src/Riganti.Selenium.sln
7+
description: Path to a Visual Studio solution
8+
required: false
9+
10+
runs:
11+
using: composite
12+
steps:
13+
14+
# nuget
15+
- uses: nuget/setup-nuget@v1
16+
with:
17+
nuget-version: '6.x'
18+
- uses: actions/cache@v3
19+
id: nuget-cache
20+
with:
21+
path: ~/.nuget/packages
22+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
23+
restore-keys: ${{ runner.os }}-nuget-
24+
25+
# .NET
26+
- uses: actions/setup-dotnet@v3
27+
with:
28+
dotnet-version: |
29+
7.0.x
30+
6.0.x
31+
5.0.x
32+
3.1.x
33+
- if: ${{ runner.os == 'Windows' }}
34+
uses: microsoft/[email protected]
35+
36+
# restore nuget packages
37+
- if: ${{ runner.os == 'Windows' }}
38+
run: msbuild ${{ inputs.sln }} -t:Restore
39+
shell: pwsh
40+
- if: ${{ runner.os != 'Windows' }}
41+
run: dotnet restore ${{ inputs.sln }}
42+
shell: bash

.github/test-report/action.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: test-report
2+
description: |
3+
Writes a short test report to GitHub Actions.
4+
Heavily inspired by https://github.com/zyborg/dotnet-tests-report
5+
and https://github.com/NasAmin/trx-parser.
6+
7+
inputs:
8+
trx-path:
9+
required: true
10+
description: Path to the TRX file.
11+
report-name:
12+
required: true
13+
description: A filename for the report.
14+
report-title:
15+
required: true
16+
description: Human-friendly title of the report.
17+
github-token:
18+
required: true
19+
description: A GitHub token.
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- uses: actions/upload-artifact@v3
25+
with:
26+
name: ${{ inputs.report-name }}
27+
path: ${{ inputs.trx-path }}
28+
- run: Write-Host "::add-mask::${{ inputs.github-token }}" ;
29+
./.github/test-report/test-report.ps1
30+
-TrxPath "${{ inputs.trx-path }}"
31+
-ReportName "${{ inputs.report-name }}"
32+
-ReportTitle "${{ inputs.report-title }}"
33+
-GithubToken "${{ inputs.github-token }}"
34+
shell: pwsh

.github/test-report/test-report.ps1

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Heavily inspired by https://github.com/zyborg/dotnet-tests-report
2+
# and https://github.com/NasAmin/trx-parser.
3+
4+
# NB: Action inputs are not obtained using the GitHubActions PS module,
5+
# because we use a composite action.
6+
param(
7+
[string] $trxPath = "tmp/test.trx",
8+
[string] $reportName,
9+
[string] $reportTitle,
10+
[string] $githubToken)
11+
12+
if (-not (Get-Module -ListAvailable GitHubActions)) {
13+
Install-Module GitHubActions -Force
14+
}
15+
Import-Module GitHubActions
16+
17+
$tmpDir = Join-Path (Get-Location) "tmp"
18+
New-Item -Path $tmpDir -ItemType Directory -Force -ErrorAction Ignore > $null
19+
if (!(Test-Path -Path $tmpDir -PathType Container)) {
20+
throw "Could not create a temporary directory."
21+
}
22+
23+
if (-not $reportName) {
24+
$reportName = "tests-$([datetime]::Now.ToString('yyyy-MM-ddThh-mm-ss'))"
25+
}
26+
if (-not $reportTitle) {
27+
$reportTitle = $reportName
28+
}
29+
30+
$reportPath = Join-Path $tmpDir "$reportName.md"
31+
32+
Write-ActionInfo "Temporary directory: '$tmpDir'"
33+
Write-ActionInfo "Test results path: '$trxPath'"
34+
Write-ActionInfo "Report name: '$reportName'"
35+
Write-ActionInfo "Report title: '$reportTitle'"
36+
Write-ActionInfo "Report path: '$reportPath'"
37+
38+
function Build-MarkdownReport {
39+
$trx2mdParams = @{
40+
trxFile = $trxPath
41+
mdFile = $reportPath
42+
xslParams = @{
43+
reportTitle = $reportTitle
44+
}
45+
}
46+
& "$PSScriptRoot/trx2md.ps1" @trx2mdParams -Verbose
47+
}
48+
49+
function Get-ReportText {
50+
$reportText = [System.IO.File]::ReadAllText($reportPath)
51+
# actual max length is 65535, we truncate to 65000 to have some margin
52+
if ($reportText.Length -gt 65000 ) {
53+
Write-ActionWarning "Report is $($reportText.Length) characters long. Shortening to 65000."
54+
$tooLongError = "...`nThe test report is too long to display.`n"
55+
$reportText = $reportText.Substring(0, [System.Math]::Min($reportText.Length, 65000 - $tooLongError.Length)) `
56+
+ $tooLongError
57+
}
58+
return $reportText;
59+
}
60+
61+
function Publish-ToCheckRun {
62+
param(
63+
[string]$reportText
64+
)
65+
66+
$ctx = Get-ActionContext
67+
$repo = Get-ActionRepo
68+
$repoFullName = "$($repo.Owner)/$($repo.Repo)"
69+
70+
Write-ActionInfo "Resolving REF"
71+
$ref = $ctx.Sha
72+
if ($ctx.EventName -eq 'pull_request') {
73+
Write-ActionInfo "Resolving PR REF"
74+
$ref = $ctx.Payload.pull_request.head.sha
75+
if (-not $ref) {
76+
Write-ActionInfo "Resolving PR REF as AFTER"
77+
$ref = $ctx.Payload.after
78+
}
79+
}
80+
if (-not $ref) {
81+
Write-ActionError "Failed to resolve REF"
82+
exit 1
83+
}
84+
Write-ActionInfo "Resolved REF as $ref"
85+
Write-ActionInfo "Resolve Repo Full Name as $repoFullName"
86+
87+
Write-ActionInfo "Adding Check Run"
88+
$conclusion = 'neutral'
89+
90+
# Set check status based on test result outcome.
91+
if ($inputs.set_check_status_from_test_outcome) {
92+
93+
Write-ActionInfo "Mapping check status to test outcome..."
94+
95+
if ($testResult.ResultSummary_outcome -eq "Failed") {
96+
97+
Write-ActionWarning "Found failing tests"
98+
$conclusion = 'failure'
99+
}
100+
elseif ($testResult.ResultSummary_outcome -eq "Completed") {
101+
102+
Write-ActionInfo "All tests passed"
103+
$conclusion = 'success'
104+
}
105+
}
106+
107+
$url = "https://api.github.com/repos/$repoFullName/check-runs"
108+
$hdr = @{
109+
Accept = 'application/vnd.github.antiope-preview+json'
110+
Authorization = "token $githubToken"
111+
}
112+
113+
$bdy = @{
114+
name = $reportName
115+
head_sha = $ref
116+
status = 'completed'
117+
conclusion = $conclusion
118+
output = @{
119+
title = $reportTitle
120+
summary = "This run completed at ``$([datetime]::Now)``"
121+
text = $reportText
122+
}
123+
}
124+
Invoke-WebRequest -Headers $hdr $url -Method Post -Body ($bdy | ConvertTo-Json)
125+
}
126+
127+
$trxNamespace = @{
128+
trx = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010"
129+
}
130+
$trxXml = [xml][System.IO.File]::ReadAllText($trxPath)
131+
$failedTests = Select-Xml -Xml $trxXml -Namespace $trxNamespace -XPath "//trx:UnitTestResult[@outcome='Failed']"
132+
if ($failedTests.Length -eq 0) {
133+
Write-ActionInfo "All tests have passed. No report is needed."
134+
exit 0
135+
}
136+
137+
Write-ActionInfo "Generating Markdown Report from TRX file"
138+
Build-MarkdownReport
139+
140+
$reportText = Get-ReportText
141+
Write-ActionInfo "Report true length: $($reportText.Length)"
142+
143+
if (-not $githubToken) {
144+
Write-ActionInfo "GitHub token is missing. Skipping upload to GitHub."
145+
} else {
146+
$reportText = Get-ReportText
147+
Publish-ToCheckRun -reportText $reportText
148+
}
149+
Set-ActionFailed "Action failed since $($failedTests.Length) tests failed."

.github/test-report/trx2md.ps1

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Author: Eugene Bekker
2+
# https://github.com/zyborg/dotnet-tests-report
3+
# Licensed under MIT license
4+
5+
[CmdletBinding()]
6+
param(
7+
[Parameter(Mandatory)]
8+
[string]$trxFile,
9+
[string]$mdFile=$null,
10+
[string]$xslFile=$null,
11+
[hashtable]$xslParams=$null
12+
)
13+
14+
if ($trxFile -notmatch '^[/\\]') {
15+
$trxFile = [System.IO.Path]::Combine($PWD, $trxFile)
16+
Write-Verbose "Resolving TRX file relative to current directory: $trxFile"
17+
}
18+
19+
if (-not $mdFile) {
20+
$mdFile = $trxFile
21+
if ([System.IO.Path]::GetExtension($trxFile) -ieq '.trx') {
22+
$mdFile = $trxFile -ireplace '.trx$',''
23+
}
24+
$mdFile += '.md'
25+
Write-Verbose "Resolving default MD file: $mdFile"
26+
}
27+
elseif ($mdFile -notmatch '^[/\\]') {
28+
$mdFile = [System.IO.Path]::Combine($PWD, $mdFile)
29+
Write-Verbose "Resolving MD file relative to current directory: $mdFile"
30+
}
31+
32+
if (-not $xslFile) {
33+
$xslFile = "$PSScriptRoot/trx2md.xsl"
34+
Write-Verbose "Resolving default XSL file: $xslFile"
35+
}
36+
elseif ($xslFile -notmatch '^[/\\]') {
37+
$xslFile = [System.IO.Path]::Combine($PWD, $xslFile)
38+
Write-Verbose "Resolving XSL file relative to current directory: $xslFile"
39+
}
40+
41+
class TrxFn {
42+
[double]DiffSeconds([datetime]$from, [datetime]$till) {
43+
return ($till - $from).TotalSeconds
44+
}
45+
}
46+
47+
48+
if (-not $script:xslt) {
49+
$script:urlr = [System.Xml.XmlUrlResolver]::new()
50+
$script:opts = [System.Xml.Xsl.XsltSettings]::new()
51+
#$script:opts.EnableScript = $true
52+
$script:xslt = [System.Xml.Xsl.XslCompiledTransform]::new()
53+
try {
54+
$script:xslt.Load($xslFile, $script:opts, $script:urlr)
55+
}
56+
catch {
57+
Write-Error $Error[0]
58+
return
59+
}
60+
Write-Verbose "Loaded XSL transformer"
61+
}
62+
63+
$script:list = [System.Xml.Xsl.XsltArgumentList]::new()
64+
$script:list.AddExtensionObject("urn:trxfn", [TrxFn]::new())
65+
if ($xslParams) {
66+
foreach ($xp in $xslParams.GetEnumerator()) {
67+
$script:list.AddParam($xp.Key, [string]::Empty, $xp.Value)
68+
}
69+
}
70+
$script:wrtr = [System.IO.StreamWriter]::new($mdFile)
71+
try {
72+
Write-Verbose "Transforming TRX to MD"
73+
$script:xslt.Transform(
74+
[string]$trxFile,
75+
[System.Xml.Xsl.XsltArgumentList]$script:list,
76+
[System.IO.TextWriter]$script:wrtr)
77+
}
78+
finally {
79+
$script:wrtr.Dispose()
80+
}

0 commit comments

Comments
 (0)