Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4a942f9
(doc) Add .NET 10 migration plan
fdcastel May 25, 2026
97d47db
(doc) Update migration plan: phase 0 setup complete
fdcastel May 25, 2026
5e21399
(doc) Drop fork-internal PR; rely on push-triggered CI
fdcastel May 25, 2026
5916614
(doc) Update .gitignore to include CLAUDE.md and /tmp
fdcastel May 25, 2026
059768c
(DM-04) Trim CI to Windows-only
fdcastel May 25, 2026
47ba942
(DM-03) Install .NET 10 SDK in CI
fdcastel May 25, 2026
9414037
(DM-05) Run unit + integration NUnit suites on every push
fdcastel May 25, 2026
7e03145
(DM-10) Target net10.0-windows across all projects
fdcastel May 25, 2026
379453e
(DM-11) Reference the PowerShell SDK instead of the bundled SMA dll
fdcastel May 25, 2026
36d395e
(DM-12) Drop binding redirects, embed manifest, modern LangVersion
fdcastel May 25, 2026
a2f6227
(DM-14) Fix net10 compile errors in core library
fdcastel May 25, 2026
6065002
(DM-13) Audit/trim chocolatey.benchmark dependencies for net10
fdcastel May 25, 2026
e1d1279
(doc) Mark Phase 0 + Phase 1 in progress; record commits and notes
fdcastel May 25, 2026
4d35694
(doc) Phase 0 + Phase 1 DONE — CI build green; record Phase 2 finds
fdcastel May 25, 2026
25cf334
(DM-24) Make ApplicationParameters.AllowPrompts settable for specs
fdcastel May 25, 2026
e701686
(DM-25) Make ReadKeyTimeout/ReadLineTimeout safe on .NET
fdcastel May 25, 2026
7d9b0eb
(DM-20) Replace BinaryFormatter DeepCopy with a reflective deep clone
fdcastel May 25, 2026
7ca709a
(DM-26) Register CodePagesEncodingProvider for the cp1252 password wo…
fdcastel May 25, 2026
23616cb
(doc) Phase 2 progress: unit suite green locally (1188 passed, 0 failed)
fdcastel May 25, 2026
ef4d18f
(doc) Phase 2 gate green on CI (DM-23); record Phase 3 first blocker
fdcastel May 25, 2026
a3848e5
(DM-30) Unblock integration setup: settable ApplicationParameters loc…
fdcastel May 25, 2026
876e2ea
(doc) Phase 3: DM-30 done; diagnose remaining 20 as pre-existing test…
fdcastel May 25, 2026
f0360c3
(DM-32) Restore proxy env vars in ConfigurationBuilderSpecs (test iso…
fdcastel May 25, 2026
46b0feb
(doc) Phase 3 gate met locally (DM-32): integration 1463 passed, 0 fa…
fdcastel May 25, 2026
9862cce
(doc) Phase 3 gate CI-confirmed green (run 26423531366): unit 1188/0,…
fdcastel May 25, 2026
8d9a765
(DM-21) Replace AlphaFS with System.IO
fdcastel May 25, 2026
c249bf8
(doc) DM-21 DONE: AlphaFS replaced by System.IO (unit 1188/0, integra…
fdcastel May 26, 2026
e1b0ada
(DM-50) Resolve InstallLocation via Environment.ProcessPath for singl…
fdcastel May 26, 2026
09aa1bf
(DM-51) Drop the ILMerged-assembly fallback in AssemblyResolution
fdcastel May 26, 2026
bdaea5f
(DM-53) Add clean-container smoke CI job
fdcastel May 26, 2026
d3c7e9b
(doc) Phase 5 gate PROVEN: smoke ran choco in a no-runtime container …
fdcastel May 26, 2026
45511a5
(DM-50/52) Replace ILMerge with self-contained single-file publish in…
fdcastel May 26, 2026
b3f186f
(doc) Phase 5 COMPLETE: self-contained publish + packaging green on C…
fdcastel May 26, 2026
416b976
(DM-43) Add Pester E2E job (PowerShell 7) against the built nupkg
fdcastel May 26, 2026
4ef6b00
(DM-43) Pester E2E: relax ErrorActionPreference so expected pack erro…
fdcastel May 26, 2026
4e1ed44
(DM-43) Pester E2E: install PS 7.6 to match choco's net10 runtime
fdcastel May 26, 2026
e2e31e8
(DM-43) Pester E2E: parse testResults.xml and exit non-zero on failures
fdcastel May 26, 2026
9802a4f
(DM-40) Make Test-ByteOrderMark PS7-safe (Get-Content -Encoding Byte …
fdcastel May 26, 2026
f568ae3
(doc) Checkpoint: Phases 0-3+5 green on CI; Phase 4 baseline 79% (360…
fdcastel May 26, 2026
7b69c68
(DM-41) Invoke-Tests: seed in-repo testpackages into hermes source
fdcastel May 26, 2026
0adfaa6
(doc) Phase 4 refined: DM-41 closes ~10 seeding failures; 67 real PS7…
fdcastel May 26, 2026
afd18c1
(doc) Phase 4: record CI-confirmed DM-41 result (148/4126, +160 new t…
fdcastel May 26, 2026
208c4e4
(doc) Phase 4 declared substantially DONE; add DOTNET_MIGRATION_REPOR…
fdcastel May 26, 2026
a28fb00
(DM-80) Drop the .NET Framework 4.8 bootstrap path
fdcastel May 26, 2026
9e5cee2
(DM-82) Update README requirements and build prereqs for net10
fdcastel May 26, 2026
0332bf0
(doc) Phase 8 partial: DM-80 + DM-82 done; DM-81 deferred for maintai…
fdcastel May 26, 2026
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
166 changes: 72 additions & 94 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,6 @@ on:
workflow_dispatch:

jobs:
# Build using mono on Ubuntu
ubuntu-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache Tools
uses: actions/cache@v4
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install Mono
run: |
sudo apt install ca-certificates gnupg
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
sudo apt install -y mono-complete
mono --version
- name: Install dotnet #needed for GitVersion
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
5.0.x
- name: Report installed dotnet versions
run: |
dotnet --info
- name: Build with Mono
run: |
chmod +x build.sh
$GITHUB_WORKSPACE//build.sh --verbosity=diagnostic --target=CI --testExecutionType=unit
- name: Upload Ubuntu build results
uses: actions/upload-artifact@v4
# Always upload build results
if: ${{ always() }}
with:
name: ubuntu-build-results
path: |
code_drop/TestResults/issues-report.html
code_drop/TestResults/NUnit/TestResult.xml
code_drop/Packages/NuGet/*.nupkg
code_drop/MsBuild.log
# Build on Windows
windows-build:
runs-on: windows-latest
Expand All @@ -64,17 +21,21 @@ jobs:
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install dotnet #needed for GitVersion
- name: Install dotnet # 5.0.x for GitVersion, 10.0.x for the build
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
5.0.x
10.0.x
- name: Report installed dotnet versions
run: |
dotnet --info
- name: Build with .Net Framework
# Full CI on every push/PR: build, run BOTH NUnit suites, and package. Phase 5
# replaced ILMerge with a self-contained single-file publish, so --target=CI now
# produces the real net10 chocolatey nupkg (no MSI; that is Phase 8).
- name: Build, test and package
shell: powershell
run: ./build.ps1 --verbosity=diagnostic --target=CI --testExecutionType=unit --shouldRunOpenCover=false --shouldBuildMsi=true
run: ./build.ps1 --verbosity=diagnostic --target=CI --testExecutionType=all --shouldRunOpenCover=false
- name: Upload Windows build results
uses: actions/upload-artifact@v4
# Always upload build results
Expand All @@ -86,64 +47,81 @@ jobs:
code_drop\TestResults\NUnit\TestResult.xml
code_drop\TestCoverage\lcov.info
code_drop\TestCoverage\OpenCover.xml
code_drop\ilmerge-chocoexe.log
code_drop\ilmerge-chocolateydll.log
code_drop\Packages\NuGet\*.nupkg
code_drop\Packages\Chocolatey\*.nupkg
code_drop\MsBuild.log
code_drop\MSIs\en-US\chocolatey-*.msi
# Build using mono on MacOS
macos-build:
runs-on: macos-14

# Phase 4: Pester E2E under PowerShell 7. Installs the built chocolatey nupkg and
# runs the real package/helper tests (tests/pester-tests) via Invoke-Tests.ps1 under
# pwsh. Runs after windows-build and reuses its packaged nupkg.
pester-e2e:
needs: windows-build
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache Tools
uses: actions/cache@v4
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install dotnet #needed for GitVersion
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
- name: Download built packages
uses: actions/download-artifact@v4
with:
dotnet-version: |
5.0.x
- name: Report installed dotnet versions
name: windows-build-results
path: code_drop
# GH windows-latest ships PowerShell 7.4 LTS (on .NET 8), which can't load
# Chocolatey.PowerShell.dll (net10.0-windows). PS 7.6 runs on .NET 10 and matches
# the Microsoft.PowerShell.SDK 7.6.2 host the migration uses, so install it.
- name: Install PowerShell 7.6 (matches choco's net10 runtime)
shell: pwsh
run: |
dotnet --info
- name: Build with Mono
$version = '7.6.2'
$url = "https://github.com/PowerShell/PowerShell/releases/download/v$version/PowerShell-$version-win-x64.zip"
Write-Host "Downloading PowerShell $version from $url"
Invoke-WebRequest -Uri $url -OutFile pwsh76.zip
Expand-Archive -Path pwsh76.zip -DestinationPath pwsh76 -Force
& "$PWD\pwsh76\pwsh.exe" --version
- name: Install Pester 5.3.1 (current-user; visible to PS 7.4 and 7.6)
shell: pwsh
run: Install-Module -Name Pester -RequiredVersion 5.3.1 -Force -SkipPublisherCheck -Scope CurrentUser
- name: Run Pester E2E (PowerShell 7.6 / .NET 10)
shell: powershell
run: |
export DOTNET_ROOT=$HOME/.dotnet
chmod +x build.sh
$GITHUB_WORKSPACE//build.sh --verbosity=diagnostic --target=CI --testExecutionType=unit
- name: Upload MacOS build results
uses: actions/upload-artifact@v4
# Always upload build results
$pwsh76 = "$env:GITHUB_WORKSPACE\pwsh76\pwsh.exe"
$script = @'
# ErrorActionPreference=Continue so that Invoke-Tests.ps1's expected Write-Error
# on two intentionally-broken-pack nuspecs doesn't abort before Pester starts.
$ErrorActionPreference = 'Continue'
Set-Location $env:GITHUB_WORKSPACE
Write-Host "PowerShell version: $($PSVersionTable.PSVersion); .NET: $([System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription)"
$pkg = Get-ChildItem -Path code_drop -Recurse -Filter '*.nupkg' | Where-Object Name -Match 'chocolatey\.\d' | Select-Object -First 1
if (-not $pkg) { throw "Could not find the built chocolatey nupkg under code_drop" }
Write-Host "Testing package: $($pkg.FullName)"
& "$env:GITHUB_WORKSPACE\Invoke-Tests.ps1" -TestPackage $pkg.FullName
# Make CI faithfully reflect Pester pass/fail: Invoke-Tests.ps1 doesn't propagate
# Pester results, so parse the NUnit-format testResults.xml and exit non-zero
# when any test failed or errored.
$results = Get-ChildItem -Path . -Recurse -Filter 'testResults.xml' -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $results) {
Write-Error "No testResults.xml produced - Pester did not complete"
exit 1
}
Write-Host "Pester results: $($results.FullName)"
[xml]$xml = Get-Content -LiteralPath $results.FullName
$root = $xml.'test-results'
$total = [int]$root.total
$failed = [int]$root.failures + [int]$root.errors
$notRun = [int]$root.'not-run'
Write-Host ("Pester totals: total={0} failures+errors={1} not-run={2}" -f $total, $failed, $notRun)
if ($failed -gt 0) {
Write-Error "$failed Pester test(s) failed/errored"
exit 1
}
'@
Set-Content -Path pester-runner.ps1 -Value $script -Encoding utf8
& $pwsh76 -NoLogo -NoProfile -File pester-runner.ps1
- name: Upload Pester results
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: macos-build-results
name: pester-results
path: |
code_drop/TestResults/issues-report.html
code_drop/TestResults/NUnit/TestResult.xml
code_drop/Packages/NuGet/*.nupkg
code_drop/MsBuild.log
# Build using Mono in Docker on Ubuntu
docker-build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
file: docker/Dockerfile.linux
push: false
tags: chocolatey/choco:latest
testResults.xml
**/testResults.xml
60 changes: 60 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Self-Contained Smoke Test

# Proves the migration's core goal: a self-contained choco.exe that runs on a
# clean Windows box with NO .NET runtime installed and no framework/reboot.
# It publishes the single-file self-contained choco.exe and runs it inside a
# Windows Server Core container that has no .NET runtime.

on:
push:
pull_request:
workflow_dispatch:

jobs:
clean-container-smoke:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install .NET 10 SDK
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
10.0.x
- name: Generate placeholder SolutionVersion.cs
shell: pwsh
run: |
@'
using System.Reflection;
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0-smoke")]
[assembly: AssemblyCompany("Chocolatey Software, Inc.")]
[assembly: AssemblyProduct("Chocolatey")]
[assembly: AssemblyCopyright("Copyright (c) 2017 - 2026 Chocolatey Software, Inc.")]
'@ | Set-Content -Path src/SolutionVersion.cs -Encoding utf8
- name: Publish self-contained single-file choco.exe
shell: pwsh
run: >
dotnet publish src/chocolatey.console/chocolatey.console.csproj
-c Release -r win-x64 --self-contained
-p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true
-o pub
- name: Run choco.exe in a clean Server Core container (no .NET runtime)
shell: pwsh
run: |
$image = "mcr.microsoft.com/windows/servercore:ltsc2022"
Write-Host "Pulling $image ..."
docker pull $image
Write-Host "Running 'choco --version' inside the container (no .NET installed)..."
$version = docker run --rm -v "${{ github.workspace }}\pub:C:\choco" $image C:\choco\choco.exe --version
if ($LASTEXITCODE -ne 0) { throw "choco.exe exited with code $LASTEXITCODE inside the clean container" }
Write-Host "choco --version => $version"
if ([string]::IsNullOrWhiteSpace($version)) { throw "choco.exe produced no version output" }
- name: Run choco list / source list in the clean container (informational)
shell: pwsh
continue-on-error: true
run: |
$image = "mcr.microsoft.com/windows/servercore:ltsc2022"
docker run --rm -v "${{ github.workspace }}\pub:C:\choco" $image cmd /c "C:\choco\choco.exe source list & C:\choco\choco.exe list"
79 changes: 2 additions & 77 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,6 @@ on:
workflow_dispatch:

jobs:
# Build and test using mono on Ubuntu
ubuntu-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache Tools
uses: actions/cache@v4
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install Mono
run: |
sudo apt install ca-certificates gnupg
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
sudo apt install -y mono-complete
mono --version
- name: Install dotnet #needed for GitVersion
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
5.0.x
- name: Report installed dotnet versions
run: |
dotnet --info
- name: Test with NUnit on Mono
run: |
chmod +x build.sh
$GITHUB_WORKSPACE//build.sh --verbosity=diagnostic --target=test --testExecutionType=all
- name: Upload Ubuntu build results
uses: actions/upload-artifact@v4
# Always upload build results
if: ${{ always() }}
with:
name: ubuntu-build-results
path: |
code_drop/TestResults/issues-report.html
code_drop/TestResults/NUnit/TestResult.xml
code_drop/MsBuild.log
# Build and test on Windows
windows-build:
runs-on: windows-latest
Expand All @@ -63,11 +21,12 @@ jobs:
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install dotnet #needed for GitVersion
- name: Install dotnet # 5.0.x for GitVersion, 10.0.x for the build
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
5.0.x
10.0.x
- name: Report installed dotnet versions
run: |
dotnet --info
Expand All @@ -85,37 +44,3 @@ jobs:
code_drop\TestCoverage\lcov.info
code_drop\TestCoverage\OpenCover.xml
code_drop\MsBuild.log
# Build and test using mono on MacOS
macos-build:
runs-on: macos-14
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Cache Tools
uses: actions/cache@v4
with:
path: tools
key: ${{ runner.os }}-tools-${{ hashFiles('recipe.cake') }}
- name: Install dotnet #needed for GitVersion
uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
with:
dotnet-version: |
5.0.x
- name: Report installed dotnet versions
run: |
dotnet --info
- name: Test with NUnit on Mono
run: |
chmod +x build.sh
$GITHUB_WORKSPACE//build.sh --verbosity=diagnostic --target=test --testExecutionType=all
- name: Upload MacOS build results
uses: actions/upload-artifact@v4
# Always upload build results
if: ${{ always() }}
with:
name: macos-build-results
path: |
code_drop/TestResults/issues-report.html
code_drop/TestResults/NUnit/TestResult.xml
code_drop/MsBuild.log
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ code_drop/
src/chocolatey.install/assets/Install.ps1

# This project uses an editorconfig file maintained via a nuget package, so do not commit any of these to the repo
.editorconfig
.editorconfig

# Temp
CLAUDE.md
/tmp
9 changes: 7 additions & 2 deletions Invoke-Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ else {

if (-not (Test-Path "$TestPath/packages") -or -not $SkipPackaging) {
$null = New-Item -Path "$TestPath/packages" -ItemType Directory -Force
# Get and pack packages
$nuspecs = Get-ChildItem -Path $PSScriptRoot/src/chocolatey.tests.integration, $PSScriptRoot/tests/packages -Recurse -Include *.nuspec | Where-Object FullName -NotMatch 'bin'
# Get and pack packages.
# tests/pester-tests/commands/testpackages is also included so the in-repo Pester
# testpackages (zip-log-disable-test, packagewithscript, installpackage, ...) are
# seeded into the 'hermes' source the same way Test Kitchen seeds them. Without
# this, ~10 Pester Contexts fail with "package was not found with the source(s)
# listed" outside Test Kitchen even on a healthy build.
$nuspecs = Get-ChildItem -Path $PSScriptRoot/src/chocolatey.tests.integration, $PSScriptRoot/tests/packages, $PSScriptRoot/tests/pester-tests/commands/testpackages -Recurse -Include *.nuspec | Where-Object FullName -NotMatch 'bin'
Get-ChildItem -Path $PSScriptRoot/tests/packages -Recurse -Include *.nupkg | Copy-Item -Destination "$TestPath/packages"

$packFailures = foreach ($file in $nuspecs) {
Expand Down
Loading