Skip to content

🌟 [Major]: Introducing Get-PesterCodeCoverage #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 75 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
b7a5559
Update action.yml and main.ps1 for Get-PesterCodeCoverage GitHub Action
MariusStorhaug Mar 3, 2025
09ebe97
Add functionality to merge coverage reports and output a combined XML…
MariusStorhaug Mar 3, 2025
92c4c6b
Refactor main.ps1 to improve code readability and maintainability by …
MariusStorhaug Mar 3, 2025
9b4e9c9
Enhance code coverage logging by summarizing JSON content and improvi…
MariusStorhaug Mar 3, 2025
434e58b
Refactor logging in main.ps1 to improve output format and remove unus…
MariusStorhaug Mar 3, 2025
dcea16b
Sort CodeCoverage files by name for improved output consistency
MariusStorhaug Mar 3, 2025
9fc1d1e
Refactor log group names in main.ps1 for clarity and consistency
MariusStorhaug Mar 3, 2025
dcb81ba
Refactor log group naming in main.ps1 for improved clarity
MariusStorhaug Mar 3, 2025
56cc096
Update log group naming in main.ps1 for improved readability
MariusStorhaug Mar 3, 2025
138b773
Enhance summary log group formatting in main.ps1 for better visual se…
MariusStorhaug Mar 3, 2025
b195b10
Refactor coverage report generation in main.ps1 for improved clarity …
MariusStorhaug Mar 4, 2025
461df5e
Enhance code coverage reporting in main.ps1 with detailed output and …
MariusStorhaug Mar 4, 2025
369d74a
Add module installation and improve coverage report formatting in mai…
MariusStorhaug Mar 4, 2025
a9e6210
Refactor markdown output in main.ps1 for improved structure and clarity
MariusStorhaug Mar 4, 2025
90b4d63
Sort commands in coverage report for improved readability and organiz…
MariusStorhaug Mar 4, 2025
910a27e
Add helper function to convert file paths to relative format in main.ps1
MariusStorhaug Mar 4, 2025
7159c76
Remove unnecessary formatting from code coverage report tables for cl…
MariusStorhaug Mar 4, 2025
7c985c5
Update details in coverage report to include counts for missed, execu…
MariusStorhaug Mar 4, 2025
9ff9cb7
Rename Convert-ToRelativePath function to ConvertTo-RelativePath for …
MariusStorhaug Mar 4, 2025
4002aec
Update coverage check to use Write-GitHubError and Write-GitHubNotice…
MariusStorhaug Mar 4, 2025
32b596d
Enhance code coverage report by formatting command output with markdo…
MariusStorhaug Mar 4, 2025
83ce1ab
Refactor code coverage report to generate HTML tables for missed and …
MariusStorhaug Mar 4, 2025
b7bd674
Refactor HTML table generation in coverage report for missed and exec…
MariusStorhaug Mar 4, 2025
756cfd7
Refactor command output in coverage report to remove HTML encoding, e…
MariusStorhaug Mar 5, 2025
c1c64d3
Normalize file paths in coverage report and transform command output …
MariusStorhaug Mar 5, 2025
43b589e
Refactor command output in coverage report to HTML encode commands an…
MariusStorhaug Mar 5, 2025
215ea4a
Refactor command output in coverage report to replace spaces with non…
MariusStorhaug Mar 5, 2025
0721fdd
Refactor command output in coverage report to remove HTML encoding, e…
MariusStorhaug Mar 5, 2025
3d85c7c
Add Normalize-IndentationExceptFirst function to adjust indentation i…
MariusStorhaug Mar 5, 2025
43b1b82
Refactor command output in coverage report to use preformatted text f…
MariusStorhaug Mar 5, 2025
763bd4b
Refactor command output in coverage report to use code formatting for…
MariusStorhaug Mar 5, 2025
3cd3042
Refactor Normalize-IndentationExceptFirst function to use HTML line b…
MariusStorhaug Mar 5, 2025
6e0f3d4
Refactor command output formatting in coverage report to enhance read…
MariusStorhaug Mar 5, 2025
6775fb3
Escape curly braces in command output for improved HTML rendering in …
MariusStorhaug Mar 5, 2025
e4c7cd3
Remove unnecessary escaping of curly braces in command output for imp…
MariusStorhaug Mar 5, 2025
cf7b9af
Add inline style for preserving whitespace in command output for impr…
MariusStorhaug Mar 5, 2025
29692b5
Refactor command output formatting in coverage report to escape curly…
MariusStorhaug Mar 5, 2025
19a2258
Fix HTML attribute quotes in command output formatting for consistency
MariusStorhaug Mar 5, 2025
d87ad46
Update code block language from 'pwsh' to 'powershell' for improved s…
MariusStorhaug Mar 5, 2025
1d6ab4e
Refactor command output formatting to ensure consistent HTML renderin…
MariusStorhaug Mar 5, 2025
f69b4a2
Fix command output formatting to ensure consistent HTML rendering in …
MariusStorhaug Mar 5, 2025
925ce64
Refactor command output to build HTML tables for missed and executed …
MariusStorhaug Mar 5, 2025
6f0346e
Refactor command output processing to improve HTML encoding and inden…
MariusStorhaug Mar 5, 2025
3e438fb
Remove HTML encoding from command output for missed and executed comm…
MariusStorhaug Mar 5, 2025
dfd9702
Refactor command processing to improve handling of missed and execute…
MariusStorhaug Mar 5, 2025
1225f8e
Replace HTML line break with environment-specific new line in indenta…
MariusStorhaug Mar 5, 2025
8b9d99d
Refactor command output to separate display for executed commands, im…
MariusStorhaug Mar 5, 2025
782ade6
Refactor command handling to streamline normalization of missed and e…
MariusStorhaug Mar 5, 2025
b023068
Enhance coverage report by listing analyzed files in a clearer format
MariusStorhaug Mar 6, 2025
ef5637f
Update default working directory in action.yml to use a relative path
MariusStorhaug Mar 6, 2025
e2b31bc
Remove GITHUB_TOKEN environment variable from Auto-Release workflow
MariusStorhaug Mar 8, 2025
c1faae5
Add path normalization function for PSModulePath and update file proc…
MariusStorhaug Mar 9, 2025
3c894b9
Refactor path normalization in ConvertTo-NormalizedModulePath functio…
MariusStorhaug Mar 9, 2025
20bbc3e
Refactor ConvertTo-NormalizedModulePath for improved readability and …
MariusStorhaug Mar 9, 2025
6908310
Refactor path normalization logic and remove unused ConvertTo-Relativ…
MariusStorhaug Mar 9, 2025
134c719
Refactor file path normalization logic and simplify output formatting…
MariusStorhaug Mar 9, 2025
f89342c
Implement retry logic for module installation in main.ps1 to enhance …
MariusStorhaug Mar 9, 2025
c80b707
Sort and remove duplicates from FilesAnalyzed in main.ps1 for improve…
MariusStorhaug Mar 9, 2025
e434034
Add StepSummary_Mode input to control GitHub step summary sections in…
MariusStorhaug Mar 13, 2025
ab58843
Refactor JSON file processing in main.ps1 to improve path normalizati…
MariusStorhaug Mar 13, 2025
9b8919d
Remove unnecessary blank line in main.ps1 for cleaner code formatting
MariusStorhaug Mar 13, 2025
dd7da3d
Update log output to use BaseName instead of Name for improved clarit…
MariusStorhaug Mar 13, 2025
0964127
Round coverage percentages to two decimal places for improved readabi…
MariusStorhaug Mar 13, 2025
01eb305
Add logging for file listing and improve group name formatting in mai…
MariusStorhaug Mar 13, 2025
f618ace
Remove '-CodeCoverage-Report' suffix from group name for cleaner outp…
MariusStorhaug Mar 13, 2025
df2c4dc
Add CodeCoveragePercentTarget input to action.yml and update main.ps1…
MariusStorhaug Mar 23, 2025
87db5ed
Add optional CodeCoveragePercentTarget input to action.yml and enhanc…
MariusStorhaug Mar 24, 2025
e397d4e
Add ShowInfo input to action.yml for improved script execution control
MariusStorhaug Mar 25, 2025
edacad4
Add success indicator
MariusStorhaug Mar 26, 2025
3d6cfbe
Rename log group titles to include 'Step Summary' for improved clarit…
MariusStorhaug Mar 26, 2025
268af1d
Add initial code coverage report for PSModuleTest
MariusStorhaug Apr 17, 2025
349704d
Refactor documentation formatting in Helpers.psm1 and update comment …
MariusStorhaug Apr 17, 2025
a9bc669
Update CodeCoveragePercentTarget to 50 in Action-Test.yml for adjuste…
MariusStorhaug Apr 17, 2025
5097429
Update README.md to specify markdown formatting for example summary
MariusStorhaug Apr 17, 2025
06798d4
Enhance descriptions for StepSummary_Mode in README.md and action.yml…
MariusStorhaug Apr 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions .github/workflows/Action-Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,57 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v4

