|
5 | 5 |
|
6 | 6 | .DESCRIPTION |
7 | 7 | Connects to GitHub using a GitHub App to generate installation access tokens and create contexts for targets. |
8 | | - This function supports recursive processing and parallel connections to multiple installations. |
9 | 8 |
|
10 | 9 | Available target types: |
11 | 10 | - User |
|
15 | 14 | .EXAMPLE |
16 | 15 | Connect-GitHubApp |
17 | 16 |
|
18 | | - Connects to GitHub as all available targets using the logged in GitHub App in parallel. |
| 17 | + Connects to GitHub as all available targets using the logged in GitHub App. |
19 | 18 |
|
20 | 19 | .EXAMPLE |
21 | 20 | Connect-GitHubApp -User 'octocat' |
|
32 | 31 |
|
33 | 32 | Connects to GitHub as the enterprise 'msx' using the logged in GitHub App. |
34 | 33 |
|
35 | | - .EXAMPLE |
36 | | - Get-GitHubAppInstallation | Connect-GitHubApp -ThrottleLimit 4 |
37 | | -
|
38 | | - Gets all app installations and connects to them in parallel with a maximum of 4 concurrent connections. |
39 | | -
|
40 | | - .EXAMPLE |
41 | | - Connect-GitHubApp -User '*' -Organization 'psmodule', 'github' -ThrottleLimit 8 |
42 | | -
|
43 | | - Connects to all users and the specified organizations in parallel with a maximum of 8 concurrent connections. |
44 | | -
|
45 | 34 | .NOTES |
46 | 35 | [Authenticating to the REST API](https://docs.github.com/rest/overview/other-authentication-methods#authenticating-for-saml-sso) |
47 | 36 |
|
|
55 | 44 | [CmdletBinding(DefaultParameterSetName = 'All Installations')] |
56 | 45 | param( |
57 | 46 | # The user account to connect to. |
58 | | - [Parameter(ParameterSetName = 'Filtered', ValueFromPipelineByPropertyName)] |
| 47 | + [Parameter(ParameterSetName = 'Filtered')] |
59 | 48 | [SupportsWildcards()] |
60 | 49 | [string[]] $User, |
61 | 50 |
|
62 | 51 | # The organization to connect to. |
63 | | - [Parameter(ParameterSetName = 'Filtered', ValueFromPipelineByPropertyName)] |
| 52 | + [Parameter(ParameterSetName = 'Filtered')] |
64 | 53 | [SupportsWildcards()] |
65 | 54 | [string[]] $Organization, |
66 | 55 |
|
67 | 56 | # The enterprise to connect to. |
68 | | - [Parameter(ParameterSetName = 'Filtered', ValueFromPipelineByPropertyName)] |
| 57 | + [Parameter(ParameterSetName = 'Filtered')] |
69 | 58 | [SupportsWildcards()] |
70 | 59 | [string[]] $Enterprise, |
71 | 60 |
|
72 | 61 | # Installation objects from pipeline for parallel processing. |
73 | 62 | [Parameter(Mandatory, ParameterSetName = 'Installation object', ValueFromPipeline)] |
74 | 63 | [GitHubAppInstallation[]] $Installation, |
75 | 64 |
|
76 | | - # The maximum number of parallel operations to run at once. |
77 | | - [Parameter(ParameterSetName = 'Filtered')] |
78 | | - [Parameter(ParameterSetName = 'Installation')] |
79 | | - [uint] $ThrottleLimit = ([Environment]::ProcessorCount), |
80 | | - |
81 | 65 | # The installation ID(s) to connect to directly. |
82 | 66 | # Accepts input from the pipeline by property name (e.g. objects with an ID property) |
83 | 67 | [Parameter(Mandatory, ParameterSetName = 'Installation ID', ValueFromPipelineByPropertyName)] |
|
108 | 92 | Write-Debug "[$stackPath] - Start" |
109 | 93 | $Context = Resolve-GitHubContext -Context $Context |
110 | 94 | Assert-GitHubContext -Context $Context -AuthType App |
111 | | - $selectedInstallations = @() |
112 | | - $moduleVersion = $script:PSModuleInfo.ModuleVersion |
113 | 95 | } |
114 | 96 |
|
115 | 97 | process { |
116 | 98 | $selectedInstallations = [System.Collections.ArrayList]::new() |
117 | 99 | switch ($PSCmdlet.ParameterSetName) { |
118 | | - 'Installation' { |
119 | | - if ($Installation.Count -eq 1) { |
120 | | - Write-Verbose "Processing installation [$($Installation.Target.Name)] [$($Installation.ID)]" |
121 | | - $token = New-GitHubAppInstallationAccessToken -Context $Context -ID $Installation.ID |
122 | | - |
123 | | - $contextParams = @{ |
124 | | - AuthType = [string]'IAT' |
125 | | - TokenType = [string]'ghs' |
126 | | - DisplayName = [string]$Context.DisplayName |
127 | | - ApiBaseUri = [string]$Context.ApiBaseUri |
128 | | - ApiVersion = [string]$Context.ApiVersion |
129 | | - HostName = [string]$Context.HostName |
130 | | - HttpVersion = [string]$Context.HttpVersion |
131 | | - PerPage = [int]$Context.PerPage |
132 | | - ClientID = [string]$Context.ClientID |
133 | | - InstallationID = [string]$Installation.ID |
134 | | - Permissions = [GitHubPermission[]]$Installation.Permissions |
135 | | - Events = [string[]]$Installation.Events |
136 | | - InstallationType = [string]$Installation.Type |
137 | | - Token = [securestring]$token.Token |
138 | | - TokenExpiresAt = [datetime]$token.ExpiresAt |
139 | | - } |
140 | | - |
141 | | - switch ($Installation.Type) { |
142 | | - 'User' { |
143 | | - $contextParams['InstallationName'] = [string]$Installation.Target.Name |
144 | | - $contextParams['Owner'] = [string]$Installation.Target.Name |
145 | | - } |
146 | | - 'Organization' { |
147 | | - $contextParams['InstallationName'] = [string]$Installation.Target.Name |
148 | | - $contextParams['Owner'] = [string]$Installation.Target.Name |
149 | | - } |
150 | | - 'Enterprise' { |
151 | | - $contextParams['InstallationName'] = [string]$Installation.Target.Name |
152 | | - $contextParams['Enterprise'] = [string]$Installation.Target.Name |
153 | | - } |
154 | | - } |
155 | | - Write-Verbose 'Logging in using a managed installation access token...' |
156 | | - $contextParams | Format-Table | Out-String -Stream | ForEach-Object { Write-Verbose $_ } |
157 | | - $attempts = 0 |
158 | | - while ($true) { |
159 | | - try { |
160 | | - $contextObj = [GitHubAppInstallationContext]::new( |
161 | | - (Set-GitHubContext -Context $contextParams.Clone() -PassThru -Default:$Default) |
162 | | - ) |
163 | | - break |
164 | | - } catch { |
165 | | - if ($attempts -lt 3) { |
166 | | - $attempts++ |
167 | | - Write-Warning "Failed to create context. Retrying... [$attempts]" |
168 | | - Start-Sleep -Seconds (1 * $attempts) |
169 | | - } else { |
170 | | - throw $_ |
171 | | - } |
172 | | - } |
173 | | - } |
174 | | - if ($VerbosePreference -eq 'Continue') { |
175 | | - $contextObj | Format-List | Out-String -Stream | ForEach-Object { Write-Verbose $_ } |
176 | | - } |
177 | | - if (-not $Silent) { |
178 | | - $name = $contextObj.Name |
179 | | - $green = $PSStyle.Foreground.BrightGreen |
180 | | - $reset = $PSStyle.Reset |
181 | | - Write-Host "$green✓$reset Connected $name!" |
182 | | - } |
183 | | - if ($PassThru) { |
184 | | - Write-Debug "Passing context [$contextObj] to the pipeline." |
185 | | - Write-Output $contextObj |
186 | | - } |
187 | | - return |
188 | | - } |
189 | | - |
190 | | - $Installation | ForEach-Object -ThrottleLimit $ThrottleLimit -UseNewRunspace -Parallel { |
191 | | - $attempts = 0 |
192 | | - while ($true) { |
193 | | - try { |
194 | | - Import-Module -Name 'GitHub' -RequiredVersion $using:moduleVersion |
195 | | - $params = @{ |
196 | | - Installation = $_ |
197 | | - Context = $using:Context |
198 | | - PassThru = $using:PassThru |
199 | | - Silent = $using:Silent |
200 | | - Default = $using:Default |
201 | | - } |
202 | | - Connect-GitHubApp @params |
203 | | - break |
204 | | - } catch { |
205 | | - if ($attempts -lt 3) { |
206 | | - $attempts++ |
207 | | - Start-Sleep -Seconds (1 * $attempts) |
208 | | - } else { |
209 | | - throw $_ |
210 | | - } |
211 | | - } |
212 | | - } |
213 | | - } |
214 | | - return |
215 | | - } |
216 | 100 | 'Filtered' { |
217 | 101 | $installations = Get-GitHubAppInstallation -Context $Context |
218 | 102 | Write-Verbose "Found [$($installations.Count)] installations." |
219 | | - |
220 | 103 | $User | ForEach-Object { |
221 | 104 | $userItem = $_ |
222 | 105 | Write-Verbose "User filter: [$userItem]." |
|
238 | 121 | $null = $selectedInstallations.Add($_) |
239 | 122 | } |
240 | 123 | } |
241 | | - $selectedInstallations | ForEach-Object -ThrottleLimit $ThrottleLimit -UseNewRunspace -Parallel { |
242 | | - $attempts = 0 |
243 | | - while ($true) { |
244 | | - try { |
245 | | - Import-Module -Name 'GitHub' -RequiredVersion $using:moduleVersion |
246 | | - $params = @{ |
247 | | - Installation = $_ |
248 | | - Context = $using:Context |
249 | | - PassThru = $using:PassThru |
250 | | - Silent = $using:Silent |
251 | | - Default = $using:Default |
252 | | - } |
253 | | - Connect-GitHubApp @params |
254 | | - break |
255 | | - } catch { |
256 | | - if ($attempts -lt 3) { |
257 | | - $attempts++ |
258 | | - Start-Sleep -Seconds (1 * $attempts) |
259 | | - } else { |
260 | | - throw $_ |
261 | | - } |
262 | | - } |
263 | | - } |
264 | | - } |
265 | | - return |
266 | 124 | break |
267 | 125 | } |
268 | 126 | 'Installation ID' { |
|
285 | 143 | } |
286 | 144 | break |
287 | 145 | } |
288 | | - 'All Installations' { |
| 146 | + default { |
289 | 147 | Write-Verbose 'No target specified. Connecting to all installations.' |
290 | | - $selectedInstallations = Get-GitHubAppInstallation -Context $Context |
291 | | - $selectedInstallations | ForEach-Object -ThrottleLimit $ThrottleLimit -UseNewRunspace -Parallel { |
292 | | - $attempts = 0 |
293 | | - while ($true) { |
294 | | - try { |
295 | | - Import-Module -Name 'GitHub' -RequiredVersion $using:moduleVersion |
296 | | - $params = @{ |
297 | | - Installation = $_ |
298 | | - Context = $using:Context |
299 | | - PassThru = $using:PassThru |
300 | | - Silent = $using:Silent |
301 | | - Default = $using:Default |
302 | | - } |
303 | | - Connect-GitHubApp @params |
304 | | - break |
305 | | - } catch { |
306 | | - if ($attempts -lt 3) { |
307 | | - $attempts++ |
308 | | - Start-Sleep -Seconds (1 * $attempts) |
309 | | - } else { |
310 | | - throw $_ |
311 | | - } |
312 | | - } |
313 | | - } |
314 | | - $selectedInstallations.AddRange((Get-GitHubAppInstallation -Context $Context)) |
315 | | - Write-Verbose "Found [$($selectedInstallations.Count)] installations." |
316 | | - } |
| 148 | + $selectedInstallations.AddRange((Get-GitHubAppInstallation -Context $Context)) |
| 149 | + Write-Verbose "Found [$($selectedInstallations.Count)] installations." |
317 | 150 | } |
318 | 151 | } |
319 | 152 |
|
|
355 | 188 | $contextParams['Enterprise'] = [string]$installation.Target.Name |
356 | 189 | } |
357 | 190 | } |
| 191 | + Write-Verbose 'Logging in using a managed installation access token...' |
| 192 | + $contextParams | Format-Table | Out-String -Stream | ForEach-Object { Write-Verbose $_ } |
| 193 | + $contextObj = [GitHubAppInstallationContext]::new((Set-GitHubContext -Context $contextParams.Clone() -PassThru -Default:$Default)) |
| 194 | + $contextObj | Format-List | Out-String -Stream | ForEach-Object { Write-Verbose $_ } |
| 195 | + if (-not $Silent) { |
| 196 | + $name = $contextObj.Name |
| 197 | + $green = $PSStyle.Foreground.Green |
| 198 | + $reset = $PSStyle.Reset |
| 199 | + Write-Host "$green✓$reset Connected $name!" |
| 200 | + } |
| 201 | + if ($PassThru) { |
| 202 | + Write-Debug "Passing context [$contextObj] to the pipeline." |
| 203 | + Write-Output $contextObj |
| 204 | + } |
| 205 | + $contextParams.Clear() |
358 | 206 | } |
359 | 207 | } |
360 | 208 |
|
|
0 commit comments