From 4efc746bb099ecfc63669cfb9d37a12ce3907323 Mon Sep 17 00:00:00 2001 From: "Vercellone, Jason" Date: Thu, 27 Apr 2023 23:23:34 -0500 Subject: [PATCH 01/90] Get-GitHubCodespace --- Formatters/GitHubCodespaces.Format.ps1xml | 41 ++++ GitHubCodespaces.ps1 | 281 ++++++++++++++++++++++ PowerShellForGitHub.psd1 | 3 + 3 files changed, 325 insertions(+) create mode 100644 Formatters/GitHubCodespaces.Format.ps1xml create mode 100644 GitHubCodespaces.ps1 diff --git a/Formatters/GitHubCodespaces.Format.ps1xml b/Formatters/GitHubCodespaces.Format.ps1xml new file mode 100644 index 00000000..85ac56b9 --- /dev/null +++ b/Formatters/GitHubCodespaces.Format.ps1xml @@ -0,0 +1,41 @@ + + + + + + GitHub.Codespace + + GitHub.Codespace + + + + + + + id + + + name + + + display_name + + + state + + + location + + + created_at + + + updated_at + + + + + + + + diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 new file mode 100644 index 00000000..7ae2b4d1 --- /dev/null +++ b/GitHubCodespaces.ps1 @@ -0,0 +1,281 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +@{ + GitHubCodespaceTypeName = 'GitHub.Codespace' + }.GetEnumerator() | ForEach-Object { + Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value + } + +filter Get-GitHubCodespace +{ +<# + .SYNOPSIS + Retrieves information about a Codespace or list of codespaces on GitHub. + + .DESCRIPTION + Retrieves information about a Codespace or list of codespaces on GitHub. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the Codespace. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER CodespaceName + Name of the Codespace. + If not supplied here, the DefaultCodespaceName configuration property value will be used. + + .PARAMETER Uri + Uri for the Codespace. + The OwnerName and CodespaceName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER OrganizationName + The name of the organization to retrieve the codespaces for. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Project + GitHub.Repository + GitHub.User + + .OUTPUTS + GitHub.Codespace + + .EXAMPLE + Get-GitHubCodespace + + Gets all codespaces for the current authenticated user. + + .EXAMPLE + Get-GitHubCodespace -OwnerName octocat + + Gets all of the codespaces for the user octocat + + .EXAMPLE + Get-GitHubUser -UserName octocat | Get-GitHubCodespace + + Gets all of the codespaces for the user octocat + + .EXAMPLE + Get-GitHubCodespace -Uri https://github.com/microsoft/PowerShellForGitHub + + Gets information about the microsoft/PowerShellForGitHub Codespace. + + .EXAMPLE + $repo | Get-GitHubCodespace + + You can pipe in a previous Codespace to get its refreshed information. + + .EXAMPLE + Get-GitHubCodespace -OrganizationName PowerShell + + Gets all of the codespaces in the PowerShell organization. +#> + [CmdletBinding(DefaultParameterSetName = 'AuthenticatedUser')] + [OutputType({$script:GitHubCodespaceTypeName})] + param( + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName='Repository')] + [string] $OwnerName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName='Repository')] + [string] $RepositoryName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName='CodespaceName')] + [string] $CodespaceName, + + [Parameter( + ValueFromPipelineByPropertyName, + ParameterSetName='Organization')] + [string] $OrganizationName, + + [Parameter( + ValueFromPipelineByPropertyName, + ParameterSetName='Organization')] + [ValidateNotNullOrEmpty()] + [String] $UserName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName='Uri')] + [Alias('RepositoryUrl')] + [string] $Uri, + + [string] $AccessToken + ) + + Write-InvocationLog + + $telemetryProperties = @{ + 'UsageType' = $PSCmdlet.ParameterSetName + } + + $uriFragment = [String]::Empty + $description = [String]::Empty + switch ($PSCmdlet.ParameterSetName) + { + 'AuthenticatedUser' { + # /user/codespaces + $uriFragment = 'user/codespaces' + $description = 'Getting codespaces for current authenticated user' + + break + } + + 'CodespaceName' { + $telemetryProperties['CodespaceName'] = Get-PiiSafeString -PlainText $CodespaceName + + $uriFragment = "user/codespaces/$CodespaceName" + $description = "Getting user/codespaces/$CodespaceName" + + break + } + + 'Organization' { + # /orgs/{org}/codespaces + # /orgs/{org}/members/{username}/codespaces + + $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName + if ([string]::IsNullOrWhiteSpace($UserName)) { + $uriFragment = "orgs/$OrganizationName/codespaces" + $description = "Getting codespaces for $OrganizationName" + } + else { + $telemetryProperties['UserName'] = Get-PiiSafeString -PlainText $UserName + $uriFragment = "orgs/$OrganizationName/members/$UserName/codespaces" + $description = "Getting codespaces for $OrganizationName" + } + + break + } + + 'Repository' { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" + $description = "Getting $OwnerName/$RepositoryName/codespaces" + + break + } + + 'Uri' { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" + $description = "Getting $OwnerName/$RepositoryName/codespaces" + + break + } + } + + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $description + 'AcceptHeader' = "$script:nebulaAcceptHeader,$script:baptisteAcceptHeader,$script:mercyAcceptHeader" + 'AccessToken' = $AccessToken + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + } + + $result = Invoke-GHRestMethodMultipleResult @params + if ($result.codespaces) { + $result = $result.codespaces + } + + return ($result | Add-GitHubCodespaceAdditionalProperties) +} + +filter Add-GitHubCodespaceAdditionalProperties +{ +<# + .SYNOPSIS + Adds type name and additional properties to ease pipelining to GitHub Repository objects. + + .PARAMETER InputObject + The GitHub object to add additional properties to. + + .PARAMETER TypeName + The type that should be assigned to the object. + + .PARAMETER OwnerName + Owner of the repository. This information might be obtainable from InputObject, so this + is optional based on what InputObject contains. + + .PARAMETER RepositoryName + Name of the repository. This information might be obtainable from InputObject, so this + is optional based on what InputObject contains. + + .INPUTS + [PSCustomObject] + + .OUTPUTS + GitHub.Repository +#> + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")] + param( + [Parameter( + Mandatory, + ValueFromPipeline)] + [AllowNull()] + [AllowEmptyCollection()] + [PSCustomObject[]] $InputObject, + + [ValidateNotNullOrEmpty()] + [string] $TypeName = $script:GitHubCodespaceTypeName + ) + foreach ($item in $InputObject) + { + $item.PSObject.TypeNames.Insert(0, $TypeName) + + if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport)) + { + if ($item.name) + { + Add-Member -InputObject $item -Name 'CodespaceUrl' -Value "user/codespaces/$($item.name)" -MemberType NoteProperty -Force + Add-Member -InputObject $item -Name 'CodespaceName' -Value $item.name -MemberType NoteProperty -Force + } + + if ($null -ne $item.owner) + { + $null = Add-GitHubUserAdditionalProperties -InputObject $item.owner + } + + if ($null -ne $item.organization) + { + $null = Add-GitHubOrganizationAdditionalProperties -InputObject $item.organization + } + + if ($null -ne $item.repository) + { + $null = Add-GitHubRepositoryAdditionalProperties -InputObject $item.repository + } + } + + Write-Output $item + } +} diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 44369427..ee18601c 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -16,6 +16,7 @@ # Format files (.ps1xml) to be loaded when importing this module FormatsToProcess = @( 'Formatters/GitHubBranches.Format.ps1xml', + 'Formatters/GitHubCodespaces.Format.ps1xml', 'Formatters/GitHubGistComments.Format.ps1xml', 'Formatters/GitHubGists.Format.ps1xml', 'Formatters/GitHubReleases.Format.ps1xml' @@ -33,6 +34,7 @@ 'GitHubAnalytics.ps1', 'GitHubAssignees.ps1', 'GitHubBranches.ps1', + 'GitHubCodespaces.ps1', 'GitHubCore.ps1', 'GitHubContents.ps1', 'GitHubEvents.ps1', @@ -78,6 +80,7 @@ 'Get-GitHubAssignee', 'Get-GitHubCloneTraffic', 'Get-GitHubCodeOfConduct', + 'Get-GitHubCodespace', 'Get-GitHubConfiguration', 'Get-GitHubContent', 'Get-GitHubEmoji', From adcd5ebe04bd5787dfdaa8a4f3d8d82934f33e2d Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 28 Apr 2023 22:04:43 -0500 Subject: [PATCH 02/90] - Start-GitHubCodespace - Stop-GitHubCodespace - Wait-GitHubCodespaceAction --- GitHubCodespaces.ps1 | 257 +++++++++++++++++++++++++++++++++++++++ PowerShellForGitHub.psd1 | 2 + 2 files changed, 259 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 7ae2b4d1..f3092fbd 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -78,6 +78,7 @@ filter Get-GitHubCodespace #> [CmdletBinding(DefaultParameterSetName = 'AuthenticatedUser')] [OutputType({$script:GitHubCodespaceTypeName})] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] param( [Parameter( Mandatory, @@ -209,6 +210,262 @@ filter Get-GitHubCodespace return ($result | Add-GitHubCodespaceAdditionalProperties) } +function Start-GitHubCodespace +{ +<# + .SYNOPSIS + Start a user's codespace. + + .DESCRIPTION + You must authenticate using an access token with the codespace scope to use this endpoint. + + GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER CodespaceName + The name of the codespace. + + .PARAMETER PassThru + Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. + You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior + of this switch. + + .PARAMETER Wait + If present will wait for the codespace to start. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + + .OUTPUTS + GitHub.Codespace + + .EXAMPLE + Start-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#start-a-codespace-for-the-authenticated-user +#> + [CmdletBinding( + SupportsShouldProcess, + ConfirmImpact='Low')] + [OutputType({$script:GitHubCodespaceTypeName})] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] + param( + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string] $CodespaceName, + + [switch] $PassThru, + + [switch] $Wait, + + [string] $AccessToken + ) + + process + { + Write-InvocationLog + + $telemetryProperties = @{ + 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + } + + $params = @{ + 'UriFragment' = "user/codespaces/$CodespaceName/start" + 'Method' = 'POST' + 'Description' = "Start Codespace $CodespaceName" + 'AccessToken' = $AccessToken + 'AcceptHeader' = $script:symmetraAcceptHeader + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + } + + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Start Codespace $CodespaceName")) + { + return + } + + $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) + + if ($Wait.IsPresent) + { + $waitParams = @{ + 'CodespaceName' = $CodespaceName + 'AccessToken' = $AccessToken + } + + $result = Wait-GitHubCodespaceAction @waitParams + } + + if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) + { + return $result + } + } +} + +function Stop-GitHubCodespace +{ +<# + .SYNOPSIS + Stop a user's codespace. + + .DESCRIPTION + You must authenticate using an access token with the codespace scope to use this endpoint. + + GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER CodespaceName + The name of the codespace. + + .PARAMETER PassThru + Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. + You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior + of this switch. + + .PARAMETER Wait + If present will wait for the codespace to stop. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + + .OUTPUTS + GitHub.Codespace + + .EXAMPLE + Stop-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#stop-a-codespace-for-the-authenticated-user +#> + [CmdletBinding( + SupportsShouldProcess, + ConfirmImpact='Low')] + [OutputType({$script:GitHubCodespaceTypeName})] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] + param( + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string] $CodespaceName, + + [switch] $PassThru, + + [switch] $Wait, + + [string] $AccessToken + ) + + process + { + Write-InvocationLog + + $telemetryProperties = @{ + 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + } + + $params = @{ + 'UriFragment' = "user/codespaces/$CodespaceName/stop" + 'Method' = 'POST' + 'Description' = "Stop Codespace $CodespaceName" + 'AccessToken' = $AccessToken + 'AcceptHeader' = $script:symmetraAcceptHeader + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + } + + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Stop Codespace $CodespaceName")) + { + return + } + + $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) + + if ($Wait.IsPresent) + { + $waitParams = @{ + 'CodespaceName' = $CodespaceName + 'AccessToken' = $AccessToken + } + + $result = Wait-GitHubCodespaceAction @waitParams + } + + if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) + { + return $result + } + } +} + +function Wait-GitHubCodespaceAction +{ + <# + .SYNOPSIS + Wait for a Codespace start or stop action. + + .PARAMETER CodespaceName + The name of the codespace. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + + .OUTPUTS + GitHub.Codespace + + .EXAMPLE + Wait-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 +#> + [CmdletBinding()] + [OutputType({$script:GitHubCodespaceTypeName})] + param( + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string] $CodespaceName, + + [string] $AccessToken + ) + + begin { + # 2s minimum + $sleepSeconds = $(Get-GitHubConfiguration -Name 'StateChangeDelaySeconds') + if ($sleepSeconds -eq 0) + { + $sleepSeconds = 2 + } + } + + process + { + Write-InvocationLog + + do + { + Start-Sleep -Seconds $sleepSeconds + $codespace = (Get-GitHubCodespace @PSBoundParameters) + } until($codespace.state -notmatch 'Queued|ing') + + return $codespace + } +} + filter Add-GitHubCodespaceAdditionalProperties { <# diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index ee18601c..a5651835 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -205,6 +205,8 @@ 'Set-GitHubRepositoryTopic', 'Set-GitHubTeam', 'Split-GitHubUri', + 'Start-GitHubCodespace', + 'Stop-GitHubCodespace', 'Test-GitHubAssignee', 'Test-GitHubAuthenticationConfigured', 'Test-GitHubGistStar', From 006ad5b3b9ac69c30a959a2dcd9c39681b1f8cb8 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 28 Apr 2023 22:38:01 -0500 Subject: [PATCH 03/90] Add vercellone to contributors list --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f373b04..c326deeb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -624,6 +624,7 @@ Thank you to all of our contributors, no matter how big or small the contributio - **[Simon Heather (@X-Guardian)](https://github.com/X-Guardian)** - **[Neil White (@variableresistor)](https://github.com/variableresistor)** - **[Mark Curole(@tigerfansga)](https://github.com/tigerfansga)** +- **[Jason Vercellone(@vercellone)](https://github.com/vercellone)** ---------- From 40349125227a5f06a228923c85b92d6794d5b00b Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:08:45 -0500 Subject: [PATCH 04/90] Format Document --- GitHubCodespaces.ps1 | 73 +++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index f3092fbd..9ff8fd19 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -3,13 +3,13 @@ @{ GitHubCodespaceTypeName = 'GitHub.Codespace' - }.GetEnumerator() | ForEach-Object { - Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value - } +}.GetEnumerator() | ForEach-Object { + Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value +} filter Get-GitHubCodespace { -<# + <# .SYNOPSIS Retrieves information about a Codespace or list of codespaces on GitHub. @@ -77,42 +77,42 @@ filter Get-GitHubCodespace Gets all of the codespaces in the PowerShell organization. #> [CmdletBinding(DefaultParameterSetName = 'AuthenticatedUser')] - [OutputType({$script:GitHubCodespaceTypeName})] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] + [OutputType({ $script:GitHubCodespaceTypeName })] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] param( [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName='Repository')] + ParameterSetName = 'Repository')] [string] $OwnerName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName='Repository')] + ParameterSetName = 'Repository')] [string] $RepositoryName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName='CodespaceName')] + ParameterSetName = 'CodespaceName')] [string] $CodespaceName, [Parameter( ValueFromPipelineByPropertyName, - ParameterSetName='Organization')] + ParameterSetName = 'Organization')] [string] $OrganizationName, [Parameter( ValueFromPipelineByPropertyName, - ParameterSetName='Organization')] + ParameterSetName = 'Organization')] [ValidateNotNullOrEmpty()] [String] $UserName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName='Uri')] + ParameterSetName = 'Uri')] [Alias('RepositoryUrl')] [string] $Uri, @@ -129,7 +129,8 @@ filter Get-GitHubCodespace $description = [String]::Empty switch ($PSCmdlet.ParameterSetName) { - 'AuthenticatedUser' { + 'AuthenticatedUser' + { # /user/codespaces $uriFragment = 'user/codespaces' $description = 'Getting codespaces for current authenticated user' @@ -137,7 +138,8 @@ filter Get-GitHubCodespace break } - 'CodespaceName' { + 'CodespaceName' + { $telemetryProperties['CodespaceName'] = Get-PiiSafeString -PlainText $CodespaceName $uriFragment = "user/codespaces/$CodespaceName" @@ -146,16 +148,19 @@ filter Get-GitHubCodespace break } - 'Organization' { + 'Organization' + { # /orgs/{org}/codespaces # /orgs/{org}/members/{username}/codespaces $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName - if ([string]::IsNullOrWhiteSpace($UserName)) { + if ([string]::IsNullOrWhiteSpace($UserName)) + { $uriFragment = "orgs/$OrganizationName/codespaces" $description = "Getting codespaces for $OrganizationName" } - else { + else + { $telemetryProperties['UserName'] = Get-PiiSafeString -PlainText $UserName $uriFragment = "orgs/$OrganizationName/members/$UserName/codespaces" $description = "Getting codespaces for $OrganizationName" @@ -164,7 +169,8 @@ filter Get-GitHubCodespace break } - 'Repository' { + 'Repository' + { $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName @@ -178,7 +184,8 @@ filter Get-GitHubCodespace break } - 'Uri' { + 'Uri' + { $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName $RepositoryName = $elements.repositoryName @@ -203,7 +210,8 @@ filter Get-GitHubCodespace } $result = Invoke-GHRestMethodMultipleResult @params - if ($result.codespaces) { + if ($result.codespaces) + { $result = $result.codespaces } @@ -212,7 +220,7 @@ filter Get-GitHubCodespace function Start-GitHubCodespace { -<# + <# .SYNOPSIS Start a user's codespace. @@ -252,9 +260,9 @@ function Start-GitHubCodespace #> [CmdletBinding( SupportsShouldProcess, - ConfirmImpact='Low')] - [OutputType({$script:GitHubCodespaceTypeName})] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] + ConfirmImpact = 'Low')] + [OutputType({ $script:GitHubCodespaceTypeName })] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] param( [Parameter(Mandatory, ValueFromPipeline, @@ -312,7 +320,7 @@ function Start-GitHubCodespace function Stop-GitHubCodespace { -<# + <# .SYNOPSIS Stop a user's codespace. @@ -352,9 +360,9 @@ function Stop-GitHubCodespace #> [CmdletBinding( SupportsShouldProcess, - ConfirmImpact='Low')] - [OutputType({$script:GitHubCodespaceTypeName})] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification="PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] + ConfirmImpact = 'Low')] + [OutputType({ $script:GitHubCodespaceTypeName })] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] param( [Parameter(Mandatory, ValueFromPipeline, @@ -433,7 +441,7 @@ function Wait-GitHubCodespaceAction Wait-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 #> [CmdletBinding()] - [OutputType({$script:GitHubCodespaceTypeName})] + [OutputType({ $script:GitHubCodespaceTypeName })] param( [Parameter(Mandatory, ValueFromPipeline, @@ -443,7 +451,8 @@ function Wait-GitHubCodespaceAction [string] $AccessToken ) - begin { + begin + { # 2s minimum $sleepSeconds = $(Get-GitHubConfiguration -Name 'StateChangeDelaySeconds') if ($sleepSeconds -eq 0) @@ -468,7 +477,7 @@ function Wait-GitHubCodespaceAction filter Add-GitHubCodespaceAdditionalProperties { -<# + <# .SYNOPSIS Adds type name and additional properties to ease pipelining to GitHub Repository objects. @@ -493,7 +502,7 @@ filter Add-GitHubCodespaceAdditionalProperties GitHub.Repository #> [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "Internal helper that is definitely adding more than one property.")] param( [Parameter( Mandatory, From b1b7b73bcfd2eefe7b14f993b3c85189e0ea1f02 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:31:39 -0500 Subject: [PATCH 05/90] Reorder parameters --- GitHubCodespaces.ps1 | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 9ff8fd19..78f486a3 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -22,9 +22,9 @@ filter Get-GitHubCodespace Owner of the Codespace. If not supplied here, the DefaultOwnerName configuration property value will be used. - .PARAMETER CodespaceName - Name of the Codespace. - If not supplied here, the DefaultCodespaceName configuration property value will be used. + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. .PARAMETER Uri Uri for the Codespace. @@ -34,6 +34,12 @@ filter Get-GitHubCodespace .PARAMETER OrganizationName The name of the organization to retrieve the codespaces for. + .PARAMETER UserName + The handle for the GitHub user account. + + .PARAMETER CodespaceName + Name of the Codespace. + .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. @@ -95,8 +101,9 @@ filter Get-GitHubCodespace [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName = 'CodespaceName')] - [string] $CodespaceName, + ParameterSetName = 'Uri')] + [Alias('RepositoryUrl')] + [string] $Uri, [Parameter( ValueFromPipelineByPropertyName, @@ -112,9 +119,8 @@ filter Get-GitHubCodespace [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName = 'Uri')] - [Alias('RepositoryUrl')] - [string] $Uri, + ParameterSetName = 'CodespaceName')] + [string] $CodespaceName, [string] $AccessToken ) @@ -234,14 +240,14 @@ function Start-GitHubCodespace .PARAMETER CodespaceName The name of the codespace. + .PARAMETER Wait + If present will wait for the codespace to start. + .PARAMETER PassThru Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior of this switch. - .PARAMETER Wait - If present will wait for the codespace to start. - .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. @@ -269,10 +275,10 @@ function Start-GitHubCodespace ValueFromPipelineByPropertyName)] [string] $CodespaceName, - [switch] $PassThru, - [switch] $Wait, + [switch] $PassThru, + [string] $AccessToken ) @@ -334,14 +340,14 @@ function Stop-GitHubCodespace .PARAMETER CodespaceName The name of the codespace. + .PARAMETER Wait + If present will wait for the codespace to stop. + .PARAMETER PassThru Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior of this switch. - .PARAMETER Wait - If present will wait for the codespace to stop. - .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. @@ -369,10 +375,10 @@ function Stop-GitHubCodespace ValueFromPipelineByPropertyName)] [string] $CodespaceName, - [switch] $PassThru, - [switch] $Wait, + [switch] $PassThru, + [string] $AccessToken ) From fbb35f0bbcb425a03a08a29a2c9733e4aa202f1f Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:33:45 -0500 Subject: [PATCH 06/90] INPUTS +GitHub.Codespace (round trip) --- GitHubCodespaces.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 78f486a3..5e2b6ae7 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -45,6 +45,7 @@ filter Get-GitHubCodespace REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .INPUTS + GitHub.Codespace GitHub.Project GitHub.Repository GitHub.User From 7590fbb301efd72695df2b31e30b11d740cf4a92 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:36:04 -0500 Subject: [PATCH 07/90] Mandatory OrganizationName --- GitHubCodespaces.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 5e2b6ae7..1c6de1cf 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -107,6 +107,7 @@ filter Get-GitHubCodespace [string] $Uri, [Parameter( + Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Organization')] [string] $OrganizationName, From df55ba9d613706bbfa0983bb6092b33922fa7775 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:38:25 -0500 Subject: [PATCH 08/90] ParametersSetName Respository => Elements --- GitHubCodespaces.ps1 | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 1c6de1cf..57248ad9 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -90,13 +90,13 @@ filter Get-GitHubCodespace [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName = 'Repository')] + ParameterSetName = 'Elements')] [string] $OwnerName, [Parameter( Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName = 'Repository')] + ParameterSetName = 'Elements')] [string] $RepositoryName, [Parameter( @@ -156,6 +156,21 @@ filter Get-GitHubCodespace break } + 'Elements' + { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" + $description = "Getting $OwnerName/$RepositoryName/codespaces" + + break + } + 'Organization' { # /orgs/{org}/codespaces @@ -177,21 +192,6 @@ filter Get-GitHubCodespace break } - 'Repository' - { - $elements = Resolve-RepositoryElements - $OwnerName = $elements.ownerName - $RepositoryName = $elements.repositoryName - - $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName - $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName - - $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" - $description = "Getting $OwnerName/$RepositoryName/codespaces" - - break - } - 'Uri' { $elements = Resolve-RepositoryElements From 62af8968f2bd4777d88b18eb90768dc4d66bd79c Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:44:39 -0500 Subject: [PATCH 09/90] dedupe Elements+Uri switch cases --- GitHubCodespaces.ps1 | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 57248ad9..5bca491b 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -156,21 +156,6 @@ filter Get-GitHubCodespace break } - 'Elements' - { - $elements = Resolve-RepositoryElements - $OwnerName = $elements.ownerName - $RepositoryName = $elements.repositoryName - - $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName - $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName - - $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" - $description = "Getting $OwnerName/$RepositoryName/codespaces" - - break - } - 'Organization' { # /orgs/{org}/codespaces @@ -192,7 +177,7 @@ filter Get-GitHubCodespace break } - 'Uri' + { $_ -in ('Elements', 'Uri') } { $elements = Resolve-RepositoryElements $OwnerName = $elements.ownerName From 4493b66b97fbf891737cba9da2eb39c898182bdd Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:48:48 -0500 Subject: [PATCH 10/90] defaultAcceptHeader --- GitHubCodespaces.ps1 | 3 --- 1 file changed, 3 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 5bca491b..8c75c008 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -196,7 +196,6 @@ filter Get-GitHubCodespace $params = @{ 'UriFragment' = $uriFragment 'Description' = $description - 'AcceptHeader' = "$script:nebulaAcceptHeader,$script:baptisteAcceptHeader,$script:mercyAcceptHeader" 'AccessToken' = $AccessToken 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties @@ -282,7 +281,6 @@ function Start-GitHubCodespace 'Method' = 'POST' 'Description' = "Start Codespace $CodespaceName" 'AccessToken' = $AccessToken - 'AcceptHeader' = $script:symmetraAcceptHeader 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } @@ -382,7 +380,6 @@ function Stop-GitHubCodespace 'Method' = 'POST' 'Description' = "Stop Codespace $CodespaceName" 'AccessToken' = $AccessToken - 'AcceptHeader' = $script:symmetraAcceptHeader 'TelemetryEventName' = $MyInvocation.MyCommand.Name 'TelemetryProperties' = $telemetryProperties } From d07918c38862f1f3d05ed201c43a4f31522bbcd6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:50:07 -0500 Subject: [PATCH 11/90] $null -ne $result.codespaces --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 8c75c008..1d53bf28 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -202,7 +202,7 @@ filter Get-GitHubCodespace } $result = Invoke-GHRestMethodMultipleResult @params - if ($result.codespaces) + if ($null -ne $result.codespaces) { $result = $result.codespaces } From fdc18218920efe0e5bc46b05729ff3cdcb74a8a5 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:52:19 -0500 Subject: [PATCH 12/90] Start/Stop a Codespace for...authenticated user --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 1d53bf28..10a01375 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -214,7 +214,7 @@ function Start-GitHubCodespace { <# .SYNOPSIS - Start a user's codespace. + Start a Codespace for the currently authenticated user. .DESCRIPTION You must authenticate using an access token with the codespace scope to use this endpoint. @@ -313,7 +313,7 @@ function Stop-GitHubCodespace { <# .SYNOPSIS - Stop a user's codespace. + Stop a Codespace for the currently authenticated user. .DESCRIPTION You must authenticate using an access token with the codespace scope to use this endpoint. From 8d29c00fd7ed3e95129acfd6ce3de728bc3b1afb Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:56:26 -0500 Subject: [PATCH 13/90] mv requirements to .NOTES --- GitHubCodespaces.ps1 | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 10a01375..df7f2b0a 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -217,9 +217,7 @@ function Start-GitHubCodespace Start a Codespace for the currently authenticated user. .DESCRIPTION - You must authenticate using an access token with the codespace scope to use this endpoint. - - GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. + Start a Codespace for the currently authenticated user. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub @@ -249,6 +247,10 @@ function Start-GitHubCodespace .LINK https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#start-a-codespace-for-the-authenticated-user + + .NOTES + You must authenticate using an access token with the codespace scope to use this endpoint. + GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. #> [CmdletBinding( SupportsShouldProcess, @@ -316,9 +318,7 @@ function Stop-GitHubCodespace Stop a Codespace for the currently authenticated user. .DESCRIPTION - You must authenticate using an access token with the codespace scope to use this endpoint. - - GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. + Stop a Codespace for the currently authenticated user. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub @@ -348,6 +348,10 @@ function Stop-GitHubCodespace .LINK https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#stop-a-codespace-for-the-authenticated-user + + .NOTES + You must authenticate using an access token with the codespace scope to use this endpoint. + GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. #> [CmdletBinding( SupportsShouldProcess, From 2a537254c11b665b860f858e2f626ef4ab753d2d Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 20:59:30 -0500 Subject: [PATCH 14/90] Internal-only helper method --- GitHubCodespaces.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index df7f2b0a..83aad6ba 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -433,6 +433,9 @@ function Wait-GitHubCodespaceAction .EXAMPLE Wait-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 + + .NOTES + Internal-only helper method. #> [CmdletBinding()] [OutputType({ $script:GitHubCodespaceTypeName })] From 845af51ab5f90bfb60d30fbfe61a09cbd74b0088 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 21:02:09 -0500 Subject: [PATCH 15/90] 2s minimum --- GitHubCodespaces.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 83aad6ba..25266707 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -450,9 +450,10 @@ function Wait-GitHubCodespaceAction begin { - # 2s minimum $sleepSeconds = $(Get-GitHubConfiguration -Name 'StateChangeDelaySeconds') - if ($sleepSeconds -eq 0) + + # 2s minimum + if ($sleepSeconds -lt 2) { $sleepSeconds = 2 } From 8b5e9c15305ef3fe568fed294dca32e30ffe4308 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 21:07:20 -0500 Subject: [PATCH 16/90] until on new line --- GitHubCodespaces.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 25266707..585c7150 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -467,7 +467,8 @@ function Wait-GitHubCodespaceAction { Start-Sleep -Seconds $sleepSeconds $codespace = (Get-GitHubCodespace @PSBoundParameters) - } until($codespace.state -notmatch 'Queued|ing') + } + until ($codespace.state -notmatch 'Queued|ing') return $codespace } From 9d955a50564bbd14e7cc5398f4e245cd1529e88e Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 21:22:31 -0500 Subject: [PATCH 17/90] until state -notmatch 'Queued|ing' comments --- GitHubCodespaces.ps1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 585c7150..0fdafc92 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -463,6 +463,14 @@ function Wait-GitHubCodespaceAction { Write-InvocationLog + # Expected states for happy paths: + # Shutdown > Queued > Starting > Available + # Available > Queued > ShuttingDown > ShutDown + # + # To allow for unexpected results, loop until the state is something other than Queued or *ing + # All known states: + # *ings: Awaiting, Exporting, Provisioning, Rebuilding, ShuttingDown, Starting, Updating + # Other: Archived, Available, Created, Deleted, Failed, Moved, Queued, Shutdown, Unavailable, Unknown do { Start-Sleep -Seconds $sleepSeconds From 29c7c3942c44dbfb943e474eefdfe52af9fec57d Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 21:23:08 -0500 Subject: [PATCH 18/90] foreach on new line --- GitHubCodespaces.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 0fdafc92..432ab89e 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -521,6 +521,7 @@ filter Add-GitHubCodespaceAdditionalProperties [ValidateNotNullOrEmpty()] [string] $TypeName = $script:GitHubCodespaceTypeName ) + foreach ($item in $InputObject) { $item.PSObject.TypeNames.Insert(0, $TypeName) From 4798d5706bb8b98ba2464e60d3a2415e712dd884 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sun, 30 Apr 2023 21:31:37 -0500 Subject: [PATCH 19/90] Start-Stop filter not function --- GitHubCodespaces.ps1 | 122 ++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 64 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 432ab89e..3fff9764 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -210,7 +210,7 @@ filter Get-GitHubCodespace return ($result | Add-GitHubCodespaceAdditionalProperties) } -function Start-GitHubCodespace +filter Start-GitHubCodespace { <# .SYNOPSIS @@ -270,48 +270,45 @@ function Start-GitHubCodespace [string] $AccessToken ) - process - { - Write-InvocationLog - - $telemetryProperties = @{ - 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName - } + Write-InvocationLog - $params = @{ - 'UriFragment' = "user/codespaces/$CodespaceName/start" - 'Method' = 'POST' - 'Description' = "Start Codespace $CodespaceName" - 'AccessToken' = $AccessToken - 'TelemetryEventName' = $MyInvocation.MyCommand.Name - 'TelemetryProperties' = $telemetryProperties - } + $telemetryProperties = @{ + 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + } - if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Start Codespace $CodespaceName")) - { - return - } + $params = @{ + 'UriFragment' = "user/codespaces/$CodespaceName/start" + 'Method' = 'POST' + 'Description' = "Start Codespace $CodespaceName" + 'AccessToken' = $AccessToken + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + } - $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Start Codespace $CodespaceName")) + { + return + } - if ($Wait.IsPresent) - { - $waitParams = @{ - 'CodespaceName' = $CodespaceName - 'AccessToken' = $AccessToken - } + $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) - $result = Wait-GitHubCodespaceAction @waitParams + if ($Wait.IsPresent) + { + $waitParams = @{ + 'CodespaceName' = $CodespaceName + 'AccessToken' = $AccessToken } - if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) - { - return $result - } + $result = Wait-GitHubCodespaceAction @waitParams + } + + if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) + { + return $result } } -function Stop-GitHubCodespace +filter Stop-GitHubCodespace { <# .SYNOPSIS @@ -371,44 +368,41 @@ function Stop-GitHubCodespace [string] $AccessToken ) - process - { - Write-InvocationLog - - $telemetryProperties = @{ - 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName - } + Write-InvocationLog - $params = @{ - 'UriFragment' = "user/codespaces/$CodespaceName/stop" - 'Method' = 'POST' - 'Description' = "Stop Codespace $CodespaceName" - 'AccessToken' = $AccessToken - 'TelemetryEventName' = $MyInvocation.MyCommand.Name - 'TelemetryProperties' = $telemetryProperties - } + $telemetryProperties = @{ + 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + } - if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Stop Codespace $CodespaceName")) - { - return - } + $params = @{ + 'UriFragment' = "user/codespaces/$CodespaceName/stop" + 'Method' = 'POST' + 'Description' = "Stop Codespace $CodespaceName" + 'AccessToken' = $AccessToken + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + } - $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Stop Codespace $CodespaceName")) + { + return + } - if ($Wait.IsPresent) - { - $waitParams = @{ - 'CodespaceName' = $CodespaceName - 'AccessToken' = $AccessToken - } + $result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) - $result = Wait-GitHubCodespaceAction @waitParams + if ($Wait.IsPresent) + { + $waitParams = @{ + 'CodespaceName' = $CodespaceName + 'AccessToken' = $AccessToken } - if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) - { - return $result - } + $result = Wait-GitHubCodespaceAction @waitParams + } + + if (Resolve-ParameterWithDefaultConfigurationValue -Name PassThru -ConfigValueName DefaultPassThru) + { + return $result } } From f924381b33010d147eb2562c8a77cc1444956fa6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Mon, 1 May 2023 00:26:16 -0500 Subject: [PATCH 20/90] (New and Remove)-GitHubCodespace --- GitHubCodespaces.ps1 | 422 ++++++++++++++++++++++++++++++++++++--- PowerShellForGitHub.psd1 | 2 + 2 files changed, 396 insertions(+), 28 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 3fff9764..4fb57fbb 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -130,7 +130,7 @@ filter Get-GitHubCodespace Write-InvocationLog $telemetryProperties = @{ - 'UsageType' = $PSCmdlet.ParameterSetName + UsageType = $PSCmdlet.ParameterSetName } $uriFragment = [String]::Empty @@ -139,7 +139,6 @@ filter Get-GitHubCodespace { 'AuthenticatedUser' { - # /user/codespaces $uriFragment = 'user/codespaces' $description = 'Getting codespaces for current authenticated user' @@ -158,9 +157,6 @@ filter Get-GitHubCodespace 'Organization' { - # /orgs/{org}/codespaces - # /orgs/{org}/members/{username}/codespaces - $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName if ([string]::IsNullOrWhiteSpace($UserName)) { @@ -194,11 +190,11 @@ filter Get-GitHubCodespace } $params = @{ - 'UriFragment' = $uriFragment - 'Description' = $description - 'AccessToken' = $AccessToken - 'TelemetryEventName' = $MyInvocation.MyCommand.Name - 'TelemetryProperties' = $telemetryProperties + UriFragment = $uriFragment + Description = $description + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties } $result = Invoke-GHRestMethodMultipleResult @params @@ -210,6 +206,376 @@ filter Get-GitHubCodespace return ($result | Add-GitHubCodespaceAdditionalProperties) } +function New-GitHubCodespace +{ + <# + .SYNOPSIS + Creates a codespace. + + .DESCRIPTION + Creates a codespace. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the Codespace. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. + + .PARAMETER Uri + Uri for the Codespace. + The OwnerName and CodespaceName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER PullRequest + The pull request number for this codespace. + + .PARAMETER RepositoryId + The ID for a Repository. Only applicable when creating a codespace for the current authenticated user. + + .PARAMETER Ref + Git ref (typically a branch name) for this codespace + + .PARAMETER ClientIp + IP for location auto-detection when proxying a request. + + .PARAMETER Devcontainer + Path to devcontainer.json config to use for this codespace. + + .PARAMETER DisplayName + Display name for this codespace + + .PARAMETER Location + The requested location for a new codespace. + Best efforts are made to respect this upon creation. + Assigned by IP if not provided. + + .PARAMETER Machine + Machine type to use for this codespace. + + .PARAMETER NoMultipleRepoPermissions + Whether to authorize requested permissions to other repos from devcontainer.json. + + .PARAMETER RetentionPeriod + Duration in minutes (up to 30 days) after codespace has gone idle in which it will be deleted. + + .PARAMETER Timeout + Time in minutes before codespace stops from inactivity. + + .PARAMETER WorkingDirectory + Working directory for this codespace. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + GitHub.Project + GitHub.PullRequest + GitHub.Repository + + .OUTPUTS + GitHub.Codespace + + .EXAMPLE + New-GitHubCodespace -RepositoryId 582779513 + + Creates a new codespace for the current authenticated user in the specified repository. + + .EXAMPLE + New-GitHubCodespace -RepositoryId 582779513 -PullRequest 508 + + Creates a new codespace for the current authenticated user in the specified repository from a pull request. + + .EXAMPLE + New-GitHubCodespace -OwnerName marykay -RepositoryName one + + Creates a codespace owned by the authenticated user in the specified repository. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'AuthenticatedUser')] + [OutputType({ $script:GitHubCodespaceTypeName })] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.")] + param( + [Parameter( + Mandatory, + ParameterSetName = 'Elements')] + [Parameter( + Mandatory, + ParameterSetName = 'ElementsPullRequest')] + [string] $OwnerName, + + [Parameter( + Mandatory, + ParameterSetName = 'Elements')] + [Parameter( + Mandatory, + ParameterSetName = 'ElementsPullRequest')] + [string] $RepositoryName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'Uri')] + [Alias('RepositoryUrl')] + [Alias('PullRequestUrl')] + [string] $Uri, + + [Parameter( + ParameterSetName = 'AuthenticatedUser')] + [Parameter( + Mandatory, + ParameterSetName = 'ElementsPullRequest')] + [Alias('PullRequestNumber')] + [int64] $PullRequest, + + [Parameter( + Mandatory, + ParameterSetName = 'AuthenticatedUser')] + [Int64] $RepositoryId, + + [Parameter( + ParameterSetName = 'AuthenticatedUser')] + [Parameter( + ParameterSetName = 'Elements')] + [string]$Ref, + + [string]$ClientIp, + + [string]$Devcontainer, + + [string]$DisplayName, + + [string]$Location, + + [string]$Machine, + + [switch]$NoMultipleRepoPermissions, + + [ValidateRange(0, 43200)] + [int]$RetentionPeriod, + + [int]$Timeout, + + [string]$WorkingDirectory, + + [string] $AccessToken + ) + + begin + { + Write-InvocationLog + + $propertyMap = @{ + ClientIp = 'client_ip' + Devcontainer = 'devcontainer_path' + DisplayName = 'display_name' + Location = 'location' + Machine = 'machine' + Ref = 'ref' + RetentionPeriod = 'retention_period_minutes' + Timeout = 'idle_timeout_minutes' + WorkingDirectory = 'working_directory' + } + } + + process + { + + $telemetryProperties = @{ + UsageType = $PSCmdlet.ParameterSetName + } + + $uriFragment = [String]::Empty + $description = [String]::Empty + if ($PSCmdlet.ParameterSetName -eq 'AuthenticatedUser') + { + $uriFragment = 'user/codespaces' + $description = 'Create a codespace for current authenticated user' + } + else + { + # ParameterSets: Elements, ElementsPullRequest, Uri + # ElementsPullRequest prevents Ref for /repos/{owner}/{repo}/pulls/{pull_number}/codespaces + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + if ($PSCmdlet.ParameterSetName -eq 'ElementsPullRequest') + { + $description = "Create a codespace from $OwnerName/$RepositoryName/pulls/$PullRequest" + $telemetryProperties['PullRequest'] = $PullRequest + $uriFragment = "repos/$OwnerName/$RepositoryName/pulls/$PullRequest/codespaces" + } + else + { + $description = "Create a codepace in $OwnerName/$RepositoryName" + $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces" + } + } + + $hashBody = @{ + multi_repo_permissions_opt_out = $NoMultipleRepoPermissions.IsPresent + } + + # Map params to hashBody properties + foreach ($p in $PSBoundParameters.GetEnumerator()) + { + if ($propertyMap.ContainsKey($p.Key) -and -not [string]::IsNullOrWhiteSpace($p.Value)) + { + $hashBody.Add($propertyMap[$p.Key], $p.Value) + } + } + + if ($PSCmdlet.ParameterSetName -eq 'AuthenticatedUser') + { + if ($PSBoundParameters.ContainsKey('PullRequest')) + { + $hashBody.Add('pull_request', + [PSCustomObject]@{ + pull_request_number = $PullRequest + repository_id = $RepositoryId + } + ) + } + else + { + $hashBody.Add('repository_id', $RepositoryId) + } + } + + $params = @{ + UriFragment = $uriFragment + Body = (ConvertTo-Json -InputObject $hashBody) + Method = 'POST' + Description = $description + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties + } + + if (-not $PSCmdlet.ShouldProcess($RepositoryName, 'Create GitHub Codespace')) + { + return + } + + return (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties) + + } +} + +filter Remove-GitHubCodespace +{ + <# + .SYNOPSIS + Remove a Codespace. + + .DESCRIPTION + Remove a Codespace. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OrganizationName + The name of the organization to retrieve the codespaces for. + + .PARAMETER UserName + The handle for the GitHub user account. + + .PARAMETER CodespaceName + The name of the codespace. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + + .OUTPUTS + None + + .EXAMPLE + Get-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 | Remove-GitHubCodespace + + .EXAMPLE + Remove-GitHubCodespace -Name vercellone-effective-goggles-qrv997q6j9929jx8 + + .EXAMPLE + Remove-GitHubCodespace -OrganizationName myorg -UserName jetsong -Name jetsong-button-masher-zzz788y6j8288xp1 + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#delete-a-codespace-for-the-authenticated-user + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#delete-a-codespace-from-the-organization +#> + [CmdletBinding( + DefaultParameterSetName = 'AuthenticatedUser', + SupportsShouldProcess)] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] + [Alias('Delete-GitHubCodespace')] + param( + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'Organization')] + [string] $OrganizationName, + + [Parameter( + ValueFromPipelineByPropertyName, + ParameterSetName = 'Organization')] + [ValidateNotNullOrEmpty()] + [String] $UserName, + + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string] $CodespaceName, + + [string] $AccessToken + ) + + Write-InvocationLog + + $telemetryProperties = @{ + CodespaceName = Get-PiiSafeString -PlainText $CodespaceName + } + + $uriFragment = [String]::Empty + if ($PSCmdlet.ParameterSetName -eq 'AuthenticatedUser') + { + $uriFragment = "user/codespaces/$CodespaceName" + } + else + { + $uriFragment = "orgs/$OrganizationName/members/$UserName/codespaces/$CodespaceName" + } + + $params = @{ + UriFragment = $uriFragment + Method = 'DELETE' + Description = "Remove Codespace $CodespaceName" + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties + } + + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Remove Codespace $CodespaceName")) + { + return + } + + Invoke-GHRestMethod @params | Out-Null +} + filter Start-GitHubCodespace { <# @@ -273,16 +639,16 @@ filter Start-GitHubCodespace Write-InvocationLog $telemetryProperties = @{ - 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + CodespaceName = Get-PiiSafeString -PlainText $CodespaceName } $params = @{ - 'UriFragment' = "user/codespaces/$CodespaceName/start" - 'Method' = 'POST' - 'Description' = "Start Codespace $CodespaceName" - 'AccessToken' = $AccessToken - 'TelemetryEventName' = $MyInvocation.MyCommand.Name - 'TelemetryProperties' = $telemetryProperties + UriFragment = "user/codespaces/$CodespaceName/start" + Method = 'POST' + Description = "Start Codespace $CodespaceName" + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties } if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Start Codespace $CodespaceName")) @@ -295,8 +661,8 @@ filter Start-GitHubCodespace if ($Wait.IsPresent) { $waitParams = @{ - 'CodespaceName' = $CodespaceName - 'AccessToken' = $AccessToken + CodespaceName = $CodespaceName + AccessToken = $AccessToken } $result = Wait-GitHubCodespaceAction @waitParams @@ -371,16 +737,16 @@ filter Stop-GitHubCodespace Write-InvocationLog $telemetryProperties = @{ - 'CodespaceName' = Get-PiiSafeString -PlainText $CodespaceName + CodespaceName = Get-PiiSafeString -PlainText $CodespaceName } $params = @{ - 'UriFragment' = "user/codespaces/$CodespaceName/stop" - 'Method' = 'POST' - 'Description' = "Stop Codespace $CodespaceName" - 'AccessToken' = $AccessToken - 'TelemetryEventName' = $MyInvocation.MyCommand.Name - 'TelemetryProperties' = $telemetryProperties + UriFragment = "user/codespaces/$CodespaceName/stop" + Method = 'POST' + Description = "Stop Codespace $CodespaceName" + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties } if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Stop Codespace $CodespaceName")) @@ -393,8 +759,8 @@ filter Stop-GitHubCodespace if ($Wait.IsPresent) { $waitParams = @{ - 'CodespaceName' = $CodespaceName - 'AccessToken' = $AccessToken + CodespaceName = $CodespaceName + AccessToken = $AccessToken } $result = Wait-GitHubCodespaceAction @waitParams diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 90c03322..8d3e1cac 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -137,6 +137,7 @@ 'Move-GitHubProjectCard', 'Move-GitHubProjectColumn', 'Move-GitHubRepositoryOwnership', + 'New-GitHubCodespace', 'New-GitHubDeploymentEnvironment', 'New-GitHubGist', 'New-GitHubGistComment', @@ -158,6 +159,7 @@ 'New-GitHubRepositoryFork', 'New-GitHubTeam', 'Remove-GitHubAssignee', + 'Remove-GitHubCodespace', 'Remove-GitHubComment', 'Remove-GitHubDeploymentEnvironment' 'Remove-GitHubGist', From f1417db145b1cc9be13ae480e67dca990cbb19d6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Mon, 8 May 2023 20:45:17 -0500 Subject: [PATCH 21/90] GitHubCodespaces.tests.ps1 --- Tests/GitHubCodespaces.tests.ps1 | 157 +++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 Tests/GitHubCodespaces.tests.ps1 diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 new file mode 100644 index 00000000..7a6bfc94 --- /dev/null +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -0,0 +1,157 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubCodespaces.ps1 module +#> + +[CmdletBinding()] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Suppress false positives in Pester code blocks')] +param() + +# This is common test code setup logic for all Pester test files +BeforeAll { + $moduleRootPath = Split-Path -Path $PSScriptRoot -Parent + . (Join-Path -Path $moduleRootPath -ChildPath 'Tests\Common.ps1') + + # Define Script-scoped, readonly, hidden variables. + @{ + defaultRepositoryName = ([Guid]::NewGuid().Guid) + }.GetEnumerator() | ForEach-Object { + Set-Variable -Force -Scope Script -Option ReadOnly -Visibility Private -Name $_.Key -Value $_.Value + } +} + +Describe 'GitHubCodespaces\Get-GitHubCodespace' { + + BeforeAll { + $newGitHubRepositoryParms = @{ + AutoInit = $true + Private = $true + RepositoryName = $defaultRepositoryName + OrganizationName = $script:organizationName + } + $repo = New-GitHubRepository @newGitHubRepositoryParms + + # Suppress HTTP 202 warning for codespace creation + $WarningPreference = 'SilentlyContinue' + + $newGitHubCodespaceParms = @{ + OwnerName = $script:organizationName + RepositoryName = $defaultRepositoryName + } + $null = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 5 + } + + AfterAll { + if (Get-Variable -Name repo -ErrorAction SilentlyContinue) + { + # Should delete any corresponding codespaces along with it + $repo | Remove-GitHubRepository -Confirm:$false + } + } + + Context 'When getting codespaces for the authenticated user' { + BeforeAll { + $codespaces = Get-GitHubCodespace | + Where-Object { $_.repository.name -eq $defaultRepositoryName } + } + + It 'Should return objects of the correct type' { + $codespaces[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return one or more results' { + $codespaces.Count | Should -BeGreaterOrEqual 1 + } + + It 'Should return the correct properties' { + foreach ($codespace in $codespaces) + { + $codespace.owner.login | Should -Be $script:OwnerName + $codespace.repository.name | Should -Be $newGitHubCodespaceParms.RepositoryName + } + } + } + + Context 'When getting a codespace for a specified owner and repository' { + + BeforeAll { + $codespaces = Get-GitHubCodespace @newGitHubCodespaceParms + } + It 'Should return objects of the correct type' { + $codespaces[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return one or more results' { + $codespaces.Count | Should -BeGreaterOrEqual 1 + } + + It 'Should return the correct properties' { + foreach ($codespace in $codespaces) + { + $codespace.owner.login | Should -Be $script:OwnerName + $codespace.repository.name | Should -Be $newGitHubCodespaceParms.RepositoryName + } + } + } + + Context 'When getting all codespaces for a specified organization' { + + BeforeAll { + $codespaces = Get-GitHubCodespace -OrganizationName $script:organizationName + } + It 'Should return objects of the correct type' { + $codespaces[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return one or more results' { + $codespaces.Count | Should -BeGreaterOrEqual 1 + } + } + + Context 'When getting a codespace for a specified organization user' { + BeforeAll { + $codespaces = Get-GitHubCodespace -OrganizationName $script:organizationName + $userCodespaces = Get-GitHubCodespace -OrganizationName $script:organizationName -UserName $script:OwnerName + } + + It 'Should have results for the organization user' { + $userCodespaces.name | Should -BeIn $codespaces.name + } + + It 'Should return the correct properties' { + foreach ($codespace in $userCodespaces) + { + $codespace.owner.login | Should -Be $script:OwnerName + } + } + } + + Context 'When getting a codespace for a specified codespace name' { + BeforeAll { + $codespaces = Get-GitHubCodespace + $codespace = Get-GitHubCodespace -CodespaceName $codespaces[0].name + } + + It 'Should return objects of the correct type' { + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return the correct properties' { + $codespace.owner.login | Should -Be $script:OwnerName + } + } +} + +AfterAll { + if (Test-Path -Path $script:originalConfigFile -PathType Leaf) + { + # Restore the user's configuration to its pre-test state + Restore-GitHubConfiguration -Path $script:originalConfigFile + $script:originalConfigFile = $null + } +} From c2d9604bd4f9ac8dd33692285bb078abd7043105 Mon Sep 17 00:00:00 2001 From: vercellone Date: Mon, 8 May 2023 20:58:08 -0500 Subject: [PATCH 22/90] Option 2: Add-Member RepositoryUrl --- GitHubCodespaces.ps1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 4fb57fbb..aac82917 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -899,14 +899,10 @@ filter Add-GitHubCodespaceAdditionalProperties $null = Add-GitHubUserAdditionalProperties -InputObject $item.owner } - if ($null -ne $item.organization) - { - $null = Add-GitHubOrganizationAdditionalProperties -InputObject $item.organization - } - if ($null -ne $item.repository) { $null = Add-GitHubRepositoryAdditionalProperties -InputObject $item.repository + Add-Member -InputObject $item -Name 'RepositoryUrl' -Value $item.repository.RepositoryUrl -MemberType NoteProperty -Force } } From e971983e176ccf3179ef0c95a3643291c6dcb799 Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 10 May 2023 20:44:55 -0500 Subject: [PATCH 23/90] Test Get-GitHubCodespace Uri, Uri FromPipeline --- Tests/GitHubCodespaces.tests.ps1 | 46 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 7a6bfc94..1c646fcc 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -25,7 +25,6 @@ BeforeAll { } Describe 'GitHubCodespaces\Get-GitHubCodespace' { - BeforeAll { $newGitHubRepositoryParms = @{ AutoInit = $true @@ -46,14 +45,6 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { Start-Sleep -Seconds 5 } - AfterAll { - if (Get-Variable -Name repo -ErrorAction SilentlyContinue) - { - # Should delete any corresponding codespaces along with it - $repo | Remove-GitHubRepository -Confirm:$false - } - } - Context 'When getting codespaces for the authenticated user' { BeforeAll { $codespaces = Get-GitHubCodespace | @@ -145,6 +136,43 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { $codespace.owner.login | Should -Be $script:OwnerName } } + + Context 'When specifiying the Uri parameter' { + BeforeAll { + $codespace = Get-GitHubCodespace -Uri $repo.RepositoryUrl + } + + It 'Should return objects of the correct type' { + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return the correct properties' { + $codespace.owner.login | Should -Be $script:OwnerName + $codespace.repository.name | Should -Be $repo.name + } + } + + Context "When specifiying the Uri parameter from the pipeline" { + BeforeAll { + $codespace = $repo | Get-GitHubCodespace + } + + It 'Should return objects of the correct type' { + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' + } + + It 'Should return the correct properties' { + $codespace.repository.name | Should -Be $repo.name + } + } + + AfterAll { + if (Get-Variable -Name repo -ErrorAction SilentlyContinue) + { + # Should delete any corresponding codespaces along with it + $repo | Remove-GitHubRepository -Confirm:$false + } + } } AfterAll { From 926f0246a5413519a497dc5f786afcf41d32e38a Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 10 May 2023 21:55:15 -0500 Subject: [PATCH 24/90] Tests: (Start|Stop)-GitHubCodespace --- Tests/GitHubCodespaces.tests.ps1 | 86 +++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 1c646fcc..6f464694 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -22,18 +22,18 @@ BeforeAll { }.GetEnumerator() | ForEach-Object { Set-Variable -Force -Scope Script -Option ReadOnly -Visibility Private -Name $_.Key -Value $_.Value } + + $newGitHubRepositoryParms = @{ + AutoInit = $true + Private = $true + RepositoryName = $defaultRepositoryName + OrganizationName = $script:organizationName + } + $repo = New-GitHubRepository @newGitHubRepositoryParms } Describe 'GitHubCodespaces\Get-GitHubCodespace' { BeforeAll { - $newGitHubRepositoryParms = @{ - AutoInit = $true - Private = $true - RepositoryName = $defaultRepositoryName - OrganizationName = $script:organizationName - } - $repo = New-GitHubRepository @newGitHubRepositoryParms - # Suppress HTTP 202 warning for codespace creation $WarningPreference = 'SilentlyContinue' @@ -165,17 +165,77 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { $codespace.repository.name | Should -Be $repo.name } } +} + +Describe 'GitHubCodespaces\Start-GitHubCodespace' { + BeforeAll { + # Suppress HTTP 202 warning for codespace creation + $WarningPreference = 'SilentlyContinue' + + $newGitHubCodespaceParms = @{ + OwnerName = $script:organizationName + RepositoryName = $defaultRepositoryName + } + $null = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 5 + } - AfterAll { - if (Get-Variable -Name repo -ErrorAction SilentlyContinue) - { - # Should delete any corresponding codespaces along with it - $repo | Remove-GitHubRepository -Confirm:$false + Context 'When starting a codespace for the authenticated user' { + BeforeAll { + $codespace = Get-GitHubCodespace @newGitHubCodespaceParms + } + + It 'Should not throw' { + # Also asserts pipeline input + { $codespace | Start-GitHubCodespace } | Should -Not -Throw + } + + It 'Should become Available' { + # Also asserts Wait and PassThru + $result = $codespace | Start-GitHubCodespace -Wait -PassThru + $result.State | Should -Be 'Available' + } + } +} + +Describe 'GitHubCodespaces\Stop-GitHubCodespace' { + BeforeAll { + # Suppress HTTP 202 warning for codespace creation + $WarningPreference = 'SilentlyContinue' + + $newGitHubCodespaceParms = @{ + OwnerName = $script:organizationName + RepositoryName = $defaultRepositoryName + } + $null = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 5 + } + + Context 'When stopping a codespace for the authenticated user' { + BeforeAll { + $codespace = Get-GitHubCodespace @newGitHubCodespaceParms + } + + It 'Should not throw' { + # Also asserts pipeline input + { $codespace | Stop-GitHubCodespace } | Should -Not -Throw + } + + It 'Should become Shutdown' { + # Also asserts Wait and PassThru + $result = $codespace | Stop-GitHubCodespace -Wait -PassThru + $result.State | Should -Be 'Shutdown' } } } AfterAll { + if (Get-Variable -Name repo -ErrorAction SilentlyContinue) + { + # Should delete any corresponding codespaces along with it + $repo | Remove-GitHubRepository -Confirm:$false + } + if (Test-Path -Path $script:originalConfigFile -PathType Leaf) { # Restore the user's configuration to its pre-test state From 18cd74b54099417f332d727dccbed972669dddcc Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 10 May 2023 22:21:52 -0500 Subject: [PATCH 25/90] Remove-GitHubCodespace -Force --- GitHubCodespaces.ps1 | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index aac82917..29fa8666 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -343,26 +343,26 @@ function New-GitHubCodespace ParameterSetName = 'AuthenticatedUser')] [Parameter( ParameterSetName = 'Elements')] - [string]$Ref, + [string] $Ref, - [string]$ClientIp, + [string] $ClientIp, - [string]$Devcontainer, + [string] $Devcontainer, - [string]$DisplayName, + [string] $DisplayName, - [string]$Location, + [string] $Location, - [string]$Machine, + [string] $Machine, - [switch]$NoMultipleRepoPermissions, + [switch] $NoMultipleRepoPermissions, [ValidateRange(0, 43200)] - [int]$RetentionPeriod, + [int] $RetentionPeriod, - [int]$Timeout, + [int] $Timeout, - [string]$WorkingDirectory, + [string] $WorkingDirectory, [string] $AccessToken ) @@ -540,6 +540,8 @@ filter Remove-GitHubCodespace ValueFromPipelineByPropertyName)] [string] $CodespaceName, + [switch] $Force, + [string] $AccessToken ) @@ -568,6 +570,11 @@ filter Remove-GitHubCodespace TelemetryProperties = $telemetryProperties } + if ($Force -and (-not $Confirm)) + { + $ConfirmPreference = 'None' + } + if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Remove Codespace $CodespaceName")) { return From f3016e33de5c51da89cfbf89821eeeaf4a5b9828 Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 10 May 2023 22:22:40 -0500 Subject: [PATCH 26/90] Tests: Delete-GitHubCodespace for auth user --- Tests/GitHubCodespaces.tests.ps1 | 36 +++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 6f464694..3a7e46fb 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -32,6 +32,36 @@ BeforeAll { $repo = New-GitHubRepository @newGitHubRepositoryParms } +Describe 'GitHubCodespaces\Delete-GitHubCodespace' { + + Context 'When deleting a codespace for the authenticated user' { + BeforeEach { + # Suppress HTTP 202 warning for codespace creation + # TODO: Suppression is not working as intended here. + $WarningPreference = 'SilentlyContinue' + + $newGitHubCodespaceParms = @{ + OwnerName = $script:organizationName + RepositoryName = $defaultRepositoryName + } + $codespace = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 3 + } + + It 'Should get no content using -Confirm:$false' { + # Also asserts pipeline input + $codespace | Remove-GitHubCodespace -Confirm:$false + { Get-GitHubCodespace -CodespaceName $codespace.name } | Should -Throw + } + + It 'Should get no content using -Force' { + # Also assert CodespaceName input + Remove-GitHubCodespace -CodespaceName $codespace.name -Force + { Get-GitHubCodespace -CodespaceName $codespace.name } | Should -Throw + } + } +} + Describe 'GitHubCodespaces\Get-GitHubCodespace' { BeforeAll { # Suppress HTTP 202 warning for codespace creation @@ -42,7 +72,7 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 5 + Start-Sleep -Seconds 3 } Context 'When getting codespaces for the authenticated user' { @@ -177,7 +207,7 @@ Describe 'GitHubCodespaces\Start-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 5 + Start-Sleep -Seconds 3 } Context 'When starting a codespace for the authenticated user' { @@ -208,7 +238,7 @@ Describe 'GitHubCodespaces\Stop-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 5 + Start-Sleep -Seconds 3 } Context 'When stopping a codespace for the authenticated user' { From b36e8c7e7b1ccbbcbb48c98a80673d2cb2bddfd1 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 19 May 2023 20:49:04 -0500 Subject: [PATCH 27/90] UserName=Mandatory for Organization parameterset --- GitHubCodespaces.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 29fa8666..29712df1 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -530,6 +530,7 @@ filter Remove-GitHubCodespace [string] $OrganizationName, [Parameter( + Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Organization')] [ValidateNotNullOrEmpty()] From ca0b5098bbed8e0733080438a1689867f83edd50 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 19 May 2023 21:02:15 -0500 Subject: [PATCH 28/90] Remove-GitHubCodespace ConfirmImpact=High --- GitHubCodespaces.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 29712df1..e9e7325b 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -519,7 +519,8 @@ filter Remove-GitHubCodespace #> [CmdletBinding( DefaultParameterSetName = 'AuthenticatedUser', - SupportsShouldProcess)] + SupportsShouldProcess, + ConfirmImpact = 'High')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] [Alias('Delete-GitHubCodespace')] param( From 54726eddb6bd6e1aebee8ed9694431690ab55d2c Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 19 May 2023 22:34:52 -0500 Subject: [PATCH 29/90] Add .LINK per endpoint --- GitHubCodespaces.ps1 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index e9e7325b..8111c943 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -82,6 +82,21 @@ filter Get-GitHubCodespace Get-GitHubCodespace -OrganizationName PowerShell Gets all of the codespaces in the PowerShell organization. + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#get-a-codespace-for-the-authenticated-user + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-in-a-repository-for-the-authenticated-user + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-for-the-authenticated-user + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#list-codespaces-for-the-organization + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#list-codespaces-for-a-user-in-organization #> [CmdletBinding(DefaultParameterSetName = 'AuthenticatedUser')] [OutputType({ $script:GitHubCodespaceTypeName })] @@ -295,6 +310,15 @@ function New-GitHubCodespace New-GitHubCodespace -OwnerName marykay -RepositoryName one Creates a codespace owned by the authenticated user in the specified repository. + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-for-the-authenticated-user + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-in-a-repository + + .LINK + https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-from-a-pull-request #> [CmdletBinding( SupportsShouldProcess, From d76bfbf1138c6510a2412394fbe04b0580e2e7d3 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 19 May 2023 23:34:05 -0500 Subject: [PATCH 30/90] New-GitHubCodespace tests --- Tests/GitHubCodespaces.tests.ps1 | 183 ++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 4 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 3a7e46fb..29861a1b 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -45,7 +45,7 @@ Describe 'GitHubCodespaces\Delete-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $codespace = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 3 + Start-Sleep -Seconds 2 } It 'Should get no content using -Confirm:$false' { @@ -72,7 +72,7 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 3 + Start-Sleep -Seconds 2 } Context 'When getting codespaces for the authenticated user' { @@ -197,6 +197,181 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { } } + +Describe 'GitHubCodespaces\New-GitHubCodespace' { + + Context -Name 'When creating a repository for the authenticated user' { + + Context -Name 'When creating a codespace with default settings with RepositoryId' { + BeforeAll { + $newGitHubCodespaceParms = @{ + RepositoryId = $repo.Id + } + $codespace = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 2 + } + + It 'Should return an object of the correct type' { + $codespace | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + $codespace.display_name | Should -Not -BeNullOrEmpty + $codespace.repository.name | Should -Be $repo.name + $codespace.idle_timeout_minutes | Should -Be 30 + $codespace.owner.UserName | Should -Be $script:OwnerName + $codespace.template | Should -BeNullOrEmpty + } + + AfterAll { + if ($codespace) + { + Remove-GitHubCodespace -CodespaceName $codespace.name -Confirm:$false + } + } + } + + Context -Name 'When creating a codespace with default settings with Ref' { + BeforeAll { + $repoWithPR = Get-GitHubRepository -OrganizationName 'super-fake-not-real-org' | + Where-Object { $_ | Get-GitHubPullRequest } | + Select-Object -First 1 + $pullRequest = $repoWithPR | Get-GitHubPullRequest | Select-Object -First 1 + $newGitHubCodespaceParms = @{ + Ref = $pullRequest.head.ref + RepositoryId = $repoWithPR.Id + } + $codespace = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 2 + } + + It 'Should return an object of the correct type' { + $codespace | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + $codespace.display_name | Should -Not -BeNullOrEmpty + $codespace.git_status.ref | Should -Be $pullRequest.head.ref + $codespace.repository.name | Should -Be $repoWithPR.name + $codespace.idle_timeout_minutes | Should -Be 30 + $codespace.owner.UserName | Should -Be $script:OwnerName + $codespace.template | Should -BeNullOrEmpty + } + + AfterAll { + if ($codespace) + { + Remove-GitHubCodespace -CodespaceName $codespace.name -Confirm:$false + } + } + } + + Context -Name 'When creating a codespace with default settings from a PullRequest' { + BeforeAll { + $repoWithPR = Get-GitHubRepository -OrganizationName 'super-fake-not-real-org' | + Where-Object { $_ | Get-GitHubPullRequest } | + Select-Object -First 1 + $pullRequest = $repoWithPR | Get-GitHubPullRequest | Select-Object -First 1 + $newGitHubCodespaceParms = @{ + PullRequest = $pullRequest.number + RepositoryId = $repoWithPR.Id + } + $codespace = New-GitHubCodespace @newGitHubCodespaceParms + Start-Sleep -Seconds 2 + } + + It 'Should return an object of the correct type' { + $codespace | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + $codespace.display_name | Should -Not -BeNullOrEmpty + $codespace.repository.name | Should -Be $repoWithPR.name + $codespace.idle_timeout_minutes | Should -Be 30 + $codespace.owner.UserName | Should -Be $script:OwnerName + $codespace.pulls_url | Should -Be $pullRequest.url + $codespace.template | Should -BeNullOrEmpty + } + + AfterAll { + if ($codespace) + { + Remove-GitHubCodespace -CodespaceName $codespace.name -Confirm:$false + } + } + } + + Context -Name 'When creating a codespace with all possible settings' { + BeforeAll { + $newGitHubCodespaceParms = @{ + # ClientIp = 'TODO ???? - should be instead of rather than in addition to Location, perhaps add some param validation to the function' + # Devcontainer = 'Will add to test in the future when Get-GitHubDevContainer is implemented and the test repo includes one' + DisplayName = 'PowerShellForGitHub pester test' + Location = 'WestUs2' + Machine = 'basicLinux32gb' + NoMultipleRepoPermissions = $true # Not sure how to assert this, but this proves it accepts the switch without error + RetentionPeriod = 10 + Timeout = 5 + # WorkingDirectory = 'TODO ???? - not sure how to handle this' + } + $codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms + } + + It 'Should return an object of the correct type' { + $codespace | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + # $codespace.devcontainer_path | Should -Be + $codespace.display_name | Should -Be $newGitHubCodespaceParms.DisplayName + $codespace.idle_timeout_minutes | Should -Be 5 + $codespace.location | Should -Be $newGitHubCodespaceParms.Location + $codespace.machine.name | Should -Be $newGitHubCodespaceParms.Machine + $codespace.owner.UserName | Should -Be $script:OwnerName + $codespace.repository.name | Should -Be $repo.name + $codespace.retention_period_minutes | Should -Be 10 + $codespace.template | Should -BeNullOrEmpty + } + + AfterAll { + if ($codespace) + { + Remove-GitHubCodespace -CodespaceName $codespace.name -Confirm:$false + } + } + } + + Context -Name 'When creating a codespace with default settings with Repository Elements' { + BeforeAll { + $newGitHubCodespaceParms = @{ + RepositoryName = $repo.name + OwnerName = $script:organizationName + } + $codespace = New-GitHubCodespace @newGitHubCodespaceParms + } + + It 'Should return an object of the correct type' { + $codespace | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + $codespace.display_name | Should -Not -BeNullOrEmpty + $codespace.repository.name | Should -Be $repo.name + $codespace.idle_timeout_minutes | Should -Be 30 + $codespace.owner.UserName | Should -Be $script:OwnerName + $codespace.template | Should -BeNullOrEmpty + } + + AfterAll { + if ($codespace) + { + Remove-GitHubCodespace -CodespaceName $codespace.name -Confirm:$false + } + } + } + } +} + Describe 'GitHubCodespaces\Start-GitHubCodespace' { BeforeAll { # Suppress HTTP 202 warning for codespace creation @@ -207,7 +382,7 @@ Describe 'GitHubCodespaces\Start-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 3 + Start-Sleep -Seconds 2 } Context 'When starting a codespace for the authenticated user' { @@ -238,7 +413,7 @@ Describe 'GitHubCodespaces\Stop-GitHubCodespace' { RepositoryName = $defaultRepositoryName } $null = New-GitHubCodespace @newGitHubCodespaceParms - Start-Sleep -Seconds 3 + Start-Sleep -Seconds 2 } Context 'When stopping a codespace for the authenticated user' { From 19c1596ac7c3d78c679d4096d749b44d01259056 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 18:00:07 -0500 Subject: [PATCH 31/90] New-GitHubCopespace -Timeout ValidateRange(5, 240) --- GitHubCodespaces.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 8111c943..1ff6cbd4 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -384,6 +384,7 @@ function New-GitHubCodespace [ValidateRange(0, 43200)] [int] $RetentionPeriod, + [ValidateRange(5, 240)] [int] $Timeout, [string] $WorkingDirectory, From 5e3a23ea58d36ac9f0780d12facfef3bee5a0b9a Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 18:01:36 -0500 Subject: [PATCH 32/90] Codespaces usage --- USAGE.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/USAGE.md b/USAGE.md index a3acb876..e044d3c5 100644 --- a/USAGE.md +++ b/USAGE.md @@ -141,6 +141,13 @@ * [Removing an environment](#removing-an-environment) * [Advanced](#advanced) * [Migrating blog comments to GitHub issues](#migrating-blog-comments-to-github-issues) + aces + * [Codespaces](#codespaces) + * [Getting codespaces](#getting-codespaces) + * [Creating a codespace](#creating-a-codespace) + * [Removing a codespace](#removing-a-codespace) + * [Starting a codespace](#updating-a-codespace) + * [Stopping a codespace](#starting-a-codespace) ---------- @@ -1288,3 +1295,88 @@ $issue | New-GitHubIssueComment -Body $CommentBody # Close issue $issue | Set-GitHubIssue -State Closed ``` + +---------- + +### Codespaces + +#### Getting codespaces +```powershell +# Get all codespaces for the current authenticated user +Get-GitHubCodespace + +# Get all codespaces for the current authenticated user in a repository +Get-GitHubCodespace -OwnerName microsoft -RepositoryName TestRepo + +# Get all codespaces for an Organizaion +Get-GitHubCodespace -OrganizationName microsoft + +# Get all codespaces for a specific organization user +Get-GitHubCodespace -OrganizationName microsoft -UserName octocat + +# Get a codespace by name +Get-GitHubCodespace -CodespaceName 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' +``` + +#### Create a codespace +```powershell +# Create a codespace in the specified repository by id +New-GitHubCodespace -RepositoryId 582779513 + +# Create a codespace in the specified repository by name +New-GitHubCodespace -OwnerName microsoft -RepositoryName TestRepo + +# Create a codespace in the specified repository by id from a pull request +New-GitHubCodespace -RepositoryId 582779513 -PullRequest 508 + +# Create a codespace in the specified repository by name from a pull request +New-GitHubCodespace -OwnerName microsoft -RepositoryName TestRepo -PullRequest 42 + +# Create a codespace in repository from pipeline +$repo = Get-GitHubRepository -OwnerName microsoft -RepositoryName TestRepo +$repo | New-GitHubCodespace + +# Create a codespace in repository from pipeline with options +$newGitHubCodespaceParms = @{ + DisplayName = 'PowerShellForGitHub usage' + Location = 'WestUs2' + Machine = 'basicLinux32gb' + NoMultipleRepoPermissions = $true + RetentionPeriod = 10 + Timeout = 5 +} +$codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms +``` + +#### Removing a codespace +```powershell +$codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' + +# Remove a codespace for the current authenticated user +Remove-GitHubCodespace -CodespaceName $codespaceName + +# Remove a codespace for an organization user +Remove-GitHubCodespace -Organization microsoft -UserName octocat -CodespaceName $codespaceName +``` + +#### Starting a codespace +```powershell +$codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' + +# Starting a codespace (asynchronous) +Start-GithubCodespace -CodespaceName $codespaceName + +# Starting a codespace (wait for Available) +Start-GithubCodespace -CodespaceName $codespaceName -Wait +``` + +#### Stopping a codespace +```powershell +$codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' + +# Stopping a codespace (asynchronous) +Stop-GithubCodespace -CodespaceName $codespaceName + +# Stopping a codespace (wait for Shutdown) +Stop-GithubCodespace -CodespaceName $codespaceName -Wait +``` \ No newline at end of file From 786f82a82bd782e22e79923abb0c740ae1d08845 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 20:01:47 -0500 Subject: [PATCH 33/90] Remaining Codespaces/organizations coverage --- GitHubCodespaces.ps1 | 267 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 3 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 1ff6cbd4..e10f9910 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -32,7 +32,7 @@ filter Get-GitHubCodespace them individually. .PARAMETER OrganizationName - The name of the organization to retrieve the codespaces for. + Name of the Organization. .PARAMETER UserName The handle for the GitHub user account. @@ -509,7 +509,7 @@ filter Remove-GitHubCodespace The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER OrganizationName - The name of the organization to retrieve the codespaces for. + Name of the Organization. .PARAMETER UserName The handle for the GitHub user account. @@ -719,6 +719,12 @@ filter Stop-GitHubCodespace The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + .PARAMETER OrganizationName + Name of the Organization. + + .PARAMETER UserName + The handle for the GitHub user account(s). + .PARAMETER CodespaceName The name of the codespace. @@ -751,11 +757,20 @@ filter Stop-GitHubCodespace GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint. #> [CmdletBinding( + DefaultParameterSetName = 'AuthenticatedUser', SupportsShouldProcess, ConfirmImpact = 'Low')] [OutputType({ $script:GitHubCodespaceTypeName })] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] param( + [Parameter(Mandatory, + ParameterSetName = 'Organization')] + [string] $OrganizationName, + + [Parameter(Mandatory, + ParameterSetName = 'Organization')] + [string] $UserName, + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] @@ -772,10 +787,24 @@ filter Stop-GitHubCodespace $telemetryProperties = @{ CodespaceName = Get-PiiSafeString -PlainText $CodespaceName + UsageType = $PSCmdlet.ParameterSetName + } + + $uriFragment = [String]::Empty + + if ($PSCmdlet.ParameterSetName -eq 'Organization') + { + $telemetryProperties['OrganizationName'] = Get-PiiSafeString -PlainText $OrganizationName + $telemetryProperties['UserName'] = Get-PiiSafeString -PlainText $UserName + $uriFragment = "orgs/$OrganizationName/members/$UserName/codespaces/$CodespaceName/stop" + } + else + { + $uriFragment = "user/codespaces/$CodespaceName/stop" } $params = @{ - UriFragment = "user/codespaces/$CodespaceName/stop" + UriFragment = $UriFragment Method = 'POST' Description = "Stop Codespace $CodespaceName" AccessToken = $AccessToken @@ -876,6 +905,238 @@ function Wait-GitHubCodespaceAction } } +filter Add-GitHubCodespaceUser +{ + <# + .SYNOPSIS + Add user(s) to Codespaces billing for an organization. + + .DESCRIPTION + Add user(s) to Codespaces billing for an organization. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OrganizationName + Name of the Organization. + + .PARAMETER UserName + The handle for the GitHub user account(s). + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .EXAMPLE + Add-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky + + .OUTPUTS + [PSObject[]] + + .NOTES + To use this endpoint, the billing settings for the organization must be set to selected_members. + For information on how to change this setting please see [these docs](https://docs.github.com/rest/codespaces/organizations#manage-access-control-for-organization-codespaces) + + .NOTES + You must authenticate using an access token with the admin:org scope to use this endpoint. + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#add-users-to-codespaces-billing-for-an-organization + #> + [CmdletBinding(SupportsShouldProcess)] + param ( + [Parameter(Mandatory)] + [string] $OrganizationName, + + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string[]] $UserName, + + [string] $AccessToken + ) + + Write-InvocationLog + + $hashBody = @{ + selected_usernames = @($UserName) + } + + $params = @{ + UriFragment = "orgs/$OrganizationName/codespaces/billing/selected_users" + Body = ConvertTo-Json -InputObject $hashBody + Method = 'POST' + Description = 'Add users to GitHub codespace billing' + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + } + + if (-not $PSCmdlet.ShouldProcess(($UserName -join ','), 'Add Codespace Users')) + { + return + } + Invoke-GHRestMethod @params +} + +filter Remove-GitHubCodespaceUser +{ + <# + .SYNOPSIS + Remove user(s) from Codespaces billing for an organization. + + .DESCRIPTION + Remove user(s) from Codespaces billing for an organization. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OrganizationName + Name of the Organization. + + .PARAMETER UserName + The handle for the GitHub user account(s). + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .EXAMPLE + Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky + + .OUTPUTS + [PSObject[]] + + .NOTES + To use this endpoint, the billing settings for the organization must be set to selected_members. + For information on how to change this setting please see [these docs](https://docs.github.com/rest/codespaces/organizations#manage-access-control-for-organization-codespaces) + + .NOTES + You must authenticate using an access token with the admin:org scope to use this endpoint. + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#removes-users-from-codespaces-billing-for-an-organization + #> + [CmdletBinding(SupportsShouldProcess)] + param ( + [Parameter(Mandatory)] + [string] $OrganizationName, + + [Parameter(Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string[]] $UserName, + + [string] $AccessToken + ) + + Write-InvocationLog + + $hashBody = @{ + selected_usernames = @($UserName) + } + + $params = @{ + UriFragment = "orgs/$OrganizationName/codespaces/billing/selected_users" + Body = ConvertTo-Json -InputObject $hashBody + Method = 'DELETE' + Description = 'Remove users from GitHub codespace billing' + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + } + + if (-not $PSCmdlet.ShouldProcess(($UserName -join ','), 'Remove Codespace Users')) + { + return + } + Invoke-GHRestMethod @params +} + +filter Set-GitHubCodespaceVisibility +{ + <# + .SYNOPSIS + Manage access control for organization codespaces. + + .DESCRIPTION + Manage access control for organization codespaces. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OrganizationName + Name of the Organization. + + .PARAMETER Visibility + Which users can access codespaces in the organization. + Disabled means that no users can access codespaces in the organization. + + .PARAMETER UserName + The handle for the GitHub user account(s). + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .EXAMPLE + Set-GitHubCodespaceVisibility -Visibility selected_members -User HowardWolosky -Force + + .NOTES + You must authenticate using an access token with the admin:org scope to use this endpoint. + + .LINK + https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#manage-access-control-for-organization-codespaces + #> + [CmdletBinding(SupportsShouldProcess, + ConfirmImpact = 'High')] + param ( + [Parameter(Mandatory)] + [string] $OrganizationName, + + [ValidateSet('disabled', 'selected_members', 'all_members', 'all_members_and_outside_collaborators')] + [string] $Visibility, + + [Parameter(ValueFromPipeline, + ValueFromPipelineByPropertyName)] + [string[]] $UserName, + + [switch] $Force, + + [string] $AccessToken + ) + + Write-InvocationLog + + if ($UserName.Count -gt 0 -and $Visibility -ne 'selected_members') + { + $message = 'You can only specify the UserName parameter when the Visibility is set to ''selected_members''' + Write-Log -Message $message -Level Error + throw $message + } + + $hashBody = @{ visibility = $Visibility } + + if ($Visibility -eq 'selected_members') + { + $hashBody.Add('selected_usernames', @($UserName)) + } + + $params = @{ + UriFragment = "orgs/$OrganizationName/codespaces/billing" + Body = ConvertTo-Json -InputObject $hashBody + Method = 'PUT' + Description = 'Set Codespace Visiblity' + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + } + + if ($Force -and (-not $Confirm)) + { + $ConfirmPreference = 'None' + } + + if ($PSCmdLet.ShouldProcess($Visibility, 'Set Codespace Visibility')) + { + Invoke-GHRestMethod @params + } +} + filter Add-GitHubCodespaceAdditionalProperties { <# From 4bfcd8535dce001a6d074a5339540c8e4ef7581a Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 20:31:59 -0500 Subject: [PATCH 34/90] FunctionsToExport +GitHubCodespace organizations --- PowerShellForGitHub.psd1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 8d3e1cac..44e3e8b8 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -69,6 +69,7 @@ # Functions to export from this module FunctionsToExport = @( 'Add-GitHubAssignee', + 'Add-GitHubCodespaceUser', 'Add-GitHubIssueLabel', 'Add-GitHubGistStar', 'Backup-GitHubConfiguration', @@ -160,6 +161,7 @@ 'New-GitHubTeam', 'Remove-GitHubAssignee', 'Remove-GitHubCodespace', + 'Remove-GitHubCodespaceUser', 'Remove-GitHubComment', 'Remove-GitHubDeploymentEnvironment' 'Remove-GitHubGist', @@ -188,6 +190,7 @@ 'Reset-GitHubConfiguration', 'Restore-GitHubConfiguration', 'Set-GitHubAuthentication', + 'Set-GitHubCodespaceVisibility', 'Set-GitHubConfiguration', 'Set-GitHubContent', 'Set-GitHubGist', From e566074845d5e430bc17706f403ccab98701d672 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 21:12:26 -0500 Subject: [PATCH 35/90] USAGE +Codespaces/organizations --- USAGE.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/USAGE.md b/USAGE.md index e044d3c5..5a212ecf 100644 --- a/USAGE.md +++ b/USAGE.md @@ -146,8 +146,15 @@ * [Getting codespaces](#getting-codespaces) * [Creating a codespace](#creating-a-codespace) * [Removing a codespace](#removing-a-codespace) - * [Starting a codespace](#updating-a-codespace) - * [Stopping a codespace](#starting-a-codespace) + * [Starting a codespace](#starting-a-codespace) + * [Stopping a codespace](#stopping-a-codespace) + * [Codespaces/organizations](#codespaces-organizations) + * [Manage access control for codespaces](#manage-organization-codespaces-billing) + * [Add users to Codespaces billing](#adding-users-to-codespaces-billing) + * [Removes users from Codespaces billing](#removing-users-from-codespaces-billing) + * [Getting codespaces](#getting-organization-codespaces) + * [Removing a codespace](#removing-an-organization-codespace) + * [Stopping a codespace](#stopping-an-organization-codespace) ---------- @@ -1308,12 +1315,6 @@ Get-GitHubCodespace # Get all codespaces for the current authenticated user in a repository Get-GitHubCodespace -OwnerName microsoft -RepositoryName TestRepo -# Get all codespaces for an Organizaion -Get-GitHubCodespace -OrganizationName microsoft - -# Get all codespaces for a specific organization user -Get-GitHubCodespace -OrganizationName microsoft -UserName octocat - # Get a codespace by name Get-GitHubCodespace -CodespaceName 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' ``` @@ -1354,9 +1355,6 @@ $codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' # Remove a codespace for the current authenticated user Remove-GitHubCodespace -CodespaceName $codespaceName - -# Remove a codespace for an organization user -Remove-GitHubCodespace -Organization microsoft -UserName octocat -CodespaceName $codespaceName ``` #### Starting a codespace @@ -1379,4 +1377,58 @@ Stop-GithubCodespace -CodespaceName $codespaceName # Stopping a codespace (wait for Shutdown) Stop-GithubCodespace -CodespaceName $codespaceName -Wait +``` + +---------- + +### Codespaces organizations + +#### Manage organization Codespaces billing +```powershell + +# Disable codespace access entirely in the organization. +Set-GitHubCodespaceVisibility -Visibility disabled + +# Allow all organization members to access codespaces. +Set-GitHubCodespaceVisibility -Visibility all_members + +# Limit codespace access to a selected list of organization members. +# Care should be taken with this option, as the users specified will overwrite any active list. +Set-GitHubCodespaceVisibility -Visibility selected_members -UserName FredFlintstone,BarneyRubble +``` + +#### Adding users to Codespaces billing +```powershell +Add-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky,GeorgeJetson +``` + +#### Removing users from Codespaces billing +```powershell +Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky,GeorgeJetson +``` + +#### Getting organization Codespaces +```powershell + +# Get all codespaces for an Organizaion +Get-GitHubCodespace -OrganizationName microsoft + +# Get all codespaces for a specific organization user +Get-GitHubCodespace -OrganizationName microsoft -UserName octocat +``` + +#### Removing an organization Codespace +```powershell +$codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' + +# Remove a codespace for an organization user +Remove-GitHubCodespace -OrganizationName microsoft -UserName octocat -CodespaceName $codespaceName +``` + +#### Stopping an organization Codespace +```powershell +$codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' + +# Stopping a codespace (wait for Shutdown) +Stop-GithubCodespace -OrganizationName microsoft -UserName octocat -CodespaceName $codespaceName -Wait ``` \ No newline at end of file From 041da9cf2839a29c32ad62b4ed08b7d2be7fee33 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 26 May 2023 21:17:57 -0500 Subject: [PATCH 36/90] Consistent CodespaceName help text --- GitHubCodespaces.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index e10f9910..be85f1e7 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -515,7 +515,7 @@ filter Remove-GitHubCodespace The handle for the GitHub user account. .PARAMETER CodespaceName - The name of the codespace. + Name of the Codespace. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the @@ -622,7 +622,7 @@ filter Start-GitHubCodespace The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub .PARAMETER CodespaceName - The name of the codespace. + Name of the Codespace. .PARAMETER Wait If present will wait for the codespace to start. @@ -726,7 +726,7 @@ filter Stop-GitHubCodespace The handle for the GitHub user account(s). .PARAMETER CodespaceName - The name of the codespace. + Name of the Codespace. .PARAMETER Wait If present will wait for the codespace to stop. @@ -842,7 +842,7 @@ function Wait-GitHubCodespaceAction Wait for a Codespace start or stop action. .PARAMETER CodespaceName - The name of the codespace. + Name of the Codespace. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the From 9e76b39f40ee72ba4690dd64aa3d3c9fa5bfa3e4 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 22:57:11 -0500 Subject: [PATCH 37/90] DevContainerPath, Geo, rm blank line --- Formatters/GitHubCodespaces.Format.ps1xml | 2 +- GitHubCodespaces.ps1 | 19 +++++++++---------- Tests/GitHubCodespaces.tests.ps1 | 8 ++++---- USAGE.md | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Formatters/GitHubCodespaces.Format.ps1xml b/Formatters/GitHubCodespaces.Format.ps1xml index 85ac56b9..7cc29a35 100644 --- a/Formatters/GitHubCodespaces.Format.ps1xml +++ b/Formatters/GitHubCodespaces.Format.ps1xml @@ -24,7 +24,7 @@ state - location + geo created_at diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index be85f1e7..6679133a 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -255,18 +255,18 @@ function New-GitHubCodespace Git ref (typically a branch name) for this codespace .PARAMETER ClientIp - IP for location auto-detection when proxying a request. + IP for geo auto-detection when proxying a request. - .PARAMETER Devcontainer + .PARAMETER DevContainerPath Path to devcontainer.json config to use for this codespace. .PARAMETER DisplayName Display name for this codespace - .PARAMETER Location - The requested location for a new codespace. - Best efforts are made to respect this upon creation. + .PARAMETER Geo + The geographic area for this codespace. Assigned by IP if not provided. + Can be one of: EuropeWest, SoutheastAsia, UsEast, UsWest .PARAMETER Machine Machine type to use for this codespace. @@ -371,11 +371,11 @@ function New-GitHubCodespace [string] $ClientIp, - [string] $Devcontainer, + [string] $DevContainerPath, [string] $DisplayName, - [string] $Location, + [string] $Geo, [string] $Machine, @@ -398,9 +398,9 @@ function New-GitHubCodespace $propertyMap = @{ ClientIp = 'client_ip' - Devcontainer = 'devcontainer_path' + DevContainerPath = 'devcontainer_path' DisplayName = 'display_name' - Location = 'location' + Geo = 'geo' Machine = 'machine' Ref = 'ref' RetentionPeriod = 'retention_period_minutes' @@ -411,7 +411,6 @@ function New-GitHubCodespace process { - $telemetryProperties = @{ UsageType = $PSCmdlet.ParameterSetName } diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 29861a1b..5f2646ed 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -304,10 +304,10 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { Context -Name 'When creating a codespace with all possible settings' { BeforeAll { $newGitHubCodespaceParms = @{ - # ClientIp = 'TODO ???? - should be instead of rather than in addition to Location, perhaps add some param validation to the function' - # Devcontainer = 'Will add to test in the future when Get-GitHubDevContainer is implemented and the test repo includes one' + # ClientIp = 'TODO ???? - should be instead of rather than in addition to Geo, perhaps add some param validation to the function' + # DevContainerPath = 'Will add to test in the future when Get-GitHubDevContainer is implemented and the test repo includes one' DisplayName = 'PowerShellForGitHub pester test' - Location = 'WestUs2' + Geo = 'UsWest' Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true # Not sure how to assert this, but this proves it accepts the switch without error RetentionPeriod = 10 @@ -325,7 +325,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { # $codespace.devcontainer_path | Should -Be $codespace.display_name | Should -Be $newGitHubCodespaceParms.DisplayName $codespace.idle_timeout_minutes | Should -Be 5 - $codespace.location | Should -Be $newGitHubCodespaceParms.Location + $codespace.geo | Should -Be $newGitHubCodespaceParms.Geo $codespace.machine.name | Should -Be $newGitHubCodespaceParms.Machine $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.repository.name | Should -Be $repo.name diff --git a/USAGE.md b/USAGE.md index 5a212ecf..4676e608 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1340,7 +1340,7 @@ $repo | New-GitHubCodespace # Create a codespace in repository from pipeline with options $newGitHubCodespaceParms = @{ DisplayName = 'PowerShellForGitHub usage' - Location = 'WestUs2' + Geo = 'UsWest' Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true RetentionPeriod = 10 From c4dd8df6e2ee342c3a5545eeb750e49abf34242d Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 23:21:56 -0500 Subject: [PATCH 38/90] fix Start/Stop PassThru help text --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 6679133a..5466e056 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -627,7 +627,7 @@ filter Start-GitHubCodespace If present will wait for the codespace to start. .PARAMETER PassThru - Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. + Returns the start action result. By default, this cmdlet does not generate any output. You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior of this switch. @@ -731,7 +731,7 @@ filter Stop-GitHubCodespace If present will wait for the codespace to stop. .PARAMETER PassThru - Returns the updated GitHub Issue. By default, this cmdlet does not generate any output. + Returns the stop action result. By default, this cmdlet does not generate any output. You can use "Set-GitHubConfiguration -DefaultPassThru" to control the default behavior of this switch. From 97a919716288542d64bf016fdc97d89090cb0143 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 23:23:51 -0500 Subject: [PATCH 39/90] rm bad PSReviewUnusedParameter PassThru --- GitHubCodespaces.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 5466e056..66e67c62 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -545,7 +545,6 @@ filter Remove-GitHubCodespace DefaultParameterSetName = 'AuthenticatedUser', SupportsShouldProcess, ConfirmImpact = 'High')] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] [Alias('Delete-GitHubCodespace')] param( [Parameter( From 9e7f03a80a8f22e856144465a6b2c237f0bcf002 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 23:35:47 -0500 Subject: [PATCH 40/90] ParameterAtribute formatting --- GitHubCodespaces.ps1 | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 66e67c62..ba210f2f 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -350,8 +350,7 @@ function New-GitHubCodespace [Alias('PullRequestUrl')] [string] $Uri, - [Parameter( - ParameterSetName = 'AuthenticatedUser')] + [Parameter(ParameterSetName = 'AuthenticatedUser')] [Parameter( Mandatory, ParameterSetName = 'ElementsPullRequest')] @@ -363,10 +362,8 @@ function New-GitHubCodespace ParameterSetName = 'AuthenticatedUser')] [Int64] $RepositoryId, - [Parameter( - ParameterSetName = 'AuthenticatedUser')] - [Parameter( - ParameterSetName = 'Elements')] + [Parameter(ParameterSetName = 'AuthenticatedUser')] + [Parameter(ParameterSetName = 'Elements')] [string] $Ref, [string] $ClientIp, @@ -560,7 +557,8 @@ filter Remove-GitHubCodespace [ValidateNotNullOrEmpty()] [String] $UserName, - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $CodespaceName, @@ -656,7 +654,8 @@ filter Start-GitHubCodespace [OutputType({ $script:GitHubCodespaceTypeName })] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] param( - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $CodespaceName, @@ -761,15 +760,18 @@ filter Stop-GitHubCodespace [OutputType({ $script:GitHubCodespaceTypeName })] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Justification = "PassThru is accessed indirectly via Resolve-ParameterWithDefaultConfigurationValue")] param( - [Parameter(Mandatory, + [Parameter( + Mandatory, ParameterSetName = 'Organization')] [string] $OrganizationName, - [Parameter(Mandatory, - ParameterSetName = 'Organization')] + [Parameter( + Mandatory, + ParameterSetName = 'Organization')] [string] $UserName, - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $CodespaceName, @@ -861,7 +863,8 @@ function Wait-GitHubCodespaceAction [CmdletBinding()] [OutputType({ $script:GitHubCodespaceTypeName })] param( - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $CodespaceName, @@ -945,7 +948,8 @@ filter Add-GitHubCodespaceUser [Parameter(Mandatory)] [string] $OrganizationName, - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string[]] $UserName, @@ -1017,7 +1021,8 @@ filter Remove-GitHubCodespaceUser [Parameter(Mandatory)] [string] $OrganizationName, - [Parameter(Mandatory, + [Parameter( + Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string[]] $UserName, @@ -1090,7 +1095,8 @@ filter Set-GitHubCodespaceVisibility [ValidateSet('disabled', 'selected_members', 'all_members', 'all_members_and_outside_collaborators')] [string] $Visibility, - [Parameter(ValueFromPipeline, + [Parameter( + ValueFromPipeline, ValueFromPipelineByPropertyName)] [string[]] $UserName, From a170b4a76494bba1fc90f80c671fd94f2af107e9 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 23:39:24 -0500 Subject: [PATCH 41/90] billable_owner --- GitHubCodespaces.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index ba210f2f..405bee8c 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1193,6 +1193,11 @@ filter Add-GitHubCodespaceAdditionalProperties Add-Member -InputObject $item -Name 'CodespaceName' -Value $item.name -MemberType NoteProperty -Force } + if ($null -ne $item.billable_owner) + { + $null = Add-GitHubUserAdditionalProperties -InputObject $item.billable_owner + } + if ($null -ne $item.owner) { $null = Add-GitHubUserAdditionalProperties -InputObject $item.owner From 022e87f861217b3dbd5dfef3a129e9f22d6eff68 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 23 Jun 2023 23:55:50 -0500 Subject: [PATCH 42/90] rm idle_timeout_minutes Should Be 30 --- Tests/GitHubCodespaces.tests.ps1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 5f2646ed..a67ac2d9 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -218,7 +218,6 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { It 'Should return the correct properties' { $codespace.display_name | Should -Not -BeNullOrEmpty $codespace.repository.name | Should -Be $repo.name - $codespace.idle_timeout_minutes | Should -Be 30 $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.template | Should -BeNullOrEmpty } @@ -253,7 +252,6 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { $codespace.display_name | Should -Not -BeNullOrEmpty $codespace.git_status.ref | Should -Be $pullRequest.head.ref $codespace.repository.name | Should -Be $repoWithPR.name - $codespace.idle_timeout_minutes | Should -Be 30 $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.template | Should -BeNullOrEmpty } @@ -287,7 +285,6 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { It 'Should return the correct properties' { $codespace.display_name | Should -Not -BeNullOrEmpty $codespace.repository.name | Should -Be $repoWithPR.name - $codespace.idle_timeout_minutes | Should -Be 30 $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.pulls_url | Should -Be $pullRequest.url $codespace.template | Should -BeNullOrEmpty @@ -357,7 +354,6 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { It 'Should return the correct properties' { $codespace.display_name | Should -Not -BeNullOrEmpty $codespace.repository.name | Should -Be $repo.name - $codespace.idle_timeout_minutes | Should -Be 30 $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.template | Should -BeNullOrEmpty } From 2cc9acb925f0241d78346cdaf23c53a5c3d72769 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sat, 24 Jun 2023 00:02:24 -0500 Subject: [PATCH 43/90] -super-fake-not-real-org --- Tests/GitHubCodespaces.tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index a67ac2d9..8c85d838 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -232,7 +232,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { Context -Name 'When creating a codespace with default settings with Ref' { BeforeAll { - $repoWithPR = Get-GitHubRepository -OrganizationName 'super-fake-not-real-org' | + $repoWithPR = Get-GitHubRepository -OrganizationName $script:organizationName | Where-Object { $_ | Get-GitHubPullRequest } | Select-Object -First 1 $pullRequest = $repoWithPR | Get-GitHubPullRequest | Select-Object -First 1 @@ -266,7 +266,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { Context -Name 'When creating a codespace with default settings from a PullRequest' { BeforeAll { - $repoWithPR = Get-GitHubRepository -OrganizationName 'super-fake-not-real-org' | + $repoWithPR = Get-GitHubRepository -OrganizationName $script:organizationName | Where-Object { $_ | Get-GitHubPullRequest } | Select-Object -First 1 $pullRequest = $repoWithPR | Get-GitHubPullRequest | Select-Object -First 1 From c9f113d4db74161f8a250f1ea87f6bd737a88ff9 Mon Sep 17 00:00:00 2001 From: vercellone Date: Sat, 24 Jun 2023 00:08:47 -0500 Subject: [PATCH 44/90] IdleRetentionPeriodMinutes --- GitHubCodespaces.ps1 | 6 +++--- Tests/GitHubCodespaces.tests.ps1 | 2 +- USAGE.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 405bee8c..6c808fed 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -274,7 +274,7 @@ function New-GitHubCodespace .PARAMETER NoMultipleRepoPermissions Whether to authorize requested permissions to other repos from devcontainer.json. - .PARAMETER RetentionPeriod + .PARAMETER IdleRetentionPeriodMinutes Duration in minutes (up to 30 days) after codespace has gone idle in which it will be deleted. .PARAMETER Timeout @@ -379,7 +379,7 @@ function New-GitHubCodespace [switch] $NoMultipleRepoPermissions, [ValidateRange(0, 43200)] - [int] $RetentionPeriod, + [int] $IdleRetentionPeriodMinutes, [ValidateRange(5, 240)] [int] $Timeout, @@ -400,7 +400,7 @@ function New-GitHubCodespace Geo = 'geo' Machine = 'machine' Ref = 'ref' - RetentionPeriod = 'retention_period_minutes' + IdleRetentionPeriodMinutes = 'retention_period_minutes' Timeout = 'idle_timeout_minutes' WorkingDirectory = 'working_directory' } diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 8c85d838..180b7ff3 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -307,7 +307,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { Geo = 'UsWest' Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true # Not sure how to assert this, but this proves it accepts the switch without error - RetentionPeriod = 10 + IdleRetentionPeriodMinutes = 10 Timeout = 5 # WorkingDirectory = 'TODO ???? - not sure how to handle this' } diff --git a/USAGE.md b/USAGE.md index 4676e608..ba76c5a1 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1343,7 +1343,7 @@ $newGitHubCodespaceParms = @{ Geo = 'UsWest' Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true - RetentionPeriod = 10 + IdleRetentionPeriodMinutes = 10 Timeout = 5 } $codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms From 2ee7720ffbfaaea0524c4b52f6298024827c64bb Mon Sep 17 00:00:00 2001 From: vercellone Date: Sat, 24 Jun 2023 00:10:06 -0500 Subject: [PATCH 45/90] TimeoutMinutes --- GitHubCodespaces.ps1 | 6 +++--- Tests/GitHubCodespaces.tests.ps1 | 2 +- USAGE.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 6c808fed..7c58e038 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -277,7 +277,7 @@ function New-GitHubCodespace .PARAMETER IdleRetentionPeriodMinutes Duration in minutes (up to 30 days) after codespace has gone idle in which it will be deleted. - .PARAMETER Timeout + .PARAMETER TimeoutMinutes Time in minutes before codespace stops from inactivity. .PARAMETER WorkingDirectory @@ -382,7 +382,7 @@ function New-GitHubCodespace [int] $IdleRetentionPeriodMinutes, [ValidateRange(5, 240)] - [int] $Timeout, + [int] $TimeoutMinutes, [string] $WorkingDirectory, @@ -401,7 +401,7 @@ function New-GitHubCodespace Machine = 'machine' Ref = 'ref' IdleRetentionPeriodMinutes = 'retention_period_minutes' - Timeout = 'idle_timeout_minutes' + TimeoutMinutes = 'idle_timeout_minutes' WorkingDirectory = 'working_directory' } } diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 180b7ff3..196d6db0 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -308,7 +308,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true # Not sure how to assert this, but this proves it accepts the switch without error IdleRetentionPeriodMinutes = 10 - Timeout = 5 + TimeoutMinutes = 5 # WorkingDirectory = 'TODO ???? - not sure how to handle this' } $codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms diff --git a/USAGE.md b/USAGE.md index ba76c5a1..900d5f3e 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1344,7 +1344,7 @@ $newGitHubCodespaceParms = @{ Machine = 'basicLinux32gb' NoMultipleRepoPermissions = $true IdleRetentionPeriodMinutes = 10 - Timeout = 5 + TimeoutMinutes = 5 } $codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms ``` From ef0af38ab6c3e59e2e99cdd21064ba50673d738d Mon Sep 17 00:00:00 2001 From: vercellone Date: Sat, 24 Jun 2023 00:36:25 -0500 Subject: [PATCH 46/90] sync w/feature/GitHubCodespaces --- Tests/GitHubCodespaces.tests.ps1 | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 196d6db0..a149e0da 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -33,7 +33,6 @@ BeforeAll { } Describe 'GitHubCodespaces\Delete-GitHubCodespace' { - Context 'When deleting a codespace for the authenticated user' { BeforeEach { # Suppress HTTP 202 warning for codespace creation @@ -99,10 +98,10 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { } Context 'When getting a codespace for a specified owner and repository' { - BeforeAll { $codespaces = Get-GitHubCodespace @newGitHubCodespaceParms } + It 'Should return objects of the correct type' { $codespaces[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } @@ -121,10 +120,10 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { } Context 'When getting all codespaces for a specified organization' { - BeforeAll { $codespaces = Get-GitHubCodespace -OrganizationName $script:organizationName } + It 'Should return objects of the correct type' { $codespaces[0].PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } @@ -199,9 +198,7 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { Describe 'GitHubCodespaces\New-GitHubCodespace' { - Context -Name 'When creating a repository for the authenticated user' { - Context -Name 'When creating a codespace with default settings with RepositoryId' { BeforeAll { $newGitHubCodespaceParms = @{ @@ -321,12 +318,12 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { It 'Should return the correct properties' { # $codespace.devcontainer_path | Should -Be $codespace.display_name | Should -Be $newGitHubCodespaceParms.DisplayName - $codespace.idle_timeout_minutes | Should -Be 5 - $codespace.geo | Should -Be $newGitHubCodespaceParms.Geo + $codespace.idle_timeout_minutes | Should -Be $newGitHubCodespaceParams.TimeoutMinutes + $codespace.location | Should -Be $newGitHubCodespaceParms.Geo $codespace.machine.name | Should -Be $newGitHubCodespaceParms.Machine $codespace.owner.UserName | Should -Be $script:OwnerName $codespace.repository.name | Should -Be $repo.name - $codespace.retention_period_minutes | Should -Be 10 + $codespace.retention_period_minutes | Should -Be $newGitHubCodespaceParams.IdleRetentionPeriodMinutes $codespace.template | Should -BeNullOrEmpty } From 65fde6064ac85efa0a567f0e839f2dbfeaa46b05 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 15 Sep 2023 18:17:10 -0500 Subject: [PATCH 47/90] Get-GitHubCodespaceMachine --- Formatters/GitHubCodespaces.Format.ps1xml | 36 ++++++ GitHubCodespaces.ps1 | 145 ++++++++++++++++++++++ PowerShellForGitHub.psd1 | 1 + USAGE.md | 14 +++ 4 files changed, 196 insertions(+) diff --git a/Formatters/GitHubCodespaces.Format.ps1xml b/Formatters/GitHubCodespaces.Format.ps1xml index 256de388..95bde172 100644 --- a/Formatters/GitHubCodespaces.Format.ps1xml +++ b/Formatters/GitHubCodespaces.Format.ps1xml @@ -34,5 +34,41 @@ + + + GitHub.CodespaceMachine + + GitHub.CodespaceMachine + + + + + + + name + + + display_name + + + operating_system + + + storage_in_bytes + + + memory_in_bytes + + + cpus + + + prebuild_availability + + + + + + diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 880c4bc3..10b5096a 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -221,6 +221,151 @@ filter Get-GitHubCodespace return ($result | Add-GitHubCodespaceAdditionalProperties) } +filter Get-GitHubCodespaceMachine +{ + <# + .SYNOPSIS + Retrieves the machine types available for a given repository or that a codespace can transition to use. + + .DESCRIPTION + Retrieves information about codespace machine types. + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the Codespace. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. + + .PARAMETER Uri + Uri for the Codespace. + The OwnerName and CodespaceName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER CodespaceName + Name of the Codespace. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .INPUTS + GitHub.Codespace + GitHub.Project + GitHub.Repository + + .OUTPUTS + GitHub.CodespaceMachine + + .EXAMPLE + Get-GitHubCodespaceMachine + + Gets all codespaces for the current authenticated user. + + .EXAMPLE + Get-GitHubCodespace -Uri https://github.com/microsoft/PowerShellForGitHub + + Gets information about the microsoft/PowerShellForGitHub Codespace. + + .EXAMPLE + $repo | Get-GitHubCodespace + + You can pipe in a previous Codespace to get its refreshed information. + + .LINK + https://docs.github.com/en/rest/codespaces/machines?apiVersion=2022-11-28#list-available-machine-types-for-a-repository + + .LINK + https://docs.github.com/en/rest/codespaces/machines?apiVersion=2022-11-28#list-machine-types-for-a-codespace + #> + [CmdletBinding(DefaultParameterSetName = 'CodespaceName')] + [OutputType({ $script:GitHubCodespaceTypeName })] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.')] + param( + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'Elements')] + [string] $OwnerName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'Elements')] + [string] $RepositoryName, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'Uri')] + [Alias('RepositoryUrl')] + [string] $Uri, + + [Parameter( + Mandatory, + ValueFromPipelineByPropertyName, + ParameterSetName = 'CodespaceName')] + [string] $CodespaceName, + + [string] $AccessToken + ) + + Write-InvocationLog + + $telemetryProperties = @{ + UsageType = $PSCmdlet.ParameterSetName + } + + $uriFragment = [String]::Empty + $description = [String]::Empty + switch ($PSCmdlet.ParameterSetName) + { + 'CodespaceName' + { + $telemetryProperties['CodespaceName'] = Get-PiiSafeString -PlainText $CodespaceName + + $uriFragment = "user/codespaces/$CodespaceName/machines" + $description = "Getting user/codespaces/$CodespaceName/machines" + + break + } + + { $_ -in ('Elements', 'Uri') } + { + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties['OwnerName'] = Get-PiiSafeString -PlainText $OwnerName + $telemetryProperties['RepositoryName'] = Get-PiiSafeString -PlainText $RepositoryName + + $uriFragment = "repos/$OwnerName/$RepositoryName/codespaces/machines" + $description = "Getting repos/$OwnerName/$RepositoryName/codespaces/machines" + + break + } + } + + $params = @{ + UriFragment = $uriFragment + Description = $description + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + TelemetryProperties = $telemetryProperties + } + + $result = Invoke-GHRestMethodMultipleResult @params + if ($null -ne $result.machines) + { + $result = $result.machines + } + + return $result +} + function New-GitHubCodespace { <# diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index 44e3e8b8..766daaaa 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -84,6 +84,7 @@ 'Get-GitHubCloneTraffic', 'Get-GitHubCodeOfConduct', 'Get-GitHubCodespace', + 'Get-GitHubCodespaceMachine' 'Get-GitHubConfiguration', 'Get-GitHubContent', 'Get-GitHubDeploymentEnvironment', diff --git a/USAGE.md b/USAGE.md index 900d5f3e..86ef2269 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1431,4 +1431,18 @@ $codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' # Stopping a codespace (wait for Shutdown) Stop-GithubCodespace -OrganizationName microsoft -UserName octocat -CodespaceName $codespaceName -Wait +``` +---------- + +### Codespaces machines + +#### Getting Codespaces machines +```powershell + +# Get machine types a codespace can transition to use +Get-GitHubCodespace | Select-Object -First 1 | Get-GitHubCodespaceMachine + +# Get all achine types available for a given repository based on its configuration +Get-GitHubCodespaceMachine -Owner microsoft -RepositoryName PowerShellForGitHub + ``` \ No newline at end of file From ad04f2c26e1a5713b019f7359cf08f7132f0fa4b Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 15 Sep 2023 18:48:34 -0500 Subject: [PATCH 48/90] PSUseDeclaredVarsMoreThanA..compliance UriFragment --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 10b5096a..be80ec05 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -971,7 +971,7 @@ filter Stop-GitHubCodespace } $params = @{ - UriFragment = "user/codespaces/$CodespaceName/stop" + UriFragment = $uriFragment Method = 'Post' Description = "Stop Codespace $CodespaceName" AccessToken = $AccessToken From b271f8099601cf22760aa7f2bfb066f4594526e6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 15 Sep 2023 18:52:39 -0500 Subject: [PATCH 49/90] USAGE TOC +Codespaces/machines --- USAGE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 86ef2269..59a67636 100644 --- a/USAGE.md +++ b/USAGE.md @@ -155,7 +155,9 @@ * [Getting codespaces](#getting-organization-codespaces) * [Removing a codespace](#removing-an-organization-codespace) * [Stopping a codespace](#stopping-an-organization-codespace) - + * [Codespaces/machines](#codespaces-machines) + * [Getting Codespaces machines](#getting-codespaces-machines) + ---------- ## Full Module Documentation From 2755b2bd7ca26b75a6cbafcac72d5d9eb71f80f6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 15 Sep 2023 19:44:31 -0500 Subject: [PATCH 50/90] access/selected_users uri for CodespaceUser --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index be80ec05..913a6a87 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1132,7 +1132,7 @@ filter Add-GitHubCodespaceUser } $params = @{ - UriFragment = "orgs/$OrganizationName/codespaces/billing/selected_users" + UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" Body = ConvertTo-Json -InputObject $hashBody Method = 'Post' Description = 'Add users to GitHub codespace billing' @@ -1205,7 +1205,7 @@ filter Remove-GitHubCodespaceUser } $params = @{ - UriFragment = "orgs/$OrganizationName/codespaces/billing/selected_users" + UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" Body = ConvertTo-Json -InputObject $hashBody Method = 'Delete' Description = 'Remove users from GitHub codespace billing' From 6f0e5af3613bd3c0ae388756687a90a86113219b Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 15 Sep 2023 19:53:33 -0500 Subject: [PATCH 51/90] Tests: Stop-GitHubCodespace -Org -User Get-GitHubCodespaceMachine --- Tests/GitHubCodespaces.tests.ps1 | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index b8c7d53e..f57129b1 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -200,6 +200,43 @@ Describe 'GitHubCodespaces\Get-GitHubCodespace' { } } +Describe 'GitHubCodespaces\Get-GitHubCodespaceMachine' { + BeforeAll { + # Suppress HTTP 202 warning for codespace creation + $WarningPreference = 'SilentlyContinue' + + $newGitHubCodespaceParms = @{ + OwnerName = $repo.owner.login + RepositoryName = $defaultRepositoryName + } + $null = New-GitHubCodespace @newGitHubCodespaceParms -Wait + } + + Context 'When listing machine types a codespace can transition to' { + BeforeAll { + $codespaceMachine = Get-GitHubCodespace @newGitHubCodespaceParms | Select-Object -First 1 | Get-GitHubCodespaceMachine + } + + It 'Should return an object of the correct type' { + $codespaceMachine | Should -BeOfType PSCustomObject + } + + It 'Should return the correct properties' { + $codespaceMachine.name | Should -Not -BeNullOrEmpty + $codespaceMachine.display_name | Should -Not -BeNullOrEmpty + $codespaceMachine.operating_system | Should -Not -BeNullOrEmpty + $codespaceMachine.storage_in_bytes | Should -Match '^\d+$' + $codespaceMachine.memory_in_bytes | Should -Match '^\d+$' + $codespaceMachine.cpus | Should -Match '^\d+$' + $codespaceMachine.prebuild_availability | Should -Not -BeNullOrEmpty + } + } + + AfterAll { + Get-GitHubCodespace @newGitHubCodespaceParms | Remove-GitHubCodespace -Confirm:$false -Force + } +} + Describe 'GitHubCodespaces\New-GitHubCodespace' { Context -Name 'When creating a repository for the authenticated user' { @@ -443,6 +480,23 @@ Describe 'GitHubCodespaces\Stop-GitHubCodespace' { } } + Context 'When stopping a codespace for an organization user' { + BeforeAll { + $userCodespace = Get-GitHubCodespace -OrganizationName $script:organizationName -UserName $script:OwnerName | Select-Object -First 1 + } + + It 'Should not throw' { + # Also asserts pipeline input + { Stop-GitHubCodespace -OrganizationName $script:organizationName -UserName $script:OwnerName -CodespaceName $userCodespace.name } | Should -Not -Throw + } + + It 'Should become Shutdown' { + # Also asserts Wait and PassThru + $result = Stop-GitHubCodespace -OrganizationName $script:organizationName -UserName $script:OwnerName -CodespaceName $userCodespace.name -Wait -PassThru + $result.State | Should -Be 'Shutdown' + } + } + AfterAll { Get-GitHubCodespace @newGitHubCodespaceParms | Remove-GitHubCodespace -Confirm:$false -Force } From 580a0f7b24b160445d79b2654c0e33b34c60bc15 Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 22 Nov 2023 16:34:27 -0600 Subject: [PATCH 52/90] update codespaces/billing to codespaces/access --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 913a6a87..b91f9875 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1290,7 +1290,7 @@ filter Set-GitHubCodespaceVisibility } $params = @{ - UriFragment = "orgs/$OrganizationName/codespaces/billing" + UriFragment = "orgs/$OrganizationName/codespaces/access" Body = ConvertTo-Json -InputObject $hashBody Method = 'Put' Description = 'Set Codespace Visiblity' From f1df0722f9686c5136907f121ba4a4703992ac20 Mon Sep 17 00:00:00 2001 From: vercellone Date: Wed, 22 Nov 2023 16:35:49 -0600 Subject: [PATCH 53/90] Added missing tests --- Tests/GitHubCodespaces.tests.ps1 | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index f57129b1..b4b89ec1 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -34,6 +34,59 @@ BeforeAll { $mainBranchName = $repo | Get-GitHubRepositoryBranch | Select-Object -ExpandProperty name -First 1 } +Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { + Context 'When setting the visibility of a codespace' { + + It 'sets the visibility successfully too ''disabled'' ' { + $setVisibilityParams = @{ + Force = $true + OrganizationName = $script:organizationName + Visibility = 'disabled' + } + Set-GitHubCodespaceVisibility @setVisibilityParams + } + + It 'sets the visibility successfully too ''all_members'' ' { + $setVisibilityParams = @{ + Force = $true + OrganizationName = $script:organizationName + Visibility = 'all_members' + } + Set-GitHubCodespaceVisibility @setVisibilityParams + } + It 'sets the visibility successfully too ''selected_members'' ' { + $setVisibilityParams = @{ + Force = $true + OrganizationName = $script:organizationName + UserName = $script:ownerName + Visibility = 'selected_members' + } + Set-GitHubCodespaceVisibility @setVisibilityParams + } + + } +} + +Describe 'GitHubCodespaces\Remove-GitHubCodespaceUser' { + Context 'When revoking a user''s access to codespaces for an organization' { + + It 'removes a user successfully' { + { Remove-GitHubCodespaceUser -OrganizationName $script:organizationName -UserName $script:ownerName } | Should -Not -Throw + } + + } +} + +Describe 'GitHubCodespaces\Add-GitHubCodespaceUser' { + Context 'When granting a user access to codespaces for an organization' { + + It 'adds a user successfully' { + { Add-GitHubCodespaceUser -OrganizationName $script:organizationName -UserName $script:ownerName } | Should -Not -Throw + } + + } +} + Describe 'GitHubCodespaces\Delete-GitHubCodespace' { Context 'When deleting a codespace for the authenticated user' { BeforeEach { From d5d9bf2d374f64e910951414de05a0b7b52509d7 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 21:02:15 -0600 Subject: [PATCH 54/90] Organization spelling Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 59a67636..f2361fe2 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1412,7 +1412,7 @@ Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky,G #### Getting organization Codespaces ```powershell -# Get all codespaces for an Organizaion +# Get all codespaces for an Organization Get-GitHubCodespace -OrganizationName microsoft # Get all codespaces for a specific organization user From 4fdf8b0a4860d0b0a039ac3e69c6b86961dceba6 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 21:02:34 -0600 Subject: [PATCH 55/90] machine spelling Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index f2361fe2..23c70c2b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1444,7 +1444,7 @@ Stop-GithubCodespace -OrganizationName microsoft -UserName octocat -CodespaceNam # Get machine types a codespace can transition to use Get-GitHubCodespace | Select-Object -First 1 | Get-GitHubCodespaceMachine -# Get all achine types available for a given repository based on its configuration +# Get all machine types available for a given repository based on its configuration Get-GitHubCodespaceMachine -Owner microsoft -RepositoryName PowerShellForGitHub ``` \ No newline at end of file From 4b11fff98eaefbf74b46ef52ec79d34145651738 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 21:03:00 -0600 Subject: [PATCH 56/90] Codespace capitalization Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 23c70c2b..edec61a6 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1388,7 +1388,7 @@ Stop-GithubCodespace -CodespaceName $codespaceName -Wait #### Manage organization Codespaces billing ```powershell -# Disable codespace access entirely in the organization. +# Disable Codespace access entirely in the organization. Set-GitHubCodespaceVisibility -Visibility disabled # Allow all organization members to access codespaces. From b517fbdac99a878c6b197b09363e7da06a5729a0 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 21:03:22 -0600 Subject: [PATCH 57/90] Codespaces capitalization Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index edec61a6..ae4b42a8 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1391,7 +1391,7 @@ Stop-GithubCodespace -CodespaceName $codespaceName -Wait # Disable Codespace access entirely in the organization. Set-GitHubCodespaceVisibility -Visibility disabled -# Allow all organization members to access codespaces. +# Allow all organization members to access Codespaces. Set-GitHubCodespaceVisibility -Visibility all_members # Limit codespace access to a selected list of organization members. From 177af01f038ff8307eb7ec57f2e7b9a45cd0b3a0 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 21:03:39 -0600 Subject: [PATCH 58/90] Codespace capitalization Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index ae4b42a8..26a09c10 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1394,7 +1394,7 @@ Set-GitHubCodespaceVisibility -Visibility disabled # Allow all organization members to access Codespaces. Set-GitHubCodespaceVisibility -Visibility all_members -# Limit codespace access to a selected list of organization members. +# Limit Codespace access to a selected list of organization members. # Care should be taken with this option, as the users specified will overwrite any active list. Set-GitHubCodespaceVisibility -Visibility selected_members -UserName FredFlintstone,BarneyRubble ``` From 4bfd42228409510e0407780efd5a363b6b2d762b Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 21:19:31 -0600 Subject: [PATCH 59/90] Add TypeName GitHub.CodespaceMachine --- GitHubCodespaces.ps1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index b91f9875..9491922f 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -3,6 +3,7 @@ @{ GitHubCodespaceTypeName = 'GitHub.Codespace' + GitHubCodespaceMachineTypeName = 'GitHub.CodespaceMachine' }.GetEnumerator() | ForEach-Object { Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value } @@ -282,7 +283,7 @@ filter Get-GitHubCodespaceMachine https://docs.github.com/en/rest/codespaces/machines?apiVersion=2022-11-28#list-machine-types-for-a-codespace #> [CmdletBinding(DefaultParameterSetName = 'CodespaceName')] - [OutputType({ $script:GitHubCodespaceTypeName })] + [OutputType({ $Script:GitHubCodespaceMachineTypeName })] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'The Uri parameter is only referenced by Resolve-RepositoryElements which get access to it from the stack via Get-Variable -Scope 1.')] param( [Parameter( @@ -362,8 +363,11 @@ filter Get-GitHubCodespaceMachine { $result = $result.machines } - - return $result + foreach ($machine in $result) + { + $machine.PSObject.TypeNames.Insert(0, $Script:GitHubCodespaceMachineTypeName) + Write-Output $machine + } } function New-GitHubCodespace From 48ee1c6304b5229e919c8e26c2e816291beee5a2 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 21:26:12 -0600 Subject: [PATCH 60/90] rm Get-GitHubCodespaceMachine property validation --- Tests/GitHubCodespaces.tests.ps1 | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index b4b89ec1..0f5219c1 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -273,16 +273,6 @@ Describe 'GitHubCodespaces\Get-GitHubCodespaceMachine' { It 'Should return an object of the correct type' { $codespaceMachine | Should -BeOfType PSCustomObject } - - It 'Should return the correct properties' { - $codespaceMachine.name | Should -Not -BeNullOrEmpty - $codespaceMachine.display_name | Should -Not -BeNullOrEmpty - $codespaceMachine.operating_system | Should -Not -BeNullOrEmpty - $codespaceMachine.storage_in_bytes | Should -Match '^\d+$' - $codespaceMachine.memory_in_bytes | Should -Match '^\d+$' - $codespaceMachine.cpus | Should -Match '^\d+$' - $codespaceMachine.prebuild_availability | Should -Not -BeNullOrEmpty - } } AfterAll { From a4ecc471a22c575e6e5edd091e9e6746d9038b21 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 22:11:26 -0600 Subject: [PATCH 61/90] (Add|Remove)-GitHubCodespaceUser 304 Not Modified --- GitHubCodespaces.ps1 | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 9491922f..18a60386 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1148,7 +1148,21 @@ filter Add-GitHubCodespaceUser { return } - Invoke-GHRestMethod @params + try + { + Invoke-GHRestMethod @params + } + catch + { + if ($_.Exception.Message -like '*(304)*') # Not Modified + { + Write-Log -Message "Codespace selected_users not modified. Requested users already included." -Level Verbose + } + else + { + throw + } + } } filter Remove-GitHubCodespaceUser @@ -1221,7 +1235,21 @@ filter Remove-GitHubCodespaceUser { return } - Invoke-GHRestMethod @params + try + { + Invoke-GHRestMethod @params + } + catch + { + if ($_.Exception.Message -like '*(304)*') # Not Modified + { + Write-Log -Message "Codespace selected_users not modified. Requested users already excluded." -Level Verbose + } + else + { + throw + } + } } filter Set-GitHubCodespaceVisibility From 90b54d0ca5e3394f8fb94f50255f347df9e77aa7 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 22:26:22 -0600 Subject: [PATCH 62/90] (Add|Remove)-GitHubCodespaceUser pipeline tests --- Tests/GitHubCodespaces.tests.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 0f5219c1..3895e3be 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -74,6 +74,11 @@ Describe 'GitHubCodespaces\Remove-GitHubCodespaceUser' { { Remove-GitHubCodespaceUser -OrganizationName $script:organizationName -UserName $script:ownerName } | Should -Not -Throw } + It 'accepts user names from pipeline' { + # By passing in the same user, we are also proving 304 Not Modified is handled + { $script:OwnerName | Remove-GitHubCodespaceUser -OrganizationName $script:organizationName } | Should -Not -Throw + } + } } @@ -84,6 +89,11 @@ Describe 'GitHubCodespaces\Add-GitHubCodespaceUser' { { Add-GitHubCodespaceUser -OrganizationName $script:organizationName -UserName $script:ownerName } | Should -Not -Throw } + It 'accepts user names from pipeline' { + # By passing in the same user, we are also proving 304 Not Modified is handled + { $script:OwnerName | Add-GitHubCodespaceUser -OrganizationName $script:organizationName } | Should -Not -Throw + } + } } From 68607572fe7ce6ea8ec1859be59c7255f2a9c111 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:28:38 -0600 Subject: [PATCH 63/90] Avoid copyrighted names Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 26a09c10..4f97d6d7 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1396,7 +1396,7 @@ Set-GitHubCodespaceVisibility -Visibility all_members # Limit Codespace access to a selected list of organization members. # Care should be taken with this option, as the users specified will overwrite any active list. -Set-GitHubCodespaceVisibility -Visibility selected_members -UserName FredFlintstone,BarneyRubble +Set-GitHubCodespaceVisibility -Visibility selected_members -UserName octocat,heptacat ``` #### Adding users to Codespaces billing From c7a046da4c8b160d95ff8e3cc5617d494ac6d7f7 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:29:55 -0600 Subject: [PATCH 64/90] Avoid copyrighted names Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 4f97d6d7..64e07c25 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1401,7 +1401,7 @@ Set-GitHubCodespaceVisibility -Visibility selected_members -UserName octocat,hep #### Adding users to Codespaces billing ```powershell -Add-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky,GeorgeJetson +Add-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat,heptacat ``` #### Removing users from Codespaces billing From a2aa2601a6e6265d48d7fe0b002c1881e51b1387 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:30:44 -0600 Subject: [PATCH 65/90] Avoid copyrighted names Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 64e07c25..ab34627b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1406,7 +1406,7 @@ Add-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat,heptacat #### Removing users from Codespaces billing ```powershell -Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky,GeorgeJetson +Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat,heptacat ``` #### Getting organization Codespaces From 2dc2efaaf2a8504caef2717fc71705681f6af51d Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:31:49 -0600 Subject: [PATCH 66/90] Codespaces capitalization Co-authored-by: Howard Wolosky --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index ab34627b..20bc99ca 100644 --- a/USAGE.md +++ b/USAGE.md @@ -149,7 +149,7 @@ * [Starting a codespace](#starting-a-codespace) * [Stopping a codespace](#stopping-a-codespace) * [Codespaces/organizations](#codespaces-organizations) - * [Manage access control for codespaces](#manage-organization-codespaces-billing) + * [Manage access control for Codespaces](#manage-organization-codespaces-billing) * [Add users to Codespaces billing](#adding-users-to-codespaces-billing) * [Removes users from Codespaces billing](#removing-users-from-codespaces-billing) * [Getting codespaces](#getting-organization-codespaces) From f23647c15be6822a8bff79dd70ea822781345119 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:34:47 -0600 Subject: [PATCH 67/90] Add suggested LF Co-authored-by: Howard Wolosky --- Tests/GitHubCodespaces.tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 3895e3be..abdeeb7a 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -54,7 +54,8 @@ Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { } Set-GitHubCodespaceVisibility @setVisibilityParams } - It 'sets the visibility successfully too ''selected_members'' ' { + + It 'sets the visibility successfully to ''selected_members'' ' { $setVisibilityParams = @{ Force = $true OrganizationName = $script:organizationName From 94b8e0eb2095019658d0cf9602a8b2197de238d9 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 22:45:26 -0600 Subject: [PATCH 68/90] 6 Codespace capitalization suggestions Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 2 +- USAGE.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 18a60386..f82c3bdb 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1139,7 +1139,7 @@ filter Add-GitHubCodespaceUser UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" Body = ConvertTo-Json -InputObject $hashBody Method = 'Post' - Description = 'Add users to GitHub codespace billing' + Description = 'Add users to GitHub Codespace billing' AccessToken = $AccessToken TelemetryEventName = $MyInvocation.MyCommand.Name } diff --git a/USAGE.md b/USAGE.md index 20bc99ca..ef486dc5 100644 --- a/USAGE.md +++ b/USAGE.md @@ -152,9 +152,9 @@ * [Manage access control for Codespaces](#manage-organization-codespaces-billing) * [Add users to Codespaces billing](#adding-users-to-codespaces-billing) * [Removes users from Codespaces billing](#removing-users-from-codespaces-billing) - * [Getting codespaces](#getting-organization-codespaces) - * [Removing a codespace](#removing-an-organization-codespace) - * [Stopping a codespace](#stopping-an-organization-codespace) + * [Getting Codespaces](#getting-organization-codespaces) + * [Removing a Codespace](#removing-an-organization-codespace) + * [Stopping a Codespace](#stopping-an-organization-codespace) * [Codespaces/machines](#codespaces-machines) * [Getting Codespaces machines](#getting-codespaces-machines) @@ -1431,7 +1431,7 @@ Remove-GitHubCodespace -OrganizationName microsoft -UserName octocat -CodespaceN ```powershell $codespaceName = 'microsoft-symmetrical-chainsaw-7q4vp6v7q3pwqq' -# Stopping a codespace (wait for Shutdown) +# Stopping a Codespace (wait for Shutdown) Stop-GithubCodespace -OrganizationName microsoft -UserName octocat -CodespaceName $codespaceName -Wait ``` ---------- @@ -1441,7 +1441,7 @@ Stop-GithubCodespace -OrganizationName microsoft -UserName octocat -CodespaceNam #### Getting Codespaces machines ```powershell -# Get machine types a codespace can transition to use +# Get machine types a Codespace can transition to use Get-GitHubCodespace | Select-Object -First 1 | Get-GitHubCodespaceMachine # Get all machine types available for a given repository based on its configuration From 307b39b5544b7f51401649a9f4081c91b1b41cd2 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 22:57:22 -0600 Subject: [PATCH 69/90] Uri OwnerName and RepositoryName will be extracted --- GitHubCodespaces.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index f82c3bdb..dbb913ae 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -29,7 +29,7 @@ filter Get-GitHubCodespace .PARAMETER Uri Uri for the Codespace. - The OwnerName and CodespaceName will be extracted from here instead of needing to provide + The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER OrganizationName @@ -243,7 +243,7 @@ filter Get-GitHubCodespaceMachine .PARAMETER Uri Uri for the Codespace. - The OwnerName and CodespaceName will be extracted from here instead of needing to provide + The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER CodespaceName @@ -391,7 +391,7 @@ function New-GitHubCodespace .PARAMETER Uri Uri for the Codespace. - The OwnerName and CodespaceName will be extracted from here instead of needing to provide + The OwnerName and RepositoryName will be extracted from here instead of needing to provide them individually. .PARAMETER PullRequest From a152ae76db19803c22f6ce8d5c5124486b256816 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:13:10 -0600 Subject: [PATCH 70/90] (Add|Remove)-GitHubCodespaceUser OUTPUTS None --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index dbb913ae..1b36e2ff 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1103,7 +1103,7 @@ filter Add-GitHubCodespaceUser Add-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky .OUTPUTS - [PSObject[]] + None .NOTES To use this endpoint, the billing settings for the organization must be set to selected_members. @@ -1190,7 +1190,7 @@ filter Remove-GitHubCodespaceUser Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky .OUTPUTS - [PSObject[]] + None .NOTES To use this endpoint, the billing settings for the organization must be set to selected_members. From c36985065bf090722174c85aeed29778787f5100 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:20:32 -0600 Subject: [PATCH 71/90] selected_members notes --- GitHubCodespaces.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 1b36e2ff..32a1b181 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1106,8 +1106,8 @@ filter Add-GitHubCodespaceUser None .NOTES - To use this endpoint, the billing settings for the organization must be set to selected_members. - For information on how to change this setting please see [these docs](https://docs.github.com/rest/codespaces/organizations#manage-access-control-for-organization-codespaces) + To use this endpoint, the billing settings for the organization must be set to selected_members, + which can done using Set-GitHubCodespaceVisibility -Visibility selected_members. .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. @@ -1193,8 +1193,8 @@ filter Remove-GitHubCodespaceUser None .NOTES - To use this endpoint, the billing settings for the organization must be set to selected_members. - For information on how to change this setting please see [these docs](https://docs.github.com/rest/codespaces/organizations#manage-access-control-for-organization-codespaces) + To use this endpoint, the billing settings for the organization must be set to selected_members, + which can done using Set-GitHubCodespaceVisibility -Visibility selected_members. .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. From c4ec5b791de823c6d42da1a353b73310d1fa242d Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:23:20 -0600 Subject: [PATCH 72/90] (Add|Remove)-GitHubCodespaceUser $null = --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 32a1b181..6630efb5 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1150,7 +1150,7 @@ filter Add-GitHubCodespaceUser } try { - Invoke-GHRestMethod @params + $null = Invoke-GHRestMethod @params } catch { @@ -1237,7 +1237,7 @@ filter Remove-GitHubCodespaceUser } try { - Invoke-GHRestMethod @params + $null = Invoke-GHRestMethod @params } catch { From 6ba94e8bf30785481198dfcb215c4b120431011e Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:27:14 -0600 Subject: [PATCH 73/90] replace UserName HowerWolosky w/octocat --- GitHubCodespaces.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 6630efb5..7db70626 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1100,7 +1100,7 @@ filter Add-GitHubCodespaceUser REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .EXAMPLE - Add-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky + Add-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat .OUTPUTS None @@ -1187,7 +1187,7 @@ filter Remove-GitHubCodespaceUser REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .EXAMPLE - Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName HowardWolosky + Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat .OUTPUTS None From 82c35a1a66efa6632240b790d70adff9d20be65e Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 23:40:59 -0600 Subject: [PATCH 74/90] Detailed manage access control usage Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 7db70626..470578d0 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1260,6 +1260,8 @@ filter Set-GitHubCodespaceVisibility .DESCRIPTION Manage access control for organization codespaces. + Sets which users can access codespaces in an organization. This is synonymous with granting + or revoking Codespaces access permissions for users according to the visibility. The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub From 4c5b7a4f3bbccd5979360ecca54020d4c07cccd9 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 23:42:29 -0600 Subject: [PATCH 75/90] PARAMETER UserName detailed help text Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 470578d0..f9326934 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1273,7 +1273,9 @@ filter Set-GitHubCodespaceVisibility Disabled means that no users can access codespaces in the organization. .PARAMETER UserName - The handle for the GitHub user account(s). + The usernames of the organization member(s) who should have access + to Codespaces in the organization. Required when visibility is SelectedMembers. + The provided list of usernames will replace any existing value. .PARAMETER AccessToken If provided, this will be used as the AccessToken for authentication with the From f8a82f4972538592ed7749fba79a2bbb2196e8b5 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 23:44:46 -0600 Subject: [PATCH 76/90] Set-GitHubCodespaceVisibility -User octocat not howard Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index f9326934..b3a123b8 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1282,7 +1282,7 @@ filter Set-GitHubCodespaceVisibility REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .EXAMPLE - Set-GitHubCodespaceVisibility -Visibility selected_members -User HowardWolosky -Force + Set-GitHubCodespaceVisibility -Visibility selected_members -User octocat -Force .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. From f1fa4f6bc4820c4fa58144a04d5d3736cca7d3e8 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 23:47:03 -0600 Subject: [PATCH 77/90] CmdletBinding SupportsShouldProcess format Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index b3a123b8..b9a8f4b7 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1290,7 +1290,8 @@ filter Set-GitHubCodespaceVisibility .LINK https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#manage-access-control-for-organization-codespaces #> - [CmdletBinding(SupportsShouldProcess, + [CmdletBinding( + SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory)] From a6d81a3dd6029b9bf469194e10ad7865a2a7d9d0 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Thu, 7 Mar 2024 23:48:44 -0600 Subject: [PATCH 78/90] Explicit groupings Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index b9a8f4b7..d41d6b3a 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1312,7 +1312,7 @@ filter Set-GitHubCodespaceVisibility Write-InvocationLog - if ($UserName.Count -gt 0 -and $Visibility -ne 'selected_members') + if (($UserName.Count -gt 0) -and ($Visibility -ne 'selected_members')) { $message = 'You can only specify the UserName parameter when the Visibility is set to ''selected_members''' Write-Log -Message $message -Level Error From a411ec8f1d18ac1b8236a03b51d19d6ca5a04fba Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:52:48 -0600 Subject: [PATCH 79/90] Delete-GitHubCodespaceUser Alias --- GitHubCodespaces.ps1 | 1 + PowerShellForGitHub.psd1 | 1 + 2 files changed, 2 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index d41d6b3a..7bab58e2 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1203,6 +1203,7 @@ filter Remove-GitHubCodespaceUser https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#removes-users-from-codespaces-billing-for-an-organization #> [CmdletBinding(SupportsShouldProcess)] + [Alias('Delete-GitHubCodespaceUser')] param ( [Parameter(Mandatory)] [string] $OrganizationName, diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index ace5f52e..1ed55b2b 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -230,6 +230,7 @@ 'Add-GitHubGistFile', 'Delete-GitHubAsset', 'Delete-GitHubBranch', + 'Delete-GitHubCodespaceUser' 'Delete-GitHubComment', 'Delete-GitHubDeploymentEnvironment', 'Delete-GitHubGist', From 837c1a3eb785e2c4e427396fa55b170af97671d9 Mon Sep 17 00:00:00 2001 From: vercellone Date: Thu, 7 Mar 2024 23:55:37 -0600 Subject: [PATCH 80/90] At this time there is no get visibility --- Tests/GitHubCodespaces.tests.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index abdeeb7a..96bce51e 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -43,6 +43,7 @@ Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { OrganizationName = $script:organizationName Visibility = 'disabled' } + # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams } @@ -52,6 +53,7 @@ Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { OrganizationName = $script:organizationName Visibility = 'all_members' } + # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams } @@ -62,6 +64,7 @@ Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { UserName = $script:ownerName Visibility = 'selected_members' } + # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams } From f44141015629eab0ffca50d365c24aa4189be893 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 00:07:25 -0600 Subject: [PATCH 81/90] (Add|Remove)-GitHubCodespaceUser perf optimization --- GitHubCodespaces.ps1 | 130 ++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 7bab58e2..e9b9eee3 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1078,7 +1078,7 @@ function Wait-GitHubCodespaceAction } } -filter Add-GitHubCodespaceUser +function Add-GitHubCodespaceUser { <# .SYNOPSIS @@ -1129,43 +1129,56 @@ filter Add-GitHubCodespaceUser [string] $AccessToken ) - Write-InvocationLog - - $hashBody = @{ - selected_usernames = @($UserName) + begin { + $userNames = @() } - $params = @{ - UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" - Body = ConvertTo-Json -InputObject $hashBody - Method = 'Post' - Description = 'Add users to GitHub Codespace billing' - AccessToken = $AccessToken - TelemetryEventName = $MyInvocation.MyCommand.Name + process { + foreach ($name in $UserName) + { + $userNames += $name + } } - if (-not $PSCmdlet.ShouldProcess(($UserName -join ','), 'Add Codespace Users')) - { - return - } - try - { - $null = Invoke-GHRestMethod @params - } - catch - { - if ($_.Exception.Message -like '*(304)*') # Not Modified + end { + Write-InvocationLog + + $hashBody = @{ + selected_usernames = @($userNames) + } + + $params = @{ + UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" + Body = ConvertTo-Json -InputObject $hashBody + Method = 'Post' + Description = 'Add users to GitHub Codespace billing' + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + } + + if (-not $PSCmdlet.ShouldProcess(($userNames -join ','), 'Add Codespace Users')) { - Write-Log -Message "Codespace selected_users not modified. Requested users already included." -Level Verbose + return } - else + try + { + $null = Invoke-GHRestMethod @params + } + catch { - throw + if ($_.Exception.Message -like '*(304)*') # Not Modified + { + Write-Log -Message "Codespace selected_users not modified. Requested users already included." -Level Verbose + } + else + { + throw + } } } } -filter Remove-GitHubCodespaceUser +function Remove-GitHubCodespaceUser { <# .SYNOPSIS @@ -1217,38 +1230,51 @@ filter Remove-GitHubCodespaceUser [string] $AccessToken ) - Write-InvocationLog - - $hashBody = @{ - selected_usernames = @($UserName) + begin { + $userNames = @() } - $params = @{ - UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" - Body = ConvertTo-Json -InputObject $hashBody - Method = 'Delete' - Description = 'Remove users from GitHub codespace billing' - AccessToken = $AccessToken - TelemetryEventName = $MyInvocation.MyCommand.Name + process { + foreach ($name in $UserName) + { + $userNames += $name + } } - if (-not $PSCmdlet.ShouldProcess(($UserName -join ','), 'Remove Codespace Users')) - { - return - } - try - { - $null = Invoke-GHRestMethod @params - } - catch - { - if ($_.Exception.Message -like '*(304)*') # Not Modified + end { + Write-InvocationLog + + $hashBody = @{ + selected_usernames = $userNames + } + + $params = @{ + UriFragment = "orgs/$OrganizationName/codespaces/access/selected_users" + Body = ConvertTo-Json -InputObject $hashBody + Method = 'Delete' + Description = 'Remove users from GitHub codespace billing' + AccessToken = $AccessToken + TelemetryEventName = $MyInvocation.MyCommand.Name + } + + if (-not $PSCmdlet.ShouldProcess(($userNames -join ','), 'Remove Codespace Users')) { - Write-Log -Message "Codespace selected_users not modified. Requested users already excluded." -Level Verbose + return } - else + try + { + $null = Invoke-GHRestMethod @params + } + catch { - throw + if ($_.Exception.Message -like '*(304)*') # Not Modified + { + Write-Log -Message "Codespace selected_users not modified. Requested users already excluded." -Level Verbose + } + else + { + throw + } } } } From 69f6a0210b5ab152cd64c82bdddbd3f82109534f Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 00:22:59 -0600 Subject: [PATCH 82/90] SentenceCase Visibility --- GitHubCodespaces.ps1 | 26 ++++++++++++++++---------- Tests/GitHubCodespaces.tests.ps1 | 12 ++++++------ USAGE.md | 6 +++--- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index e9b9eee3..ae1a6211 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1106,8 +1106,8 @@ function Add-GitHubCodespaceUser None .NOTES - To use this endpoint, the billing settings for the organization must be set to selected_members, - which can done using Set-GitHubCodespaceVisibility -Visibility selected_members. + To use this endpoint, the billing settings for the organization must be set to SelectedMembers, + which can done using Set-GitHubCodespaceVisibility -Visibility SelectedMembers. .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. @@ -1206,8 +1206,8 @@ function Remove-GitHubCodespaceUser None .NOTES - To use this endpoint, the billing settings for the organization must be set to selected_members, - which can done using Set-GitHubCodespaceVisibility -Visibility selected_members. + To use this endpoint, the billing settings for the organization must be set to SelectedMembers, + which can done using Set-GitHubCodespaceVisibility -Visibility SelectedMembers. .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. @@ -1309,7 +1309,7 @@ filter Set-GitHubCodespaceVisibility REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. .EXAMPLE - Set-GitHubCodespaceVisibility -Visibility selected_members -User octocat -Force + Set-GitHubCodespaceVisibility -Visibility SelectedMembers -User octocat -Force .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. @@ -1324,7 +1324,7 @@ filter Set-GitHubCodespaceVisibility [Parameter(Mandatory)] [string] $OrganizationName, - [ValidateSet('disabled', 'selected_members', 'all_members', 'all_members_and_outside_collaborators')] + [ValidateSet('Disabled', 'SelectedMembers', 'AllMembers', 'AllMembersAndOutsideCollaborators')] [string] $Visibility, [Parameter( @@ -1339,16 +1339,22 @@ filter Set-GitHubCodespaceVisibility Write-InvocationLog - if (($UserName.Count -gt 0) -and ($Visibility -ne 'selected_members')) + if (($UserName.Count -gt 0) -and ($Visibility -ne 'SelectedMembers')) { - $message = 'You can only specify the UserName parameter when the Visibility is set to ''selected_members''' + $message = 'You can only specify the UserName parameter when the Visibility is set to ''SelectedMembers''' Write-Log -Message $message -Level Error throw $message } - $hashBody = @{ visibility = $Visibility } + $visibilityMap = @{ + Disabled = 'disabled' + SelectedMembers = 'selected_members' + AllMembers = 'all_members' + AllMembersAndOutsideCollaborators = 'all_members_and_outside_collaborators' + } + $hashBody = @{ visibility = $visibilityMap[$Visibility] } - if ($Visibility -eq 'selected_members') + if ($Visibility -eq 'SelectedMembers') { $hashBody.Add('selected_usernames', @($UserName)) } diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index 96bce51e..ef787b4a 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -37,32 +37,32 @@ BeforeAll { Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { Context 'When setting the visibility of a codespace' { - It 'sets the visibility successfully too ''disabled'' ' { + It 'sets the visibility successfully too ''Disabled'' ' { $setVisibilityParams = @{ Force = $true OrganizationName = $script:organizationName - Visibility = 'disabled' + Visibility = 'Disabled' } # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams } - It 'sets the visibility successfully too ''all_members'' ' { + It 'sets the visibility successfully too ''AllMembers'' ' { $setVisibilityParams = @{ Force = $true OrganizationName = $script:organizationName - Visibility = 'all_members' + Visibility = 'AllMembers' } # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams } - It 'sets the visibility successfully to ''selected_members'' ' { + It 'sets the visibility successfully to ''SelectedMembers'' ' { $setVisibilityParams = @{ Force = $true OrganizationName = $script:organizationName UserName = $script:ownerName - Visibility = 'selected_members' + Visibility = 'SelectedMembers' } # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. Set-GitHubCodespaceVisibility @setVisibilityParams diff --git a/USAGE.md b/USAGE.md index ef486dc5..9c2f5b17 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1389,14 +1389,14 @@ Stop-GithubCodespace -CodespaceName $codespaceName -Wait ```powershell # Disable Codespace access entirely in the organization. -Set-GitHubCodespaceVisibility -Visibility disabled +Set-GitHubCodespaceVisibility -Visibility Disabled # Allow all organization members to access Codespaces. -Set-GitHubCodespaceVisibility -Visibility all_members +Set-GitHubCodespaceVisibility -Visibility AllMembers # Limit Codespace access to a selected list of organization members. # Care should be taken with this option, as the users specified will overwrite any active list. -Set-GitHubCodespaceVisibility -Visibility selected_members -UserName octocat,heptacat +Set-GitHubCodespaceVisibility -Visibility SelectedMembers -UserName octocat,heptacat ``` #### Adding users to Codespaces billing From cba3aa480517e2c9f8bff6c46fd37b5011d07225 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 00:35:21 -0600 Subject: [PATCH 83/90] .INPUTS GitHub.User --- GitHubCodespaces.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index ae1a6211..34b9ba60 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1102,6 +1102,9 @@ function Add-GitHubCodespaceUser .EXAMPLE Add-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat + .INPUTS + GitHub.User + .OUTPUTS None @@ -1202,6 +1205,9 @@ function Remove-GitHubCodespaceUser .EXAMPLE Remove-GitHubCodespaceUser -OrganizationName microsoft -UserName octocat + .INPUTS + GitHub.User + .OUTPUTS None @@ -1311,6 +1317,9 @@ filter Set-GitHubCodespaceVisibility .EXAMPLE Set-GitHubCodespaceVisibility -Visibility SelectedMembers -User octocat -Force + .INPUTS + GitHub.User + .NOTES You must authenticate using an access token with the admin:org scope to use this endpoint. From 4d1f9ab5380403178b7c1089bafbbac477017896 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 01:00:30 -0600 Subject: [PATCH 84/90] machines | Add-GitHubCodespaceAdditionalProperties --- GitHubCodespaces.ps1 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 34b9ba60..7d9237b8 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -363,11 +363,7 @@ filter Get-GitHubCodespaceMachine { $result = $result.machines } - foreach ($machine in $result) - { - $machine.PSObject.TypeNames.Insert(0, $Script:GitHubCodespaceMachineTypeName) - Write-Output $machine - } + return ($result | Add-GitHubCodespaceAdditionalProperties -TypeName $Script:GitHubCodespaceMachineTypeName) } function New-GitHubCodespace @@ -1426,7 +1422,7 @@ filter Add-GitHubCodespaceAdditionalProperties if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport)) { - if ($item.name) + if ($item.name -and $TypeName -eq $script:GitHubCodespaceTypeName) { Add-Member -InputObject $item -Name 'CodespaceUrl' -Value "user/codespaces/$($item.name)" -MemberType NoteProperty -Force Add-Member -InputObject $item -Name 'CodespaceName' -Value $item.name -MemberType NoteProperty -Force From 402beb093c992058184a27128fff34a56ea80836 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 01:01:25 -0600 Subject: [PATCH 85/90] better examples --- GitHubCodespaces.ps1 | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 7d9237b8..ebe539c3 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -262,19 +262,26 @@ filter Get-GitHubCodespaceMachine GitHub.CodespaceMachine .EXAMPLE - Get-GitHubCodespaceMachine + Get-GitHubCodespaceMachine -OwnerName microsoft -RepositoryName PowerShellForGitHub - Gets all codespaces for the current authenticated user. - - .EXAMPLE - Get-GitHubCodespace -Uri https://github.com/microsoft/PowerShellForGitHub + Gets all codespace machines for the microsoft/PowerShellForGitHub repository. - Gets information about the microsoft/PowerShellForGitHub Codespace. + name display_name operating_system storage_in_bytes memory_in_bytes cpus prebuild_availability + ---- ------------ ---------------- ---------------- --------------- ---- --------------------- + basicLinux32gb 2 cores, 8 GB RAM, 32 GB storage linux 34359738368 8589934592 2 + standardLinux32gb 4 cores, 16 GB RAM, 32 GB storage linux 34359738368 17179869184 4 + premiumLinux 8 cores, 32 GB RAM, 64 GB storage linux 68719476736 34359738368 8 + largePremiumLinux 16 cores, 64 GB RAM, 128 GB storage linux 137438953472 68719476736 16 .EXAMPLE - $repo | Get-GitHubCodespace + Get-GitHubCodespaceMachine -CodespaceName laughing-chainsaw-8v6qq79wvg6f7x7x - You can pipe in a previous Codespace to get its refreshed information. + Gets all codespace machines available for use by an existing codespace. + + name display_name operating_system storage_in_bytes memory_in_bytes cpus prebuild_availability + ---- ------------ ---------------- ---------------- --------------- ---- --------------------- + basicLinux32gb 2 cores, 8 GB RAM, 32 GB storage linux 34359738368 8589934592 2 ready + standardLinux32gb 4 cores, 16 GB RAM, 32 GB storage linux 34359738368 17179869184 4 ready .LINK https://docs.github.com/en/rest/codespaces/machines?apiVersion=2022-11-28#list-available-machine-types-for-a-repository @@ -454,7 +461,7 @@ function New-GitHubCodespace Creates a new codespace for the current authenticated user in the specified repository from a pull request. .EXAMPLE - New-GitHubCodespace -OwnerName marykay -RepositoryName one + New-GitHubCodespace -OwnerName microsoft -RepositoryName PowerShellForGitHub Creates a codespace owned by the authenticated user in the specified repository. From 0838682758b8c74f6f0bdc0c0bd07980866bece5 Mon Sep 17 00:00:00 2001 From: vercellone Date: Fri, 8 Mar 2024 01:11:51 -0600 Subject: [PATCH 86/90] pipeline validation for SelectedMembers --- Tests/GitHubCodespaces.tests.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index ef787b4a..c184f9da 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -68,6 +68,16 @@ Describe 'GitHubCodespaces\Set-GitHubCodespaceVisibility' { Set-GitHubCodespaceVisibility @setVisibilityParams } + It 'accepts users via the pipeline for visibility ''SelectedMembers'' ' { + $setVisibilityParams = @{ + Force = $true + OrganizationName = $script:organizationName + Visibility = 'SelectedMembers' + } + # At this time, the API does not offer any way to retrieve the current Visibility for a Codespace. The best we can do is validate that this function call doesn't fail. + $script:ownerName | Set-GitHubCodespaceVisibility @setVisibilityParams + } + } } From 273c854c3538be4b9a6b848a4b8de357aa0cf4c6 Mon Sep 17 00:00:00 2001 From: vercellone Date: Mon, 18 Mar 2024 17:47:23 -0500 Subject: [PATCH 87/90] .PSObject.TypeNames[0] | Should -Be --- Tests/GitHubCodespaces.tests.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/GitHubCodespaces.tests.ps1 b/Tests/GitHubCodespaces.tests.ps1 index c184f9da..e97f01ee 100644 --- a/Tests/GitHubCodespaces.tests.ps1 +++ b/Tests/GitHubCodespaces.tests.ps1 @@ -295,7 +295,7 @@ Describe 'GitHubCodespaces\Get-GitHubCodespaceMachine' { } It 'Should return an object of the correct type' { - $codespaceMachine | Should -BeOfType PSCustomObject + $codespaceMachine.PSObject.TypeNames[0] | Should -Be 'GitHub.CodespaceMachine' } } @@ -316,7 +316,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { } It 'Should return an object of the correct type' { - $codespace | Should -BeOfType PSCustomObject + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } It 'Should return the correct properties' { @@ -355,7 +355,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { } It 'Should return an object of the correct type' { - $codespace | Should -BeOfType PSCustomObject + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } It 'Should return the correct properties' { @@ -395,7 +395,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { } It 'Should return an object of the correct type' { - $codespace | Should -BeOfType PSCustomObject + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } It 'Should return the correct properties' { @@ -431,7 +431,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { } It 'Should return an object of the correct type' { - $codespace | Should -BeOfType PSCustomObject + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } It 'Should return the correct properties' { @@ -464,7 +464,7 @@ Describe 'GitHubCodespaces\New-GitHubCodespace' { } It 'Should return an object of the correct type' { - $codespace | Should -BeOfType PSCustomObject + $codespace.PSObject.TypeNames[0] | Should -Be 'GitHub.Codespace' } It 'Should return the correct properties' { From 740001febbc2a188923d95ddd31b731abc6640d7 Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Fri, 12 Apr 2024 21:06:24 -0500 Subject: [PATCH 88/90] nits Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index ebe539c3..17daa769 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -370,6 +370,7 @@ filter Get-GitHubCodespaceMachine { $result = $result.machines } + return ($result | Add-GitHubCodespaceAdditionalProperties -TypeName $Script:GitHubCodespaceMachineTypeName) } @@ -940,7 +941,7 @@ filter Stop-GitHubCodespace [Parameter( Mandatory, - ParameterSetName = 'Organization')] + ParameterSetName = 'Organization')] [string] $UserName, [Parameter( @@ -1135,18 +1136,21 @@ function Add-GitHubCodespaceUser [string] $AccessToken ) - begin { + begin + { $userNames = @() } - process { + process + { foreach ($name in $UserName) { $userNames += $name } } - end { + end + { Write-InvocationLog $hashBody = @{ @@ -1166,6 +1170,7 @@ function Add-GitHubCodespaceUser { return } + try { $null = Invoke-GHRestMethod @params @@ -1239,18 +1244,21 @@ function Remove-GitHubCodespaceUser [string] $AccessToken ) - begin { + begin + { $userNames = @() } - process { + process + { foreach ($name in $UserName) { $userNames += $name } } - end { + end + { Write-InvocationLog $hashBody = @{ @@ -1270,6 +1278,7 @@ function Remove-GitHubCodespaceUser { return } + try { $null = Invoke-GHRestMethod @params @@ -1429,7 +1438,7 @@ filter Add-GitHubCodespaceAdditionalProperties if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport)) { - if ($item.name -and $TypeName -eq $script:GitHubCodespaceTypeName) + if ($item.name -and ($TypeName -eq $script:GitHubCodespaceTypeName)) { Add-Member -InputObject $item -Name 'CodespaceUrl' -Value "user/codespaces/$($item.name)" -MemberType NoteProperty -Force Add-Member -InputObject $item -Name 'CodespaceName' -Value $item.name -MemberType NoteProperty -Force From 0df6ced157add87603d710628604d88ecceaff8e Mon Sep 17 00:00:00 2001 From: Jason Vercellone Date: Fri, 12 Apr 2024 21:13:16 -0500 Subject: [PATCH 89/90] Set-GitHubCodespaceVisibility $null = Invoke-GHRestMethod @params Co-authored-by: Howard Wolosky --- GitHubCodespaces.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 17daa769..552f4de3 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -1396,7 +1396,7 @@ filter Set-GitHubCodespaceVisibility if ($PSCmdLet.ShouldProcess($Visibility, 'Set Codespace Visibility')) { - Invoke-GHRestMethod @params + $null = Invoke-GHRestMethod @params } } From 7e253abf3bec64e6e5f627286dd3689e6be820ee Mon Sep 17 00:00:00 2001 From: vercellone Date: Mon, 15 Apr 2024 23:35:33 -0500 Subject: [PATCH 90/90] Made CodespaceName an optional param of the AuthenticatedUser parameterset for readability --- GitHubCodespaces.ps1 | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/GitHubCodespaces.ps1 b/GitHubCodespaces.ps1 index 552f4de3..6495bc40 100644 --- a/GitHubCodespaces.ps1 +++ b/GitHubCodespaces.ps1 @@ -135,9 +135,8 @@ filter Get-GitHubCodespace [String] $UserName, [Parameter( - Mandatory, ValueFromPipelineByPropertyName, - ParameterSetName = 'CodespaceName')] + ParameterSetName = 'AuthenticatedUser')] [string] $CodespaceName, [string] $AccessToken @@ -155,18 +154,20 @@ filter Get-GitHubCodespace { 'AuthenticatedUser' { - $uriFragment = 'user/codespaces' - $description = 'Getting codespaces for current authenticated user' - - break - } - - 'CodespaceName' - { - $telemetryProperties['CodespaceName'] = Get-PiiSafeString -PlainText $CodespaceName + if ([string]::IsNullOrWhiteSpace($CodespaceName)) + { + # list-codespaces-for-the-authenticated-user + $uriFragment = 'user/codespaces' + $description = 'Getting codespaces for current authenticated user' + } + else + { + # get-a-codespace-for-the-authenticated-user + $telemetryProperties['CodespaceName'] = Get-PiiSafeString -PlainText $CodespaceName - $uriFragment = "user/codespaces/$CodespaceName" - $description = "Getting user/codespaces/$CodespaceName" + $uriFragment = "user/codespaces/$CodespaceName" + $description = "Getting user/codespaces/$CodespaceName" + } break }