Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
472 changes: 261 additions & 211 deletions .azure-pipelines/release.yml

Large diffs are not rendered by default.

24 changes: 21 additions & 3 deletions .azure-pipelines/scripts/install-vs-cpp-workload.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ $cppWorkloads = @(
'Microsoft.VisualStudio.Workload.VCTools'
)

# ARM64 cross-compilation requires an additional component that is not
# included in the default C++ workload install. We ensure it's present
# so that vcpkg and MSBuild can target arm64-windows triplets even when
# running on an x64 host (or on an ARM64 host that only has the default
# ARM64 → ARM64 native tools and not the broader "all targets" set).
$arm64Component = 'Microsoft.VisualStudio.Component.VC.Tools.ARM64'

function Get-VsWhere {
if (Test-Path $script:vswherePath) {
return $script:vswherePath
Expand Down Expand Up @@ -106,11 +113,20 @@ function Invoke-VsSetup {
# --- Locate or bootstrap vswhere ---
$vswhereExe = Get-VsWhere

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

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

Invoke-VsSetup -ExePath $bootstrapper -Description 'VS Build Tools install' -ArgumentList @(
'--add', 'Microsoft.VisualStudio.Workload.VCTools',
'--add', $arm64Component,
'--includeRecommended',
'--quiet',
'--norestart',
Expand All @@ -151,6 +168,7 @@ if (-not $install) {
'modify',
'--installPath', $install.installationPath,
'--add', $workload,
'--add', $arm64Component,
'--includeRecommended',
'--quiet',
'--norestart',
Expand Down
22 changes: 8 additions & 14 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,14 @@ jobs:
path: MicrosoftGit

build:
runs-on: windows-2025
runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
name: Build and Unit Test
needs: validate

strategy:
matrix:
configuration: [ Release ]
architecture: [ x64, arm64 ]
fail-fast: false

steps:
Expand Down Expand Up @@ -290,47 +291,40 @@ jobs:
if: steps.skip.outputs.result != 'true'
uses: microsoft/setup-msbuild@v3.0.0

- name: Install vcpkg native dependencies
if: steps.skip.outputs.result != 'true'
shell: cmd
run: |
"%VCPKG_INSTALLATION_ROOT%\vcpkg.exe" install --triplet x64-windows-static-aot --x-install-root=out\vcpkg_installed\static --x-manifest-root=src || exit /b 1
"%VCPKG_INSTALLATION_ROOT%\vcpkg.exe" install --triplet x64-windows-dynamic --x-install-root=out\vcpkg_installed\dynamic --x-manifest-root=src || exit /b 1

- name: Build VFS for Git
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\Build.bat ${{ matrix.configuration }}
run: src\scripts\Build.bat ${{ matrix.configuration }} 0.2.173.2 minimal ${{ matrix.architecture }}

- name: Run unit tests
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\RunUnitTests.bat ${{ matrix.configuration }}
run: src\scripts\RunUnitTests.bat ${{ matrix.configuration }} ${{ matrix.architecture }}

- name: Create build artifacts
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts ${{ matrix.architecture }}

- name: Upload functional tests drop
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: FunctionalTests_${{ matrix.configuration }}
name: FunctionalTests_${{ matrix.configuration }}_${{ matrix.architecture }}
path: artifacts\GVFS.FunctionalTests

- name: Upload FastFetch drop
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: FastFetch_${{ matrix.configuration }}
name: FastFetch_${{ matrix.configuration }}_${{ matrix.architecture }}
path: artifacts\FastFetch

- name: Upload GVFS installer
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: GVFS_${{ matrix.configuration }}
name: GVFS_${{ matrix.configuration }}_${{ matrix.architecture }}
path: artifacts\GVFS.Installers

functional_tests:
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/functional-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
strategy:
matrix:
configuration: [ Release ]
architecture: [ x86_64, arm64 ]
architecture: [ x64, arm64 ]
nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # 12 parallel jobs to speed up the tests
fail-fast: false # most failures are flaky tests, no need to stop the other jobs from succeeding

Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: GVFS_${{ matrix.configuration }}
name: GVFS_${{ matrix.configuration }}_${{ matrix.architecture }}
path: gvfs
repository: ${{ inputs.vfs_repository || github.repository }}
run-id: ${{ inputs.vfs_run_id || github.run_id }}
Expand All @@ -114,7 +114,7 @@ jobs:
if: steps.skip.outputs.result != 'true' && steps.download-gvfs.outcome == 'failure'
uses: actions/download-artifact@v8
with:
name: GVFS_${{ matrix.configuration }}
name: GVFS_${{ matrix.configuration }}_${{ matrix.architecture }}
path: gvfs
repository: ${{ inputs.vfs_repository || github.repository }}
run-id: ${{ inputs.vfs_run_id || github.run_id }}
Expand All @@ -126,7 +126,7 @@ jobs:
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: FunctionalTests_${{ matrix.configuration }}
name: FunctionalTests_${{ matrix.configuration }}_${{ matrix.architecture }}
path: ft
repository: ${{ inputs.vfs_repository || github.repository }}
run-id: ${{ inputs.vfs_run_id || github.run_id }}
Expand All @@ -136,7 +136,7 @@ jobs:
if: steps.skip.outputs.result != 'true' && steps.download-ft.outcome == 'failure'
uses: actions/download-artifact@v8
with:
name: FunctionalTests_${{ matrix.configuration }}
name: FunctionalTests_${{ matrix.configuration }}_${{ matrix.architecture }}
path: ft
repository: ${{ inputs.vfs_repository || github.repository }}
run-id: ${{ inputs.vfs_run_id || github.run_id }}
Expand All @@ -147,7 +147,7 @@ jobs:
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: FastFetch_${{ matrix.configuration }}
name: FastFetch_${{ matrix.configuration }}_${{ matrix.architecture }}
path: ft
repository: ${{ inputs.vfs_repository || github.repository }}
run-id: ${{ inputs.vfs_run_id || github.run_id }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/upgrade-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ jobs:
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: GVFS_${{ matrix.configuration }}
name: GVFS_${{ matrix.configuration }}_x64
path: gvfs-new

- name: Download current GVFS installer (retry)
if: steps.skip.outputs.result != 'true' && steps.download-gvfs.outcome == 'failure'
uses: actions/download-artifact@v8
with:
name: GVFS_${{ matrix.configuration }}
name: GVFS_${{ matrix.configuration }}_x64
path: gvfs-new

# -- Setup --
Expand Down
28 changes: 21 additions & 7 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,28 @@
with direct downloads from the public internet.
-->
<UseTerrapinAssetCache Condition="'$(UseTerrapinAssetCache)' == ''">false</UseTerrapinAssetCache>

<!--
Target CPU architecture. Drives RID selection, vcpkg triplets, and the
native Platform mapping below. Default x64.
Valid values: x64, arm64 (lowercase; matches RID and vcpkg conventions).
-->
<VfsArch Condition="'$(VfsArch)' == ''">x64</VfsArch>

<!--
Native (vcxproj) Platform name corresponding to $(VfsArch).
vcxproj uses x64/ARM64 (mixed case); RID/vcpkg use x64/arm64 (lowercase).
-->
<VfsNativePlatform Condition="'$(VfsArch)' == 'arm64'">ARM64</VfsNativePlatform>
<VfsNativePlatform Condition="'$(VfsNativePlatform)' == ''">x64</VfsNativePlatform>
</PropertyGroup>

<!-- Managed project properties -->
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<LangVersion>latest</LangVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
<RuntimeIdentifier>win-$(VfsArch)</RuntimeIdentifier>
<PlatformTarget>$(VfsNativePlatform)</PlatformTarget>
<SelfContained>true</SelfContained>
<PublishAot>true</PublishAot>
<OptimizationPreference>Speed</OptimizationPreference>
Expand Down Expand Up @@ -74,7 +88,7 @@
See THIRD-PARTY-NOTICES.md for license details on these native libraries.
-->
<PropertyGroup Condition="'$(PublishAot)' == 'true'">
<VcpkgInstalledDir>$(RepoOutPath)vcpkg_installed\static\x64-windows-static-aot\</VcpkgInstalledDir>
<VcpkgInstalledDir>$(RepoOutPath)vcpkg_installed\static\$(VfsArch)-windows-static-aot\</VcpkgInstalledDir>
</PropertyGroup>

<!-- Set libgit2 library name unconditionally — all builds use vcpkg-sourced libgit2 -->
Expand Down Expand Up @@ -103,17 +117,17 @@
Copy from the vcpkg dynamic build output.
-->
<ItemGroup Condition="'$(PublishAot)' != 'true' and '$(MSBuildProjectExtension)' == '.csproj' and '$(IncludeBuildOutput)' != 'false'">
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\x64-windows-dynamic\bin\git2.dll">
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\$(VfsArch)-windows-dynamic\bin\git2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Link>git2.dll</Link>
</Content>
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\x64-windows-dynamic\bin\pcre.dll">
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\$(VfsArch)-windows-dynamic\bin\pcre.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Link>pcre.dll</Link>
</Content>
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\x64-windows-dynamic\bin\z.dll">
<Content Include="$(RepoOutPath)vcpkg_installed\dynamic\$(VfsArch)-windows-dynamic\bin\z.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Link>z.dll</Link>
Expand All @@ -122,7 +136,7 @@

<!-- Native project properties -->
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
<Platform>x64</Platform>
<Platform>$(VfsNativePlatform)</Platform>
<OutDir>$(ProjectOutPath)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectOutPath)intermediate\$(Platform)\$(Configuration)\</IntDir>
<GeneratedIncludePath>$(IntDir)include\</GeneratedIncludePath>
Expand Down
8 changes: 4 additions & 4 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@
<Error Condition="'$(UseTerrapinAssetCache)' == 'true' and ('$(TerrapinRetrievalToolPath)' == '' or !Exists('$(TerrapinRetrievalToolPath)'))"
Text="UseTerrapinAssetCache=true but TerrapinRetrievalToolPath is empty or does not exist. The release pipeline must pre-download the Microsoft.Build.Vcpkg NuGet package and pass -p:TerrapinRetrievalToolPath=&lt;path-to-TerrapinRetrievalTool.exe&gt;." />

<Exec Command="&quot;$(_VcpkgExe)&quot; install --x-wait-for-lock --triplet x64-windows-static-aot --x-install-root=&quot;$(RepoOutPath)vcpkg_installed\static&quot; $(_VcpkgManifestArg) $(_VcpkgAssetSources)"
<Exec Command="&quot;$(_VcpkgExe)&quot; install --x-wait-for-lock --triplet $(VfsArch)-windows-static-aot --x-install-root=&quot;$(RepoOutPath)vcpkg_installed\static&quot; $(_VcpkgManifestArg) $(_VcpkgAssetSources)"
StandardOutputImportance="High" StandardErrorImportance="High" />
<Exec Command="&quot;$(_VcpkgExe)&quot; install --x-wait-for-lock --triplet x64-windows-dynamic --x-install-root=&quot;$(RepoOutPath)vcpkg_installed\dynamic&quot; $(_VcpkgManifestArg) $(_VcpkgAssetSources)"
<Exec Command="&quot;$(_VcpkgExe)&quot; install --x-wait-for-lock --triplet $(VfsArch)-windows-dynamic --x-install-root=&quot;$(RepoOutPath)vcpkg_installed\dynamic&quot; $(_VcpkgManifestArg) $(_VcpkgAssetSources)"
StandardOutputImportance="High" StandardErrorImportance="High" />

<Error Condition="!Exists('$(RepoOutPath)vcpkg_installed\dynamic\x64-windows-dynamic\bin\git2.dll')"
<Error Condition="!Exists('$(RepoOutPath)vcpkg_installed\dynamic\$(VfsArch)-windows-dynamic\bin\git2.dll')"
Text="vcpkg install completed but git2.dll (dynamic) is missing. Check vcpkg output above for errors." />
<Error Condition="!Exists('$(RepoOutPath)vcpkg_installed\static\x64-windows-static-aot\lib\git2.lib')"
<Error Condition="!Exists('$(RepoOutPath)vcpkg_installed\static\$(VfsArch)-windows-static-aot\lib\git2.lib')"
Text="vcpkg install completed but git2.lib (static) is missing. Check vcpkg output above for errors." />

<Touch Files="$(_VcpkgStampFile)" AlwaysCreate="true" />
Expand Down
Loading
Loading