Skip to content
16 changes: 9 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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 |
Expand Down
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

- &copy; 2012-2014 Vladimir Keleshev <vladimir@keleshev.com>
Expand Down
148 changes: 148 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 1 addition & 1 deletion tests/Integration/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down