Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
63 changes: 63 additions & 0 deletions .github/workflows/benchmarks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Benchmarks

on:
workflow_dispatch:

permissions:
contents: read

env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
benchmarksPath: './benchmarks/DurationMancer.Benchmarks/DurationMancer.Benchmarks.csproj'
buildConfiguration: 'Release'

jobs:
benchmarks:
name: Run Benchmarks
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis and for GitVersion based versioning

# --- GitVersion ---
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v4.2.0
with:
versionSpec: '6.5.x'
- name: Determine Version
id: version_step # step id used as reference for output values
uses: gittools/actions/gitversion/command@v4.2.0
with:
arguments: '/output buildserver /l console /config GitVersion.yaml /updateprojectfiles' # have to self-define all arguments; /updateprojectfiles not impl. in execute task

# --- Setup .NET ---
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x

# --- Restore ---
- name: Restore
run: dotnet restore ${{ env.benchmarksPath }}

# --- Build ---
- name: Build ${{ env.GitVersion_FullSemVer }}
run: dotnet build ${{ env.benchmarksPath }} --no-restore -c Release

# --- Run Benchmarks ---
- name: Run Benchmarks for ${{ env.GitVersion_FullSemVer }}
run: dotnet run --project ${{ env.benchmarksPath }} --no-build -c Release -f net10.0

# --- Publish Benchmark Results ---
- name: Upload Benchmark Results
uses: actions/upload-artifact@v4
with:
name: BenchmarkResults-${{ env.GitVersion_FullSemVer }}
path: ./BenchmarkDotNet.Artifacts/results
retention-days: 30
125 changes: 125 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: Build and analyze

