File: sparse-checkout.yml

package info (click to toggle)
python-azure 20251014%2Bgit-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 766,472 kB
  • sloc: python: 6,314,744; ansic: 804; javascript: 287; makefile: 198; sh: 198; xml: 109
file content (147 lines) | stat: -rw-r--r-- 6,181 bytes parent folder | download | duplicates (2)
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
parameters:
  - name: Paths
    type: object
    default: []
  - name: Repositories
    type: object
    default:
      - Name: $(Build.Repository.Name)
        Commitish: $(Build.SourceVersion)
        WorkingDirectory: $(System.DefaultWorkingDirectory)
  - name: SkipCheckoutNone
    type: boolean
    default: false
  - name: TokenToUseForAuth
    type: string
    default: ''
  - name: PreserveAuthToken
    type: boolean
    default: false

steps:
  - ${{ if not(parameters.SkipCheckoutNone) }}:
      - checkout: none

  - ${{ if ne(parameters.TokenToUseForAuth, '') }}:
    - pwsh: |
        $base64Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nobody:${{ parameters.TokenToUseForAuth }}"))
        Write-Host "##vso[task.setvariable variable=_base64AuthToken;issecret=true;]$base64Token"
        git config set --global "http.extraheader" "AUTHORIZATION: basic $base64Token"
      displayName: Setup git config auth header

  - task: PowerShell@2
    ${{ if eq(length(parameters.Repositories), 1) }}:
      displayName: 'Sparse checkout ${{ parameters.Repositories[0].Name }}'
    ${{ else }}:
      displayName: 'Sparse checkout repositories'
    inputs:
      targetType: inline
      # Define this inline, because of the chicken/egg problem with loading a script when nothing
      # has been checked out yet.
      script: |
        # Setting $PSNativeCommandArgumentPassing to 'Legacy' to use PowerShell
        # 7.2 behavior for command argument passing. Newer behaviors will result
        # in errors from git.exe.
        $PSNativeCommandArgumentPassing = 'Legacy'

        function Retry()
        {
            Run 3 @args
        }

        function Run()
        {
            $retries, $command, $arguments = $args
            if ($retries -isnot [int]) {
                $command, $arguments = $args
                $retries = 0
            }
            Write-Host "==>" $command $arguments
            $attempt = 0
            $sleep = 5

            while ($true) {
                $attempt++
                & $command $arguments
                if (!$LASTEXITCODE) { return }
                if ($attempt -gt $retries) { exit $LASTEXITCODE }
                Write-Warning "Attempt $attempt failed: $_. Trying again in $sleep seconds..."
                Start-Sleep -Seconds $sleep
                $sleep *= 2
            }
        }

        function SparseCheckout([Array]$paths, [Hashtable]$repository)
        {
            $dir = $repository.WorkingDirectory
            if (!$dir) {
              $dir = "./$($repository.Name)"
            }
            New-Item $dir -ItemType Directory -Force | Out-Null
            Push-Location $dir

            if (Test-Path .git/info/sparse-checkout) {
              $hasInitialized = $true
              Write-Host "Repository $($repository.Name) has already been initialized in $pwd. Skipping this step."
            } else {
              Write-Host "Repository $($repository.Name) is being initialized in $pwd"

              if ($repository.Commitish -match '^refs/pull/\d+/merge$') {
                Retry git clone --no-checkout --filter=tree:0 -c remote.origin.fetch=''+$($repository.Commitish):refs/remotes/origin/$($repository.Commitish)'' https://github.com/$($repository.Name) .
              } else {
                Retry git clone --no-checkout --filter=tree:0 https://github.com/$($repository.Name) .
              }

              # Turn off git GC for sparse checkout. Note: The devops checkout task does this by default
              Run git config gc.auto 0

              Run git sparse-checkout init

              # Set non-cone mode otherwise path filters will not work in git >= 2.37.0
              # See https://github.blog/2022-06-27-highlights-from-git-2-37/#tidbits
              # '/*' '!/*/' -> only checkout files in top level directory
              # '/eng' -> checkout required eng/ scripts/configs
              # '.config' -> required for files like .config/1espt/PipelineAutobaseliningConfig.yml and .config/guardian/.gdnbaselines used by 1es PT scripts
              git sparse-checkout set --no-cone '/*' '!/*/' '/eng' '/.config'
            }

            # Prevent wildcard expansion in Invoke-Expression (e.g. for checkout path '/*')
            $quotedPaths = $paths | ForEach-Object { "'$_'" }
            $gitsparsecmd = "git sparse-checkout add $quotedPaths"
            Write-Host $gitsparsecmd
            Invoke-Expression -Command $gitsparsecmd

            Write-Host "Set sparse checkout paths to:"
            Get-Content .git/info/sparse-checkout

            # sparse-checkout commands after initial checkout will auto-checkout again
            if (!$hasInitialized) {
              # Remove refs/heads/ prefix from branch names
              $commitish = $repository.Commitish -replace '^refs/heads/', ''

              # use -- to prevent git from interpreting the commitish as a path
              # This will use the default branch if repo.Commitish is empty
              Retry git -c advice.detachedHead=false checkout $commitish --
            } else {
              Write-Host "Skipping checkout as repo has already been initialized"
            }

            Pop-Location
        }

        # Paths may be sourced as a yaml object literal OR a dynamically generated variable json string.
        # If the latter, convertToJson will wrap the 'string' in quotes, so remove them.
        $paths = '${{ convertToJson(parameters.Paths) }}'.Trim('"') | ConvertFrom-Json
        # Replace windows backslash paths, as Azure Pipelines default directories are sometimes formatted like 'D:\a\1\s'
        $repositories = '${{ convertToJson(parameters.Repositories) }}' -replace '\\', '/' | ConvertFrom-Json -AsHashtable
        foreach ($repo in $Repositories) {
          SparseCheckout $paths $repo
        }
      pwsh: true
      workingDirectory: $(System.DefaultWorkingDirectory)

  - ${{ if and(ne(parameters.TokenToUseForAuth, ''), not(parameters.PreserveAuthToken)) }}:
    - pwsh: |
        git config unset --global "http.extraheader"
      displayName: Removing git config auth header
      condition: always()