Updated README, refactored CommandBaseTests, and enhanced CommandBase #52
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Workflow to build and release OcrInspector for production | |
name: Build, Test & Release | |
# Permissions for the workflow | |
permissions: | |
contents: write | |
checks: write | |
pull-requests: write | |
statuses: write | |
# Trigger workflow on push to the main branch | |
on: | |
push: | |
branches: | |
- main | |
# Set environment variables | |
env: | |
artifactStagingDirectory: ${{ github.workspace }}/artifact_staging | |
artifactType: 'Production' | |
binariesDirectory: ${{ github.workspace }}/binaries | |
buildConfiguration: 'Release' | |
buildPlatform: 'any cpu' | |
projectName: CommandBridge | |
# Default settings for all run steps | |
defaults: | |
run: | |
working-directory: src | |
jobs: | |
# Job to get the version of the build | |
new-version: | |
name: New Version | |
runs-on: windows-latest | |
# Outputs of the job | |
outputs: | |
buildVersion: ${{ steps.parse-version.outputs.version }} | |
validVersion: ${{ steps.validate-version.outputs.valid }} | |
steps: | |
# Step to checkout the repository | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
# Step to parse the build version for GitHub tag | |
- name: Parse Build Version for GitHub Tag | |
id: parse-version | |
shell: pwsh | |
run: echo "version=$(Get-Date -UFormat '%Y.%m.%d').${{ github.run_number }}" >> $env:GITHUB_OUTPUT | |
# Step to validate the parsed version | |
- name: Validate Version ${{ steps.parse-version.outputs.version }} | |
id: validate-version | |
shell: pwsh | |
run: | | |
$version = "${{ steps.parse-version.outputs.version }}" | |
echo "valid=$($version -match '^\d+(\.\d+){3}$')" >> $env:GITHUB_OUTPUT | |
# Job to build the project and run tests on Windows platform | |
new-build: | |
name: Build, Test & Package | |
runs-on: windows-latest | |
needs: | |
- new-version | |
# Environment variables for the job to build the project and run tests | |
env: | |
buildVersion: ${{ needs.new-version.outputs.buildVersion }} | |
steps: | |
# Step to checkout the repository | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
# Step to setup .NET SDK version 8.0.x on Windows platform | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: 8.0.x | |
# Step to restore dependencies | |
- name: Restore Dependencies | |
shell: pwsh | |
run: dotnet restore | |
# Step to build the project | |
- name: Build ${{ env.projectName }} v${{ env.buildVersion }} | |
shell: pwsh | |
run: dotnet build | |
# Step to run unit tests and collect code coverage on Windows platform using PowerShell Core (pwsh) shell | |
- name: Unit Tests and Code Coverage | |
shell: pwsh | |
run: dotnet test -l:"trx;LogFileName=${{ env.artifactStagingDirectory }}/TestOutput.v${{ env.buildVersion }}.xml" --collect:"Xplat Code Coverage" | |
working-directory: src/${{ env.projectName }}.UnitTests | |
# Step to upload build artifacts to GitHub for test results | |
- name: Upload Unit Tests Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-results | |
path: ${{ env.artifactStagingDirectory }}/TestOutput.v${{ env.buildVersion }}.xml | |
# Step to copy the coverage file to the artifact staging directory with a different file name | |
- name: Copy Coverage File to Artifact Staging Directory | |
working-directory: src/${{ env.projectName }}.UnitTests | |
shell: pwsh | |
run: | | |
# Get the most recently modified 'coverage.cobertura.xml' file from the './TestResults' directory and its subdirectories | |
$coverageFile = Get-ChildItem ` | |
-Path './TestResults' ` | |
-Recurse -Filter 'coverage.cobertura.xml' ` | |
-File | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName | |
# Define the new file name and destination path | |
$newFileName = 'coverage.cobertura.v${{ env.buildVersion }}.xml' | |
$destinationPath = Join-Path -Path ${{ env.artifactStagingDirectory }} -ChildPath $newFileName | |
# Ensure the destination directory exists | |
if (-not (Test-Path -Path ${{ env.artifactStagingDirectory }})) { | |
New-Item -ItemType Directory -Path ${{ env.artifactStagingDirectory }} | |
} | |
# Copy the most recently modified 'coverage.cobertura.xml' file to the artifact staging directory with the new file name | |
Copy-Item -Path $coverageFile -Destination $destinationPath | |
# Step to upload build artifacts to GitHub for code coverage | |
- name: Upload Code Coverage Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-coverage | |
path: ${{ env.artifactStagingDirectory }}/coverage.cobertura.v${{ env.buildVersion }}.xml | |
# Step to package the project for release as a NuGet package on Windows platform | |
- name: New Packages v${{ env.buildVersion }} | |
shell: pwsh | |
run: dotnet pack -o ${{ env.artifactStagingDirectory }} -c Release /p:Version=${{ env.buildVersion }} | |
# Step to upload the build artifact to GitHub for download | |
- name: Upload Build Artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: build-artifacts | |
path: ${{ env.artifactStagingDirectory }}/*.nupkg | |
# Job to publish test results and code coverage | |
publish-test-results: | |
name: Publish Unit Tests Results | |
runs-on: ubuntu-latest | |
needs: | |
- new-build | |
- new-version | |
steps: | |
# Step to checkout the repository on Ubuntu platform | |
- uses: actions/checkout@v4 | |
# Step to download build artifacts for test results from Windows platform to Ubuntu platform | |
- name: Download Build Artifacts for Test Results | |
uses: actions/download-artifact@v4 | |
with: | |
name: test-results | |
path: ${{ env.artifactStagingDirectory }} | |
# Step to publish test results to GitHub Actions UI | |
- name: Publish Test Results | |
uses: EnricoMi/publish-unit-test-result-action@v2 | |
if: always() | |
with: | |
check_name: Unit Tests Results | |
files: | | |
${{ env.artifactStagingDirectory }}/TestOutput.v${{ needs.new-version.outputs.buildVersion }}.xml | |
# Job to publish code coverage summary to GitHub Actions UI and as a build artifact for download | |
publish-test-coverage: | |
name: Publish Coverage Results | |
runs-on: ubuntu-latest | |
needs: | |
- new-build | |
- new-version | |
# Environment variables for the job to build the project and run tests | |
env: | |
buildVersion: ${{ needs.new-version.outputs.buildVersion }} | |
steps: | |
# Step to checkout the repository on Ubuntu platform | |
- uses: actions/checkout@v4 | |
# Step to download build artifacts for code coverage from Windows platform to Ubuntu platform | |
- name: Download Build Artifacts for Code Coverage Results | |
uses: actions/download-artifact@v4 | |
with: | |
name: test-coverage | |
path: ${{ env.artifactStagingDirectory }} | |
# Step to generate code coverage summary in markdown format using PowerShell Core (pwsh) | |
# shell and upload as a build artifact for download and display in GitHub Actions UI as a job summary | |
- name: New Code Coverage Summary | |
id: new-coverage-file | |
shell: pwsh | |
run: | | |
$xmlSource = "${{ env.artifactStagingDirectory }}/coverage.cobertura.v${{ env.buildVersion }}.xml" | |
$outputFile = "${{ env.artifactStagingDirectory }}/coverage.cobertura.v${{ env.buildVersion }}.md" | |
$showBadges = $true | |
$showPackages = $true | |
$showClassSummary = $false | |
$showClassDetails = $false | |
# Determine if the source is a URL or a file path | |
if ($xmlSource -match "^http(s)?://") { | |
# Load XML from URL | |
$xml = [xml](Invoke-WebRequest -Uri $xmlSource).Content | |
} else { | |
# Load XML from file | |
[xml]$xml = Get-Content -Path $xmlSource | |
} | |
# Extract coverage rates | |
$lineCoverage = [math]::Round($xml.coverage.'line-rate', 2) * 100 | |
$branchCoverage = [math]::Round($xml.coverage.'branch-rate', 2) * 100 | |
# Start building the markdown content | |
$markdown = @" | |
# Code Coverage Report | |
"@ | |
if ($showBadges) { | |
$markdown += @" | |
![Line Coverage](https://img.shields.io/badge/Line%20Coverage-$lineCoverage%25-success?style=flat) ![Branch Coverage](https://img.shields.io/badge/Branch%20Coverage-$branchCoverage%25-success?style=flat) | |
"@ | |
} | |
$markdown += @" | |
## Overview | |
- **Lines Covered**: $($xml.coverage.'lines-covered') | |
- **Valid Lines**: $($xml.coverage.'lines-valid') | |
- **Branches Covered**: $($xml.coverage.'branches-covered') | |
- **Valid Branches**: $($xml.coverage.'branches-valid') | |
"@ | |
if ($showPackages) { | |
$markdown += @" | |
## Packages | |
"@ | |
foreach ($package in $xml.coverage.packages.package) { | |
$packageName = $package.name | |
$packageLineRate = [math]::Round($package.'line-rate', 2) * 100 | |
$packageBranchRate = [math]::Round($package.'branch-rate', 2) * 100 | |
$packageComplexity = $package.complexity | |
$markdown += @" | |
### Package: $packageName | |
- **Line Coverage Rate**: $packageLineRate% | |
- **Branch Coverage Rate**: $packageBranchRate% | |
- **Complexity**: $packageComplexity | |
"@ | |
if ($showClassSummary) { | |
$markdown += @" | |
#### Classes Summary | |
| Class Name | Filename | Line Coverage Rate | Branch Coverage Rate | Complexity | | |
|---------------------------------------|---------------------|--------------------|----------------------|------------| | |
"@ | |
foreach ($class in $package.classes.class) { | |
$className = $class.name | |
$classFilename = $class.filename | |
$classLineRate = [math]::Round($class.'line-rate', 2) * 100 | |
$classBranchRate = [math]::Round($class.'branch-rate', 2) * 100 | |
$classComplexity = $class.complexity | |
$markdown += @" | |
| $className | $classFilename | $classLineRate% | $classBranchRate% | $classComplexity | | |
"@ | |
} | |
} | |
if ($showClassDetails) { | |
$markdown += "`n#### Class Details`n" | |
foreach ($class in $package.classes.class) { | |
$className = $class.name | |
$classFilename = $class.filename | |
$classLineRate = [math]::Round($class.'line-rate', 2) * 100 | |
$classBranchRate = [math]::Round($class.'branch-rate', 2) * 100 | |
$classComplexity = $class.complexity | |
$markdown += @" | |
##### $className | |
- **Filename**: `$classFilename` | |
- **Line Coverage Rate**: $classLineRate% | |
- **Branch Coverage Rate**: $classBranchRate% | |
- **Complexity**: $classComplexity | |
###### Lines | |
| Line Number | Hits | Branch | | |
|-------------|------|--------| | |
"@ | |
foreach ($line in $class.lines.line) { | |
$lineNumber = $line.number | |
$hits = $line.hits | |
$branch = $line.branch | |
$markdown += @" | |
| $lineNumber | $hits | $branch | | |
"@ | |
} | |
} | |
} | |
} | |
} | |
# Write the markdown content to the output file | |
$markdown | Out-File -FilePath $outputFile -Encoding utf8 | |
# Step to upload the code coverage summary file as a build artifact | |
# This makes the coverage summary available for download from the workflow run details in GitHub Actions UI | |
- name: Upload Code Coverage Summary | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-coverage-summary | |
path: ${{ env.artifactStagingDirectory }}/coverage.cobertura.v${{ env.buildVersion }}.md | |
# Step to generate code coverage summary in markdown format using PowerShell Core (pwsh) | |
# and display it in the GitHub Actions UI as a job summary | |
- name: Collect Job Summary | |
shell: pwsh | |
run: | | |
# Read the content of the coverage report file | |
$content = Get-Content -Path "${{ env.artifactStagingDirectory }}/coverage.cobertura.v${{ env.buildVersion }}.md" | |
# Append the content to the GitHub Actions job summary to display it in the workflow run details | |
$content | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 | |
# Job to publish build artifacts to NuGet feed for production release | |
publish-build-artifacts: | |
name: Publish Build Artifacts | |
runs-on: ubuntu-latest | |
if: success() | |
needs: | |
- new-build | |
- new-version | |
steps: | |
# Step to checkout the repository on Ubuntu platform | |
- uses: actions/checkout@v4 | |
# Step to download build artifacts from Windows platform to Ubuntu platform | |
- name: Download Build Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: build-artifacts | |
path: ${{ env.artifactStagingDirectory }} | |
- name: '' | |
shell: pwsh | |
run: | | |
dotnet nuget push "${{ env.artifactStagingDirectory }}/*.nupkg" --api-key ${{ secrets.NUGET_PUBLIC_KEY }} --source ${{ vars.NUGET_PUBLIC_SOURCE }} | |
# Job to create a GitHub release and tag the new version | |
new-release: | |
name: New GitHub Release Version ${{ needs.new-version.outputs.buildVersion }} | |
runs-on: ubuntu-latest | |
if: success() | |
needs: | |
- new-build | |
- new-version | |
# Set environment variables specific to the release job | |
env: | |
buildVersion: ${{ needs.new-version.outputs.buildVersion }} | |
artifactStagingDirectory: ${{ github.workspace }}/artifact-staging | |
steps: | |
# Step to checkout the repository on Ubuntu platform | |
- uses: actions/checkout@v4 | |
# Step to download build artifacts from Windows platform to Ubuntu platform | |
- name: Download Build Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: build-artifacts | |
path: ${{ env.artifactStagingDirectory }} | |
# Step to create a GitHub release and tag | |
- name: Create GitHub Release & Tag v${{ env.buildVersion }} | |
uses: softprops/action-gh-release@v2 | |
with: | |
files: ${{ env.artifactStagingDirectory }}/*.nupkg | |
tag_name: v${{ env.buildVersion }} | |
name: ${{ env.artifactType }} v${{ env.buildVersion }} | |
generate_release_notes: true | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |