Skip to content

Commit

Permalink
Finished first draft of test workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderSehr committed Jun 16, 2024
1 parent f1012df commit 14da135
Show file tree
Hide file tree
Showing 4 changed files with 252 additions and 10 deletions.
99 changes: 99 additions & 0 deletions .github/workflows/platform.ci-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: ".Platform - Run CI tests"

on:
push: # TODO: Remove trigger once done
workflow_dispatch:
inputs:
testFile:
type: string
description: "The regex of the test file(s) to run"
required: false
default: '.*'
testCase:
type: string
description: "The test case to run"
required: false
default: ''
schedule:
- cron: "0 0 * * *"

env:
workflowPath: ".github/workflows/platform.ci-tests.yml"


jobs:
###########################
# Initialize pipeline #
###########################
job_initialize_pipeline:
runs-on: ubuntu-latest
name: "Initialize pipeline"
steps:
- name: "Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: "Set input parameters to output variables"
id: get-workflow-param
uses: ./.github/actions/templates/avm-getWorkflowInput
with:
workflowPath: "${{ env.workflowPath}}"
outputs:
workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }}

###############
# Removal #
###############
job_run_tests:
runs-on: ubuntu-20.04
name: "Run CI tests"
needs:
- job_initialize_pipeline
steps:
- name: "Checkout"
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set environment
uses: ./.github/actions/templates/avm-setEnvironment

- name: Run CI tests
id: pester_run_step
uses: azure/powershell@v2
with:
inlineScript: |
# Load used functions
. (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'tests' 'Test-CI.ps1')
$functionInput = @{
RepoRootPath = $env:GITHUB_WORKSPACE
BranchName = $env:GITHUB_REF
TestFile = '${{ (fromJson(needs.job_initialize_pipeline.outputs.workflowInput)).testFile }}'
TestCase = '${{ (fromJson(needs.job_initialize_pipeline.outputs.workflowInput)).testCase }}'
}
Write-Verbose "Invoke task with" -Verbose
Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
$outputsFilePath = Test-CI @functionInput
Write-Output ('{0}={1}' -f 'formattedPesterResultsPath', $outputsFilePath) >> $env:GITHUB_OUTPUT
azPSVersion: "latest"

