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
49 changes: 39 additions & 10 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,38 @@ on:
branches: [ master, releases/shipped ]
push:
branches: [ master, releases/shipped ]
workflow_dispatch:
inputs:
git_version:
description: 'Microsoft Git version tag to include in the build (leave empty for default)'
required: false
type: string

env:
GIT_VERSION: ${{ github.event.inputs.git_version || 'v2.50.1.vfs.0.1' }}

jobs:
validate:
runs-on: windows-2025
name: Validation
steps:
- name: Checkout source
uses: actions/checkout@v4

- name: Validate Microsoft Git version
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
& "$env:GITHUB_WORKSPACE\.github\workflows\scripts\validate_release.ps1" `
-Repository microsoft/git `
-Tag $env:GIT_VERSION && `
Write-Host ::notice title=Validation::Using microsoft/git version $env:GIT_VERSION

build:
runs-on: windows-2025
name: Build and Unit Test
needs: validate

strategy:
matrix:
Expand Down Expand Up @@ -41,6 +68,13 @@ jobs:
shell: cmd
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts

- name: Download microsoft/git installers
shell: cmd
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download %GIT_VERSION% --repo microsoft/git --pattern "Git*.exe" --dir artifacts\GVFS.Installers

- name: Upload functional tests drop
uses: actions/upload-artifact@v4
with:
Expand All @@ -59,20 +93,15 @@ jobs:
name: Installers_${{ matrix.configuration }}
path: artifacts\GVFS.Installers

- name: Upload NuGet packages
uses: actions/upload-artifact@v4
with:
name: NuGetPackages_${{ matrix.configuration }}
path: artifacts\NuGetPackages

functional_test:
runs-on: windows-2025
runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
name: Functional Tests
needs: build

strategy:
matrix:
configuration: [ Debug, Release ]
architecture: [ x86_64, arm64 ]

steps:
- name: Download installers
Expand Down Expand Up @@ -103,7 +132,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: InstallationLogs_${{ matrix.configuration }}
name: InstallationLogs_${{ matrix.configuration }}_${{ matrix.architecture }}
path: install\logs

- name: Run functional tests
Expand All @@ -117,14 +146,14 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: FunctionalTests_Results_${{ matrix.configuration }}
name: FunctionalTests_Results_${{ matrix.configuration }}_${{ matrix.architecture }}
path: TestResult.xml

- name: Upload Git trace2 output
if: always()
uses: actions/upload-artifact@v4
with:
name: GitTrace2_${{ matrix.configuration }}
name: GitTrace2_${{ matrix.configuration }}_${{ matrix.architecture }}
path: C:\temp\git-trace2.log

- name: ProjFS details (post-test)
Expand Down
124 changes: 124 additions & 0 deletions .github/workflows/scripts/validate_release.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
param(
[Parameter(Mandatory=$true)]
[string]$Tag,

[Parameter(Mandatory=$true)]
[string]$Repository
)

function Write-GitHubActionsCommand {
param(
[Parameter(Mandatory=$true)]
[string]$Command,

[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$true)]
[string]$Title
)

Write-Host "::$Command title=$Title::$Message"
}


function Write-GitHubActionsWarning {
param(
[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$false)]
[string]$Title = "Warning"
)

if ($env:GITHUB_ACTIONS -eq "true") {
Write-GitHubActionsCommand -Command "warning" -Message $Message -Title $Title
} else {
Write-Host "! Warning: $Message" -ForegroundColor Yellow
}
}

function Write-GitHubActionsError {
param(
[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$false)]
[string]$Title = "Error"
)

if ($env:GITHUB_ACTIONS -eq "true") {
Write-GitHubActionsCommand -Command "error" -Message $Message -Title $Title
} else {
Write-Host "x Error: $Message" -ForegroundColor Red
}
}

if ([string]::IsNullOrWhiteSpace($Tag)) {
Write-GitHubActionsError -Message "Tag parameter is required"
exit 1
}

if ([string]::IsNullOrWhiteSpace($Repository)) {
Write-GitHubActionsError -Message "Repository parameter is required"
exit 1
}

Write-Host "Validating $Repository release '$Tag'..."

# Prepare headers for GitHub API
$headers = @{
'Accept' = 'application/vnd.github.v3+json'
'User-Agent' = 'VFSForGit-Build'
}

if ($env:GITHUB_TOKEN) {
$headers['Authorization'] = "Bearer $env:GITHUB_TOKEN"
}

# Check if the tag exists in microsoft/git repository
try {
$releaseResponse = Invoke-RestMethod `
-Uri "https://api.github.com/repos/$Repository/releases/tags/$Tag" `
-Headers $headers

Write-Host "✓ Tag '$Tag' found in $Repository" -ForegroundColor Green
Write-Host " Release : $($releaseResponse.name)"
Write-Host " Published : $($releaseResponse.published_at.ToString('u'))"

# Check if this a pre-release
if ($releaseResponse.prerelease -eq $true) {
Write-GitHubActionsWarning `
-Message "Using a pre-released version of $Repository" `
-Title "Pre-release $Repository version"
}

# Get the latest release for comparison
try {
$latestResponse = Invoke-RestMethod `
-Uri "https://api.github.com/repos/$Repository/releases/latest" `
-Headers $headers
$latestTag = $latestResponse.tag_name

# Check if this is the latest release
if ($Tag -eq $latestTag) {
Write-Host "✓ Using the latest release" -ForegroundColor Green
exit 0
}

# Not the latest!
$warningTitle = "Outdated $Repository release"
$warningMsg = "Not using latest release of $Repository (latest: $latestTag)"
Write-GitHubActionsWarning -Message $warningMsg -Title $warningTitle
} catch {
Write-GitHubActionsWarning -Message "Could not check latest release info for ${Repository}: $($_.Exception.Message)"
}
} catch {
if ($_.Exception.Response.StatusCode -eq 404) {
Write-GitHubActionsError -Message "Tag '$Tag' does not exist in $Repository"
exit 1
} else {
Write-GitHubActionsError -Message "Error validating release '$Tag': $($_.Exception.Message)"
exit 1
}
}
57 changes: 45 additions & 12 deletions GVFS/GVFS.FunctionalTests/Tools/GitHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,55 @@ public static ProcessResult InvokeGitAgainstGVFSRepo(
string command,
Dictionary<string, string> environmentVariables = null,
bool removeWaitingMessages = true,
bool removeUpgradeMessages = true)
bool removeUpgradeMessages = true,
bool removePartialHydrationMessages = true,
bool removeFSMonitorMessages = true)
{
ProcessResult result = GitProcess.InvokeProcess(gvfsRepoRoot, command, environmentVariables);
string errors = result.Errors;
string output = FilterMessages(result.Output, false, false, false, removePartialHydrationMessages, removeFSMonitorMessages);
string errors = FilterMessages(result.Errors, true, removeWaitingMessages, removeUpgradeMessages, removePartialHydrationMessages, removeFSMonitorMessages);

if (!string.IsNullOrEmpty(errors) && (removeWaitingMessages || removeUpgradeMessages))
return new ProcessResult(
output,
errors,
result.ExitCode);
}

private static IEnumerable<string> SplitLinesKeepingNewlines(string input)
{
for (int start = 0; start < input.Length; )
{
IEnumerable<string> errorLines = errors.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
IEnumerable<string> filteredErrorLines = errorLines.Where(line =>
int nextLine = input.IndexOf('\n', start) + 1;

if (nextLine == 0)
{
if (string.IsNullOrWhiteSpace(line) ||
// No more newlines, yield the rest
nextLine = input.Length;
}

yield return input.Substring(start, nextLine - start);
start = nextLine;
}
}

private static string FilterMessages(
string input,
bool removeEmptyLines,
bool removeWaitingMessages,
bool removeUpgradeMessages,
bool removePartialHydrationMessages,
bool removeFSMonitorMessages)
{
if (!string.IsNullOrEmpty(input) && (removeWaitingMessages || removeUpgradeMessages || removePartialHydrationMessages || removeFSMonitorMessages))
{
IEnumerable<string> lines = SplitLinesKeepingNewlines(input);
IEnumerable<string> filteredLines = lines.Where(line =>
{
if ((removeEmptyLines && string.IsNullOrWhiteSpace(line)) ||
(removeUpgradeMessages && line.StartsWith("A new version of VFS for Git is available.")) ||
(removeWaitingMessages && line.StartsWith("Waiting for ")))
(removeWaitingMessages && line.StartsWith("Waiting for ")) ||
(removePartialHydrationMessages && line.StartsWith("You are in a partially-hydrated checkout with ")) ||
(removeFSMonitorMessages && line.TrimEnd().EndsWith(" is incompatible with fsmonitor")))
{
return false;
}
Expand All @@ -85,13 +121,10 @@ public static ProcessResult InvokeGitAgainstGVFSRepo(
}
});

errors = filteredErrorLines.Any() ? string.Join(Environment.NewLine, filteredErrorLines) : string.Empty;
return filteredLines.Any() ? string.Join("", filteredLines) : string.Empty;
}

return new ProcessResult(
result.Output,
errors,
result.ExitCode);
return input;
}

public static void ValidateGitCommand(
Expand Down
11 changes: 0 additions & 11 deletions GVFS/GVFS.Installers/GVFS.Installers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

<ItemGroup>
<PackageReference Include="Tools.InnoSetup" Version="6.3.1" />
<PackageReference Include="GitForWindows.GVFS.Installer" Version="$(GitPackageVersion)" />
<PackageReference Include="GitForWindows.GVFS.Portable" Version="$(GitPackageVersion)" />
<PackageReference Include="MicroBuild.Core" Version="0.2.0" ExcludeAssets="none" />
</ItemGroup>

Expand All @@ -24,13 +22,8 @@

<ItemGroup>
<None Include="Setup.iss" />
<Content Include="$(PkgGitForWindows_GVFS_Installer)\tools\*" />
<Content Include="$(PkgGitForWindows_GVFS_Portable)\tools\*" />
<Content Include="install.bat" />
<Content Include="info.bat" />
<NuspecTemplate Include="GVFS.Installers.template.nuspec"
TargetPath="GVFS.Installers.nuspec"
Properties="$version$=$(GVFSVersion)" />
</ItemGroup>

<ItemGroup>
Expand All @@ -44,10 +37,6 @@
<Exec Command='"$(PkgTools_InnoSetup)\tools\ISCC.exe" /DLayoutDir="$(LayoutPath)" /DGVFSVersion=$(GVFSVersion) Setup.iss /O"$(OutputPath)"' />
</Target>

<Target Name="CreateNuspecFile" AfterTargets="CreateInstaller">
<CompileTemplatedFile Template="@(NuspecTemplate)" OutputFile="$(OutputPath)\%(TargetPath)" />
</Target>

<Target Name="CleanInstaller" BeforeTargets="AfterClean">
<ItemGroup>
<FilesToDelete Include="$(OutputPath)**\*"/>
Expand Down
15 changes: 0 additions & 15 deletions GVFS/GVFS.Installers/GVFS.Installers.template.nuspec

This file was deleted.

12 changes: 12 additions & 0 deletions GVFS/GVFS.Installers/info.bat
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,31 @@ SET VFS_BUND_PROJFSLIB=C:\Program Files\VFS for Git\ProjFS\ProjectedFSLib.dll
SET VFS_EXEC=C:\Program Files\VFS for Git\GVFS.exe
SET GIT_EXEC=C:\Program Files\Git\cmd\git.exe

REM Lookup the current Windows version
FOR /F "tokens=*" %%i IN ('powershell -Command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"') DO SET OS_VER=%%i

ECHO Print system information...
ECHO OS version: %OS_VER%
ECHO CPU architecture: %PROCESSOR_ARCHITECTURE%

ECHO.
ECHO Checking ProjFS Windows feature...
powershell -Command "Get-WindowsOptionalFeature -Online -FeatureName Client-ProjFS"

ECHO.
ECHO Checking ProjFS and GVFS services...
ECHO GVFS.Service:
sc query GVFS.Service

ECHO.
ECHO Test.GVFS.Service:
sc query Test.GVFS.Service

ECHO.
ECHO prjflt:
sc query prjflt

ECHO.
ECHO Checking ProjFS files...
IF EXIST "%SYS_PRJFLT%" (
ECHO [ FOUND ] %SYS_PRJFLT%
Expand Down
Loading
Loading