Skip to content

Commit c3c208a

Browse files
committed
Add ARM64 to ADO release pipeline
Restructures the release pipeline to build, ESRP-sign, and publish both x64 and ARM64 installers in parallel. Uses the same ${{ each }} pattern as microsoft/git's release pipeline (1ES templates don't support strategy.matrix). Changes: * .azure-pipelines/release.yml: single Build job replaced with a build_matrix parameter that generates Build_x64 and Build_arm64 jobs. Each job runs on its native pool (GitClientPME-1ESHostedPool- intel-pc for x64, GitClientPME-1ESHostedPool-arm64-pc for arm64), builds with the arch arg to Build.bat, signs its own payload and installer via ESRP, and stages arch-suffixed pipeline artifacts. The release stage downloads both Installer_x64 and Installer_arm64 and publishes both SetupGVFS.<v>.exe and SetupGVFS.<v>-arm64.exe as assets on the same draft GitHub Release. * scripts/CreateBuildArtifacts.bat: gains an optional 3rd ARCH arg (default x64) to select the correct win-<arch> output paths. * .github/workflows/build.yaml: passes matrix.architecture to CreateBuildArtifacts.bat. Assisted-by: Claude Opus 4.7 Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
1 parent 14dd818 commit c3c208a

9 files changed

Lines changed: 318 additions & 224 deletions

File tree

.azure-pipelines/release.yml

Lines changed: 243 additions & 211 deletions
Large diffs are not rendered by default.

.azure-pipelines/scripts/install-vs-cpp-workload.ps1

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ $cppWorkloads = @(
5454
'Microsoft.VisualStudio.Workload.VCTools'
5555
)
5656

