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
157 changes: 50 additions & 107 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ on:

permissions:
contents: read
actions: read

env:
GIT_VERSION: ${{ github.event.inputs.git_version || 'v2.53.0.vfs.0.5' }}
Expand Down Expand Up @@ -122,6 +123,48 @@ jobs:
-Tag $env:GIT_VERSION && `
Write-Host ::notice title=Validation::Using microsoft/git version $env:GIT_VERSION

- name: Download microsoft/git installers
if: steps.check.outputs.result == ''
shell: cmd
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download %GIT_VERSION% --repo microsoft/git --pattern "Git*.exe" --dir MicrosoftGit

- name: Create Git install script
if: steps.check.outputs.result == ''
shell: cmd
run: |
>MicrosoftGit\install.bat (
echo @ECHO OFF
echo SETLOCAL
echo.
echo IF "%%PROCESSOR_ARCHITECTURE%%"=="AMD64" ^(
echo SET GIT_ARCH=64-bit
echo ^) ELSE IF "%%PROCESSOR_ARCHITECTURE%%"=="ARM64" ^(
echo SET GIT_ARCH=arm64
echo ^) ELSE ^(
echo ECHO Unknown architecture: %%PROCESSOR_ARCHITECTURE%%
echo exit 1
echo ^)
echo.
echo FOR /F "tokens=* USEBACKQ" %%%%F IN ^( `where /R %%~dp0 Git*-%%GIT_ARCH%%.exe` ^) DO SET GIT_INSTALLER=%%%%F
echo.
echo SET LOGDIR=%%~dp0\logs
echo IF EXIST %%LOGDIR%% ^( rmdir /S /Q %%LOGDIR%% ^)
echo mkdir %%LOGDIR%%
echo.
echo ECHO Installing Git ^(%%GIT_ARCH%%^)...
echo %%GIT_INSTALLER%% /LOG="%%LOGDIR%%\git.log" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLOWDOWNGRADE=1
)

- name: Upload microsoft/git installers
if: steps.check.outputs.result == ''
uses: actions/upload-artifact@v7
with:
name: MicrosoftGit
path: MicrosoftGit

build:
runs-on: windows-2025
name: Build and Unit Test
Expand Down Expand Up @@ -173,14 +216,6 @@ jobs:
shell: cmd
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts

- name: Download microsoft/git installers
if: steps.skip.outputs.result != 'true'
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
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
Expand All @@ -195,116 +230,24 @@ jobs:
name: FastFetch_${{ matrix.configuration }}
path: artifacts\FastFetch

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

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

strategy:
matrix:
configuration: [ Debug, Release ]
architecture: [ x86_64, arm64 ]
nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 10 parallel jobs to speed up the tests
fail-fast: false # most failures are flaky tests, no need to stop the other jobs from succeeding

steps:
- name: Skip this job if there is a previous successful run
if: needs.validate.outputs.skip != ''
id: skip
uses: actions/github-script@v8
with:
script: |
core.info(`Skipping: There already is a successful run: ${{ needs.validate.outputs.skip }}`)
return true

- name: Download installers
if: steps.skip.outputs.result != 'true'
uses: actions/download-artifact@v8
with:
name: Installers_${{ matrix.configuration }}
path: install

- name: Download functional tests drop
if: steps.skip.outputs.result != 'true'
uses: actions/download-artifact@v8
with:
name: FunctionalTests_${{ matrix.configuration }}
path: ft

- name: ProjFS details (pre-install)
if: steps.skip.outputs.result != 'true'
shell: cmd
run: install\info.bat

- name: Install product
if: steps.skip.outputs.result != 'true'
shell: cmd
run: install\install.bat

- name: ProjFS details (post-install)
if: steps.skip.outputs.result != 'true'
shell: cmd
run: install\info.bat

- name: Upload installation logs
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: InstallationLogs_${{ matrix.configuration }}_${{ matrix.architecture }}-${{ matrix.nr }}
path: install\logs

- name: Run functional tests
if: steps.skip.outputs.result != 'true'
shell: cmd
run: |
SET PATH=C:\Program Files\VFS for Git;%PATH%
SET GIT_TRACE2_PERF=C:\temp\git-trace2.log
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci --slice=${{ matrix.nr }},10

- name: Upload functional test results
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: FunctionalTests_Results_${{ matrix.configuration }}_${{ matrix.architecture }}-${{ matrix.nr }}
path: TestResult.xml

- name: Upload Git trace2 output
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: GitTrace2_${{ matrix.configuration }}_${{ matrix.architecture }}-${{ matrix.nr }}
path: C:\temp\git-trace2.log

- name: ProjFS details (post-test)
if: always() && steps.skip.outputs.result != 'true'
shell: cmd
run: install\info.bat

ft_results:
runs-on: ubuntu-latest # quickest runners
name: Functional Tests
needs: [functional_test]

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

steps:
- name: Success! # for easier identification of successful runs in the Checks Required for Pull Requests
run: echo "All functional test jobs successful for ${{ matrix.configuration }} / ${{ matrix.architecture }}!"
uses: ./.github/workflows/functional-tests.yaml
with:
skip: ${{ needs.validate.outputs.skip }}

result:
runs-on: ubuntu-latest
name: Build, Unit and Functional Tests Successful
needs: [functional_test]
needs: [functional_tests]

steps:
- name: Success! # for easier identification of successful runs in the Checks Required for Pull Requests
Expand Down
162 changes: 162 additions & 0 deletions .github/workflows/functional-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
name: Functional Tests

on:
workflow_call:
inputs:
vfs_run_id:
description: 'Workflow run ID to download FT executables and GVFS installer from (defaults to the calling run)'
required: false
type: string
default: ''
git_repository:
description: 'Repository to download the Git installer artifact from (defaults to the calling repository)'
required: false
type: string
default: ''
git_run_id:
description: 'Workflow run ID to download the Git installer artifact from (defaults to the calling run)'
required: false
type: string
default: ''
git_artifact_name:
description: 'Name of the artifact containing the Git installer (must include an install.bat script)'
required: false
type: string
default: 'MicrosoftGit'
skip:
description: 'URL of a previous successful run; if non-empty, all steps are skipped (job still succeeds for required checks)'
required: false
type: string
default: ''
output_prefix:
description: 'Prefix for uploaded artifact names (e.g. "VFSForGit" to namespace artifacts in cross-repo runs)'
required: false
type: string
default: ''
secrets:
vfs_token:
description: 'Token for downloading VFSForGit artifacts (required for cross-repository downloads; defaults to GITHUB_TOKEN)'
required: false
git_token:
description: 'Token for downloading the Git installer artifact (required for cross-repository downloads; defaults to GITHUB_TOKEN)'
required: false

permissions:
contents: read
actions: read

jobs:
functional_test:
runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
name: Test

env:
ARTIFACT_PREFIX: ${{ inputs.output_prefix && format('{0}_', inputs.output_prefix) || '' }}
FT_MATRIX_NAME: ${{ format('{0}_{1}-{2}', matrix.configuration, matrix.architecture, matrix.nr) }}

strategy:
matrix:
configuration: [ Debug, Release ]
architecture: [ x86_64, arm64 ]
nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 10 parallel jobs to speed up the tests
fail-fast: false # most failures are flaky tests, no need to stop the other jobs from succeeding

steps:
- name: Skip this job if there is a previous successful run
if: inputs.skip != ''
id: skip
uses: actions/github-script@v8
with:
script: |
core.info(`Skipping: There already is a successful run: ${{ inputs.skip }}`)
return true

- name: Download Git installer
if: steps.skip.outputs.result != 'true'
uses: actions/download-artifact@v8
with:
name: ${{ inputs.git_artifact_name }}
path: git
repository: ${{ inputs.git_repository || github.repository }}
run-id: ${{ inputs.git_run_id || github.run_id }}
github-token: ${{ secrets.git_token || github.token }}

- name: Download GVFS installer
if: steps.skip.outputs.result != 'true'
uses: actions/download-artifact@v8
with:
name: GVFS_${{ matrix.configuration }}
path: gvfs
repository: microsoft/VFSForGit
run-id: ${{ inputs.vfs_run_id || github.run_id }}
github-token: ${{ secrets.vfs_token || github.token }}

- name: Download functional tests drop
if: steps.skip.outputs.result != 'true'
uses: actions/download-artifact@v8
with:
name: FunctionalTests_${{ matrix.configuration }}
path: ft
repository: microsoft/VFSForGit
run-id: ${{ inputs.vfs_run_id || github.run_id }}
github-token: ${{ secrets.vfs_token || github.token }}

- name: ProjFS details (pre-install)
if: steps.skip.outputs.result != 'true'
shell: cmd
continue-on-error: true
run: gvfs\info.bat

- name: Install Git
if: steps.skip.outputs.result != 'true'
shell: cmd
run: git\install.bat

- name: Install VFS for Git
if: steps.skip.outputs.result != 'true'
shell: cmd
run: gvfs\install.bat

- name: ProjFS details (post-install)
if: steps.skip.outputs.result != 'true'
shell: cmd
continue-on-error: true
run: gvfs\info.bat

- name: Upload installation logs
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
continue-on-error: true
with:
name: ${{ env.ARTIFACT_PREFIX }}InstallationLogs_${{ env.FT_MATRIX_NAME }}
path: |
git\logs
gvfs\logs

- name: Run functional tests
if: steps.skip.outputs.result != 'true'
shell: cmd
run: |
SET PATH=C:\Program Files\VFS for Git;%PATH%
SET GIT_TRACE2_PERF=C:\temp\git-trace2.log
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci --slice=${{ matrix.nr }},10

- name: Upload functional test results
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: ${{ env.ARTIFACT_PREFIX }}FunctionalTests_Results_${{ env.FT_MATRIX_NAME }}
path: TestResult.xml

- name: Upload Git trace2 output
if: always() && steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: ${{ env.ARTIFACT_PREFIX }}GitTrace2_${{ env.FT_MATRIX_NAME }}
path: C:\temp\git-trace2.log

- name: ProjFS details (post-test)
if: always() && steps.skip.outputs.result != 'true'
shell: cmd
continue-on-error: true
run: gvfs\info.bat
18 changes: 2 additions & 16 deletions GVFS/GVFS.Installers/install.bat
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
@ECHO OFF
SETLOCAL

REM Determine the correct architecture for the installer
IF "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
SET GIT_ARCH=64-bit
) ELSE IF "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
SET GIT_ARCH=arm64
) ELSE (
ECHO Unknown architecture: %PROCESSOR_ARCHITECTURE%
exit 1
)

REM Lookup full paths to Git and VFS for Git installers
FOR /F "tokens=* USEBACKQ" %%F IN ( `where /R %~dp0 Git*-%GIT_ARCH%.exe` ) DO SET GIT_INSTALLER=%%F
REM Lookup full path to VFS for Git installer
FOR /F "tokens=* USEBACKQ" %%F IN ( `where /R %~dp0 SetupGVFS*.exe` ) DO SET GVFS_INSTALLER=%%F

REM Create new empty directory for logs
Expand All @@ -22,8 +11,5 @@ IF EXIST %LOGDIR% (
)
mkdir %LOGDIR%

ECHO Installing Git (%GIT_ARCH%)...
%GIT_INSTALLER% /LOG="%LOGDIR%\git.log" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /ALLOWDOWNGRADE=1

ECHO Installing VFS for Git...
%GVFS_INSTALLER% /LOG="%LOGDIR%\gvfs.log" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /DIR="C:\Program Files\VFS for Git"
%GVFS_INSTALLER% /LOG="%LOGDIR%\gvfs.log" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /DIR="C:\Program Files\VFS for Git"
Loading