From d8c00e02d5894b59e6cad862a3ca9a48aca41bac Mon Sep 17 00:00:00 2001 From: Dennis Ameling Date: Thu, 27 Feb 2025 12:05:09 +0100 Subject: [PATCH] Add support for Windows x64 and arm64 builds --- .github/workflows/continuous-integration.yml | 22 ++++++++++++++----- .github/workflows/release.yml | 21 +++++++++++++----- .../Git-Credential-Manager.csproj | 5 ++--- .../Installer.Windows.csproj | 18 ++++++++++----- src/windows/Installer.Windows/Setup.iss | 15 +++++++++++-- src/windows/Installer.Windows/layout.ps1 | 12 ++++++---- 6 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index b8da48e7b..dff2af117 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -14,6 +14,9 @@ jobs: windows: name: Windows runs-on: windows-latest + strategy: + matrix: + runtime: [win-x86, win-x64, win-arm64] steps: - uses: actions/checkout@v4 @@ -27,24 +30,31 @@ jobs: run: dotnet restore - name: Build - run: dotnet build --configuration WindowsRelease + run: | + dotnet build src/windows/Installer.Windows/Installer.Windows.csproj ` + --configuration=Release ` + --runtime=${{ matrix.runtime }} - name: Test + # GitHub's hosted runners are x64 so can test x64 and x86, but not arm64 + if: matrix.runtime != 'win-arm64' run: | - dotnet test --verbosity normal --configuration=WindowsRelease + dotnet test --verbosity normal ` + --configuration=WindowsRelease ` + --runtime=${{ matrix.runtime }} - name: Prepare artifacts shell: bash run: | mkdir -p artifacts/bin - mv out/windows/Installer.Windows/bin/Release/net472/win-x86 artifacts/bin/ - cp out/windows/Installer.Windows/bin/Release/net472/win-x86.sym/* artifacts/bin/win-x86/ - mv out/windows/Installer.Windows/bin/Release/net472/gcm*.exe artifacts/ + mv out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }}/gcm*.exe artifacts/ + mv out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }} artifacts/bin/ + cp out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }}.sym/* artifacts/bin/${{ matrix.runtime }}/ - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: win-x86 + name: ${{ matrix.runtime }} path: | artifacts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c8b32151f..fb38c470f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -146,6 +146,9 @@ jobs: runs-on: windows-latest environment: release needs: prereqs + strategy: + matrix: + runtime: [win-x86, win-x64, win-arm64] steps: - uses: actions/checkout@v4 @@ -156,18 +159,23 @@ jobs: - name: Build run: | - dotnet build --configuration=WindowsRelease + dotnet build src/windows/Installer.Windows/Installer.Windows.csproj ` + --configuration=Release ` + --runtime=${{ matrix.runtime }} - name: Run Windows unit tests + # GitHub's hosted runners are x64 so can test x64 and x86, but not arm64 + if: matrix.runtime != 'win-arm64' run: | - dotnet test --configuration=WindowsRelease + dotnet test --configuration=WindowsRelease --runtime=${{ matrix.runtime }} - name: Lay out Windows payload and symbols run: | cd $env:GITHUB_WORKSPACE\src\windows\Installer.Windows\ - ./layout.ps1 -Configuration WindowsRelease ` + ./layout.ps1 -Configuration Release ` -Output $env:GITHUB_WORKSPACE\payload ` - -SymbolOutput $env:GITHUB_WORKSPACE\symbols + -SymbolOutput $env:GITHUB_WORKSPACE\symbols ` + -RuntimeIdentifier ${{ matrix.runtime }} - name: Log into Azure uses: azure/login@v2 @@ -198,9 +206,10 @@ jobs: run: | dotnet build $env:GITHUB_WORKSPACE\src\windows\Installer.Windows ` /p:PayloadPath=$env:GITHUB_WORKSPACE\payload /p:NoLayout=true ` - --configuration=WindowsRelease + --configuration=WindowsRelease ` + --runtime=${{ matrix.runtime }} mkdir installers - Move-Item -Path .\out\windows\Installer.Windows\bin\Release\net472\*.exe ` + Move-Item -Path .\out\windows\Installer.Windows\bin\Release\net472\${{ matrix.runtime }}\gcm*.exe ` -Destination $env:GITHUB_WORKSPACE\installers - name: Sign installers with Azure Code Signing diff --git a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj index 456adf547..8c469897e 100644 --- a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj +++ b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj @@ -1,11 +1,10 @@ - + Exe net8.0 net472;net8.0 - win-x86;osx-x64;linux-x64;osx-arm64;linux-arm64;linux-arm - x86 + win-x86;win-x64;win-arm64;osx-x64;linux-x64;osx-arm64;linux-arm64;linux-arm git-credential-manager GitCredentialManager $(RepoAssetsPath)gcmicon.ico diff --git a/src/windows/Installer.Windows/Installer.Windows.csproj b/src/windows/Installer.Windows/Installer.Windows.csproj index bbd49a291..7be79ce88 100644 --- a/src/windows/Installer.Windows/Installer.Windows.csproj +++ b/src/windows/Installer.Windows/Installer.Windows.csproj @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ net472 false false - $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\win-x86 + $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\$(RuntimeIdentifier) 6.3.1 @@ -27,12 +27,20 @@ - "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" - "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" + "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system /DGcmRuntimeIdentifier="$(RuntimeIdentifier)" "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" + "$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user /DGcmRuntimeIdentifier="$(RuntimeIdentifier)" "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)" - + + + + + + diff --git a/src/windows/Installer.Windows/Setup.iss b/src/windows/Installer.Windows/Setup.iss index f03d16c9b..c15efe6d8 100644 --- a/src/windows/Installer.Windows/Setup.iss +++ b/src/windows/Installer.Windows/Setup.iss @@ -15,6 +15,10 @@ #error Installer target property 'InstallTarget' must be specifed #endif +#ifndef GcmRuntimeIdentifier + #error GCM Runtime Identifier 'GcmRuntimeIdentifier' must be specifed (e.g. win-x64) +#endif + #if InstallTarget == "user" #define GcmAppId "{{aa76d31d-432c-42ee-844c-bc0bc801cef3}}" #define GcmLongName "Git Credential Manager (User)" @@ -40,7 +44,6 @@ #define GcmRepoRoot "..\..\.." #define GcmAssets GcmRepoRoot + "\assets" #define GcmExe "git-credential-manager.exe" -#define GcmArch "x86" #ifnexist PayloadDir + "\" + GcmExe #error Payload files are missing @@ -67,9 +70,17 @@ AppUpdatesURL={#GcmUrl} AppContact={#GcmUrl} AppCopyright={#GcmCopyright} AppReadmeFile={#GcmReadme} +; Windows ARM64 supports installing and running x64 binaries, but not vice versa. +#if GcmRuntimeIdentifier=="win-x64" +ArchitecturesAllowed=x64compatible +ArchitecturesInstallIn64BitMode=x64compatible +#elif GcmRuntimeIdentifier=="win-arm64" +ArchitecturesAllowed=arm64 +ArchitecturesInstallIn64BitMode=arm64 +#endif VersionInfoVersion={#GcmVersion} LicenseFile={#GcmRepoRoot}\LICENSE -OutputBaseFilename={#GcmSetupExe}-win-{#GcmArch}-{#GcmVersionSimple} +OutputBaseFilename={#GcmSetupExe}-{#GcmRuntimeIdentifier}-{#GcmVersionSimple} DefaultDirName={autopf}\{#GcmShortName} Compression=lzma2 SolidCompression=yes diff --git a/src/windows/Installer.Windows/layout.ps1 b/src/windows/Installer.Windows/layout.ps1 index 070c9bf49..e7e051673 100644 --- a/src/windows/Installer.Windows/layout.ps1 +++ b/src/windows/Installer.Windows/layout.ps1 @@ -1,8 +1,13 @@ # Inputs -param ([Parameter(Mandatory)] $CONFIGURATION, [Parameter(Mandatory)] $OUTPUT, $SYMBOLOUTPUT) +param ([Parameter(Mandatory)] $CONFIGURATION, [Parameter(Mandatory)] $OUTPUT, [Parameter(Mandatory)] $RuntimeIdentifier, $SYMBOLOUTPUT) Write-Output "Output: $OUTPUT" +if ($RuntimeIdentifier -ne 'win-x86' -and $RuntimeIdentifier -ne 'win-x64' -and $RuntimeIdentifier -ne 'win-arm64') { + Write-Host "Unsupported RuntimeIdentifier: $RuntimeIdentifier" + exit 1 +} + # Directories $THISDIR = $pwd.path $ROOT = (Get-Item $THISDIR).parent.parent.parent.FullName @@ -39,15 +44,14 @@ Write-Output "Publishing core application..." dotnet publish "$GCM_SRC" ` --framework net472 ` --configuration "$CONFIGURATION" ` - --runtime win-x86 ` + --runtime $RuntimeIdentifier ` --output "$PAYLOAD" # Delete libraries that are not needed for Windows but find their way # into the publish output. Remove-Item -Path "$PAYLOAD/*.dylib" -Force -# Delete extraneous files that get included for other architectures -# We only care about x86 as the core GCM executable is only targeting x86 +# Delete extraneous files that get included for other runtimes Remove-Item -Path "$PAYLOAD/arm/" -Recurse -Force Remove-Item -Path "$PAYLOAD/arm64/" -Recurse -Force Remove-Item -Path "$PAYLOAD/x64/" -Recurse -Force