Add support for codespaces (#407)
Adds initial support for GitHub Codespaces. #### References Endpoints ~~excluded~~ below will be added in subsequent PRs **[Codespaces/codespaces](https://docs.github.com/en/rest/codespaces/codespaces)** - [x] [List codespaces in a repository for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-in-a-repository-for-the-authenticated-user) - [x] [Create a codespace in a repository](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-in-a-repository) ~~[List devcontainer configurations in a repository for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-devcontainer-configurations-in-a-repository-for-the-authenticated-user)~~ ~~[Get default attributes for a codespace](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#get-default-attributes-for-a-codespace)~~ - [x] [Create a codespace from a pull request](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-from-a-pull-request) - [x] [List codespaces for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-for-the-authenticated-user) - [x] [Create a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-for-the-authenticated-user) - [x] [Get a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#get-a-codespace-for-the-authenticated-user) ~~[Update a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#update-a-codespace-for-the-authenticated-user)~~ - [x] [Delete a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#delete-a-codespace-for-the-authenticated-user) ~~[Export a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#export-a-codespace-for-the-authenticated-user)~~ ~~[Get details about a codespace export](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#get-details-about-a-codespace-export)~~ ~~[Create a repository from an unpublished codespace](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-repository-from-an-unpublished-codespace)~~ - [x] [Start a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#start-a-codespace-for-the-authenticated-user) - [x] [Stop a codespace for the authenticated user](https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#stop-a-codespace-for-the-authenticated-user) **[Codespaces/organizations](https://docs.github.com/en/rest/codespaces/organizations)** - [x] [List codespaces for the organization](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#list-codespaces-for-the-organization) ~~[Manage access control for organization codespaces](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#manage-access-control-for-organization-codespaces)~~ ~~[Add users to Codespaces billing for an organization](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#add-users-to-codespaces-billing-for-an-organization)~~ ~~[Removes users from Codespaces billing for an organization](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#removes-users-from-codespaces-billing-for-an-organization)~~ - [x] [List codespaces for a user in organization](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#list-codespaces-for-a-user-in-organization) - [x] [Delete a codespace from the organization](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#delete-a-codespace-from-the-organization) ~~[Stop a codespace for an organization user](https://docs.github.com/en/rest/codespaces/organizations?apiVersion=2022-11-28#stop-a-codespace-for-an-organization-user)~~
This commit is contained in:
Родитель
482fe23317
Коммит
9ec863b142
|
@ -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)**
|
||||
|
||||
----------
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Configuration>
|
||||
<ViewDefinitions>
|
||||
<!--================== GitHub.Codespace Type View =================-->
|
||||
<View>
|
||||
<Name>GitHub.Codespace</Name>
|
||||
<ViewSelectedBy>
|
||||
<TypeName>GitHub.Codespace</TypeName>
|
||||
</ViewSelectedBy>
|
||||
<TableControl>
|
||||
<TableRowEntries>
|
||||
<TableRowEntry>
|
||||
<TableColumnItems>
|
||||
<TableColumnItem>
|
||||
<PropertyName>id</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>name</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>display_name</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>state</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>created_at</PropertyName>
|
||||
</TableColumnItem>
|
||||
<TableColumnItem>
|
||||
<PropertyName>updated_at</PropertyName>
|
||||
</TableColumnItem>
|
||||
</TableColumnItems>
|
||||
</TableRowEntry>
|
||||
</TableRowEntries>
|
||||
</TableControl>
|
||||
</View>
|
||||
</ViewDefinitions>
|
||||
</Configuration>
|
|
@ -0,0 +1,964 @@
|
|||
# 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 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 OrganizationName
|
||||
Name of the Organization.
|
||||
|
||||
.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.
|
||||
|
||||
.INPUTS
|
||||
GitHub.Codespace
|
||||
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.
|
||||
|
||||
.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 })]
|
||||
[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 = 'Organization')]
|
||||
[string] $OrganizationName,
|
||||
|
||||
[Parameter(
|
||||
ValueFromPipelineByPropertyName,
|
||||
ParameterSetName = 'Organization')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String] $UserName,
|
||||
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipelineByPropertyName,
|
||||
ParameterSetName = 'CodespaceName')]
|
||||
[string] $CodespaceName,
|
||||
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
Write-InvocationLog
|
||||
|
||||
$telemetryProperties = @{
|
||||
UsageType = $PSCmdlet.ParameterSetName
|
||||
}
|
||||
|
||||
$uriFragment = [String]::Empty
|
||||
$description = [String]::Empty
|
||||
switch ($PSCmdlet.ParameterSetName)
|
||||
{
|
||||
'AuthenticatedUser'
|
||||
{
|
||||
$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'
|
||||
{
|
||||
$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
|
||||
}
|
||||
|
||||
{ $_ -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"
|
||||
$description = "Getting $OwnerName/$RepositoryName/codespaces"
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$params = @{
|
||||
UriFragment = $uriFragment
|
||||
Description = $description
|
||||
AccessToken = $AccessToken
|
||||
TelemetryEventName = $MyInvocation.MyCommand.Name
|
||||
TelemetryProperties = $telemetryProperties
|
||||
}
|
||||
|
||||
$result = Invoke-GHRestMethodMultipleResult @params
|
||||
if ($null -ne $result.codespaces)
|
||||
{
|
||||
$result = $result.codespaces
|
||||
}
|
||||
|
||||
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 geo auto-detection when proxying a request.
|
||||
|
||||
.PARAMETER DevContainerPath
|
||||
Path to devcontainer.json config to use for this codespace.
|
||||
|
||||
.PARAMETER DisplayName
|
||||
Display name for this codespace
|
||||
|
||||
.PARAMETER Geo
|
||||
The geographic area for this codespace.
|
||||
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 IdleRetentionPeriodMinutes
|
||||
Duration in minutes (up to 30 days) after codespace has gone idle in which it will be deleted.
|
||||
|
||||
.PARAMETER TimeoutMinutes
|
||||
Time in minutes before codespace stops from inactivity.
|
||||
|
||||
.PARAMETER WorkingDirectory
|
||||
Working directory for this codespace.
|
||||
|
||||
.PARAMETER Wait
|
||||
If present will wait for the codespace to be available.
|
||||
|
||||
.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.
|
||||
|
||||
.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,
|
||||
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, and most of the others get dynamically accessed via $propertyMap.')]
|
||||
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] $DevContainerPath,
|
||||
|
||||
[string] $DisplayName,
|
||||
|
||||
[ValidateSet('EuropeWest', 'SoutheastAsia', 'UsEast', 'UsWest')]
|
||||
[string] $Geo,
|
||||
|
||||
[string] $Machine,
|
||||
|
||||
[switch] $NoMultipleRepoPermissions,
|
||||
|
||||
[ValidateRange(0, 43200)]
|
||||
[int] $IdleRetentionPeriodMinutes,
|
||||
|
||||
[ValidateRange(5, 240)]
|
||||
[int] $TimeoutMinutes,
|
||||
|
||||
[string] $WorkingDirectory,
|
||||
|
||||
[switch] $Wait,
|
||||
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
begin
|
||||
{
|
||||
Write-InvocationLog
|
||||
|
||||
$propertyMap = @{
|
||||
ClientIp = 'client_ip'
|
||||
DevContainerPath = 'devcontainer_path'
|
||||
DisplayName = 'display_name'
|
||||
Geo = 'geo'
|
||||
Machine = 'machine'
|
||||
Ref = 'ref'
|
||||
IdleRetentionPeriodMinutes = 'retention_period_minutes'
|
||||
TimeoutMinutes = 'idle_timeout_minutes'
|
||||
WorkingDirectory = 'working_directory'
|
||||
}
|
||||
}
|
||||
|
||||
process
|
||||
{
|
||||
$telemetryProperties = @{
|
||||
UsageType = $PSCmdlet.ParameterSetName
|
||||
Wait = $Wait.IsPresent
|
||||
}
|
||||
|
||||
$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 -Depth 5)
|
||||
Method = 'Post'
|
||||
Description = $description
|
||||
AccessToken = $AccessToken
|
||||
TelemetryEventName = $MyInvocation.MyCommand.Name
|
||||
TelemetryProperties = $telemetryProperties
|
||||
}
|
||||
|
||||
if (-not $PSCmdlet.ShouldProcess($RepositoryName, 'Create GitHub Codespace'))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
$result = (Invoke-GHRestMethod @params | Add-GitHubCodespaceAdditionalProperties)
|
||||
|
||||
if ($Wait.IsPresent)
|
||||
{
|
||||
$waitParams = @{
|
||||
CodespaceName = $result.CodespaceName
|
||||
AccessToken = $AccessToken
|
||||
}
|
||||
|
||||
$result = Wait-GitHubCodespaceAction @waitParams
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Name of the Organization.
|
||||
|
||||
.PARAMETER UserName
|
||||
The handle for the GitHub user account.
|
||||
|
||||
.PARAMETER CodespaceName
|
||||
Name of the Codespace.
|
||||
|
||||
.PARAMETER Force
|
||||
If this switch is specified, you will not be prompted for confirmation of command execution.
|
||||
|
||||
.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,
|
||||
ConfirmImpact = 'High')]
|
||||
[Alias('Delete-GitHubCodespace')]
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipelineByPropertyName,
|
||||
ParameterSetName = 'Organization')]
|
||||
[string] $OrganizationName,
|
||||
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipelineByPropertyName,
|
||||
ParameterSetName = 'Organization')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String] $UserName,
|
||||
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipeline,
|
||||
ValueFromPipelineByPropertyName)]
|
||||
[string] $CodespaceName,
|
||||
|
||||
[switch] $Force,
|
||||
|
||||
[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 ($Force -and (-not $Confirm))
|
||||
{
|
||||
$ConfirmPreference = 'None'
|
||||
}
|
||||
|
||||
if (-not $PSCmdlet.ShouldProcess($CodespaceName, "Remove Codespace $CodespaceName"))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
Invoke-GHRestMethod @params | Out-Null
|
||||
}
|
||||
|
||||
filter Start-GitHubCodespace
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Start a Codespace for the currently authenticated user.
|
||||
|
||||
.DESCRIPTION
|
||||
Start a Codespace for the currently authenticated user.
|
||||
|
||||
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
|
||||
|
||||
.PARAMETER CodespaceName
|
||||
Name of the Codespace.
|
||||
|
||||
.PARAMETER Wait
|
||||
If present will wait for the codespace to start.
|
||||
|
||||
.PARAMETER PassThru
|
||||
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.
|
||||
|
||||
.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
|
||||
|
||||
.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,
|
||||
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] $Wait,
|
||||
|
||||
[switch] $PassThru,
|
||||
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
Write-InvocationLog
|
||||
|
||||
$telemetryProperties = @{
|
||||
CodespaceName = Get-PiiSafeString -PlainText $CodespaceName
|
||||
Wait = $Wait.IsPresent
|
||||
}
|
||||
|
||||
$params = @{
|
||||
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"))
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
filter Stop-GitHubCodespace
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Stop a Codespace for the currently authenticated user.
|
||||
|
||||
.DESCRIPTION
|
||||
Stop a Codespace for the currently authenticated user.
|
||||
|
||||
The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
|
||||
|
||||
.PARAMETER CodespaceName
|
||||
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 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
|
||||
|
||||
.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,
|
||||
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] $Wait,
|
||||
|
||||
[switch] $PassThru,
|
||||
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
Write-InvocationLog
|
||||
|
||||
$telemetryProperties = @{
|
||||
CodespaceName = Get-PiiSafeString -PlainText $CodespaceName
|
||||
Wait = $Wait.IsPresent
|
||||
}
|
||||
|
||||
$params = @{
|
||||
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"))
|
||||
{
|
||||
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
|
||||
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
|
||||
|
||||
.NOTES
|
||||
Internal-only helper method.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
[OutputType({ $script:GitHubCodespaceTypeName })]
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory,
|
||||
ValueFromPipeline,
|
||||
ValueFromPipelineByPropertyName)]
|
||||
[string] $CodespaceName,
|
||||
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
begin
|
||||
{
|
||||
$sleepSeconds = $(Get-GitHubConfiguration -Name 'StateChangeDelaySeconds')
|
||||
|
||||
# 2s minimum
|
||||
if ($sleepSeconds -lt 2)
|
||||
{
|
||||
$sleepSeconds = 2
|
||||
}
|
||||
}
|
||||
|
||||
process
|
||||
{
|
||||
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
|
||||
$codespace = (Get-GitHubCodespace @PSBoundParameters)
|
||||
Write-Log -Message "[$CodespaceName] state is $($codespace.state)" -Level Verbose
|
||||
}
|
||||
until ($codespace.state -notmatch 'Queued|ing')
|
||||
|
||||
return $codespace
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
.INPUTS
|
||||
[PSCustomObject]
|
||||
|
||||
.OUTPUTS
|
||||
GitHub.Codespace
|
||||
#>
|
||||
[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.billable_owner)
|
||||
{
|
||||
$null = Add-GitHubUserAdditionalProperties -InputObject $item.billable_owner
|
||||
}
|
||||
|
||||
if ($null -ne $item.owner)
|
||||
{
|
||||
$null = Add-GitHubUserAdditionalProperties -InputObject $item.owner
|
||||
}
|
||||
|
||||
if ($null -ne $item.repository)
|
||||
{
|
||||
$null = Add-GitHubRepositoryAdditionalProperties -InputObject $item.repository
|
||||
Add-Member -InputObject $item -Name 'RepositoryUrl' -Value $item.repository.RepositoryUrl -MemberType NoteProperty -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output $item
|
||||
}
|
||||
}
|
|
@ -997,6 +997,7 @@ $script:datePropertyNames = @(
|
|||
'due_on',
|
||||
'last_edited_at',
|
||||
'last_read_at',
|
||||
'last_used_at',
|
||||
'merged_at',
|
||||
'published_at',
|
||||
'pushed_at',
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
FormatsToProcess = @(
|
||||
'Formatters/GitHubBranches.Format.ps1xml',
|
||||
'Formatters/GitHubCodespaces.Format.ps1xml',
|
||||
'Formatters/GitHubDeployments.Format.ps1xml',
|
||||
'Formatters/GitHubGistComments.Format.ps1xml',
|
||||
'Formatters/GitHubGists.Format.ps1xml',
|
||||
|
@ -34,6 +35,7 @@
|
|||
'GitHubAnalytics.ps1',
|
||||
'GitHubAssignees.ps1',
|
||||
'GitHubBranches.ps1',
|
||||
'GitHubCodespaces.ps1',
|
||||
'GitHubCore.ps1',
|
||||
'GitHubContents.ps1',
|
||||
'GitHubEvents.ps1',
|
||||
|
@ -80,6 +82,7 @@
|
|||
'Get-GitHubAssignee',
|
||||
'Get-GitHubCloneTraffic',
|
||||
'Get-GitHubCodeOfConduct',
|
||||
'Get-GitHubCodespace',
|
||||
'Get-GitHubConfiguration',
|
||||
'Get-GitHubContent',
|
||||
'Get-GitHubDeploymentEnvironment',
|
||||
|
@ -134,6 +137,7 @@
|
|||
'Move-GitHubProjectCard',
|
||||
'Move-GitHubProjectColumn',
|
||||
'Move-GitHubRepositoryOwnership',
|
||||
'New-GitHubCodespace',
|
||||
'New-GitHubDeploymentEnvironment',
|
||||
'New-GitHubGist',
|
||||
'New-GitHubGistComment',
|
||||
|
@ -155,6 +159,7 @@
|
|||
'New-GitHubRepositoryFork',
|
||||
'New-GitHubTeam',
|
||||
'Remove-GitHubAssignee',
|
||||
'Remove-GitHubCodespace',
|
||||
'Remove-GitHubComment',
|
||||
'Remove-GitHubDeploymentEnvironment'
|
||||
'Remove-GitHubGist',
|
||||
|
@ -207,6 +212,8 @@
|
|||
'Set-GitHubRepositoryTopic',
|
||||
'Set-GitHubTeam',
|
||||
'Split-GitHubUri',
|
||||
'Start-GitHubCodespace',
|
||||
'Stop-GitHubCodespace',
|
||||
'Test-GitHubAssignee',
|
||||
'Test-GitHubAuthenticationConfigured',
|
||||
'Test-GitHubGistStar',
|
||||
|
|
|
@ -0,0 +1,450 @@
|
|||
# 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
|
||||
}
|
||||
|
||||
$newGitHubRepositoryParms = @{
|
||||
AutoInit = $true
|
||||
Private = $true
|
||||
RepositoryName = $defaultRepositoryName
|
||||
OrganizationName = $script:organizationName
|
||||
}
|
||||
$repo = New-GitHubRepository @newGitHubRepositoryParms
|
||||
# Get the main/master branch name
|
||||
$mainBranchName = $repo | Get-GitHubRepositoryBranch | Select-Object -ExpandProperty name -First 1
|
||||
}
|
||||
|
||||
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 = $repo.owner.login
|
||||
RepositoryName = $defaultRepositoryName
|
||||
}
|
||||
$codespace = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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
|
||||
$WarningPreference = 'SilentlyContinue'
|
||||
|
||||
$newGitHubCodespaceParms = @{
|
||||
OwnerName = $repo.owner.login
|
||||
RepositoryName = $defaultRepositoryName
|
||||
}
|
||||
$null = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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 | Where-Object { $_ }).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 | Where-Object { $_ }).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 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
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
Get-GitHubCodespace @newGitHubCodespaceParms | Remove-GitHubCodespace -Confirm:$false -Force
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 -Wait
|
||||
}
|
||||
|
||||
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.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 {
|
||||
$prBranchName = 'testCodespaceByRef'
|
||||
$prBranch = $repo | New-GitHubRepositoryBranch -BranchName $mainBranchName -TargetBranchName $prBranchName
|
||||
$setContentParms = @{
|
||||
Path = 'README.md'
|
||||
Content = 'When creating a codespace with default settings with Ref'
|
||||
CommitMessage = $prBranchName
|
||||
BranchName = $prBranchName
|
||||
}
|
||||
$repo | Set-GitHubContent @setContentParms
|
||||
$pullRequest = $prBranch | New-GitHubPullRequest -Title $prBranchName -Head $prBranchName -Base $mainBranchName
|
||||
|
||||
$newGitHubCodespaceParms = @{
|
||||
Ref = $pullRequest.head.ref
|
||||
RepositoryId = $repo.Id
|
||||
}
|
||||
$codespace = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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 $repo.name
|
||||
$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 {
|
||||
$prBranchName = 'testCodespaceFromPR'
|
||||
$prBranch = $repo | New-GitHubRepositoryBranch -BranchName $mainBranchName -TargetBranchName $prBranchName
|
||||
$setContentParms = @{
|
||||
Path = 'README.md'
|
||||
Content = 'When creating a codespace with default settings from a PullRequest'
|
||||
CommitMessage = $prBranchName
|
||||
BranchName = $prBranchName
|
||||
}
|
||||
$repo | Set-GitHubContent @setContentParms
|
||||
$pullRequest = $prBranch | New-GitHubPullRequest -Title $prBranchName -Head $prBranchName -Base $mainBranchName
|
||||
|
||||
$newGitHubCodespaceParms = @{
|
||||
PullRequest = $pullRequest.number
|
||||
RepositoryId = $repo.Id
|
||||
}
|
||||
$codespace = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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.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 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'
|
||||
Geo = 'UsWest' # location was deprecated in favor of Geo
|
||||
Machine = 'basicLinux32gb'
|
||||
NoMultipleRepoPermissions = $true # Not sure how to assert this, but this proves it accepts the switch without error
|
||||
IdleRetentionPeriodMinutes = 10
|
||||
TimeoutMinutes = 5
|
||||
# WorkingDirectory = 'TODO ???? - not sure how to handle this'
|
||||
}
|
||||
$codespace = $repo | New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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 $newGitHubCodespaceParms.TimeoutMinutes
|
||||
$codespace.location | Should -Match 'WestUs' # location should align with our requested 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 $newGitHubCodespaceParms.IdleRetentionPeriodMinutes
|
||||
$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 = $repo.owner.login
|
||||
}
|
||||
$codespace = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
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.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
|
||||
$WarningPreference = 'SilentlyContinue'
|
||||
|
||||
$newGitHubCodespaceParms = @{
|
||||
OwnerName = $repo.owner.login
|
||||
RepositoryName = $defaultRepositoryName
|
||||
}
|
||||
$null = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
Context 'When starting a codespace for the authenticated user' {
|
||||
BeforeAll {
|
||||
$codespace = Get-GitHubCodespace @newGitHubCodespaceParms | Select-Object -First 1
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
Get-GitHubCodespace @newGitHubCodespaceParms | Remove-GitHubCodespace -Confirm:$false -Force
|
||||
}
|
||||
}
|
||||
|
||||
Describe 'GitHubCodespaces\Stop-GitHubCodespace' {
|
||||
BeforeAll {
|
||||
# Suppress HTTP 202 warning for codespace creation
|
||||
$WarningPreference = 'SilentlyContinue'
|
||||
|
||||
$newGitHubCodespaceParms = @{
|
||||
OwnerName = $repo.owner.login
|
||||
RepositoryName = $defaultRepositoryName
|
||||
}
|
||||
$null = New-GitHubCodespace @newGitHubCodespaceParms -Wait
|
||||
}
|
||||
|
||||
Context 'When stopping a codespace for the authenticated user' {
|
||||
BeforeAll {
|
||||
$codespace = Get-GitHubCodespace @newGitHubCodespaceParms | Select-Object -First 1
|
||||
}
|
||||
|
||||
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 {
|
||||
Get-GitHubCodespace @newGitHubCodespaceParms | Remove-GitHubCodespace -Confirm:$false -Force
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Restore-GitHubConfiguration -Path $script:originalConfigFile
|
||||
$script:originalConfigFile = $null
|
||||
}
|
||||
}
|
117
USAGE.md
117
USAGE.md
|
@ -141,6 +141,17 @@
|
|||
* [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](#starting-a-codespace)
|
||||
* [Stopping a codespace](#stopping-a-codespace)
|
||||
* [Codespaces](#codespaces-organizations)
|
||||
* [Getting codespaces](#getting-organization-codespaces)
|
||||
* [Removing a codespace](#removing-an-organization-codespace)
|
||||
* [Stopping a codespace](#stopping-an-organization-codespace)
|
||||
|
||||
----------
|
||||
|
||||
|
@ -1288,3 +1299,109 @@ $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 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'
|
||||
Geo = 'UsWest'
|
||||
Machine = 'basicLinux32gb'
|
||||
NoMultipleRepoPermissions = $true
|
||||
IdleRetentionPeriodMinutes = 10
|
||||
TimeoutMinutes = 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
|
||||
```
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
----------
|
||||
|
||||
### Codespaces organizations
|
||||
|
||||
#### Getting organization Codespaces
|
||||
```powershell
|
||||
|
||||
# Get all codespaces for an Organization
|
||||
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
|
||||
```
|
Загрузка…
Ссылка в новой задаче