57+
# ARM64 cross-compilation requires an additional component that is not
58+
# included in the default C++ workload install. We ensure it's present
59+
# so that vcpkg and MSBuild can target arm64-windows triplets even when
60+
# running on an x64 host (or on an ARM64 host that only has the default
61+
# ARM64 → ARM64 native tools and not the broader "all targets" set).
62+
$arm64Component = 'Microsoft.VisualStudio.Component.VC.Tools.ARM64'
63+
5764
function Get-VsWhere {
5865
if (Test-Path $script:vswherePath) {
5966
return $script:vswherePath
@@ -106,11 +113,20 @@ function Invoke-VsSetup {
106113
# --- Locate or bootstrap vswhere ---
107114
$vswhereExe = Get-VsWhere
108115

109-
# --- Quick exit if a VS install with the C++ workload is already present ---
116+
# --- Quick exit if a VS install with the C++ workload AND arm64 tools is already present ---
117+
# Check requires a C++ workload (either one) AND the ARM64 component.
118+
# vswhere -requires with -requiresAny means "any one of the listed components".
119+
# To enforce AND, we run vswhere with the ARM64 component as a hard requirement
120+
# and the C++ workloads as a separate check.
110121
$existing = Find-VsInstall -VswhereExe $vswhereExe -RequiredWorkloads $cppWorkloads
111122
if ($existing) {
112-
Write-Host "VS install with C++ workload already present: $($existing.installationPath) ($($existing.productId))"
113-
exit 0
123+
# Also check for ARM64 component
124+
$arm64Present = Find-VsInstall -VswhereExe $vswhereExe -RequiredWorkloads @($arm64Component)
125+
if ($arm64Present) {
126+
Write-Host "VS install with C++ workload + ARM64 tools already present: $($existing.installationPath) ($($existing.productId))"
127+
exit 0
128+
}
129+
Write-Host "VS install has C++ workload but missing ARM64 tools; will add..."
114130
}
115131

116132
# --- Find any VS install (regardless of workloads) ---
@@ -126,6 +142,7 @@ if (-not $install) {
126142

127143
Invoke-VsSetup -ExePath $bootstrapper -Description 'VS Build Tools install' -ArgumentList @(
128144
'--add', 'Microsoft.VisualStudio.Workload.VCTools',
145+
'--add', $arm64Component,
129146
'--includeRecommended',
130147
'--quiet',
131148
'--norestart',
@@ -151,6 +168,7 @@ if (-not $install) {
151168
'modify',
152169
'--installPath', $install.installationPath,
153170
'--add', $workload,
171+
'--add', $arm64Component,
154172
'--includeRecommended',
155173
'--quiet',
156174
'--norestart',

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ jobs:
304304
- name: Create build artifacts
305305
if: steps.skip.outputs.result != 'true'
306306
shell: cmd
307-
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts
307+
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts ${{ matrix.architecture }}
308308

309309
- name: Upload functional tests drop
310310
if: steps.skip.outputs.result != 'true'

Directory.Build.props

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@
112112
<NativeLibrary Include="secur32.lib" />
113113
</ItemGroup>
114114

115+
<!--
116+
NativeAOT cross-compilation support. When the build host architecture
117+
differs from the target (e.g. x64 host building for arm64), ILCompiler
118+
requires an explicit PackageReference for the cross-compile runtime pack.
119+
The package is a no-op when host == target architecture.
120+
-->
121+
<ItemGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
122+
<PackageReference Include="runtime.win-arm64.Microsoft.DotNet.ILCompiler" />
123+
</ItemGroup>
124+
115125
<!--
116126
Non-AOT projects (tests) need git2.dll for runtime P/Invoke.
117127
Copy from the vcpkg dynamic build output.

Directory.Packages.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
<PackageVersion Include="Moq" Version="4.10.1" />
3737
<PackageVersion Include="NUnit3TestAdapter" Version="3.13.0" />
3838
<PackageVersion Include="NUnitLite" Version="3.12.0" />
39+
40+
<!-- NativeAOT cross-compilation: when building on an x64 host targeting
41+
arm64, ILCompiler requires an explicit PackageReference for the
42+
cross-compile runtime pack. This is a no-op when host == target. -->
43+
<PackageVersion Include="runtime.win-arm64.Microsoft.DotNet.ILCompiler" Version="10.0.9" />
3944
</ItemGroup>
4045

4146
</Project>

GVFS/GVFS.Installers/GVFS.Installers.csproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
-->
1414
<InstallerArchSuffix Condition="'$(VfsArch)' == 'arm64'">-arm64</InstallerArchSuffix>
1515
<InstallerArchSuffix Condition="'$(InstallerArchSuffix)' == ''"></InstallerArchSuffix>
16+
17+
<!--
18+
Inno Setup ArchitecturesInstallIn64BitMode / ArchitecturesAllowed value.
19+
x64 uses "x64compatible" (allows install on x64 and ARM64-via-Prism).
20+
ARM64 uses "arm64" (native ARM64 only).
21+
-->
22+
<InstallerTargetArch Condition="'$(VfsArch)' == 'arm64'">arm64</InstallerTargetArch>
23+
<InstallerTargetArch Condition="'$(InstallerTargetArch)' == ''">x64compatible</InstallerTargetArch>
1624
</PropertyGroup>
1725

1826
<ItemDefinitionGroup>
@@ -35,7 +43,7 @@
3543
</ItemGroup>
3644

3745
<Target Name="CreateInstaller" BeforeTargets="Build" Condition="'$(SkipCreateInstaller)' != 'true'">
38-
<Exec Command='"$(PkgTools_InnoSetup)\tools\ISCC.exe" /DLayoutDir="$(LayoutPath)" /DGVFSVersion=$(GVFSVersion) /DArchSuffix=$(InstallerArchSuffix) Setup.iss /O"$(OutputPath)"' />
46+
<Exec Command='"$(PkgTools_InnoSetup)\tools\ISCC.exe" /DLayoutDir="$(LayoutPath)" /DGVFSVersion=$(GVFSVersion) /DArchSuffix=$(InstallerArchSuffix) /DTargetArch=$(InstallerTargetArch) Setup.iss /O"$(OutputPath)"' />
3947
</Target>
4048

4149
<Target Name="CleanInstaller" BeforeTargets="AfterClean">

GVFS/GVFS.Installers/Setup.iss

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
#define GVFSStatuscacheTokenFileName "EnableGitStatusCacheToken.dat"
1717
#define ServiceName "GVFS.Service"
1818

19+
; Architecture directives: x64 builds allow installation on x64 and ARM64
20+
; (under Prism emulation); ARM64 builds target native ARM64 only.
21+
; ArchSuffix and TargetArch are set via /D on the ISCC command line from
22+
; GVFS.Installers.csproj; defaults handle the case where they're not set
23+
; (e.g. old invocations without the arch parameters).
24+
#ifndef TargetArch
25+
#define TargetArch "x64compatible"
26+
#endif
27+
#ifndef ArchSuffix
28+
#define ArchSuffix ""
29+
#endif
30+
1931
[Setup]
2032
AppId={{489CA581-F131-4C28-BE04-4FB178933E6D}
2133
AppName={#MyAppName}
@@ -38,8 +50,8 @@ MinVersion=10.0.17763
3850
DisableDirPage=yes
3951
DisableReadyPage=yes
4052
SetupIconFile="{#LayoutDir}\GitVirtualFileSystem.ico"
41-
ArchitecturesInstallIn64BitMode=x64compatible
42-
ArchitecturesAllowed=x64compatible
53+
ArchitecturesInstallIn64BitMode={#TargetArch}
54+
ArchitecturesAllowed={#TargetArch}
4355
WizardImageStretch=no
4456
WindowResizable=no
4557
CloseApplications=no

scripts/Build.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ FOR %%P IN (
183183
"%VFS_SRCDIR%\GVFS\GVFS.PerfProfiling\GVFS.PerfProfiling.csproj"
184184
) DO (
185185
ECHO Publishing %%~nP...
186-
dotnet publish %%P --no-restore -v:%VERBOSITY% -c %CONFIGURATION% /p:VfsArch=%ARCH% || GOTO ERROR
186+
dotnet publish %%P -v:%VERBOSITY% -c %CONFIGURATION% /p:VfsArch=%ARCH% || GOTO ERROR
187187
)
188188

189189
ECHO ^*******************************
@@ -196,7 +196,7 @@ FOR %%P IN (
196196
"%VFS_SRCDIR%\GVFS\GVFS.Installers\GVFS.Installers.csproj"
197197
) DO (
198198
ECHO Publishing %%~nP...
199-
dotnet publish %%P --no-restore -v:%VERBOSITY% -c %CONFIGURATION% /p:VfsArch=%ARCH% || GOTO ERROR
199+
dotnet publish %%P -v:%VERBOSITY% -c %CONFIGURATION% /p:VfsArch=%ARCH% || GOTO ERROR
200200
)
201201

202202
GOTO :EOF

scripts/CreateBuildArtifacts.bat

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ IF "%~2"=="" (
1414
SET OUTROOT=%2
1515
)
1616

17+
IF "%~3"=="" (
18+
SET ARCH=x64
19+
) ELSE (
20+
SET ARCH=%3
21+
)
22+
IF /I "%ARCH%"=="ARM64" SET ARCH=arm64
23+
IF /I "%ARCH%"=="X64" SET ARCH=x64
24+
1725
IF EXIST %OUTROOT% (
1826
rmdir /s /q %OUTROOT%
1927
)
@@ -33,7 +41,7 @@ ECHO ^* Collecting GVFS.Installers *
3341
ECHO ^******************************
3442
mkdir %OUTROOT%\GVFS.Installers
3543
xcopy /S /Y ^
36-
%VFS_OUTDIR%\GVFS.Installers\bin\%CONFIGURATION%\win-x64\* ^
44+
%VFS_OUTDIR%\GVFS.Installers\bin\%CONFIGURATION%\win-%ARCH%\* ^
3745
%OUTROOT%\GVFS.Installers\ || GOTO ERROR
3846

3947
ECHO ^************************
@@ -42,24 +50,25 @@ ECHO ^************************
4250
ECHO Collecting FastFetch...
4351
mkdir %OUTROOT%\FastFetch
4452
xcopy /S /Y ^
45-
%VFS_OUTDIR%\FastFetch\bin\%CONFIGURATION%\net10.0-windows10.0.17763.0\win-x64\publish\* ^
53+
%VFS_OUTDIR%\FastFetch\bin\%CONFIGURATION%\net10.0-windows10.0.17763.0\win-%ARCH%\publish\* ^
4654
%OUTROOT%\FastFetch\ || GOTO ERROR
4755

4856
ECHO ^***********************************
4957
ECHO ^* Collecting GVFS.FunctionalTests *
5058
ECHO ^***********************************
5159
mkdir %OUTROOT%\GVFS.FunctionalTests
5260
xcopy /S /Y ^
53-
%VFS_OUTDIR%\GVFS.FunctionalTests\bin\%CONFIGURATION%\net10.0-windows10.0.17763.0\win-x64\publish\* ^
61+
%VFS_OUTDIR%\GVFS.FunctionalTests\bin\%CONFIGURATION%\net10.0-windows10.0.17763.0\win-%ARCH%\publish\* ^
5462
%OUTROOT%\GVFS.FunctionalTests\ || GOTO ERROR
5563

5664
GOTO :EOF
5765

5866
:USAGE
59-
ECHO usage: %~n0%~x0 [^<configuration^>] [^<destination^>]
67+
ECHO usage: %~n0%~x0 [^<configuration^>] [^<destination^>] [^<arch^>]
6068
ECHO.
6169
ECHO configuration Solution configuration (default: Debug).
6270
ECHO destination Destination directory to copy artifacts (default: %VFS_PUBLISHDIR%).
71+
ECHO arch Target CPU architecture: x64 or arm64 (default: x64).
6372
ECHO.
6473
EXIT 1
6574

0 commit comments

Comments
 (0)