diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67305d9..d004012 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,10 +48,7 @@ jobs: run: dotnet tool restore - name: Build - run: dotnet build --configuration ${{ env.CONFIGURATION }} - - - name: Build Roslyn 4.4 variant - run: dotnet build src/DocoptNet/DocoptNet.csproj -f netstandard2.0 -p:RoslynVersion=4.4 --configuration ${{ env.CONFIGURATION }} + run: dotnet pwsh ./build.ps1 -Build -Configuration ${{ env.CONFIGURATION }} - name: Pack (Windows only) if: runner.os == 'Windows' @@ -79,11 +76,16 @@ jobs: } Add-Content $releaseNotesFile -Encoding UTF8 "Commit @ ${{ github.sha }}" - $packArgs = @() + + $packParams = @{ + Configuration = '${{ env.CONFIGURATION }}' + PackageReleaseNotesFile = $releaseNotesFile + } if ($versionSuffix) { - $packArgs += @('--version-suffix', $versionSuffix) + $packParams.VersionSuffix = $versionSuffix } - dotnet pack --no-build --configuration ${{ env.CONFIGURATION }} @packArgs "-p:PackageReleaseNotesFile=$releaseNotesFile" + + & ./build.ps1 -Pack @packParams if ($LASTEXITCODE) { throw "Pack failed" } Get-ChildItem -File -Filter docopt.net.*.nupkg dist | diff --git a/README.md b/README.md index 2b2e99b..1b526c1 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,58 @@ Install [the package][nupkg] in a .NET project using: dotnet add package docopt.net +## Building from Source + +The repository uses a PowerShell script to orchestrate multi-Roslyn variant builds. Ensure you have the required tools installed: + +```bash +dotnet tool restore +``` + +### Build + +To build the project with both Roslyn 3.10 (baseline) and Roslyn 4.4 variants: + +```bash +dotnet pwsh ./build.ps1 +``` + +or simply: + +```bash +dotnet pwsh ./build.ps1 -Build -Configuration Release +``` + +### Test + +To run tests: + +```bash +dotnet pwsh ./build.ps1 -Test +``` + +To run tests without rebuilding: + +```bash +dotnet pwsh ./build.ps1 -Test -NoBuild +``` + +### Pack + +To create a NuGet package containing both analyzer variants: + +```bash +dotnet pwsh ./build.ps1 -Pack +``` + +**Note:** Running `dotnet pack` directly without first building all Roslyn variants will fail with an error message. Always use `./build.ps1 -Pack` to ensure both analyzer variants are included in the package. + +To pack with a version suffix: + +```bash +dotnet pwsh ./build.ps1 -Pack -VersionSuffix "beta1" +``` + ## Copyright and License - © 2012-2014 Vladimir Keleshev diff --git a/build.ps1 b/build.ps1 new file mode 100755 index 0000000..4e878e0 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,148 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Build, test, and pack DocoptNet with multi-Roslyn variant support. + +.DESCRIPTION + This script orchestrates builds across Roslyn 3.10 (baseline) and Roslyn 4.4 variants, + runs tests for both variants, and produces a NuGet package containing both analyzer DLLs. + +.PARAMETER Build + Build the solution (default parameter set). + +.PARAMETER Test + Run tests. Note: May fail on non-Windows platforms if .NET Framework tests cannot run. + +.PARAMETER Pack + Create a NuGet package containing both analyzer variants. + +.PARAMETER Configuration + The build configuration (default: Release). + +.PARAMETER NoBuild + Skip the build step when running tests (only applies to baseline tests). + +.PARAMETER VersionSuffix + Optional version suffix for the NuGet package (e.g., "beta1"). + +.PARAMETER PackageReleaseNotesFile + Optional path to a file containing release notes for the NuGet package. + +.EXAMPLE + ./build.ps1 + Build both Roslyn variants (baseline + 4.4). + +.EXAMPLE + ./build.ps1 -Test + Build and test both Roslyn variants. + +.EXAMPLE + ./build.ps1 -Test -NoBuild + Run tests without rebuilding baseline (Roslyn 4.4 tests always build as needed). + +.EXAMPLE + ./build.ps1 -Pack -VersionSuffix "beta1" + Build and pack with version suffix. + +.EXAMPLE + ./build.ps1 -Pack -PackageReleaseNotesFile "/path/to/notes.txt" + Build and pack with release notes from a file. +#> + +[CmdletBinding(DefaultParameterSetName = 'Build')] +param( + [Parameter(ParameterSetName = 'Build')] + [switch] $Build, + + [Parameter(ParameterSetName = 'Test', Mandatory)] + [switch] $Test, + + [Parameter(ParameterSetName = 'Pack', Mandatory)] + [switch] $Pack, + + [Parameter(ParameterSetName = 'Build')] + [Parameter(ParameterSetName = 'Test')] + [Parameter(ParameterSetName = 'Pack')] + [string] $Configuration = 'Release', + + [Parameter(ParameterSetName = 'Test')] + [switch] $NoBuild, + + [Parameter(ParameterSetName = 'Pack')] + [string] $VersionSuffix, + + [Parameter(ParameterSetName = 'Pack')] + [string] $PackageReleaseNotesFile +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +# Make the script directory-independent +Push-Location $PSScriptRoot +try { + function Invoke-DotNet { + param( + [string[]] $Arguments + ) + + Write-Host "dotnet $($Arguments -join ' ')" -ForegroundColor Cyan + & dotnet @Arguments + if ($LASTEXITCODE -ne 0) { + throw "dotnet command failed with exit code $LASTEXITCODE" + } + } + + function Invoke-BuildFlow { + Write-Host "`n=== Building Baseline (Roslyn 3.10) ===" -ForegroundColor Green + Invoke-DotNet 'build', '--configuration', $Configuration + + Write-Host "`n=== Building Roslyn 4.4 Variant ===" -ForegroundColor Green + Invoke-DotNet 'build', 'src/DocoptNet/DocoptNet.csproj', '-f', 'netstandard2.0', '-p:RoslynVersion=4.4', '--configuration', $Configuration + } + + function Invoke-TestFlow { + if (-not $NoBuild) { + Invoke-BuildFlow + } + + Write-Host "`n=== Running Tests ===" -ForegroundColor Green + Invoke-DotNet 'test', '--no-build', '--configuration', $Configuration + + # Note: Roslyn 4.4 analyzer is validated through integration tests + # that use the packed NuGet package containing both analyzer variants + } + + function Invoke-PackFlow { + Invoke-BuildFlow + + Write-Host "`n=== Packing NuGet Package ===" -ForegroundColor Green + $packArgs = @('pack', 'src/DocoptNet/DocoptNet.csproj', '--no-build', '--configuration', $Configuration) + if ($VersionSuffix) { + $packArgs += @('--version-suffix', $VersionSuffix) + } + if ($PackageReleaseNotesFile) { + $packArgs += "-p:PackageReleaseNotesFile=$PackageReleaseNotesFile" + } + Invoke-DotNet $packArgs + } + + # Execute the appropriate flow based on parameter set + switch ($PSCmdlet.ParameterSetName) { + 'Build' { + Invoke-BuildFlow + } + 'Test' { + Invoke-TestFlow + } + 'Pack' { + Invoke-PackFlow + } + } + + Write-Host "`n=== Success ===" -ForegroundColor Green +} +finally { + Pop-Location +} diff --git a/tests/Integration/run.ps1 b/tests/Integration/run.ps1 index 1bacac1..3a21f23 100644 --- a/tests/Integration/run.ps1 +++ b/tests/Integration/run.ps1 @@ -24,7 +24,7 @@ try } Remove-Item -Recurse -Force (Join-Path $props.RestorePackagesPath docopt.net) -ErrorAction SilentlyContinue if (!$noPack) { - dotnet pack -c Release ../.. + & ../../build.ps1 -Pack -Configuration Release if ($LASTEXITCODE) { throw } } Remove-Item bin, obj -Recurse -Force -ErrorAction SilentlyContinue