- name: "Output to GitHub job summaries"
if: always()
shell: pwsh
run: |
# Grouping task logs
Write-Output '::group::Output to GitHub job summaries'
$mdPesterOutputFilePath = '${{ steps.pester_run_step.outputs.formattedPesterResultsPath }}'
if (-not (Test-Path $mdPesterOutputFilePath)) {
Write-Warning ('Input file [{0}] not found. Please check if the previous task threw an error and try again.' -f $mdPesterOutputFilePath)
} else {
Get-Content $mdPesterOutputFilePath >> $env:GITHUB_STEP_SUMMARY
Write-Verbose ('Successfully printed out file [{0}] to Job Summaries' -f $mdPesterOutputFilePath) -Verbose
}
Write-Output '::endgroup::'
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Parse a Pester output containing checks & results and generate formatted markdow
.DESCRIPTION
Parse a Pester output containing checks & results and generate formatted markdown file out of it.
.PARAMETER RepoRootPath
Optional. The path to the root of the repository
.PARAMETER PesterTestResults
Mandatory. The Pester tests results to parse. Can be fetched by running Pester with the `-PassThru` parameter. For example:
Expand Down Expand Up @@ -68,6 +71,9 @@ function Set-PesterGitHubOutput {

[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter(Mandatory = $false)]
[string] $RepoRootPath = (Get-Item $PSScriptRoot).Parent.Parent.Parent.Parent.Parent.FullName,

[Parameter(Mandatory = $true)]
[PSCustomObject] $PesterTestResults,

Expand All @@ -94,6 +100,8 @@ function Set-PesterGitHubOutput {
Write-Verbose ('Formatting [{0}] skipped tests' -f $skippedTests.Count)
Write-Verbose ('Formatting [{0}] tests with explicit warnings' -f $warnings.Count)

$moduleSplitRegex = '[\/|\\]avm[\/|\\](res|ptn)[\/|\\]'

######################
# Set output content #
######################
Expand Down Expand Up @@ -134,9 +142,16 @@ function Set-PesterGitHubOutput {
$intermediateNameElements[-1] = '**{0}**' -f $failedTest.ExpandedName
$testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim()

if ($failedTest.ScriptBlock.File -match $moduleSplitRegex) {
# Module test
$errorFileIdentifier = $failedTest.ErrorRecord.TargetObject.File -split $moduleSplitRegex
$errorTestFile = ('avm/{0}/{1}' -f $errorFileIdentifier[1], $errorFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
} else {
# None-module test
$testFile = $failedTest.ScriptBlock.File -replace ('{0}[\\|\/]*' -f [regex]::Escape($RepoRootPath))
}

$errorTestLine = $failedTest.ErrorRecord.TargetObject.Line
$errorFileIdentifier = $failedTest.ErrorRecord.TargetObject.File -split '[\/|\\]avm[\/|\\](res|ptn)[\/|\\]'
$errorTestFile = ('avm/{0}/{1}' -f $errorFileIdentifier[1], $errorFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
$errorMessage = ($failedTest.ErrorRecord.TargetObject.Message.Trim() -replace '_', '\_') -replace '\n', '<br>' # Replace new lines with <br> to enable line breaks in markdown

$testReference = '{0}:{1}' -f (Split-Path $errorTestFile -Leaf), $errorTestLine
Expand Down Expand Up @@ -181,10 +196,16 @@ function Set-PesterGitHubOutput {
$intermediateNameElements[-1] = '**{0}**' -f $passedTest.ExpandedName
$testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim()

$testLine = $passedTest.ScriptBlock.StartPosition.StartLine
$testFileIdentifier = $passedTest.ScriptBlock.File -split '[\/|\\]avm[\/|\\](res|ptn)[\/|\\]'
$testFile = ('avm/{0}/{1}' -f $testFileIdentifier[1], $testFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
if ($passedTest.ScriptBlock.File -match $moduleSplitRegex) {
# Module test
$testFileIdentifier = $passedTest.ScriptBlock.File -split $moduleSplitRegex
$testFile = ('avm/{0}/{1}' -f $testFileIdentifier[1], $testFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
} else {
# None-module test
$testFile = $passedTest.ScriptBlock.File -replace ('{0}[\\|\/]*' -f [regex]::Escape($RepoRootPath))
}

$testLine = $passedTest.ScriptBlock.StartPosition.StartLine
$testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine
if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) {
# Creating URL to test file to enable users to 'click' on it
Expand Down Expand Up @@ -229,10 +250,16 @@ function Set-PesterGitHubOutput {

$reason = ('Test {0}' -f $skippedTest.ErrorRecord.Exception.Message -replace '\|', '\|').Trim()

$testLine = $skippedTest.ScriptBlock.StartPosition.StartLine
$testFileIdentifier = $skippedTest.ScriptBlock.File -split '[\/|\\]avm[\/|\\](res|ptn)[\/|\\]'
$testFile = ('avm/{0}/{1}' -f $testFileIdentifier[1], $testFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
if ($skippedTest.ScriptBlock.File -match $moduleSplitRegex) {
# Module test
$testFileIdentifier = $skippedTest.ScriptBlock.File -split $moduleSplitRegex
$testFile = ('avm/{0}/{1}' -f $testFileIdentifier[1], $testFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]
} else {
# None-module test
$testFile = $skippedTest.ScriptBlock.File -replace ('{0}[\\|\/]*' -f [regex]::Escape($RepoRootPath))
}

$testLine = $skippedTest.ScriptBlock.StartPosition.StartLine
$testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine
if (-not [String]::IsNullOrEmpty($GitHubRepository) -and -not [String]::IsNullOrEmpty($BranchName)) {
# Creating URL to test file to enable users to 'click' on it
Expand Down Expand Up @@ -275,8 +302,15 @@ function Set-PesterGitHubOutput {
$intermediateNameElements[-1] = '**{0}**' -f $test.ExpandedName
$testName = ((($intermediateNameElements -join ' / ' | Out-String) -replace '\|', '\|') -replace '_', '\_').Trim()

$testLine = $test.ScriptBlock.StartPosition.StartLine
$testFileIdentifier = $test.ScriptBlock.File -split '[\/|\\]avm[\/|\\](res|ptn)[\/|\\]'
if ($test.ScriptBlock.File -match $moduleSplitRegex) {
# Module test
$testLine = $test.ScriptBlock.StartPosition.StartLine
$testFileIdentifier = $test.ScriptBlock.File -split $moduleSplitRegex
} else {
# None-module test
$testFile = $test.ScriptBlock.File -replace ('{0}[\\|\/]*' -f [regex]::Escape($RepoRootPath))
}

$testFile = ('avm/{0}/{1}' -f $testFileIdentifier[1], $testFileIdentifier[2]) -replace '\\', '/' # e.g., [avm\res\cognitive-services\account\tests\unit\custom.tests.ps1]

$testReference = '{0}:{1}' -f (Split-Path $testFile -Leaf), $testLine
Expand Down
42 changes: 42 additions & 0 deletions avm/utilities/tests/Pester-output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Pester validation summary

| Total No. of Processed Tests| Passed Tests :white_check_mark: | Failed Tests :x: | Skipped Tests :paperclip: | Tests with warnings :warning: |
| :-- | :-- | :-- | :-- | :-- |
| 3 | 3 | 0 | 0 | 0 |


<details>
<summary>List of failed Tests</summary>

No tests failed.

</details>


<details>
<summary>List of passed Tests</summary>

| Name | Source |
| :-- | :-- |
| Test sequence ordering / **Remove first sequence should be as expected** | <code>[Get-OrderedResourcesList.tests.ps1:10](https://github.com/C:\dev\ip\bicep-registry-modules\fork-AlexanderSehr/blob/users/alsehr/pesterCiTests/avm\utilities\tests\pipelines\Get-OrderedResourcesList.tests.ps1#L10)</code> |
| Test sequence ordering / **Remove last sequence should be as expected** | <code>[Get-OrderedResourcesList.tests.ps1:77](https://github.com/C:\dev\ip\bicep-registry-modules\fork-AlexanderSehr/blob/users/alsehr/pesterCiTests/avm\utilities\tests\pipelines\Get-OrderedResourcesList.tests.ps1#L77)</code> |
| Test sequence ordering / **Remove sequence should be as expected if both first & last priorities are provided** | <code>[Get-OrderedResourcesList.tests.ps1:146](https://github.com/C:\dev\ip\bicep-registry-modules\fork-AlexanderSehr/blob/users/alsehr/pesterCiTests/avm\utilities\tests\pipelines\Get-OrderedResourcesList.tests.ps1#L146)</code> |

</details>


<details>
<summary>List of skipped Tests</summary>

No tests were skipped.

</details>


<details>
<summary>List of explicit warnings</summary>

No tests with warnings.

</details>

67 changes: 67 additions & 0 deletions avm/utilities/tests/Test-CI.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

function Test-CI {

[CmdletBinding()]
param (
[Parameter()]
[string] $RepoRootPath = (Get-Item $PSScriptRoot).Parent.Parent.Parent.FullName,

[Parameter()]
[string] $BranchName = (git branch --show-current),

[Parameter()]
[string] $TestFile = '.*',

[Parameter()]
[string] $TestCase # TODO: Add support
)

# Load used functions
. (Join-Path $RepoRootPath 'avm' 'utilities' 'pipelines' 'staticValidation' 'compliance' 'Set-PesterGitHubOutput.ps1')

$testFiles = (Get-ChildItem -Path (Join-Path $RepoRootPath 'avm' 'utilities' 'tests') -Recurse -File -Filter '*.tests.ps1').FullName | Where-Object {
$_ -match $TestFile
}

# ------------------- #
# Invoke Pester tests #
# ------------------- #
$pesterConfiguration = @{
Run = @{
Container = New-PesterContainer -Path $testFiles -Data @{
RepoRootPath = $RepoRootPath
}
PassThru = $true
}
Output = @{
Verbosity = 'Detailed'
}
}

Write-Verbose 'Invoke test with' -Verbose
Write-Verbose ($pesterConfiguration | ConvertTo-Json -Depth 4 | Out-String) -Verbose

$testResults = Invoke-Pester -Configuration $pesterConfiguration

# ----------------------------------------- #
# Create formatted Pester Test Results File #
# ----------------------------------------- #

$functionInput = @{
RepoRootPath = $RepoRootPath
PesterTestResults = $testResults
OutputFilePath = Join-Path $RepoRootPath 'avm' 'utilities' 'tests' 'Pester-output.md'
GitHubRepository = $RepoRootPath
BranchName = $BranchName
}

Write-Verbose 'Invoke Pester formatting function with' -Verbose
Write-Verbose ($functionInput | ConvertTo-Json -Depth 0 | Out-String) -Verbose

Set-PesterGitHubOutput @functionInput -Verbose

return $functionInput.OutputFilePath
}



0 comments on commit 14da135

Please sign in to comment.