...
1parameters:
2 - name: Paths
3 type: object
4 default: []
5 - name: Repositories
6 type: object
7 default:
8 - Name: $(Build.Repository.Name)
9 Commitish: $(Build.SourceVersion)
10 WorkingDirectory: $(System.DefaultWorkingDirectory)
11 - name: SkipDefaultCheckout
12 type: boolean
13 default: false
14
15steps:
16 - ${{ if not(parameters.SkipDefaultCheckout) }}:
17 - checkout: none
18
19 - task: PowerShell@2
20 displayName: 'Sparse checkout repositories'
21 inputs:
22 targetType: inline
23 # Define this inline, because of the chicken/egg problem with loading a script when nothing
24 # has been checked out yet.
25 script: |
26 function SparseCheckout([Array]$paths, [Hashtable]$repository)
27 {
28 $dir = $repository.WorkingDirectory
29 if (!$dir) {
30 $dir = "./$($repository.Name)"
31 }
32 New-Item $dir -ItemType Directory -Force
33 Push-Location $dir
34
35 if (Test-Path .git/info/sparse-checkout) {
36 $hasInitialized = $true
37 Write-Host "Repository $($repository.Name) has already been initialized. Skipping this step."
38 } else {
39 Write-Host "Repository $($repository.Name) is being initialized."
40
41 Write-Host "git clone --no-checkout --filter=tree:0 https://github.com/$($repository.Name) ."
42 git clone --no-checkout --filter=tree:0 https://github.com/$($repository.Name) .
43
44 Write-Host "git sparse-checkout init"
45 git sparse-checkout init
46
47 Write-Host "git sparse-checkout set '/*' '!/*/' '/eng'"
48 git sparse-checkout set '/*' '!/*/' '/eng'
49 }
50
51 # Prevent wildcard expansion in Invoke-Expression (e.g. for checkout path '/*')
52 $quotedPaths = $paths | ForEach-Object { "'$_'" }
53 $gitsparsecmd = "git sparse-checkout add $quotedPaths"
54 Write-Host $gitsparsecmd
55 Invoke-Expression -Command $gitsparsecmd
56
57 Write-Host "Set sparse checkout paths to:"
58 Get-Content .git/info/sparse-checkout
59
60 # sparse-checkout commands after initial checkout will auto-checkout again
61 if (!$hasInitialized) {
62 Write-Host "git checkout $($repository.Commitish)"
63 git checkout $($repository.Commitish) # this will use the default branch if repo.Commitish is empty
64 } else {
65 Write-Host "Skipping checkout as repo has already been initialized"
66 }
67
68 Pop-Location
69 }
70
71 # Paths may be sourced as a yaml object literal OR a dynamically generated variable json string.
72 # If the latter, convertToJson will wrap the 'string' in quotes, so remove them.
73 $paths = '${{ convertToJson(parameters.Paths) }}'.Trim('"') | ConvertFrom-Json
74 # Replace windows backslash paths, as Azure Pipelines default directories are sometimes formatted like 'D:\a\1\s'
75 $repositories = '${{ convertToJson(parameters.Repositories) }}' -replace '\\', '/' | ConvertFrom-Json -AsHashtable
76 foreach ($repo in $Repositories) {
77 SparseCheckout $paths $repo
78 }
79 pwsh: true
80 workingDirectory: $(System.DefaultWorkingDirectory)
View as plain text