Binding Discovery: Wrap calls to .GetCustomAttributes in try/catch #2309
Workflow file for this run
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
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - 'main' | |
| paths-ignore: | |
| - README.md | |
| - CHANGELOG.md | |
| pull_request: | |
| branches: [ "main" ] | |
| workflow_dispatch: | |
| inputs: | |
| deploy_packages: | |
| description: 'deploy_packages: If the created package should be deployed (additional manual approval required by a release admin)' | |
| type: boolean | |
| default: false | |
| required: true | |
| is_production_release: | |
| description: 'is_production_release: Whether the release is a production release and not a pre-releaae (enabling this will update change log, increases version and tags commit)' | |
| type: boolean | |
| default: false | |
| required: true | |
| custom_version_suffix: | |
| description: 'custom_version_suffix: Custom suffix for the NuGet packages (without leading -) for non-production releases. Default: empty for production release, "ci<DATE>" for other runs. The build ID is always appended.' | |
| required: false | |
| custom_configuration: | |
| description: 'custom_configuration: Custom build configuration. Default: "Debug" for CI builds, "Release" for deployments.' | |
| required: false | |
| default: 'Default' | |
| type: choice | |
| options: | |
| - Default | |
| - Debug | |
| - Release | |
| specs_filter: | |
| description: 'specs_filter: Filter for Specs execution (e.g. Category=basicExecution)' | |
| required: false | |
| permissions: | |
| checks: write | |
| env: | |
| SPECS_FILTER: "" # use for testing CI: "&Category=basicExecution" | |
| REQNROLL_TEST_PIPELINEMODE: true | |
| DOTNET_VERSIONS: | | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| product_version_prefix: ${{ steps.versions.outputs.product_version_prefix }} | |
| product_version_suffix: ${{ steps.versions.outputs.product_version_suffix }} | |
| product_main_version: ${{ steps.versions.outputs.product_main_version }} | |
| product_patch_version: ${{ steps.versions.outputs.product_patch_version }} | |
| product_full_version: ${{ steps.versions.outputs.product_full_version }} | |
| product_configuration: ${{ steps.versions.outputs.product_configuration }} | |
| deploy_packages: ${{ steps.versions.outputs.deploy_packages }} | |
| is_production_release: ${{ steps.versions.outputs.is_production_release }} | |
| build_params: ${{ steps.build_params.outputs.build_params }} | |
| test_params: ${{ steps.build_params.outputs.test_params }} | |
| specs_filter: ${{ steps.build_params.outputs.specs_filter }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: versions | |
| name: Calculate versions | |
| shell: pwsh | |
| run: | | |
| $deployPackages = $false | |
| if ("${{ inputs.deploy_packages }}" -eq 'true') { | |
| $deployPackages = $true | |
| } | |
| Write-Output "deploy_packages=$($deployPackages.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT | |
| Write-Output "Deploy packages: $deployPackages" | |
| $isProductionRelease = $false | |
| if ("${{ inputs.is_production_release }}" -eq 'true') { | |
| $isProductionRelease = $true | |
| } | |
| Write-Output "is_production_release=$($isProductionRelease.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT | |
| Write-Output "Is production release: $isProductionRelease" | |
| $versionSuffix = "${{ inputs.custom_version_suffix }}" | |
| if ($isProductionRelease){ | |
| if ($versionSuffix -ne "") { | |
| throw "The 'custom_version_suffix' setting cannot be used for production releases." | |
| } | |
| } | |
| else { | |
| if ($versionSuffix -eq "") { | |
| $date = [datetime]::Today | |
| $dateString = $date.ToString('yyyyMMdd') | |
| $versionSuffix = "ci$dateString-${env:GITHUB_RUN_NUMBER}" | |
| } | |
| else { | |
| $versionSuffix = "$versionSuffix-${env:GITHUB_RUN_NUMBER}" | |
| } | |
| } | |
| Write-Output "product_version_suffix=$versionSuffix" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Version Suffix: $versionSuffix" | |
| $productConfig = "${{ inputs.custom_configuration }}" | |
| if (($productConfig -eq "Default") -or ($productConfig -eq "")) { | |
| if ($deployPackages){ | |
| $productConfig = "Release" | |
| } | |
| else { | |
| $productConfig = "Debug" | |
| } | |
| } | |
| Write-Output "product_configuration=$productConfig" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Configuration: $productConfig" | |
| $buildPropsXml = [xml](Get-Content Directory.Build.props) | |
| $versionPrefix = $buildPropsXml.SelectSingleNode('//Project/PropertyGroup/VersionPrefix/text()').Value.Trim() | |
| Write-Output "product_version_prefix=$versionPrefix" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Version Prefix: $versionPrefix" | |
| $mainVersion = &{$versionPrefix -match '^\d+\.\d+' > $null; $matches[0]} | |
| Write-Output "product_main_version=$mainVersion" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Main Version: $mainVersion" | |
| $patchVersion = &{$versionPrefix -match '\d+$' > $null; $matches[0]} | |
| Write-Output "product_patch_version=$patchVersion" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Patch Version: $patchVersion" | |
| $fullVersion = $versionPrefix | |
| if ($versionSuffix -ne "") { | |
| $fullVersion = "$fullVersion-$versionSuffix" | |
| } | |
| Write-Output "product_full_version=$fullVersion" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Full Version: $fullVersion" | |
| - id: build_params | |
| name: Calculate build parameters | |
| shell: pwsh | |
| env: | |
| APPINSIGHTS_KEY: ${{ secrets.APPINSIGHTS_KEY }} | |
| run: | | |
| # Load version fields to variables | |
| $versionSuffix = '${{ steps.versions.outputs.product_version_suffix }}' | |
| $productConfig = '${{ steps.versions.outputs.product_configuration }}' | |
| $deployPackages = '${{ steps.versions.outputs.deploy_packages }}' -eq 'true' | |
| # Calculate 'build_params' | |
| $buildParams = "-p:VersionSuffix=$versionSuffix -c $productConfig" | |
| Write-Output "build_params=$buildParams" >> $env:GITHUB_OUTPUT | |
| Write-Output "Build Params: $buildParams" | |
| # Calculate 'main_build_params' | |
| $mainBuildParams = $buildParams | |
| if ($deployPackages) { | |
| $mainBuildParams = "$mainBuildParams -p:AppInsightsInstrumentationKey=$env:APPINSIGHTS_KEY" | |
| Write-Output "Main Build Params Updated for Deployment" | |
| } | |
| Write-Output "main_build_params=$mainBuildParams" >> $env:GITHUB_OUTPUT | |
| # Calculate 'test_params' | |
| $gitHubActionsLoggerSettings = '"GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true;annotations.titleFormat=[@traits.Category] @test;annotations.messageFormat=@error\n@trace"' | |
| $testParams = "--verbosity minimal --logger $gitHubActionsLoggerSettings -- RunConfiguration.CollectSourceInformation=true RunConfiguration.TreatNoTestsAsError=true" | |
| Write-Output "test_params=$testParams" >> $env:GITHUB_OUTPUT | |
| Write-Output "Test Params: $testParams" | |
| # Calculate 'specs_filter' | |
| $specsFilter = "${{ inputs.specs_filter }}" | |
| if ($specsFilter -ne "") { | |
| $specsFilter = "&$specsFilter" | |
| } | |
| else { | |
| $specsFilter = $env:SPECS_FILTER | |
| } | |
| Write-Output "specs_filter=$specsFilter" >> $env:GITHUB_OUTPUT | |
| Write-Output "Specs Filter: $specsFilter" | |
| - name: Update Changelog | |
| shell: pwsh | |
| run: | | |
| $releaseDate = [System.DateTime]::Today.ToString("yyyy-MM-dd") | |
| $newHeading = "# v${{ steps.versions.outputs.product_full_version }} - $releaseDate" | |
| $content = [System.IO.File]::ReadAllText("CHANGELOG.md").Replace("# [vNext]",$newHeading) | |
| [System.IO.File]::WriteAllText("CHANGELOG.md", $content) | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build | |
| run: dotnet build --no-restore ${{ steps.build_params.outputs.main_build_params }} | |
| - name: Upload packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: packages-v${{ steps.versions.outputs.product_full_version }} | |
| if-no-files-found: error | |
| path: "GeneratedNuGetPackages/${{ steps.versions.outputs.product_configuration }}/*.*nupkg" | |
| - name: Upload RuntimeTests | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: RuntimeTests | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.RuntimeTests/bin/ | |
| - name: Upload GeneratorTests | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: GeneratorTests | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.GeneratorTests/bin/ | |
| - name: Upload PluginTests | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: PluginTests | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.PluginTests/bin/ | |
| - name: Upload TestProjectGenerator | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: TestProjectGeneratorTests | |
| if-no-files-found: error | |
| path: Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator.Tests/bin/ | |
| - name: Upload SystemTests | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: SystemTests | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.SystemTests/bin/ | |
| - name: Upload Specs | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Specs | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.Specs/bin/ | |
| - name: Upload Formatters Tests | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: FormattersTests | |
| if-no-files-found: error | |
| path: Tests/Reqnroll.Formatters.Tests/bin/ | |
| validate-packages: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/ | |
| - name: Install NuGet Package Validation Tool | |
| run: dotnet tool install --global Meziantou.Framework.NuGetPackageValidation.Tool | |
| - name: Validate NuGet packages | |
| shell: pwsh | |
| run: | | |
| Write-Output "Validating NuGet packages..." | |
| $packages = Get-ChildItem "GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/*.nupkg" -Exclude "*.snupkg" | |
| $errorCount = 0 | |
| $totalPackages = $packages.Count | |
| # Determine excluded rules based on branch | |
| $excludedRules = @() | |
| if ("${{ github.ref }}" -ne "refs/heads/main") { | |
| $excludedRules += "AssembliesMustBeOptimized" | |
| Write-Output "::notice::Assembly optimization validation skipped for non-main branch" | |
| } | |
| foreach ($package in $packages) { | |
| Write-Output "Validating package: $($package.Name)" | |
| try { | |
| # Build validation command with conditional exclusions | |
| $validationArgs = @($package.FullName) | |
| if ($excludedRules.Count -gt 0) { | |
| $validationArgs += "--excluded-rules" | |
| $validationArgs += ($excludedRules -join ",") | |
| } | |
| # Run validation | |
| $validationResult = & meziantou.validate-nuget-package @validationArgs | |
| $exitCode = $LASTEXITCODE | |
| if ($exitCode -eq 0) { | |
| Write-Output "✅ $($package.Name) passed validation" | |
| } else { | |
| Write-Output "::warning title=Package Validation Issues::$($package.Name) has validation issues" | |
| Write-Output $validationResult | |
| # For now, we'll log warnings but not fail the build to allow gradual improvement | |
| # This can be changed to fail the build once all validation issues are resolved | |
| Write-Output "::notice::Package validation issues detected but not failing build (gradual improvement mode)" | |
| } | |
| } catch { | |
| Write-Output "::error title=Package Validation Error::Error validating $($package.Name): $_" | |
| $errorCount++ | |
| } | |
| } | |
| if ($errorCount -gt 0) { | |
| Write-Output "::error title=Package Validation Failed::$errorCount package(s) had validation errors" | |
| exit 1 | |
| } else { | |
| Write-Output "✅ Validation completed for $totalPackages packages" | |
| exit 0 | |
| } | |
| component-tests: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/ | |
| - name: Download RuntimeTests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: RuntimeTests | |
| path: Tests/Reqnroll.RuntimeTests/bin/ | |
| - name: Download GeneratorTests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: GeneratorTests | |
| path: Tests/Reqnroll.GeneratorTests/bin/ | |
| - name: Download PluginTests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: PluginTests | |
| path: Tests/Reqnroll.PluginTests/bin/ | |
| - name: Download TestProjectGenerator | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: TestProjectGeneratorTests | |
| path: Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator.Tests/bin/ | |
| - name: Runtime Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.RuntimeTests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.RuntimeTests.dll --filter "Category!=quarantaine{{ needs.build.outputs.specs_filter }}" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/runtimetests-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Generator Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.GeneratorTests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.GeneratorTests.dll --filter "Category!=quarantaine{{ needs.build.outputs.specs_filter }}" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/generatortests-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Plugin Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.PluginTests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.PluginTests.dll --filter "Category!=quarantaine{{ needs.build.outputs.specs_filter }}" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/plugintests-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: TestProjectGenerator Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator.Tests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.TestProjectGenerator.Tests.dll --filter "Category!=quarantaine{{ needs.build.outputs.specs_filter }}" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/testprjgentests-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Upload TRX files | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: component-tests-trx-v${{ steps.versions.outputs.product_full_version }} | |
| if-no-files-found: error | |
| path: "TestResults/*.trx" | |
| specs: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| env: | |
| # Disable telemetry, because we use many small projects | |
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | |
| REQNROLL_TELEMETRY_ENABLED: 0 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set Runner ImageVersion to Env | |
| shell: pwsh | |
| run: | | |
| Write-Output "ImageVersion=$env:ImageVersion" >> $env:GITHUB_ENV | |
| - name: Cache RRC folder | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/RRC | |
| key: RRC-Specs-${{ runner.os }}-${{ env.ImageVersion }} # Use the runner version as key, so if new dependencies get installed we get a new cache entry | |
| - name: Download packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/ | |
| - name: Download Specs | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: Specs | |
| path: Tests/Reqnroll.Specs/bin/ | |
| - name: Specs | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.Specs/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.Specs.dll --filter "Category!=quarantaine{{ needs.build.outputs.specs_filter }}" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/specs-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Upload TRX files | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: specs-trx-v${{ needs.build.outputs.product_full_version }} | |
| if-no-files-found: error | |
| path: "TestResults/specs-results.trx" | |
| system-tests-windows: | |
| runs-on: windows-latest | |
| needs: build | |
| env: | |
| # D:\ (temporary) drive has better performance then C:\ (remote) drive on the Github Runner, so place all temporary files on D:\, see https://github.com/actions/setup-dotnet/issues/260 | |
| DOTNET_INSTALL_DIR: D:\dotnet | |
| REQNROLL_TEST_TEMPFOLDER: D:\testrundata | |
| NUGET_PACKAGES: D:\nuget\packages | |
| # Disable telemetry, because we use many small projects | |
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | |
| REQNROLL_TELEMETRY_ENABLED: 0 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set Runner ImageVersion and Week number to Env | |
| shell: pwsh | |
| run: | | |
| Write-Output "ImageVersion=$env:ImageVersion" >> $env:GITHUB_ENV | |
| $WeekNumber = Get-Date -UFormat %V | |
| Write-Output "WeekNumber=$WeekNumber" >> $env:GITHUB_ENV | |
| - name: Cache Reqnroll Resource Cache (RRC) folder | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ env.REQNROLL_TEST_TEMPFOLDER }}/RRC | |
| # Use the runner version in the key, so if new dependencies get installed we get a new cache entry | |
| # Also add week number so that if new tests require new cached templates they should eventually get into the RRC | |
| key: RRC-SystemTests-${{ runner.os }}-${{ env.ImageVersion }}-W${{ env.WeekNumber }} | |
| - name: Download packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/ | |
| - name: Download SystemTests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: SystemTests | |
| path: Tests/Reqnroll.SystemTests/bin/ | |
| - name: Download Formatters Tests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: FormattersTests | |
| path: Tests/Reqnroll.Formatters.Tests/bin/ | |
| - name: Setup required .NET SDKs | |
| # It is faster to install all required .NET versions to D: drive than installing only the missing one to C: drive and use it from there. | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSIONS }} | |
| - name: .NET Information | |
| run: | | |
| dotnet --info | |
| - name: System Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.SystemTests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.SystemTests.dll --logger "trx;LogFileName=${{ github.workspace }}/TestResults/systemtests-windows-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Formatters Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.Formatters.Tests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.Formatters.Tests.dll --logger "console;verbosity=detailed" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/Formatterstests-windows-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Upload Test Result TRX Files | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: systemtests-windows-trx-v${{ needs.build.outputs.product_full_version }} | |
| if-no-files-found: error | |
| path: "TestResults/*.trx" | |
| system-tests-linux: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| env: | |
| # Disable telemetry, because we use many small projects | |
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | |
| REQNROLL_TELEMETRY_ENABLED: 0 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set Runner ImageVersion and Week number to Env | |
| shell: pwsh | |
| run: | | |
| Write-Output "ImageVersion=$env:ImageVersion" >> $env:GITHUB_ENV | |
| $WeekNumber = Get-Date -UFormat %V | |
| Write-Output "WeekNumber=$WeekNumber" >> $env:GITHUB_ENV | |
| - name: Cache Reqnroll Resource Cache (RRC) folder | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/RRC | |
| # Use the runner version in the key, so if new dependencies get installed we get a new cache entry | |
| # Also add week number so that if new tests require new cached templates they should eventually get into the RRC | |
| key: RRC-SystemTests-${{ runner.os }}-${{ env.ImageVersion }}-W${{ env.WeekNumber }} | |
| - name: Download packages | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: GeneratedNuGetPackages/${{ needs.build.outputs.product_configuration }}/ | |
| - name: Download SystemTests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: SystemTests | |
| path: Tests/Reqnroll.SystemTests/bin/ | |
| - name: Download Formatters Tests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: FormattersTests | |
| path: Tests/Reqnroll.Formatters.Tests/bin/ | |
| - name: Setup required .NET SDKs | |
| # The default image contains .NET 8 only, but reusing it would not provide much performance benefit | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSIONS }} | |
| - name: .NET Information | |
| run: | | |
| dotnet --info | |
| - name: System Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.SystemTests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.SystemTests.dll --filter "TestCategory!=MsBuild&TestCategory!=NetFramework" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/systemtests-linux-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Formatters Tests | |
| shell: pwsh | |
| run: dotnet test ./Tests/Reqnroll.Formatters.Tests/bin/${{ needs.build.outputs.product_configuration }}/*/Reqnroll.Formatters.Tests.dll --filter "TestCategory!=MsBuild&TestCategory!=NetFramework" --logger "trx;LogFileName=${{ github.workspace }}/TestResults/Formatterstests-linux-results.trx" ${{ needs.build.outputs.test_params }} | |
| - name: Upload Test Result TRX Files | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: systemtests-linux-trx-v${{ needs.build.outputs.product_full_version }} | |
| if-no-files-found: error | |
| path: "TestResults/*.trx" | |
| build-docs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Doc Dependencies | |
| working-directory: docs | |
| run: | | |
| pip install -r requirements.txt | |
| - name: Build Doc | |
| working-directory: docs | |
| run: | | |
| sphinx-build -M html . _build --fail-on-warning | |
| - name: Upload HTML Doc Files | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: html-docs | |
| if-no-files-found: error | |
| path: "docs/_build/html/**/*" | |
| release: | |
| runs-on: ubuntu-latest | |
| needs: [build, validate-packages, component-tests, specs, system-tests-windows, system-tests-linux] | |
| environment: production_environment | |
| if: github.ref == 'refs/heads/main' && needs.build.outputs.deploy_packages == 'true' | |
| permissions: | |
| # Give the default GITHUB_TOKEN write permission to commit and push the | |
| # added or changed files to the repository. | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # avoid shallow clone git commit | |
| ref: ${{ github.head_ref }} | |
| ssh-key: ${{secrets.RELEASE_GIT_SSH_KEY}} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: packages-v${{ needs.build.outputs.product_full_version }} | |
| path: release_packages | |
| - name: Deploy NuGet packages | |
| env: | |
| NUGET_PUBLISH_KEY: ${{ secrets.NUGET_PUBLISH_KEY }} | |
| shell: pwsh | |
| run: | | |
| Write-Output "Deploying v${{ needs.build.outputs.product_full_version }} (v${{ needs.build.outputs.product_main_version }}) packages to nuget.org" | |
| ls ${{ github.workspace }}/release_packages | |
| ${{ github.workspace }}/.github/workflows/publish_packages.ps1 -packagesDir ${{ github.workspace }}/release_packages | |
| - name: Calculate Next Version | |
| if: needs.build.outputs.is_production_release == 'true' | |
| id: next_version | |
| shell: pwsh | |
| run: | | |
| $patchVersion = "${{ needs.build.outputs.product_patch_version }}" | |
| $nextPatch = [int]$patchVersion + 1 | |
| $nextVersion = "${{ needs.build.outputs.product_main_version }}.$nextPatch" | |
| Write-Output "product_next_version=$nextVersion" >> $env:GITHUB_OUTPUT | |
| Write-Output "Product Next Version: $nextVersion" | |
| - name: Bump Version | |
| if: needs.build.outputs.is_production_release == 'true' | |
| shell: pwsh | |
| run: | | |
| [System.IO.File]::WriteAllText("Directory.Build.props", [System.IO.File]::ReadAllText("Directory.Build.props").Replace("<VersionPrefix>${{ needs.build.outputs.product_version_prefix }}</VersionPrefix>", "<VersionPrefix>${{ steps.next_version.outputs.product_next_version }}</VersionPrefix>")) | |
| - name: Update Changelog | |
| if: needs.build.outputs.is_production_release == 'true' | |
| id: changelog | |
| shell: pwsh | |
| run: | | |
| $newHeading = "# [vNext]$([Environment]::NewLine)$([Environment]::NewLine)## Improvements:$([Environment]::NewLine)$([Environment]::NewLine)## Bug fixes:$([Environment]::NewLine)$([Environment]::NewLine)*Contributors of this release (in alphabetical order):* $([Environment]::NewLine)$([Environment]::NewLine)" | |
| $releaseDate = [System.DateTime]::Today.ToString("yyyy-MM-dd") | |
| $releaseTitle = "v${{ needs.build.outputs.product_full_version }} - $releaseDate" | |
| $newHeading = $newHeading + "# $releaseTitle" | |
| $content = [System.IO.File]::ReadAllText("CHANGELOG.md").Replace("# [vNext]",$newHeading) | |
| [System.IO.File]::WriteAllText("CHANGELOG.md", $content) | |
| Write-Output "New Heading:" | |
| Write-Output $newHeading | |
| # calculate release notes | |
| $match = [System.Text.RegularExpressions.Regex]::Match($content, "(?ms)^# .*?^# (?<title>[^\r\n]*?)\s*$\s*(?<notes>.*?)\s*(?:^# |\Z)") | |
| $releaseNotes = $(if ($match.Success) { $match.Groups["notes"].Value } else { "N/A" }) | |
| [System.IO.File]::WriteAllText("release_notes.txt", $releaseNotes) | |
| Write-Output "release_title=$releaseTitle" >> $env:GITHUB_OUTPUT | |
| Write-Output "release_notes_file=release_notes.txt" >> $env:GITHUB_OUTPUT | |
| - name: Update changes in GitHub repository | |
| if: needs.build.outputs.is_production_release == 'true' | |
| run: | | |
| git status | |
| git config --global user.name 'Reqnroll CI' | |
| git config --global user.email 'ci@reqnroll.net' | |
| git tag v${{ needs.build.outputs.product_full_version }} | |
| git push origin tag v${{ needs.build.outputs.product_full_version }} | |
| git add -u | |
| git commit -m '[automated commit] bump version after release of ${{ needs.build.outputs.product_full_version }}' | |
| git push | |
| - name: Create GitHub Release | |
| if: needs.build.outputs.is_production_release == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release create "v${{ needs.build.outputs.product_full_version }}" \ | |
| --verify-tag \ | |
| --title="${{ steps.changelog.outputs.release_title }}" \ | |
| --notes-file="${{ steps.changelog.outputs.release_notes_file }}" |