# Upload artifact from tests:
- name: Upload artifact [Environments-macOS-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: Environments-macOS-CodeCoverage
path: ./tests/CodeCoverage/Environments-macOS-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Upload artifact [Environments-Windows-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: Environments-Windows-CodeCoverage
path: ./tests/CodeCoverage/Environments-Windows-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Upload artifact [Module-macOS-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: Module-macOS-CodeCoverage
path: ./tests/CodeCoverage/Module-macOS-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Upload artifact [Module-Windows-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: Module-Windows-CodeCoverage
path: ./tests/CodeCoverage/Module-Windows-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Upload artifact [MyTests-macOS-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: MyTests-macOS-CodeCoverage
path: ./tests/CodeCoverage/MyTests-macOS-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Upload artifact [MyTests-Windows-CodeCoverage]
uses: actions/upload-artifact@v4
with:
name: MyTests-Windows-CodeCoverage
path: ./tests/CodeCoverage/MyTests-Windows-CodeCoverage
retention-days: 1
if-no-files-found: error

- name: Action-Test
uses: ./
with:
working-directory: ./tests
subject: PSModule
StepSummary_Mode: Full
CodeCoveragePercentTarget: 50
2 changes: 0 additions & 2 deletions .github/workflows/Auto-Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,3 @@ jobs:

- name: Auto-Release
uses: PSModule/Auto-Release@v1
env:
GITHUB_TOKEN: ${{ github.token }}
107 changes: 101 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,112 @@
# Template-Action
# Get-PesterCodeCoverage

A template repository for GitHub Actions
A GitHub Action that aggregates Pester code coverage reports and generates a detailed summary with coverage statistics.
Fails the workflow if coverage falls below specified targets.

This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule). It is recommended to use the
[Process-PSModule workflow](https://github.com/PSModule/Process-PSModule) to automate the whole process of managing the PowerShell module.

## Features

- Combines multiple code coverage reports from parallel test runs
- Generates markdown/HTML tables showing missed & executed commands
- Displays analyzed files and coverage statistics
- Configurable step summary sections
- Threshold enforcement for minimum code coverage

## Usage

### Inputs

### Secrets
| Name | Description | Required | Default |
|------|-------------|----------|---------|
| `Debug` | Enable debug output | No | `false` |
| `Verbose` | Enable verbose output | No | `false` |
| `Version` | Exact version of GitHub module to install | No | Latest |
| `Prerelease` | Allow prerelease versions | No | `false` |
| `WorkingDirectory` | Working directory for the action | No | `.` |
| `StepSummary_Mode` | Controls which sections to show in the GitHub step summary. Use 'Full' for all sections, 'None' to disable, or a comma-separated list of 'Missed, Executed, Files'. | No | `Missed, Files` |
| `CodeCoveragePercentTarget` | Target code coverage percentage | No | Max target from individual reports |

### Example Workflow

```yaml
- name: Process Code Coverage
uses: PSModule/Get-PesterCodeCoverage@v1
with:
StepSummary_Mode: Full
CodeCoveragePercentTarget: 80
```

## Outputs

### GitHub Step Summary

The action generates a detailed summary visible in the GitHub Actions UI:

1. **Coverage Overview Table**
- Coverage percentage vs target
- Analyzed/executed/missed command counts
- Number of files analyzed

2. **Expandable Sections**
- **Missed Commands**: HTML table with code snippets
- **Executed Commands**: HTML table with code snippets
- **Analyzed Files**: List of covered files

Example summary:

```markdown
✅ Code Coverage Report

Summary:
| Coverage | Target | Analyzed | Executed | Missed | Files |
|----------|--------|---------------|---------------|---------------|---------------|
| 85% | 80% | 1000 commands | 850 commands | 150 commands | 15 files |

▶️ Missed commands [150] (click to expand)
▶️ Executed commands [850] (click to expand)
▶️ Files analyzed [15] (click to expand)
```

## Requirements

1. **Pester Code Coverage Reports**
Preceding steps must generate JSON coverage reports named `*-CodeCoverage*.json`

2. **GitHub CLI**
The action uses `gh run download` to fetch artifacts from the current workflow run

## Behavior

1. **Coverage Calculation**
- Combines multiple coverage reports
- Removes duplicate entries
- Calculates aggregate coverage percentage

2. **Threshold Enforcement**
Fails the workflow if coverage is below either:
- Explicitly specified `CodeCoveragePercentTarget`
- Highest target from individual reports (if no target specified)

3. **Output Control**
Configure visibility of sections using `StepSummary_Mode`:
```yaml
# Show all sections
StepSummary_Mode: Full

# Disable summary
StepSummary_Mode: None

### Outputs
# Custom selection
StepSummary_Mode: Missed, Files
```

### Example
## Troubleshooting

Enable debugging by setting inputs:
```yaml
Example here
with:
Debug: true
Verbose: true
```
30 changes: 18 additions & 12 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
name: {{ NAME }}
description: {{ DESCRIPTION }}
name: Get-PesterCodeCoverage
description: A GitHub Action that is used to gather Code Coverage for the PSModule process.
author: PSModule
branding:
icon: upload-cloud
color: white

inputs:
subject:
description: The subject to greet
required: false
default: World
Debug:
description: Enable debug output.
required: false
Expand All @@ -28,21 +24,31 @@ inputs:
WorkingDirectory:
description: The working directory where the script will run from.
required: false
default: ${{ github.workspace }}
default: '.'
StepSummary_Mode:
description: |
Controls which sections to show in the GitHub step summary.
Use 'Full' for all sections, 'None' to disable, or a comma-separated list of 'Missed, Executed, Files'.
required: false
default: Missed, Files
CodeCoveragePercentTarget:
description: The target for code coverage.
required: false

runs:
using: composite
steps:
- name: {{ NAME }}
- name: Get-PesterCodeCoverage
uses: PSModule/GitHub-Script@v1
env:
{{ ORG }}_{{ NAME }}_INPUT_subject: ${{ inputs.subject }}
PSMODULE_GET_PESTERCODECOVERAGE_INPUT_StepSummary_Mode: ${{ inputs.StepSummary_Mode }}
PSMODULE_GET_PESTERCODECOVERAGE_INPUT_CodeCoveragePercentTarget: ${{ inputs.CodeCoveragePercentTarget }}
with:
Name: Get-PesterCodeCoverage
Debug: ${{ inputs.Debug }}
Prerelease: ${{ inputs.Prerelease }}
Verbose: ${{ inputs.Verbose }}
Version: ${{ inputs.Version }}
WorkingDirectory: ${{ inputs.WorkingDirectory }}
Script: |
# {{ NAME }}
${{ github.action_path }}/scripts/main.ps1
ShowInfo: false
Script: ${{ github.action_path }}/scripts/main.ps1
68 changes: 68 additions & 0 deletions scripts/Helpers.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
function Normalize-IndentationExceptFirst {
<#
.SYNOPSIS
Normalizes the indentation of a multi-line string, except for the first line.

.DESCRIPTION
This function takes a multi-line string and normalizes the indentation of all lines except the first one.
It removes the minimum leading whitespace from all subsequent lines.

.PARAMETER Code
The multi-line string to normalize.

.OUTPUTS
Returns the normalized multi-line string.
s#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Scope = 'Function', Justification = 'Function isnt exported.')]
[OutputType([string])]
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Code
)

# Split the code into lines
$lines = $Code -split "`r?`n"

# If there's 0 or 1 line, there's nothing special to do
if ($lines.Count -le 1) {
return $Code
}

# The first line stays as-is; we skip it for indentation measurement
$firstLine = $lines[0]
$subsequentLines = $lines[1..($lines.Count - 1)]

# Find the minimum leading indentation among the *subsequent* lines
$minIndent = ($subsequentLines | Where-Object { $_ -match '\S' } | ForEach-Object {
# If the line starts with whitespace, capture how many characters
if ($_ -match '^(\s+)') {
$matches[1].Length
} else {
0
}
} | Measure-Object -Minimum).Minimum

# Remove that leading indentation from each subsequent line
for ($i = 0; $i -lt $subsequentLines.Count; $i++) {
$line = $subsequentLines[$i]

# Only attempt to remove indentation if we actually have some whitespace
if ($line -match '^(\s+)(.*)$') {
# $matches[1] = leading whitespace; $matches[2] = the rest
$leading = $matches[1]
$rest = $matches[2]

# If we have enough whitespace to remove $minIndent worth, do it
if ($leading.Length -ge $minIndent) {
$leading = $leading.Substring($minIndent)
}
# Recombine
$subsequentLines[$i] = $leading + $rest
}
}

$newLine = [Environment]::NewLine
# Reconstruct the final code: first line + adjusted subsequent lines
return ($firstLine + $newLine + ($subsequentLines -join $newLine))
}
Loading
Loading