Build and test #855
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
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: ShareJobsData | |
SLN_FILENAME: ShareJobsData.sln | |
TEST_RESULTS_ARTIFACT_NAME: test-results | |
CODE_COVERAGE_ARTIFACT_NAME: code-coverage-report | |
steps: | |
- name: Dump github context for debug purposes | |
env: | |
GITHUB_CONTEXT: ${{ toJSON(github) }} | |
run: $env:GITHUB_CONTEXT | |
- name: Enable git core.longpaths | |
if: matrix.os == 'windows-latest' | |
run: git config --global core.longpaths true | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v4 | |
with: | |
global-json-file: ShareJobsData/global.json | |
- name: Cache/Restore NuGets | |
uses: actions/cache@v4 | |
with: | |
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 | |
id: dotnet-test | |
working-directory: ${{ env.SLN_DIR }} | |
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}}/ShareJobsData/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 | |
uses: codecov/codecov-action@v4 | |
if: matrix.os == 'ubuntu-latest' | |
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 }}." | |