Skip to content

Build and test

Build and test #576

Workflow file for this run

name: Build and test
on:
workflow_dispatch:
push:
branches: [ main ]
paths-ignore:
- "**.md"
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * 0' # Once a week: "At 00:00 on Sunday."
defaults:
run:
shell: pwsh
jobs:
main:
name: Build and test
permissions:
contents: read
strategy:
fail-fast: false # don't fail if one of the matrix jobs fails. Example: try to run the windows matrix even if the ubuntu matrix fails.
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
env:
SLN_DIR: MarkdownLinkCheckLogParser
SLN_FILENAME: MarkdownLinkCheckLogParser.sln
TEST_RESULTS_ARTIFACT_NAME: test-results
CODE_COVERAGE_ARTIFACT_NAME: code-coverage-report
steps:
- name: Dump github co ntext for debug purposes
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
run: $env:GITHUB_CONTEXT
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: MarkdownLinkCheckLogParser/global.json
- name: Cache/Restore NuGets
uses: actions/cache@v4
with:
save-always: true
path:
~/.nuget/packages
key: ${{ runner.os }}-nuget
restore-keys: |
${{ runner.os }}-nuget-
- name: Install reportgenerator dotnet tool
run: dotnet tool install --global dotnet-reportgenerator-globaltool
- name: Restore dependencies
working-directory: ${{ env.SLN_DIR }}
run: dotnet restore ${{ env.SLN_FILENAME }}
- name: Build
working-directory: ${{ env.SLN_DIR }}
run: dotnet build ${{ env.SLN_FILENAME }} -c Release -warnaserror --no-restore --no-incremental
- name: Test and code coverage
working-directory: ${{ env.SLN_DIR }}
id: dotnet-test
run: |
$os = $PSVersionTable.OS
$testResultsDir = $(Join-Path -Path (Get-Location) -ChildPath "tests/test-results")
$testCoverageDir = $(Join-Path -Path (Get-Location) -ChildPath "tests/coverage-results/")
$testCoverageMergeFile = $(Join-Path -Path $testCoverageDir -ChildPath "coverage.json")
$testCoverageFile = $(Join-Path -Path $testCoverageDir -ChildPath "coverage.opencover.xml")
Write-Output "test-results-dir=$testResultsDir" >> $env:GITHUB_OUTPUT
Write-Output "test-coverage-dir=$testCoverageDir" >> $env:GITHUB_OUTPUT
Write-Output "test-coverage-file=$testCoverageFile" >> $env:GITHUB_OUTPUT
dotnet test ${{ env.SLN_FILENAME }} `
-c Release `
--no-build `
--logger "trx;LogFilePrefix=framework" `
--logger GitHubActions `
--logger "liquid.custom;Template=${{github.workspace}}/MarkdownLinkCheckLogParser/tests/liquid-test-logger-template.md;runnerOs=${{ runner.os }};os=$os;LogFilePrefix=framework" `
--results-directory "$testResultsDir" `
/p:CollectCoverage=true `
/p:CoverletOutput="$testCoverageDir" `
/p:MergeWith="$testCoverageMergeFile" `
/p:CoverletOutputFormat="json%2copencover" `
-m:1
Write-Output "test-results-dir is set to $testResultsDir"
Write-Output "test-coverage-dir is set to $testCoverageDir"
Write-Output "test-coverage-file is set to $testCoverageFile"
$downloadArtifactMessage = "You can inspect the test results by downloading the workflow artifact named: ${{ env.TEST_RESULTS_ARTIFACT_NAME }}."
if($LASTEXITCODE -eq 0) {
Write-Output "::notice title=Tests (${{ runner.os }})::Tests passed on ${{ runner.os }}. $downloadArtifactMessage"
}
else {
Write-Output "::error title=Tests (${{ runner.os }})::Tests failed on ${{ runner.os }}. $downloadArtifactMessage"
}
- name: Set run even if tests fail condition
id: even-if-tests-fail
if: matrix.os == 'ubuntu-latest' && always()
run: |
# Some of the steps below provide feedback on the test run and I want to run them even if
# some of the previous steps failed. For that I need:
# - the 'always()' condition: without it the step only runs if the job is successful, it's like the 'if' condition on any step always has a hidden '&& success()' clause.
# - the '(steps.<step-id>.conclusion == 'success' || steps.<step-id>.conclusion == 'failure')' condition: to run the steps only if the <step-id> step has ran, regardless
# if it failed or not. It won't run if the <step-id> step has been skipped or cancelled.
#
# As such, the output from this step is meant to be used on the 'if' property of steps as follows:
# if: steps.even-if-tests-fail.outputs.condition == 'true' && always()
$condition = '${{ (steps.dotnet-test.conclusion == 'success' || steps.dotnet-test.conclusion == 'failure') }}'
Write-Output "condition=$condition" >> $env:GITHUB_OUTPUT
Write-Output "condition is set to $condition"
- name: Generate code coverage report
id: code-coverage-report-generator
if: matrix.os == 'ubuntu-latest' && steps.even-if-tests-fail.outputs.condition == 'true' && always()
run: |
$testCoverageReportDir = $(Join-Path -Path ${{ steps.dotnet-test.outputs.test-coverage-dir }} -ChildPath "report")
Write-Output "test-coverage-report-dir=$testCoverageReportDir" >> $env:GITHUB_OUTPUT
reportgenerator `
"-reports:${{ steps.dotnet-test.outputs.test-coverage-file }}" `
"-targetdir:$testCoverageReportDir" `
-reportTypes:htmlInline
- name: Upload code coverage report to artifacts
if: matrix.os == 'ubuntu-latest' && steps.even-if-tests-fail.outputs.condition == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}
path: ${{ steps.code-coverage-report-generator.outputs.test-coverage-report-dir }}
- name: Upload test results to artifacts
if: matrix.os == 'ubuntu-latest' && steps.even-if-tests-fail.outputs.condition == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: ${{ env.TEST_RESULTS_ARTIFACT_NAME }}
path: ${{ steps.dotnet-test.outputs.test-results-dir }}
- name: Upload test coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }} # even though it's not required for public repos it helps with intermittent failures caused by https://community.codecov.com/t/upload-issues-unable-to-locate-build-via-github-actions-api/3954, https://github.com/codecov/codecov-action/issues/598
files: ${{ steps.dotnet-test.outputs.test-coverage-file }}
fail_ci_if_error: true
- name: Log Codecov info
if: matrix.os == 'ubuntu-latest'
run: |
$codeCoveUrl = "https://app.codecov.io/gh/${{ github.repository }}/"
Write-Output "::notice title=Code coverage (${{ runner.os }})::Code coverage has been uploaded to Codecov at $codeCoveUrl. You can download the code coverage report from the workflow artifact named: ${{ env.CODE_COVERAGE_ARTIFACT_NAME }}."