on:
push:
branches: [main, release/*, develop]
pull_request:
types: [opened, synchronize, reopened]
branches: [main, release/*, develop]
workflow_dispatch:

permissions:
contents: read
pull-requests: write

env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 # Opt out of telemetry to speed up the build
DOTNET_NOLOGO: 1 # Prevents the dotnet CLI logo from displaying that speeds up build times
libraryPath: './src/DurationMancer/DurationMancer.csproj'
testsPath: './tests/DurationMancer.Tests/DurationMancer.Tests.csproj'
buildConfiguration: 'Release'
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

jobs:
build:
name: Build and analyze
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis and for GitVersion based versioning

# --- GitVersion ---
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v4.2.0
with:
versionSpec: '6.5.x'
- name: Determine Version
id: version_step # step id used as reference for output values
uses: gittools/actions/gitversion/command@v4.2.0
with:
arguments: '/output buildserver /l console /config GitVersion.yaml /updateprojectfiles' # have to self-define all arguments; /updateprojectfiles not impl. in execute task

# --- Tool setup ---
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Setup JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'

# --- SonarCloud installation ---
- name: Install SonarQube Cloud scanner
run: dotnet tool install dotnet-sonarscanner --global

# --- Restore ---
- name: Restore library
run: dotnet restore ${{ env.libraryPath }}
- name: Restore tests
run: dotnet restore ${{ env.testsPath }}

# --- SonarCloud begin ---
- name: Prepare SonarQube analyze
run: >
dotnet-sonarscanner begin /k:"HaGGi13_DurationMancer" /o:"haggi13"
/d:sonar.host.url="https://sonarcloud.io"
/v:"${{ env.GitVersion_FullSemVer }}"
/d:sonar.token="$SONAR_TOKEN"
/d:sonar.cs.opencover.reportsPaths=./TestResults/coverage*.opencover.xml
/d:sonar.exclusions="benchmarks/**"
/d:sonar.coverage.exclusions="benchmarks/**"

# --- Build ---
- name: Build library ${{ env.GitVersion_FullSemVer }}
run: >
dotnet build ${{ env.libraryPath }}
--no-restore
-c ${{ env.buildConfiguration }}
- name: Build tests
run: >
dotnet build ${{ env.testsPath }}
--no-restore
-c ${{ env.buildConfiguration }}

# --- Test ---
- name: Test
run: >
dotnet test ${{ env.testsPath }} --no-build -c ${{ env.buildConfiguration }}
--logger trx
--results-directory "./TestResults/"
--logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true"
/p:CollectCoverage=true
/p:CoverletOutputFormat="opencover"
/p:CoverletOutput="./../../TestResults/coverage"

- name: Upload dotnet test results
uses: actions/upload-artifact@v4
with:
name: TestResults
path: ./TestResults/
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}

# --- SonarCloud end ---
- name: Run SonarQube analyze
run: dotnet-sonarscanner end /d:sonar.token="$SONAR_TOKEN"

# --- NuGet Pack + Upload ---
- name: Pack NuGet package
run: >
dotnet pack ${{ env.libraryPath }}
--no-build
-c ${{ env.buildConfiguration }}
-o ./nupkg
/p:PackageVersion=${{ env.GitVersion_FullSemVer }}

- name: Upload NuGet package artifact
uses: actions/upload-artifact@v4
with:
name: NuGetPackage
path: ./nupkg/*.nupkg
retention-days: 3
112 changes: 112 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Release to NuGet

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # e.g., v1.0.0, v2.3.1

permissions:
contents: write # Needed for GitHub Release creation
id-token: write # Needed for GitHub OIDC token issuance

env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
libraryPath: './src/DurationMancer/DurationMancer.csproj'
testsPath: './tests/DurationMancer.Tests/DurationMancer.Tests.csproj'
buildConfiguration: 'Release'

jobs:
release:
name: Pack & Publish
runs-on: ubuntu-latest
environment: nuget # GitHub Environment with protection rules (recommended)
steps:

# --- Checkout ---
- name: Code checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

# --- GitVersion ---
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v4.2.0
with:
versionSpec: '6.5.x'
- name: Determine Version
id: version_step # step id used as reference for output values
uses: gittools/actions/gitversion/command@v4.2.0
with:
arguments: '/output buildserver /l console /config GitVersion.yaml /updateprojectfiles' # have to self-define all arguments; /updateprojectfiles not impl. in execute task

# --- .NET Setup ---
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x

# --- Restore ---
- name: Restore library
run: dotnet restore ${{ env.libraryPath }}
- name: Restore tests
run: dotnet restore ${{ env.testsPath }}

# --- Build ---
- name: Build library ${{ env.GitVersion_FullSemVer }}
run: >
dotnet build ${{ env.libraryPath }}
--no-restore
-c ${{ env.buildConfiguration }}
- name: Build tests
run: >
dotnet build ${{ env.testsPath }}
--no-restore
-c ${{ env.buildConfiguration }}

# --- Test (safety net before publish) ---
- name: Test
run: >
dotnet test ${{ env.testsPath }}
--no-build
-c ${{ env.buildConfiguration }}
--logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true"

# --- Pack ---
- name: Pack NuGet package
run: >
dotnet pack ${{ env.libraryPath }}
--no-build
-c ${{ env.buildConfiguration }}
-o ./nupkg
/p:PackageVersion=${{ env.GitVersion_FullSemVer }}

# --- Validate package ---
- name: Validate NuGet package
run: dotnet nuget verify ./nupkg/*.nupkg --all || true # 'verify' checks signatures; use 'true' fallback if unsigned

# --- Trusted Publishing: OIDC login
- name: NuGet login (OIDC → temp API key)
env:
NUGET_USER: ${{ secrets.NUGET_USER }}
uses: NuGet/login@v1
id: nuget_login
with:
user: $NUGET_USER

# --- Push to nuget.org ---
- name: Push to NuGet.org
env:
NUGET_API_KEY: ${{ steps.nuget_login.outputs.NUGET_API_KEY }}
run: >
dotnet nuget push ./nupkg/*.nupkg
--api-key $NUGET_API_KEY
--source https://api.nuget.org/v3/index.json
--skip-duplicate

# --- GitHub Release ---
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: ./nupkg/*.nupkg
4 changes: 3 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<Project>

<PropertyGroup>
<TargetFrameworks>net6.0;net8.0;net9.0;net10.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

</Project>
12 changes: 11 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,15 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- tests/DurationMancer.Tests -->
<PackageVersion Include="AwesomeAssertions" Version="9.3.0" />
<PackageVersion Include="AwesomeAssertions.Analyzers" Version="9.0.8" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
<PackageVersion Include="GitHubActionsTestLogger" Version="3.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
</Project>
</Project>
4 changes: 3 additions & 1 deletion DurationMancer.slnx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<Solution>
<Project Path="src/DurationMancer.csproj" />
<Project Path="benchmarks/DurationMancer.Benchmarks/DurationMancer.Benchmarks.csproj" />
<Project Path="src/DurationMancer/DurationMancer.csproj" />
<Project Path="tests/DurationMancer.Tests/DurationMancer.Tests.csproj" />
</Solution>
Loading
Loading