Release Package workflow #62
This file contains hidden or 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
# Publishes beta-versions only | |
name: Package | |
on: | |
push: | |
branches: | |
- main | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Check .NET 8 | |
id: check-dotnet8 | |
run: | | |
DOTNET8_VERSION=$(dotnet --version) | |
if [[ "$DOTNET8_VERSION" =~ ^8\.0\.[0-9]+$ ]]; then | |
echo "dotnet8_installed=true" >> $GITHUB_ENV | |
else | |
echo "dotnet8_installed=false" >> $GITHUB_ENV | |
fi | |
- name: Setup .NET 8 | |
if: env.dotnet8_installed == 'false' | |
uses: actions/setup-dotnet@v4 # https://github.com/actions/setup-dotnet | |
with: | |
dotnet-version: 8.0.x | |
dotnet-quality: 'ga' | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Restore | |
run: dotnet restore ./Ocelot.Administration.IdentityServer4.sln -p:TargetFramework=net8.0 | |
- name: Build | |
run: dotnet build --no-restore ./Ocelot.Administration.IdentityServer4.sln --framework net8.0 | |
- name: Unit tests | |
run: dotnet test --no-restore --no-build ./unit/Ocelot.Administration.IdentityServer4.UnitTests.csproj --collect:"XPlat Code Coverage" --framework net8.0 | |
- name: Acceptance tests | |
run: dotnet test --no-restore --no-build ./acceptance/Ocelot.Administration.IdentityServer4.AcceptanceTests.csproj --collect:"XPlat Code Coverage" --framework net8.0 | |
- name: Find files | |
id: files | |
run: | | |
echo "GITHUB REF is ${{ github.ref }}" | |
echo "GITHUB REF NAME is ${{ github.ref_name }}" | |
echo "GITHUB SHA is ${{ github.sha }}" | |
# Coverage by unit tests -> https://github.com/coverlet-coverage/coverlet | |
coverage_1st_folder=$(ls -d ./unit/TestResults/*/ | head -1) | |
echo "Detected first folder : $coverage_1st_folder" | |
coverage_file="${coverage_1st_folder%/}/coverage.cobertura.xml" | |
echo "Detecting unit coverage file... -> $coverage_file" | |
if [ -f "$coverage_file" ]; then | |
echo Unit coverage file exists. | |
echo "UNIT_COVERAGE_FILE_EXISTS=true" >> $GITHUB_OUTPUT | |
echo "UNIT_COVERAGE_FILE=$coverage_file" >> $GITHUB_OUTPUT | |
else | |
echo Unit coverage file DOES NOT exist! | |
echo "UNIT_COVERAGE_FILE_EXISTS=false" >> $GITHUB_OUTPUT | |
exit 1 | |
fi | |
# Coverage by acceptance tests -> https://github.com/coverlet-coverage/coverlet | |
coverage_1st_folder=$(ls -d ./acceptance/TestResults/*/ | head -1) | |
echo "Detected first folder : $coverage_1st_folder" | |
coverage_file="${coverage_1st_folder%/}/coverage.cobertura.xml" | |
echo "Detecting acceptance coverage file... -> $coverage_file" | |
if [ -f "$coverage_file" ]; then | |
echo Acceptance coverage file exists. | |
echo "ACCEPTANCE_COVERAGE_FILE_EXISTS=true" >> $GITHUB_OUTPUT | |
echo "ACCEPTANCE_COVERAGE_FILE=$coverage_file" >> $GITHUB_OUTPUT | |
else | |
echo Acceptance coverage file DOES NOT exist! | |
echo "ACCEPTANCE_COVERAGE_FILE_EXISTS=false" >> $GITHUB_OUTPUT | |
exit 1 | |
fi | |
- name: Install tools | |
run: | | |
# .NET tools aka .config/dotnet-tools.json | |
echo Installing .NET tools aka dotnet-tools.json ... | |
dotnet tool restore | |
# Install XML tools | |
echo Installing XML tools ... | |
sudo apt update | |
sudo apt install libxml2-utils # aka xmllint read-command. xmlstarlet is not required | |
# Extract actual coverage % from the Coverlet XML-file | |
- name: Read coverage | |
id: coverage | |
run: | | |
echo Coverage by unit tests | |
line_coverage_u=$(xmllint --xpath "string(//coverage/@line-rate)" ${{ steps.files.outputs.UNIT_COVERAGE_FILE }}) | |
echo " Line coverage: $line_coverage_u" | |
echo "LineCoverageUnit=$line_coverage_u" >> $GITHUB_OUTPUT | |
echo "LINE_COVERAGE_UNIT=$line_coverage_u" >> $GITHUB_ENV | |
branch_coverage_u=$(xmllint --xpath "string(//coverage/@branch-rate)" ${{ steps.files.outputs.UNIT_COVERAGE_FILE }}) | |
echo " Branch coverage: $branch_coverage_u" | |
echo "BranchCoverageUnit=$branch_coverage_u" >> $GITHUB_OUTPUT | |
echo "BRANCH_COVERAGE_UNIT=$branch_coverage_u" >> $GITHUB_ENV | |
echo Coverage by acceptance tests | |
line_coverage_a=$(xmllint --xpath "string(//coverage/@line-rate)" ${{ steps.files.outputs.ACCEPTANCE_COVERAGE_FILE }}) | |
echo " Line coverage: $line_coverage_a" | |
echo "LineCoverageAcceptance=$line_coverage_a" >> $GITHUB_OUTPUT | |
echo "LINE_COVERAGE_ACCEPTANCE=$line_coverage_a" >> $GITHUB_ENV | |
branch_coverage_a=$(xmllint --xpath "string(//coverage/@branch-rate)" ${{ steps.files.outputs.ACCEPTANCE_COVERAGE_FILE }}) | |
echo " Branch coverage: $branch_coverage_a" | |
echo "BranchCoverageAcceptance=$branch_coverage_a" >> $GITHUB_OUTPUT | |
echo "BRANCH_COVERAGE_ACCEPTANCE=$branch_coverage_a" >> $GITHUB_ENV | |
lcu=$(printf "%1.4f" $line_coverage_u) | |
lca=$(printf "%1.4f" $line_coverage_a) | |
bcu=$(printf "%1.4f" $branch_coverage_u) | |
bca=$(printf "%1.4f" $branch_coverage_a) | |
echo '+------ COVERAGE MATRIX -------+' | |
echo '| | Line | Branch |' | |
echo '|------------|--------|--------|' | |
echo '| Unit |' $lcu \| $bcu \| | |
echo '| Acceptance |' $lca \| $bca \| | |
echo '+------------------------------+' | |
# The action below replaces the following command: dotnet tool run reportgenerator -reports:$coverage_file -targetdir:coveragereport-md -reporttypes:MarkdownSummaryGithub | |
# Docs: https://reportgenerator.io/ | |
- name: Generate coverage report (Unit) | |
if: steps.files.outputs.UNIT_COVERAGE_FILE_EXISTS == 'true' | |
uses: danielpalme/[email protected] # Docs: https://github.com/marketplace/actions/reportgenerator | |
with: | |
reports: ${{ steps.files.outputs.UNIT_COVERAGE_FILE }} | |
targetdir: coveragereport-u | |
reporttypes: HtmlInline;MarkdownSummaryGithub | |
- name: Generate coverage report (Acceptance) | |
if: steps.files.outputs.ACCEPTANCE_COVERAGE_FILE_EXISTS == 'true' | |
uses: danielpalme/[email protected] # Docs: https://github.com/marketplace/actions/reportgenerator | |
with: | |
reports: ${{ steps.files.outputs.ACCEPTANCE_COVERAGE_FILE }} | |
targetdir: coveragereport-a | |
reporttypes: HtmlInline;MarkdownSummaryGithub | |
- name: List report files | |
run: | | |
echo Listing files of unit-report... | |
find coveragereport-u -type f -print | sort | |
echo Listing files of acceptance-report... | |
find coveragereport-a -type f -print | sort | |
# DOCS Storing and sharing data from a workflow -> https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-and-sharing-data-from-a-workflow | |
- name: Upload artifacts of coverage report (Unit) | |
if: steps.files.outputs.UNIT_COVERAGE_FILE_EXISTS == 'true' && success() | |
uses: actions/upload-artifact@v4 # https://github.com/actions/upload-artifact | |
with: | |
name: CoverageReport-UnitTests # artifact name | |
path: coveragereport-u # directory containing files to upload | |
- name: Upload artifacts of coverage report (Acceptance) | |
if: steps.files.outputs.ACCEPTANCE_COVERAGE_FILE_EXISTS == 'true' && success() | |
uses: actions/upload-artifact@v4 # https://github.com/actions/upload-artifact | |
with: | |
name: CoverageReport-AcceptanceTests # artifact name | |
path: coveragereport-a # directory containing files to upload | |
- name: Publish coverage in job summary # only applicable if 'MarkdownSummaryGithub' or one of the other Markdown report types is generated | |
run: | | |
echo Listing files of MD report... | |
find coveragereport-u/*.md -type f -print | sort | |
find coveragereport-a/*.md -type f -print | sort | |
# Reformat both MD-files for better presentation | |
file_u="coveragereport-u/SummaryGithub.md" | |
file_a="coveragereport-a/SummaryGithub.md" | |
md='| _Coverage Matrix_ | Line | Branch |'$'\n' | |
md+='| - | - | - |'$'\n' | |
line=$(grep -F "|**Ocelot.Administration.IdentityServer4**|" $file_u) | |
line="${line/Ocelot.Administration.IdentityServer4/Unit}" | |
line="${line//\*\*/ }" | |
md+=$line$'\n' | |
line=$(grep -F "|**Ocelot.Administration.IdentityServer4**|" $file_a) | |
line="${line/Ocelot.Administration.IdentityServer4/Acceptance}" | |
line="${line//\*\*/ }" | |
md+=$line$'\n'$'\n' | |
md+='---'$'\n' | |
#echo Matrix markdown is "$md" | |
escaped_md="${md//|/\\|}" | |
escaped_md="${escaped_md//./\\.}" | |
escaped_md="${escaped_md//$'\n'/\\n}" | |
#echo Escaped markdown is $escaped_md | |
echo Reformatting MD-files... | |
# Unit | |
sed -i 's/# Summary/# Code Coverage Summary/g' $file_u | |
sed -i "1a $escaped_md" $file_u # insert markdown-string after the 1st line | |
sed -i 's|<details open><summary>Summary</summary>|<details><summary>Coverage Summary</summary>|g' $file_u | |
sed -i '/## Coverage/d' $file_u # delete line | |
sed -i '/<details><summary>Coverage Summary/i ## Unit Test Coverage' $file_u # insert line | |
# Acceptance | |
sed -i 's/# Summary/\n---\n/g' $file_a | |
sed -i 's|<details open><summary>Summary</summary>|<details><summary>Coverage Summary</summary>|g' $file_a | |
sed -i '/## Coverage/d' $file_a # delete line | |
sed -i '/<details><summary>Coverage Summary/i ## Acceptance Test Coverage' $file_a # insert line | |
# Adding a job summary -> https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-job-summary | |
echo Publishing coverage in job summary... | |
cat $file_u >> $GITHUB_STEP_SUMMARY | |
cat $file_a >> $GITHUB_STEP_SUMMARY | |
shell: bash | |
publish: | |
needs: build | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- name: .NET Version | |
run: dotnet --version | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: | | |
8.0.x | |
9.0.x | |
- name: .NET Info | |
run: dotnet --info | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: README.md | |
run: | | |
echo Original README.md | |
echo ------------------------ | |
cat README.md | |
echo ------------------------ | |
# Replaces relative GitHub paths with NuGet-friendly absolute URLs | |
sed -i 's|/ocelot_icon.png|https://raw.githubusercontent.com/ThreeMammals/Ocelot.Administration.IdentityServer4/refs/heads/main/ocelot_icon.png|g; s|/idser4_logo.png|https://raw.githubusercontent.com/ThreeMammals/Ocelot.Administration.IdentityServer4/refs/heads/main/idser4_logo.png|g' README.md | |
echo New content of README.md | |
echo ------------------------ | |
cat README.md | |
- name: Restore dependencies | |
run: dotnet restore ./Ocelot.Administration.IdentityServer4.sln | |
- name: Pack project | |
run: dotnet pack ./src/Ocelot.Administration.IdentityServer4.csproj --configuration Release --output ./packages /p:ContinuousIntegrationBuild=true | |
# - name: Publish to GitHub Packages | |
# run: dotnet nuget push ./packages/*.nupkg --source "https://nuget.pkg.github.com/ThreeMammals/index.json" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate | |
# - name: Publish to NuGet | |
# run: dotnet nuget push ./packages/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{ secrets.NUGET_API_KEY_2025 }} --skip-duplicate |