Skip to content

Commit 6434243

Browse files
Copilotegil
andauthored
ci: Upgrade build system to Nuke following AngleSharp ecosystem standards (#51)
* Initial plan * Modernize CI workflow to use dotnet CLI directly Co-authored-by: egil <[email protected]> * Update build.sh to use modern dotnet CLI instead of deprecated Cake/mono Co-authored-by: egil <[email protected]> * Upgrade build system from dotnet CLI to Nuke build automation system Co-authored-by: egil <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: egil <[email protected]>
1 parent 600656d commit 6434243

21 files changed

+1289
-362
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1515

1616
- name: Build
1717
run: ./build.sh
@@ -20,7 +20,7 @@ jobs:
2020
runs-on: windows-latest
2121

2222
steps:
23-
- uses: actions/checkout@v2
23+
- uses: actions/checkout@v4
2424

2525
- name: Build
2626
run: |

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ PublishScripts/
189189

190190
# NuGet Packages
191191
*.nupkg
192+
nupkgs/
192193
# The packages folder can be ignored because of Package Restore
193194
**/[Pp]ackages/*
194195
# except build/, which is used as an MSBuild target.
@@ -346,4 +347,10 @@ ASALocalRun/
346347
# BeatPulse healthcheck temp database
347348
healthchecksdb
348349

349-
*.ncrunchsolution
350+
*.ncrunchsolution
351+
352+
# Nuke build artifacts
353+
.nuke/temp/
354+
bin/
355+
nuke/bin/
356+
nuke/obj/

.nuke/build.schema.json

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"definitions": {
4+
"Host": {
5+
"type": "string",
6+
"enum": [
7+
"AppVeyor",
8+
"AzurePipelines",
9+
"Bamboo",
10+
"Bitbucket",
11+
"Bitrise",
12+
"GitHubActions",
13+
"GitLab",
14+
"Jenkins",
15+
"Rider",
16+
"SpaceAutomation",
17+
"TeamCity",
18+
"Terminal",
19+
"TravisCI",
20+
"VisualStudio",
21+
"VSCode"
22+
]
23+
},
24+
"ExecutableTarget": {
25+
"type": "string",
26+
"enum": [
27+
"Clean",
28+
"Compile",
29+
"CreatePackage",
30+
"Default",
31+
"Package",
32+
"PrePublish",
33+
"Publish",
34+
"PublishPackage",
35+
"PublishPreRelease",
36+
"PublishRelease",
37+
"Restore",
38+
"RunUnitTests"
39+
]
40+
},
41+
"Verbosity": {
42+
"type": "string",
43+
"description": "",
44+
"enum": [
45+
"Verbose",
46+
"Normal",
47+
"Minimal",
48+
"Quiet"
49+
]
50+
},
51+
"NukeBuild": {
52+
"properties": {
53+
"Continue": {
54+
"type": "boolean",
55+
"description": "Indicates to continue a previously failed build attempt"
56+
},
57+
"Help": {
58+
"type": "boolean",
59+
"description": "Shows the help text for this build assembly"
60+
},
61+
"Host": {
62+
"description": "Host for execution. Default is 'automatic'",
63+
"$ref": "#/definitions/Host"
64+
},
65+
"NoLogo": {
66+
"type": "boolean",
67+
"description": "Disables displaying the NUKE logo"
68+
},
69+
"Partition": {
70+
"type": "string",
71+
"description": "Partition to use on CI"
72+
},
73+
"Plan": {
74+
"type": "boolean",
75+
"description": "Shows the execution plan (HTML)"
76+
},
77+
"Profile": {
78+
"type": "array",
79+
"description": "Defines the profiles to load",
80+
"items": {
81+
"type": "string"
82+
}
83+
},
84+
"Root": {
85+
"type": "string",
86+
"description": "Root directory during build execution"
87+
},
88+
"Skip": {
89+
"type": "array",
90+
"description": "List of targets to be skipped. Empty list skips all dependencies",
91+
"items": {
92+
"$ref": "#/definitions/ExecutableTarget"
93+
}
94+
},
95+
"Target": {
96+
"type": "array",
97+
"description": "List of targets to be invoked. Default is '{default_target}'",
98+
"items": {
99+
"$ref": "#/definitions/ExecutableTarget"
100+
}
101+
},
102+
"Verbosity": {
103+
"description": "Logging verbosity during build execution. Default is 'Normal'",
104+
"$ref": "#/definitions/Verbosity"
105+
}
106+
}
107+
}
108+
},
109+
"allOf": [
110+
{
111+
"properties": {
112+
"Configuration": {
113+
"type": "string",
114+
"description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
115+
"enum": [
116+
"Debug",
117+
"Release"
118+
]
119+
},
120+
"ReleaseNotesFilePath": {
121+
"type": "string",
122+
"description": "ReleaseNotesFilePath - To determine the SemanticVersion"
123+
},
124+
"Solution": {
125+
"type": "string",
126+
"description": "Path to a solution file that is automatically loaded"
127+
}
128+
}
129+
},
130+
{
131+
"$ref": "#/definitions/NukeBuild"
132+
}
133+
]
134+
}

.nuke/parameters.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"$schema": "./build.schema.json",
3+
"Solution": "src/AngleSharp.Diffing.sln"
4+
}

build.cake

Lines changed: 0 additions & 11 deletions
This file was deleted.

build.cmd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:; set -eo pipefail
2+
:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
3+
:; ${SCRIPT_DIR}/build.sh "$@"
4+
:; exit $?
5+
6+
@ECHO OFF
7+
powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %*

build.ps1

Lines changed: 55 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,74 @@
1+
[CmdletBinding()]
12
Param(
2-
[string]$Script = "build.cake",
3-
[string]$Target = "Default",
4-
[ValidateSet("Release", "Debug")]
5-
[string]$Configuration = "Release",
6-
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
7-
[string]$Verbosity = "Verbose",
8-
[switch]$Experimental,
9-
[switch]$WhatIf,
10-
[switch]$Mono,
11-
[switch]$SkipToolPackageRestore,
123
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
13-
[string[]]$ScriptArgs
4+
[string[]]$BuildArguments
145
)
156

16-
$PSScriptRoot = split-path -parent $MyInvocation.MyCommand.Definition;
17-
$UseDryRun = "";
18-
$UseMono = "";
19-
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
20-
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
21-
$NUGET_OLD_EXE = Join-Path $TOOLS_DIR "nuget_old.exe"
22-
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
23-
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
24-
$NUGET_OLD_URL = "https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe"
7+
Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)"
258

26-
# Should we use experimental build of Roslyn?
27-
$UseExperimental = "";
28-
if ($Experimental.IsPresent) {
29-
$UseExperimental = "--experimental"
30-
}
9+
Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 }
10+
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
3111

32-
# Is this a dry run?
33-
if ($WhatIf.IsPresent) {
34-
$UseDryRun = "--dryrun"
35-
}
12+
###########################################################################
13+
# CONFIGURATION
14+
###########################################################################
3615

37-
# Should we use mono?
38-
if ($Mono.IsPresent) {
39-
$UseMono = "--mono"
40-
}
16+
$BuildProjectFile = "$PSScriptRoot\nuke\_build.csproj"
17+
$TempDirectory = "$PSScriptRoot\\.nuke\temp"
4118

42-
# Try download NuGet.exe if do not exist.
43-
if (!(Test-Path $NUGET_EXE)) {
44-
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE)
45-
}
19+
$DotNetGlobalFile = "$PSScriptRoot\\global.json"
20+
$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1"
21+
$DotNetChannel = "STS"
4622

47-
# Try download NuGet.exe if do not exist.
48-
if (!(Test-Path $NUGET_OLD_URL)) {
49-
(New-Object System.Net.WebClient).DownloadFile($NUGET_OLD_URL, $NUGET_OLD_EXE)
50-
}
23+
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
24+
$env:DOTNET_NOLOGO = 1
5125

52-
# Make sure NuGet (latest) exists where we expect it.
53-
if (!(Test-Path $NUGET_EXE)) {
54-
Throw "Could not find nuget.exe"
26+
###########################################################################
27+
# EXECUTION
28+
###########################################################################
29+
30+
function ExecSafe([scriptblock] $cmd) {
31+
& $cmd
32+
if ($LASTEXITCODE) { exit $LASTEXITCODE }
5533
}
5634

57-
# Make sure NuGet (v3.5.0) exists where we expect it.
58-
if (!(Test-Path $NUGET_OLD_EXE)) {
59-
Throw "Could not find nuget_old.exe"
35+
# If dotnet CLI is installed globally and it matches requested version, use for execution
36+
if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
37+
$(dotnet --version) -and $LASTEXITCODE -eq 0) {
38+
$env:DOTNET_EXE = (Get-Command "dotnet").Path
6039
}
40+
else {
41+
# Download install script
42+
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
43+
New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null
44+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
45+
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
46+
47+
# If global.json exists, load expected version
48+
if (Test-Path $DotNetGlobalFile) {
49+
$DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
50+
if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
51+
$DotNetVersion = $DotNetGlobal.sdk.version
52+
}
53+
}
6154

62-
# Restore tools from NuGet?
63-
if (-Not $SkipToolPackageRestore.IsPresent)
64-
{
65-
Push-Location
66-
Set-Location $TOOLS_DIR
67-
Invoke-Expression "$NUGET_EXE install -ExcludeVersion"
68-
Pop-Location
69-
if ($LASTEXITCODE -ne 0) {
70-
exit $LASTEXITCODE
55+
# Install by channel or version
56+
$DotNetDirectory = "$TempDirectory\dotnet-win"
57+
if (!(Test-Path variable:DotNetVersion)) {
58+
ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
59+
} else {
60+
ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
7161
}
62+
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
63+
$env:PATH = "$DotNetDirectory;$env:PATH"
7264
}
7365

74-
# Make sure that Cake has been installed.
75-
if (!(Test-Path $CAKE_EXE)) {
76-
Throw "Could not find Cake.exe"
66+
Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"
67+
68+
if (Test-Path env:NUKE_ENTERPRISE_TOKEN) {
69+
& $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null
70+
& $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null
7771
}
7872

79-
# Start Cake
80-
Invoke-Expression "$CAKE_EXE `"$Script`" --target=`"$Target`" --configuration=`"$Configuration`" --verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs"
81-
exit $LASTEXITCODE
73+
ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
74+
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }

0 commit comments

Comments
 (0)