-
Notifications
You must be signed in to change notification settings - Fork 466
264 lines (233 loc) · 9.31 KB
/
build.yaml
File metadata and controls
264 lines (233 loc) · 9.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
name: VFS for Git
run-name: ${{ inputs.run_name || 'VFS for Git' }}
on:
pull_request:
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
run_name:
description: 'Optional display name for this run (used for cross-repo automation)'
required: false
type: string
permissions:
contents: read
actions: read
env:
GIT_VERSION: ${{ github.event.inputs.git_version || 'v2.53.0.vfs.0.7' }}
jobs:
validate:
runs-on: windows-2025
name: Validation
outputs:
skip: ${{ steps.check.outputs.result }}
steps:
- name: Look for prior successful runs
id: check
if: github.event.inputs.git_version == ''
uses: actions/github-script@v9
with:
github-token: ${{secrets.GITHUB_TOKEN}}
result-encoding: string
script: |
/*
* It would be nice if GitHub Actions offered a convenient way to avoid running
* successful workflow runs _again_ for the respective commit (or for a tree-same one):
* We would expect the same outcome in those cases, right?
*
* Let's check for such a scenario: Look for previous runs that have been successful
* and that correspond to the same commit, or at least a tree-same one. If there is
* one, skip running the build and tests _again_.
*
* There are challenges, though: We need to require those _jobs_ to succeed before PRs
* can be merged. You can mark workflow _jobs_ as required on GitHub, but not
* _workflows_. So if those jobs are now simply skipped, the requirement isn't met and
* the PR cannot be merged. We can't just skip the job. Instead, we need to run the job
* _but skip every single step_ so that the job can "succeed".
*/
try {
// Figure out workflow ID, commit and tree
const { data: run } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.runId,
});
const workflow_id = run.workflow_id;
const head_sha = run.head_sha;
const tree_id = run.head_commit.tree_id;
// See whether there is a successful run for that commit or tree
const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 500,
workflow_id,
});
// first look at commit-same runs, then at finished ones, then at in-progress ones
const rank = (a) => (a.status === 'in_progress' ? 0 : (head_sha === a.head_sha ? 2 : 1))
const demoteInProgressToEnd = (a, b) => (rank(b) - rank(a))
for (const run of runs.workflow_runs.sort(demoteInProgressToEnd)) {
if (head_sha !== run.head_sha && tree_id !== run.head_commit?.tree_id) continue
if (context.runId === run.id) continue // do not wait for the current run to finish ;-)
if (run.event === 'workflow_dispatch') continue // skip runs that were started manually: they can override the Git version
if (run.status === 'in_progress') {
// poll until the run is done
const pollIntervalInSeconds = 30
let seconds = 0
for (;;) {
console.log(`Found existing, in-progress run at ${run.html_url}; Waiting for it to finish (waited ${seconds} seconds so far)...`)
await new Promise((resolve) => { setTimeout(resolve, pollIntervalInSeconds * 1000) })
seconds += pollIntervalInSeconds
const { data: polledRun } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: run.id
})
if (polledRun.status !== 'in_progress') break
}
}
if (run.status === 'completed' && run.conclusion === 'success') {
core.notice(`Skipping: There already is a successful run: ${run.html_url}`)
return run.html_url
}
}
return ''
} catch (e) {
core.error(e)
core.warning(e)
}
- name: Checkout source
if: steps.check.outputs.result == ''
uses: actions/checkout@v6
- name: Validate Microsoft Git version
if: steps.check.outputs.result == ''
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
- 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
needs: validate
strategy:
matrix:
configuration: [ Debug, Release ]
fail-fast: false
steps:
- name: Skip this job if there is a previous successful run
if: needs.validate.outputs.skip != ''
id: skip
uses: actions/github-script@v9
with:
script: |
core.info(`Skipping: There already is a successful run: ${{ needs.validate.outputs.skip }}`)
return true
- name: Checkout source
if: steps.skip.outputs.result != 'true'
uses: actions/checkout@v6
with:
path: src
- name: Install .NET SDK
if: steps.skip.outputs.result != 'true'
uses: actions/setup-dotnet@v5
with:
global-json-file: src/global.json
- name: Add MSBuild to PATH
if: steps.skip.outputs.result != 'true'
uses: microsoft/setup-msbuild@v3.0.0
- name: Build VFS for Git
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\Build.bat ${{ matrix.configuration }}
- name: Run unit tests
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\RunUnitTests.bat ${{ matrix.configuration }}
- name: Create build artifacts
if: steps.skip.outputs.result != 'true'
shell: cmd
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts
- name: Upload functional tests drop
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: FunctionalTests_${{ matrix.configuration }}
path: artifacts\GVFS.FunctionalTests
- name: Upload FastFetch drop
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: FastFetch_${{ matrix.configuration }}
path: artifacts\FastFetch
- name: Upload GVFS installer
if: steps.skip.outputs.result != 'true'
uses: actions/upload-artifact@v7
with:
name: GVFS_${{ matrix.configuration }}
path: artifacts\GVFS.Installers
functional_tests:
name: Functional Tests
needs: [validate, build]
uses: ./.github/workflows/functional-tests.yaml
with:
skip: ${{ needs.validate.outputs.skip }}
upgrade_tests:
name: Upgrade Tests
needs: [validate, build]
uses: ./.github/workflows/upgrade-tests.yaml
with:
skip: ${{ needs.validate.outputs.skip }}
result:
runs-on: ubuntu-latest
name: Build, Unit and Functional Tests Successful
needs: [functional_tests, upgrade_tests]
steps:
- name: Success! # for easier identification of successful runs in the Checks Required for Pull Requests
run: echo "Workflow run is successful!"