diff --git a/examples/Organizations/Organization.ps1 b/examples/Organizations/Organization.ps1
new file mode 100644
index 000000000..4e4fcfbe3
--- /dev/null
+++ b/examples/Organizations/Organization.ps1
@@ -0,0 +1,41 @@
+$orgParam = @{
+ Enterprise = 'msx'
+ Name = 'Marius-Test7'
+ Owner = 'GitHub-Automation'
+ BillingEmail = 'post@msx.no'
+}
+$org = New-GitHubOrganization @orgParam
+
+$installAppParam = @{
+ Enterprise = 'msx'
+ Organization = $org.login
+ ClientID = (Get-GitHubContext).ClientID
+ RepositorySelection = 'all'
+}
+Install-GitHubApp @installAppParam
+
+$updateOrgParam = @{
+ Name = $org.login
+ Description = 'Test organization created by PowerShell script'
+ Location = 'Oslo, Norway'
+ BillingEmail = 'post@msx.no'
+ Company = 'MSX AS'
+ Email = 'info@msx.no'
+ Blog = 'https://msx.no/blog'
+ TwitterUsername = 'msx_no'
+ HasOrganizationProjects = $true
+ DefaultRepositoryPermission = 'read'
+ MembersCanCreateRepositories = $true
+ MembersCanCreatePublicRepositories = $true
+ MembersCanCreatePrivateRepositories = $true
+ MembersCanCreateInternalRepositories = $true
+ MembersCanCreatePages = $true
+ MembersCanCreatePublicPages = $true
+ MembersCanCreatePrivatePages = $true
+ MembersCanForkPrivateRepositories = $true
+ WebCommitSignoffRequired = $false
+ SecretScanningPushProtectionEnabledForNewRepositories = $true
+ SecretScanningPushProtectionCustomLinkEnabled = $false
+ SecretScanningPushProtectionCustomLink = ''
+}
+Update-GitHubOrganization @updateOrgParam
diff --git a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1
index 48528dba2..a99927110 100644
--- a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1
+++ b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1
@@ -225,7 +225,7 @@
$this.MembersCanInviteCollaborators = $Object.members_can_invite_collaborators
$this.MembersCanCreatePages = $Object.members_can_create_pages
$this.MembersCanForkPrivateRepositories = $Object.members_can_fork_private_repositories ?? $Object.membersCanForkPrivateRepositories
- $this.RequireWebCommitSignoff = $Object.web_commit_signoff_required ?? $Object.requiresTwoFactorAuthentication
+ $this.RequireWebCommitSignoff = $Object.web_commit_signoff_required ?? $Object.webCommitSignoffRequired
$this.DeployKeysEnabledForRepositories = $Object.deploy_keys_enabled_for_repositories
$this.MembersCanCreatePublicPages = $Object.members_can_create_public_pages
$this.MembersCanCreatePrivatePages = $Object.members_can_create_private_pages
diff --git a/src/functions/private/Apps/GitHub Apps/Install-GitHubAppOnEnterpriseOrganization.ps1 b/src/functions/private/Apps/GitHub Apps/Install-GitHubAppOnEnterpriseOrganization.ps1
index b66c98e66..d8d847476 100644
--- a/src/functions/private/Apps/GitHub Apps/Install-GitHubAppOnEnterpriseOrganization.ps1
+++ b/src/functions/private/Apps/GitHub Apps/Install-GitHubAppOnEnterpriseOrganization.ps1
@@ -11,6 +11,7 @@
.EXAMPLE
Install-GitHubAppOnEnterpriseOrganization -Enterprise 'msx' -Organization 'org' -ClientID '123456'
#>
+ [OutputType([GitHubAppInstallation])]
[CmdletBinding()]
param(
# The enterprise slug or ID.
@@ -29,7 +30,7 @@
# - all - all repositories that the authenticated GitHub App installation can access.
# - selected - select specific repositories.
[Parameter(Mandatory)]
- [ValidateSet('all', 'selected')]
+ [ValidateSet('All', 'Selected')]
[string] $RepositorySelection,
# The names of the repositories to which the installation will be granted access.
@@ -49,6 +50,9 @@
}
process {
+ if ($RepositorySelection) {
+ $RepositorySelection = $RepositorySelection.ToLower()
+ }
$body = @{
client_id = $ClientID
repository_selection = $RepositorySelection
@@ -64,7 +68,7 @@
}
Invoke-GitHubAPI @inputObject | ForEach-Object {
- Write-Output $_.Response
+ [GitHubAppInstallation]::new($_.Response)
}
}
diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1
index 9261893b5..2c4d9279b 100644
--- a/src/functions/public/API/Invoke-GitHubAPI.ps1
+++ b/src/functions/public/API/Invoke-GitHubAPI.ps1
@@ -315,6 +315,10 @@ function Invoke-GitHubAPI {
}
$exception = @"
+
+----------------------------------
+Context:
+$($Context | Format-List | Out-String)
----------------------------------
Request:
$([pscustomobject]$APICall | Select-Object -ExcludeProperty Body, Headers | Format-List | Out-String)
diff --git a/src/functions/public/Organization/New-GitHubOrganization.ps1 b/src/functions/public/Organization/New-GitHubOrganization.ps1
new file mode 100644
index 000000000..7279e9358
--- /dev/null
+++ b/src/functions/public/Organization/New-GitHubOrganization.ps1
@@ -0,0 +1,88 @@
+function New-GitHubOrganization {
+ <#
+ .SYNOPSIS
+ Creates a new GitHub organization within a specified enterprise.
+
+ .DESCRIPTION
+ This function creates a new GitHub organization within the specified enterprise.
+
+ .EXAMPLE
+ New-GitHubOrganization -Enterprise 'my-enterprise' -Name 'my-org' -Owner 'user1' -BillingEmail 'billing@example.com'
+
+ .OUTPUTS
+ GitHubOrganization
+
+ .LINK
+ https://psmodule.io/GitHub/Functions/Organization/New-GitHubOrganization/
+ #>
+ [OutputType([GitHubOrganization])]
+ [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
+ param(
+ # The name of the enterprise to create the organization in.
+ [Parameter()]
+ [string]$Enterprise,
+
+ # The name of the organization to create.
+ [Parameter(Mandatory)]
+ [string]$Name,
+
+ # The owners of the organization. This should be a list of GitHub usernames.
+ [Parameter(Mandatory)]
+ [string[]]$Owner,
+
+ # The billing email for the organization.
+ [Parameter()]
+ [string]$BillingEmail,
+
+ # The context to run the command in. Used to get the details for the API call.
+ # Can be either a string or a GitHubContext object.
+ [Parameter()]
+ [object] $Context
+ )
+
+ begin {
+ $stackPath = Get-PSCallStackPath
+ Write-Debug "[$stackPath] - Start"
+ $Context = Resolve-GitHubContext -Context $Context
+ Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT
+ }
+
+ process {
+ $enterpriseObject = Get-GitHubEnterprise -Name $Enterprise -Context $Context
+ Write-Verbose "Creating organization in enterprise: $($enterpriseObject.Name)"
+ $graphQLFields = ([GitHubOrganization]::PropertyToGraphQLMap).Values
+
+ $inputParams = @{
+ adminLogins = $Owner
+ billingEmail = $BillingEmail
+ enterpriseId = $enterpriseObject.NodeID
+ login = $Name
+ profileName = $Name
+ }
+
+ $updateGraphQLInputs = @{
+ Query = @"
+mutation(`$input:CreateEnterpriseOrganizationInput!) {
+ createEnterpriseOrganization(input:`$input) {
+ organization {
+ $graphQLFields
+ }
+ }
+}
+"@
+ Variables = @{
+ input = $inputParams
+ }
+ Context = $Context
+ }
+ if ($PSCmdlet.ShouldProcess("Creating organization '$Name' in enterprise '$Enterprise'")) {
+ $orgresult = Invoke-GitHubGraphQLQuery @updateGraphQLInputs
+ [GitHubOrganization]::new($orgresult.createEnterpriseOrganization.organization, $Context)
+ }
+ }
+
+ end {
+ Write-Debug "[$stackPath] - End"
+ }
+}
+
diff --git a/src/functions/public/Organization/Remove-GitHubOrganization.ps1 b/src/functions/public/Organization/Remove-GitHubOrganization.ps1
index 0d9f3c310..8f31b57c3 100644
--- a/src/functions/public/Organization/Remove-GitHubOrganization.ps1
+++ b/src/functions/public/Organization/Remove-GitHubOrganization.ps1
@@ -24,16 +24,16 @@
https://psmodule.io/GitHub/Functions/Organization/Remove-GitHubOrganization
#>
[OutputType([void])]
- [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
+ [CmdletBinding(DefaultParameterSetName = 'Remove an organization', SupportsShouldProcess, ConfirmImpact = 'High')]
param(
# The organization name. The name is not case sensitive.
- [Parameter(
- Mandatory,
- ValueFromPipeline,
- ValueFromPipelineByPropertyName
- )]
+ [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string] $Name,
+ # The input object to process. Can be a single or an array of GitHubOrganization objects.
+ [Parameter(Mandatory, ParameterSetName = 'ArrayInput', ValueFromPipeline)]
+ [GitHubOrganization[]] $InputObject,
+
# The context to run the command in. Used to get the details for the API call.
# Can be either a string or a GitHubContext object.
[Parameter()]
@@ -48,14 +48,28 @@
}
process {
- $inputObject = @{
- Method = 'DELETE'
- APIEndpoint = "/orgs/$Name"
- Context = $Context
- }
+ switch ($PSCmdlet.ParameterSetName) {
+ 'ArrayInput' {
+ foreach ($item in $InputObject) {
+ $params = @{
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubOrganization @params
+ }
+ break
+ }
+ default {
+ $apiParams = @{
+ Method = 'DELETE'
+ APIEndpoint = "/orgs/$Name"
+ Context = $Context
+ }
- if ($PSCmdlet.ShouldProcess("organization [$Name]", 'DELETE')) {
- $null = Invoke-GitHubAPI @inputObject
+ if ($PSCmdlet.ShouldProcess("organization [$Name]", 'Delete')) {
+ $null = Invoke-GitHubAPI @apiParams
+ }
+ }
}
}
@@ -63,5 +77,3 @@
Write-Debug "[$stackPath] - End"
}
}
-
-#SkipTest:FunctionTest:Will add a test for this function in a future PR
diff --git a/tests/Organizations.Tests.ps1 b/tests/Organizations.Tests.ps1
index 4136b6b53..7d1740e5c 100644
--- a/tests/Organizations.Tests.ps1
+++ b/tests/Organizations.Tests.ps1
@@ -20,7 +20,9 @@
param()
BeforeAll {
- # DEFAULTS ACCROSS ALL TESTS
+ $testName = 'MsxOrgTests'
+ $os = $env:RUNNER_OS
+ $number = Get-Random
}
Describe 'Organizations' {
@@ -32,25 +34,21 @@ Describe 'Organizations' {
LogGroup 'Context' {
Write-Host ($context | Select-Object * | Out-String)
}
+ $orgPrefix = "$testName-$os-"
+ $orgName = "$orgPrefix$number"
+
+ if ($AuthType -eq 'APP') {
+ $installationContext = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
+ LogGroup 'Context - Installation' {
+ Write-Host ($installationContext | Select-Object * | Out-String)
+ }
+ }
}
AfterAll {
Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
Write-Host ('-' * 60)
}
- # Tests for APP goes here
- if ($AuthType -eq 'APP') {
- It 'Connect-GitHubApp - Connects as a GitHub App to ' {
- $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
- LogGroup 'Context' {
- Write-Host ($context | Select-Object * | Out-String)
- }
- }
- }
-
- # Tests for runners goes here
- if ($Type -eq 'GitHub Actions') {}
-
It "Get-GitHubOrganization - Gets a specific organization 'PSModule'" {
$organization = Get-GitHubOrganization -Name 'PSModule'
LogGroup 'Organization' {
@@ -58,6 +56,7 @@ Describe 'Organizations' {
}
$organization | Should -Not -BeNullOrEmpty
}
+
It "Get-GitHubOrganization - List public organizations for the user 'psmodule-user'" {
$organizations = Get-GitHubOrganization -Username 'psmodule-user'
LogGroup 'Organization' {
@@ -65,6 +64,7 @@ Describe 'Organizations' {
}
$organizations | Should -Not -BeNullOrEmpty
}
+
It 'Get-GitHubOrganizationMember - Gets the members of a specific organization' -Skip:($OwnerType -in ('user', 'enterprise')) {
$members = Get-GitHubOrganizationMember -Organization $owner
LogGroup 'Members' {
@@ -73,29 +73,78 @@ Describe 'Organizations' {
$members | Should -Not -BeNullOrEmpty
}
- # Tests for IAT UAT and PAT goes here
- It 'Get-GitHubOrganization - Gets the organizations for the authenticated user' -Skip:($OwnerType -notin ('user')) {
+ It 'Get-GitHubOrganization - Gets the organizations for the authenticated user' -Skip:($Type -eq 'GitHub Actions') {
+ $orgs = Get-GitHubOrganization | Where-Object { $_.Name -like "$orgPrefix*" } | Out-String
+ LogGroup 'Organizations' {
+ $orgs | Format-Table -AutoSize | Out-String
+ }
{ Get-GitHubOrganization } | Should -Not -Throw
}
- if ($OwnerType -eq 'organization' -and $Type -ne 'GitHub Actions') {
- It 'Update-GitHubOrganization - Sets the organization configuration' {
- { Update-GitHubOrganization -Name $owner -Company 'ABC' } | Should -Not -Throw
- {
- $email = (New-Guid).Guid + '@psmodule.io'
- Update-GitHubOrganization -Name $owner -BillingEmail $email
- } | Should -Not -Throw
- {
- $email = (New-Guid).Guid + '@psmodule.io'
- Update-GitHubOrganization -Name $owner -Email $email
- } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -TwitterUsername 'PSModule' } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -Location 'USA' } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -Description 'Test Organization' } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -DefaultRepositoryPermission read } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -MembersCanCreateRepositories $true } | Should -Not -Throw
- { Update-GitHubOrganization -Name $owner -Website 'https://psmodule.io' } | Should -Not -Throw
+ It 'Update-GitHubOrganization - Sets the organization configuration' -Skip:($OwnerType -ne 'organization' -or $Type -eq 'GitHub Actions') {
+ { Update-GitHubOrganization -Name $owner -Company 'ABC' } | Should -Not -Throw
+ {
+ $email = (New-Guid).Guid + '@psmodule.io'
+ Update-GitHubOrganization -Name $owner -BillingEmail $email
+ } | Should -Not -Throw
+ {
+ $email = (New-Guid).Guid + '@psmodule.io'
+ Update-GitHubOrganization -Name $owner -Email $email
+ } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -TwitterUsername 'PSModule' } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -Location 'USA' } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -Description 'Test Organization' } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -DefaultRepositoryPermission read } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -MembersCanCreateRepositories $true } | Should -Not -Throw
+ { Update-GitHubOrganization -Name $owner -Website 'https://psmodule.io' } | Should -Not -Throw
+ }
+
+ It 'New-GitHubOrganization - Creates a new organization' -Skip:($OwnerType -ne 'enterprise') {
+ $orgParam = @{
+ Enterprise = 'msx'
+ Name = $orgName
+ Owner = 'MariusStorhaug'
+ BillingEmail = 'post@msx.no'
+ }
+ LogGroup 'Organization' {
+ $org = New-GitHubOrganization @orgParam
+ Write-Host ($org | Select-Object * | Out-String)
+ }
+ }
+
+ It 'Update-GitHubOrganization - Updates the organization location using enterprise installation' -Skip:($OwnerType -ne 'enterprise') {
+ { Update-GitHubOrganization -Name $orgName -Location 'New Location' } | Should -Throw
+ }
+
+ It 'Remove-GitHubOrganization - Removes an organization using enterprise installation' -Skip:($OwnerType -ne 'enterprise') {
+ { Remove-GitHubOrganization -Name $orgName -Confirm:$false } | Should -Throw
+ }
+
+ It 'Install-GitHubApp - Installs a GitHub App to an organization' -Skip:($OwnerType -ne 'enterprise') {
+ $installation = Install-GitHubApp -Enterprise $owner -Organization $orgName -ClientID $installationContext.ClientID -RepositorySelection 'all'
+ LogGroup 'Installed App' {
+ Write-Host ($installation | Select-Object * | Out-String)
+ }
+ $installation | Should -Not -BeNullOrEmpty
+ $installation | Should -BeOfType 'GitHubAppInstallation'
+ }
+
+ It 'Connect-GitHubApp - Connects as a GitHub App to the organization' -Skip:($OwnerType -ne 'enterprise') {
+ $orgContext = Connect-GitHubApp -Organization $orgName -Context $context -PassThru -Silent
+ LogGroup 'Context' {
+ Write-Host ($orgContext | Select-Object * | Out-String)
}
+ $orgContext | Should -Not -BeNullOrEmpty
+ }
+
+ It 'Update-GitHubOrganization - Updates the organization location using organization installation' -Skip:($OwnerType -ne 'enterprise') {
+ $orgContext = Connect-GitHubApp -Organization $orgName -Context $context -PassThru -Silent
+ Update-GitHubOrganization -Name $orgName -Location 'New Location' -Context $orgContext
+ }
+
+ It 'Remove-GitHubOrganization - Removes an organization using organization installation' -Skip:($OwnerType -ne 'enterprise') {
+ $orgContext = Connect-GitHubApp -Organization $orgName -Context $context -PassThru -Silent
+ Remove-GitHubOrganization -Name $orgName -Confirm:$false -Context $orgContext
}
Context 'Invitations' -Skip:($Owner -notin 'psmodule-test-org', 'psmodule-test-org2') {