.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

393 lines
14 KiB

name: Build ILSpy
on:
push:
branches: '**'
pull_request:
branches: [ master, release/** ]
permissions:
contents: read
env:
DOTNET_SDK_VERSION: '11.0.x'
DOTNET_SDK_QUALITY: 'preview'
StagingDirectory: buildartifacts
jobs:
Build:
name: Desktop (Windows)
permissions:
packages: write # for dotnet nuget push
runs-on: windows-2025-vs2026
strategy:
fail-fast: false
matrix:
Configuration: [ Debug, Release ]
env:
BuildPlatform: Any CPU
BuildAndPublishVsix: true
defaults:
run:
shell: pwsh
steps:
- run: mkdir -p $env:StagingDirectory
- uses: actions/checkout@v6
with:
submodules: true
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
dotnet-quality: ${{ env.DOTNET_SDK_QUALITY }}
cache: true
cache-dependency-path: '**/packages.lock.json'
env:
DOTNET_INSTALL_DIR: ${{ runner.temp }}/.dotnet
DOTNET_ROOT: ${{ runner.temp }}/.dotnet
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Install dotnet-format
env:
DOTNET_FORMAT_VERSION: 10.0.100-rtm.25531.102
DOTNET_FORMAT_SOURCE: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json
run: dotnet tool install -g dotnet-format --version "${{env.DOTNET_FORMAT_VERSION}}" --source "${{env.DOTNET_FORMAT_SOURCE}}"
- name: Install wix (locked version)
run: dotnet tool install --global wix --version 6.0.2
- name: Install wix extension (locked version)
run: wix.exe extension add -g WixToolset.UI.wixext/6.0.2
- name: Get Version
id: version
run: |
.\BuildTools\ghactions-install.ps1
Get-ChildItem Env: | Where-Object {$_.Name -Match "^ILSPY_"} | %{ echo "$($_.Name)=$($_.Value)" } | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Restore the application
run: >
dotnet restore ILSpy.sln
/p:RestoreEnablePackagePruning=false
/p:Configuration=${{ matrix.configuration }}
/p:Platform="$env:BuildPlatform"
- name: Build
run: >
dotnet build ILSpy.sln --no-restore
-c ${{ matrix.configuration }}
/p:Platform="$env:BuildPlatform" /m
- name: Format check
run: dotnet-format whitespace --verify-no-changes --verbosity detailed ILSpy.sln
- name: Execute unit tests
run: >
dotnet test --solution ilspy.sln
--configuration ${{ matrix.configuration }}
--no-build --report-trx
--results-directory test-results/${{ matrix.configuration }}
- name: Upload Test Logs
uses: actions/upload-artifact@v7
if: success() || failure()
with:
name: test-results-${{ matrix.configuration }}
path: 'test-results/${{ matrix.configuration }}/*.trx'
- name: Create Test Report
uses: test-summary/action@v2
if: always()
with:
paths: "test-results/${{ matrix.configuration }}/*.trx"
folded: true
- name: Publish x64/arm64 framework-dependent/self-contained
run: .\publish.ps1 -Configuration ${{ matrix.configuration }}
- name: Zip ILSpy (framework-dependent)
run: >
7z a -tzip $env:StagingDirectory\ILSpy_binaries.zip ${{ matrix.configuration == 'release' && '''-xr!*.pdb''' || '' }}
.\ILSpy\bin\${{ matrix.configuration }}\net10.0\win-x64\publish\fwdependent\*
- name: Zip ILSpy Release (x64 self-contained)
if: matrix.configuration == 'release'
run: >
7z a -tzip $env:StagingDirectory\ILSpy_selfcontained_x64.zip '-xr!*.pdb'
.\ILSpy\bin\Release\net10.0\win-x64\publish\selfcontained\*
- name: Zip ILSpy Release (arm64 framework-dependent)
if: matrix.configuration == 'release'
run: >
7z a -tzip $env:StagingDirectory\ILSpy_binaries_arm64.zip '-xr!*.pdb'
.\ILSpy\bin\Release\net10.0\win-arm64\publish\fwdependent\*
- name: Pack NuGets
if: matrix.configuration == 'release'
run: |
dotnet pack ICSharpCode.Decompiler --no-restore
dotnet pack ICSharpCode.BamlDecompiler --no-restore
dotnet pack ICSharpCode.ILSpyX --no-restore
- name: Build Installer (x64 and arm64, framework-dependent)
if: matrix.configuration == 'release'
run: |
dotnet msbuild ILSpy.Installer.sln /t:Restore /p:Configuration="Release" /p:Platform="Any CPU"
dotnet msbuild ILSpy.Installer.sln /p:Configuration="Release" /p:Platform="Any CPU"
dotnet msbuild ILSpy.Installer.sln /p:Configuration="Release" /p:Platform="Any CPU" /p:PlatformForInstaller="ARM64"
- name: Build VS Extensions (for 2017-2019 and 2022)
if: matrix.configuration == 'release' && env.BuildAndPublishVsix == 'true'
run: |
msbuild ILSpy.VSExtensions.sln /t:Restore /p:Configuration="Release" /p:Platform="Any CPU"
msbuild ILSpy.VSExtensions.sln /p:Configuration="Release" /p:Platform="Any CPU"
- name: Verify package contents
if: matrix.configuration == 'debug'
run: |
.\BuildTools\create-filelists.ps1
git diff --exit-code
# https://github.com/actions/upload-artifact
- name: Upload VSIX (VS 2019) release build artifacts
if: matrix.configuration == 'release' && env.BuildAndPublishVsix == 'true'
uses: actions/upload-artifact@v7
with:
name: ILSpy VS Addin for VS 2017-2019 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ILSpy.AddIn\bin\${{ matrix.configuration }}\net472\*.vsix
if-no-files-found: error
- name: Upload VSIX (VS 2022) release build artifacts
if: matrix.configuration == 'release' && env.BuildAndPublishVsix == 'true'
uses: actions/upload-artifact@v7
with:
name: ILSpy VS Addin for VS 2022 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ILSpy.AddIn.VS2022\bin\${{ matrix.configuration }}\net472\*.vsix
if-no-files-found: error
- name: Upload Decompiler NuGet release build artifacts
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ICSharpCode.Decompiler NuGet Package (${{ matrix.configuration }})
path: ICSharpCode.Decompiler\bin\Release\ICSharpCode.Decompiler*.nupkg
if-no-files-found: error
- name: Publish Decompiler NuGet
if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'
run: |
dotnet nuget push "ICSharpCode.Decompiler\bin\Release\ICSharpCode.Decompiler*.nupkg" `
--api-key ${{ secrets.GITHUB_TOKEN }} `
--source https://nuget.pkg.github.com/${{ github.repository_owner }}
- name: Upload ILSpyX NuGet release build artifacts
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ICSharpCode.ILSpyX NuGet Package (${{ matrix.configuration }})
path: ICSharpCode.ILSpyX\bin\Release\ICSharpCode.ILSpyX*.nupkg
if-no-files-found: error
- name: Publish ILSpyX NuGet
if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'
run: |
dotnet nuget push "ICSharpCode.ILSpyX\bin\Release\ICSharpCode.ILSpyX*.nupkg" `
--api-key ${{ secrets.GITHUB_TOKEN }} `
--source https://nuget.pkg.github.com/${{ github.repository_owner }}
- name: Upload BamlDecompiler NuGet release build artifacts
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ICSharpCode.BamlDecompiler NuGet Package (${{ matrix.configuration }})
path: ICSharpCode.BamlDecompiler\bin\Release\ICSharpCode.BamlDecompiler*.nupkg
if-no-files-found: error
- name: Publish BamlDecompiler NuGet
if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'
run: |
dotnet nuget push "ICSharpCode.BamlDecompiler\bin\Release\ICSharpCode.BamlDecompiler*.nupkg" `
--api-key ${{ secrets.GITHUB_TOKEN }} `
--source https://nuget.pkg.github.com/${{ github.repository_owner }}
- name: Upload zip binaries build artifacts
uses: actions/upload-artifact@v7
with:
name: ILSpy ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ${{ env.StagingDirectory }}\ILSpy_binaries.zip
if-no-files-found: error
- name: Upload x64 self-contained zip (Release-only)
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ILSpy self-contained x64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ${{ env.StagingDirectory }}\ILSpy_selfcontained_x64.zip
if-no-files-found: error
- name: Upload arm64 framework-dependent zip (Release-only)
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ILSpy arm64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ${{ env.StagingDirectory }}\ILSpy_binaries_arm64.zip
if-no-files-found: error
- name: Upload x64 installer artifact
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ILSpy Installer x64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ILSpy.Installer\wix\*-x64.msi
if-no-files-found: error
- name: Upload arm64 installer artifact
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ILSpy Installer arm64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})
path: ILSpy.Installer\wix\*-arm64.msi
if-no-files-found: error
- name: Upload ilspycmd release build artifacts
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v7
with:
name: ilspycmd dotnet tool (${{ matrix.configuration }})
path: ICSharpCode.ILSpyCmd\bin\Release\ilspycmd*.nupkg
if-no-files-found: error
# Linux and macOS build the desktop solution filter, run the UI and decompiler tests on
# their own platform, and package self-contained Release bundles. NuGet packing and all
# Windows-specific packaging stay in the Windows job above. The decompiler tests need the
# ILSpy-tests submodule (the TargetNet40 configs compile against its legacy reference
# assemblies even on non-Windows); configs that genuinely need Windows (legacy csc, mcs,
# 32-bit, roundtrip) self-exclude via Tester.SupportedOnCurrentPlatform and
# [Platform("Win")]. ILSpy.Tests.Windows runs only in the Windows job by design.
Desktop:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux
- os: macos-15
platform: macos
runs-on: ${{ matrix.os }}
defaults:
run:
shell: pwsh
steps:
- run: mkdir -p $env:StagingDirectory
- uses: actions/checkout@v6
with:
submodules: true
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
dotnet-quality: ${{ env.DOTNET_SDK_QUALITY }}
cache: true
cache-dependency-path: '**/packages.lock.json'
env:
DOTNET_INSTALL_DIR: ${{ runner.temp }}/.dotnet
DOTNET_ROOT: ${{ runner.temp }}/.dotnet
- name: Get Version
id: version
run: |
./BuildTools/ghactions-install.ps1
Get-ChildItem Env: | Where-Object {$_.Name -Match "^ILSPY_"} | %{ echo "$($_.Name)=$($_.Value)" } | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Restore the application
run: >
dotnet restore ILSpy.Desktop.slnf
/p:RestoreEnablePackagePruning=false
/p:Configuration=Release
/p:Platform="Any CPU"
- name: Build
run: >
dotnet build ILSpy.Desktop.slnf --no-restore
-c Release
/p:Platform="Any CPU" /m
- name: Execute UI tests
run: >
dotnet test --project ILSpy.Tests/ILSpy.Tests.csproj
--configuration Release
--no-build --report-trx
--results-directory test-results
- name: Execute decompiler tests
run: >
dotnet test --project ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
--configuration Release
--no-build --report-trx
--results-directory test-results
- name: Upload Test Logs
uses: actions/upload-artifact@v7
if: success() || failure()
with:
name: test-results-${{ matrix.platform }}
path: 'test-results/*.trx'
- name: Create Test Report
uses: test-summary/action@v2
if: always()
with:
paths: "test-results/*.trx"
folded: true
- name: Publish (self-contained)
run: ./publish.ps1 -Configuration Release -Platform ${{ matrix.platform }}
- name: Package
run: ./BuildTools/package-${{ matrix.platform }}.ps1 -Configuration Release -Version "${{ steps.version.outputs.ILSPY_VERSION_NUMBER }}" -StagingDirectory $env:StagingDirectory
- name: Upload zip build artifact (Linux)
if: matrix.platform == 'linux'
uses: actions/upload-artifact@v7
with:
name: ILSpy Linux x64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (Release)
path: ${{ env.StagingDirectory }}/ILSpy_linux-x64_*.zip
if-no-files-found: error
- name: Upload deb build artifact
if: matrix.platform == 'linux'
uses: actions/upload-artifact@v7
with:
name: ILSpy Linux x64 deb ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (Release)
path: ${{ env.StagingDirectory }}/*.deb
if-no-files-found: error
- name: Upload rpm build artifact
if: matrix.platform == 'linux'
uses: actions/upload-artifact@v7
with:
name: ILSpy Linux x64 rpm ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (Release)
path: ${{ env.StagingDirectory }}/*.rpm
if-no-files-found: error
- name: Upload app bundle build artifact (macOS)
if: matrix.platform == 'macos'
uses: actions/upload-artifact@v7
with:
name: ILSpy macOS arm64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (Release)
path: ${{ env.StagingDirectory }}/ILSpy_macos-arm64_*.zip
if-no-files-found: error