From 6b501fcb0c6775fd04af9796de0aa065c1a4a415 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 25 Nov 2024 09:48:12 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=9A=80=20[Feature]:=20Implement=20Git?= =?UTF-8?q?Hub=20team=20management=20functions=20(Create,=20Update,=20Dele?= =?UTF-8?q?te,=20Get)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/Teams/Delete-GitHubTeam.ps1 | 45 +++++++++ .../public/Teams/Get-GitHubTeamByName.ps1 | 43 +++++++++ .../public/Teams/Get-GitHubTeamListByOrg.ps1 | 37 +++++++ src/functions/public/Teams/New-GitHubTeam.ps1 | 96 +++++++++++++++++++ .../public/Teams/Update-GitHubTeam.ps1 | 92 ++++++++++++++++++ tools/utilities/GitHubAPI.ps1 | 4 +- 6 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 src/functions/public/Teams/Delete-GitHubTeam.ps1 create mode 100644 src/functions/public/Teams/Get-GitHubTeamByName.ps1 create mode 100644 src/functions/public/Teams/Get-GitHubTeamListByOrg.ps1 create mode 100644 src/functions/public/Teams/New-GitHubTeam.ps1 create mode 100644 src/functions/public/Teams/Update-GitHubTeam.ps1 diff --git a/src/functions/public/Teams/Delete-GitHubTeam.ps1 b/src/functions/public/Teams/Delete-GitHubTeam.ps1 new file mode 100644 index 00000000..cce03071 --- /dev/null +++ b/src/functions/public/Teams/Delete-GitHubTeam.ps1 @@ -0,0 +1,45 @@ +function Remove-GitHubTeam { + <# + .SYNOPSIS + Delete a team + + .DESCRIPTION + To delete a team, the authenticated user must be an organization owner or team maintainer. + If you are an organization owner, deleting a parent team will delete all of its child teams as well. + + .EXAMPLE + An example + + .NOTES + General notes + #> + [OutputType([void])] + [CmdletBinding(SupportsShouldProcess)] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # The slug of the team name. + [Parameter(Mandatory)] + [Alias('Team', 'TeamName', 'slug', 'team_slug')] + [string] $Name, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name DefaultContext) + ) + + $inputObject = @{ + Context = $Context + Method = 'Delete' + APIEndpoint = "/orgs/$Organization/teams/$Name" + } + + if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Delete')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } + } +} diff --git a/src/functions/public/Teams/Get-GitHubTeamByName.ps1 b/src/functions/public/Teams/Get-GitHubTeamByName.ps1 new file mode 100644 index 00000000..39e87bfa --- /dev/null +++ b/src/functions/public/Teams/Get-GitHubTeamByName.ps1 @@ -0,0 +1,43 @@ +function Get-GitHubTeamByName { + <# + .SYNOPSIS + Get a team by name + + .DESCRIPTION + Gets a team using the team's slug. To create the slug, GitHub replaces special characters in the name string, changes all words to lowercase, + and replaces spaces with a - separator. For example, "My TEam Näme" would become my-team-name. + + .EXAMPLE + Get-GitHubTeamByName -Organization 'github' -Name 'my-team-name' + + .NOTES + [Get team by name](https://docs.github.com/en/rest/teams/teams#get-a-team-by-name) + #> + [OutputType([void])] + [CmdletBinding()] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # The slug of the team name. + [Parameter(Mandatory)] + [Alias('Team', 'TeamName', 'slug', 'team_slug')] + [string] $Name, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name DefaultContext) + ) + + $inputObject = @{ + Context = $Context + Method = 'Get' + APIEndpoint = "/orgs/$Organization/teams/$Name" + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } +} diff --git a/src/functions/public/Teams/Get-GitHubTeamListByOrg.ps1 b/src/functions/public/Teams/Get-GitHubTeamListByOrg.ps1 new file mode 100644 index 00000000..d3fa493a --- /dev/null +++ b/src/functions/public/Teams/Get-GitHubTeamListByOrg.ps1 @@ -0,0 +1,37 @@ +function Get-GitHubTeamListByOrg { + <# + .SYNOPSIS + List teams + + .DESCRIPTION + Lists all teams in an organization that are visible to the authenticated user. + + .EXAMPLE + Get-GitHubTeamListByOrg -Organization 'github' + + .NOTES + [List teams](https://docs.github.com/rest/teams/teams#list-teams) + #> + [OutputType([pscustomobject])] + [CmdletBinding()] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name DefaultContext) + ) + + $inputObject = @{ + Context = $Context + Method = 'Get' + APIEndpoint = "/orgs/$Organization/teams" + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } +} diff --git a/src/functions/public/Teams/New-GitHubTeam.ps1 b/src/functions/public/Teams/New-GitHubTeam.ps1 new file mode 100644 index 00000000..4a8b6b63 --- /dev/null +++ b/src/functions/public/Teams/New-GitHubTeam.ps1 @@ -0,0 +1,96 @@ +function New-GitHubTeam { + <# + .SYNOPSIS + Create a team + + .DESCRIPTION + To create a team, the authenticated user must be a member or owner of `{org}`. By default, organization members can create teams. + Organization owners can limit team creation to organization owners. For more information, see + "[Setting team creation permissions](https://docs.github.com/articles/setting-team-creation-permissions-in-your-organization)." + + When you create a new team, you automatically become a team maintainer without explicitly adding yourself to the optional array of + `maintainers`. For more information, see + "[About teams](https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/about-teams)". + + .NOTES + [Create a team](https://docs.github.com/rest/teams/teams#create-a-team) + #> + [CmdletBinding(SupportsShouldProcess)] + param( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # The name of the team. + [Parameter(Mandatory)] + [string] $Name, + + # The description of the team. + [Parameter()] + [string] $Description, + + # List GitHub IDs for organization members who will become team maintainers. + [Parameter()] + [string[]] $Maintainers, + + # The full name (e.g., "organization-name/repository-name") of repositories to add the team to. + [Parameter()] + [string[]] $RepoNames, + + # The level of privacy this team should have. The options are: + # For a non-nested team: + # - secret - only visible to organization owners and members of this team. + # - closed - visible to all members of this organization. + # Default: secret + # For a parent or child team: + # - closed - visible to all members of this organization. + # Default for child team: closed + [Parameter()] + [ValidateSet('secret', 'closed')] + [string] $Privacy = 'closed', + + # The notification setting the team has chosen. The options are: + # notifications_enabled - team members receive notifications when the team is @mentioned. + # notifications_disabled - no one receives notifications. + # Default: notifications_enabled + [Parameter()] + [ValidateSet('notifications_enabled', 'notifications_disabled')] + [string] $NotificationSetting, + + # Closing down notice. The permission that new repositories will be added to the team with when none is specified. + [Parameter()] + [ValidateSet('pull', 'push')] + [string] $Permission = 'pull', + + # The ID of a team to set as the parent team. + [Parameter()] + [int] $ParentTeamID + ) + + $body = @{ + name = $Name + description = $Description + maintainers = $Maintainers + repo_names = $RepoNames + privacy = $Privacy + notification_setting = $NotificationSetting + permission = $Permission + parent_team_id = $ParentTeamID + } + + $body | Remove-HashtableEntry -NullOrEmptyValues + + $inputObject = @{ + Context = $Context + Method = 'POST' + Body = $body + APIEndpoint = "/orgs/$Organization/teams" + } + + if ($PSCmdlet.ShouldProcess("'$Name' in '$Organization'", 'Create team')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } + } +} diff --git a/src/functions/public/Teams/Update-GitHubTeam.ps1 b/src/functions/public/Teams/Update-GitHubTeam.ps1 new file mode 100644 index 00000000..379d8580 --- /dev/null +++ b/src/functions/public/Teams/Update-GitHubTeam.ps1 @@ -0,0 +1,92 @@ +function Update-GitHubTeam { + <# + .SYNOPSIS + Update a team + + .DESCRIPTION + To edit a team, the authenticated user must either be an organization owner or a team maintainer. + + .EXAMPLE + + + .NOTES + [Update a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#update-a-team) + #> + [OutputType([pscustomobject])] + [CmdletBinding()] + param ( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Org')] + [string] $Organization, + + # The slug of the team name. + [Parameter(Mandatory)] + [Alias('Team', 'TeamName', 'slug', 'team_slug')] + [string] $Name, + + # The context to run the command in + [Parameter()] + [string] $Context = (Get-GitHubConfig -Name DefaultContext), + + # The new team name. + [Parameter()] + [Alias()] + [string] $NewName, + + # The description of the team. + [Parameter()] + [string] $Description, + + # The level of privacy this team should have. The options are: + # For a non-nested team: + # - secret - only visible to organization owners and members of this team. + # - closed - visible to all members of this organization. + # Default: secret + # For a parent or child team: + # - closed - visible to all members of this organization. + # Default for child team: closed + [Parameter()] + [ValidateSet('secret', 'closed')] + [string] $Privacy = 'closed', + + # The notification setting the team has chosen. The options are: + # notifications_enabled - team members receive notifications when the team is @mentioned. + # notifications_disabled - no one receives notifications. + # Default: notifications_enabled + [Parameter()] + [ValidateSet('notifications_enabled', 'notifications_disabled')] + [string] $NotificationSetting, + + # Closing down notice. The permission that new repositories will be added to the team with when none is specified. + [Parameter()] + [ValidateSet('pull', 'push')] + [string] $Permission = 'pull', + + # The ID of a team to set as the parent team. + [Parameter()] + [int] $ParentTeamID + ) + + $body = @{ + name = $NewName + description = $Description + privacy = $Privacy + notification_setting = $NotificationSetting + permission = $Permission + parent_team_id = $ParentTeamID + } + + $body | Remove-HashtableEntry -NullOrEmptyValues + + $inputObject = @{ + Context = $Context + Method = 'Patch' + APIEndpoint = "/orgs/$Organization/teams/$Name" + Body = $body + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } +} diff --git a/tools/utilities/GitHubAPI.ps1 b/tools/utilities/GitHubAPI.ps1 index 80fe3c92..1cfceaab 100644 --- a/tools/utilities/GitHubAPI.ps1 +++ b/tools/utilities/GitHubAPI.ps1 @@ -21,8 +21,8 @@ $response = Invoke-RestMethod -Uri $APIDocURI -Method Get # @{n = 'PUT'; e = { (($_.value.psobject.Properties.Name) -contains 'PUT') } }, ` # @{n = 'PATCH'; e = { (($_.value.psobject.Properties.Name) -contains 'PATCH') } } | Format-Table -$path = '/app/installations/{installation_id}/access_tokens' -$method = 'post' +$path = '/orgs/{org}/teams' +$method = 'get' $response.paths.$path.$method $response.paths.$path.$method.tags | clip # -> Namespace/foldername $response.paths.$path.$method.operationId | clip # -> FunctionName From 7ae3d16379d280f6b5b1e4414948c86b820c0a01 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 25 Nov 2024 09:55:51 +0100 Subject: [PATCH 2/2] Fixing and trixing --- src/functions/public/Teams/Delete-GitHubTeam.ps1 | 2 +- src/functions/public/Teams/Get-GitHubRepoTeam.ps1 | 1 - src/functions/public/Teams/Update-GitHubTeam.ps1 | 8 +++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/functions/public/Teams/Delete-GitHubTeam.ps1 b/src/functions/public/Teams/Delete-GitHubTeam.ps1 index cce03071..5f4e04a9 100644 --- a/src/functions/public/Teams/Delete-GitHubTeam.ps1 +++ b/src/functions/public/Teams/Delete-GitHubTeam.ps1 @@ -11,7 +11,7 @@ An example .NOTES - General notes + [Delete a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#delete-a-team) #> [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Teams/Get-GitHubRepoTeam.ps1 b/src/functions/public/Teams/Get-GitHubRepoTeam.ps1 index c472512a..b827a812 100644 --- a/src/functions/public/Teams/Get-GitHubRepoTeam.ps1 +++ b/src/functions/public/Teams/Get-GitHubRepoTeam.ps1 @@ -20,5 +20,4 @@ filter Get-GitHubRepoTeam { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } - } diff --git a/src/functions/public/Teams/Update-GitHubTeam.ps1 b/src/functions/public/Teams/Update-GitHubTeam.ps1 index 379d8580..038b924c 100644 --- a/src/functions/public/Teams/Update-GitHubTeam.ps1 +++ b/src/functions/public/Teams/Update-GitHubTeam.ps1 @@ -13,7 +13,7 @@ [Update a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#update-a-team) #> [OutputType([pscustomobject])] - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess)] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] @@ -86,7 +86,9 @@ Body = $body } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Update')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } }