diff --git a/src/classes/public/GitHubPermission.ps1 b/src/classes/public/GitHubPermission.ps1 index c3f07529d..c1c8628cc 100644 --- a/src/classes/public/GitHubPermission.ps1 +++ b/src/classes/public/GitHubPermission.ps1 @@ -487,6 +487,19 @@ 'Fine-grained', 'Repository' ), + [GitHubPermission]::new( + 'artifact_metadata', + 'Artifact metadata', + 'Manage artifact attestation metadata for a repository.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#repository-permissions-for-artifact-metadata', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Repository' + ), # ------------------------------ # Organization Fine-Grained Permission Definitions @@ -569,6 +582,19 @@ 'Fine-grained', 'Organization' ), + [GitHubPermission]::new( + 'custom_properties_for_organizations', + 'Custom properties for organizations', + 'Read and write custom properties for organizations.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#organization-permissions-for-custom-properties-for-organizations', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Organization' + ), [GitHubPermission]::new( 'organization_custom_roles', 'Custom repository roles', @@ -607,6 +633,31 @@ 'Fine-grained', 'Organization' ), + [GitHubPermission]::new( + 'organization_copilot_metrics', + 'Copilot metrics', + 'View Copilot usage metrics for an organization.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#organization-permissions-for-copilot-metrics', + @( + 'read' + ), + 'Fine-grained', + 'Organization' + ), + [GitHubPermission]::new( + 'organization_credentials', + 'Organization credentials', + 'Manage credentials for an organization.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#organization-permissions-for-organization-credentials', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Organization' + ), [GitHubPermission]::new( 'issue_fields', 'Issue Fields', @@ -762,6 +813,19 @@ 'Fine-grained', 'Organization' ), + [GitHubPermission]::new( + 'organization_dependabot_dismissal_requests', + 'Organization Dependabot dismissal requests', + 'Review and manage Dependabot alert dismissal requests for an organization.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#organization-permissions-for-organization-dependabot-dismissal-requests', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Organization' + ), [GitHubPermission]::new( 'organization_code_scanning_dismissal_requests', 'Organization dismissal requests for code scanning', @@ -879,6 +943,19 @@ 'Fine-grained', 'Organization' ), + [GitHubPermission]::new( + 'organization_runner_custom_images', + 'Runner custom images', + 'View and manage custom images for self-hosted runners available to an organization.', + 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' + + '#organization-permissions-for-runner-custom-images', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Organization' + ), [GitHubPermission]::new( 'team_discussions', 'Team discussions', @@ -1259,6 +1336,84 @@ ), 'Fine-grained', 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_ai_controls', + 'Enterprise AI controls', + 'Manage AI controls at the enterprise level.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-enterprise-ai-controls', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_copilot_metrics', + 'Enterprise Copilot metrics', + 'View Copilot usage metrics at the enterprise level.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-enterprise-copilot-metrics', + @( + 'read' + ), + 'Fine-grained', + 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_credentials', + 'Enterprise credentials', + 'Manage credentials at the enterprise level.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-enterprise-credentials', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_custom_enterprise_roles', + 'Custom enterprise roles', + 'Create, edit, delete and list custom enterprise roles.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-custom-enterprise-roles', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_custom_properties_for_organizations', + 'Custom properties for organizations', + 'View repository custom properties and administer definitions for enterprise organizations.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-custom-properties-for-organizations', + @( + 'read', + 'write', + 'admin' + ), + 'Fine-grained', + 'Enterprise' + ), + [GitHubPermission]::new( + 'enterprise_teams', + 'Enterprise teams', + 'Manage teams at the enterprise level.', + 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' + + '#enterprise-permissions-for-enterprise-teams', + @( + 'read', + 'write' + ), + 'Fine-grained', + 'Enterprise' ) ) } diff --git a/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForOrganization.ps1 b/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForOrganization.ps1 new file mode 100644 index 000000000..ba478faca --- /dev/null +++ b/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForOrganization.ps1 @@ -0,0 +1,55 @@ +function Get-GitHubOidcSubjectClaimForOrganization { + <# + .SYNOPSIS + Get the customization template for an OIDC subject claim for an organization + + .DESCRIPTION + Gets the customization template for an OpenID Connect (OIDC) subject claim for an organization. + + .EXAMPLE + ```powershell + Get-GitHubOidcSubjectClaimForOrganization -Organization 'PSModule' -Context $GitHubContext + ``` + + Gets the OIDC subject claim customization template for the 'PSModule' organization. + + .NOTES + [Get the customization template for an OIDC subject claim for an organization] + (https://docs.github.com/rest/actions/oidc#get-the-customization-template-for-an-oidc-subject-claim-for-an-organization) + #> + [OutputType([pscustomobject])] + [CmdletBinding()] + param( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Organization, + + # 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(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + # Required permissions: Administration org (read) or read:org + } + + process { + $apiParams = @{ + Method = 'GET' + APIEndpoint = "/orgs/$Organization/actions/oidc/customization/sub" + Context = $Context + } + + Invoke-GitHubAPI @apiParams | ForEach-Object { + Write-Output $_.Response + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForRepository.ps1 b/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForRepository.ps1 new file mode 100644 index 000000000..2bc1d3753 --- /dev/null +++ b/src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForRepository.ps1 @@ -0,0 +1,59 @@ +function Get-GitHubOidcSubjectClaimForRepository { + <# + .SYNOPSIS + Get the customization template for an OIDC subject claim for a repository + + .DESCRIPTION + Gets the customization template for an OpenID Connect (OIDC) subject claim for a repository. + + .EXAMPLE + ```powershell + Get-GitHubOidcSubjectClaimForRepository -Owner 'PSModule' -Repository 'GitHub' -Context $GitHubContext + ``` + + Gets the OIDC subject claim customization template for the 'GitHub' repository. + + .NOTES + [Get the customization template for an OIDC subject claim for a repository] + (https://docs.github.com/rest/actions/oidc#get-the-customization-template-for-an-oidc-subject-claim-for-a-repository) + #> + [OutputType([pscustomobject])] + [CmdletBinding()] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Repository, + + # 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(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + # Required permissions: Actions repo (read) or repo + } + + process { + $apiParams = @{ + Method = 'GET' + APIEndpoint = "/repos/$Owner/$Repository/actions/oidc/customization/sub" + Context = $Context + } + + Invoke-GitHubAPI @apiParams | ForEach-Object { + Write-Output $_.Response + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForOrganization.ps1 b/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForOrganization.ps1 new file mode 100644 index 000000000..08bc51b84 --- /dev/null +++ b/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForOrganization.ps1 @@ -0,0 +1,64 @@ +function Set-GitHubOidcSubjectClaimForOrganization { + <# + .SYNOPSIS + Set the customization template for an OIDC subject claim for an organization + + .DESCRIPTION + Creates or updates the customization template for an OpenID Connect (OIDC) subject claim for an organization. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaimForOrganization -Organization 'PSModule' -IncludeClaimKeys @('repo', 'context') -Context $GitHubContext + ``` + + Sets the OIDC subject claim customization template for the 'PSModule' organization. + + .NOTES + [Set the customization template for an OIDC subject claim for an organization] + (https://docs.github.com/rest/actions/oidc#set-the-customization-template-for-an-oidc-subject-claim-for-an-organization) + #> + [OutputType([void])] + [CmdletBinding(SupportsShouldProcess)] + param( + # The organization name. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Organization, + + # Array of unique strings. Each claim key can only contain alphanumeric characters and underscores. + [Parameter(Mandatory)] + [string[]] $IncludeClaimKeys, + + # 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(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + # Required permissions: Administration org (write) or write:org + } + + process { + $body = @{ + include_claim_keys = $IncludeClaimKeys + } + + $apiParams = @{ + Method = 'PUT' + APIEndpoint = "/orgs/$Organization/actions/oidc/customization/sub" + Body = $body + Context = $Context + } + + if ($PSCmdlet.ShouldProcess("OIDC subject claim for organization [$Organization]", 'Set')) { + $null = Invoke-GitHubAPI @apiParams + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForRepository.ps1 b/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForRepository.ps1 new file mode 100644 index 000000000..70a1ff781 --- /dev/null +++ b/src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForRepository.ps1 @@ -0,0 +1,82 @@ +function Set-GitHubOidcSubjectClaimForRepository { + <# + .SYNOPSIS + Set the customization template for an OIDC subject claim for a repository + + .DESCRIPTION + Creates or updates the customization template for an OpenID Connect (OIDC) subject claim for a repository. + When UseDefault is true, the include_claim_keys are ignored by the API. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaimForRepository -Owner 'PSModule' -Repository 'GitHub' -IncludeClaimKeys @('repo', 'context') -Context $GitHubContext + ``` + + Sets the OIDC subject claim customization template for the 'GitHub' repository. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaimForRepository -Owner 'PSModule' -Repository 'GitHub' -UseDefault -IncludeClaimKeys @('repo') -Context $GitHubContext + ``` + + Resets the OIDC subject claim customization for the 'GitHub' repository to use the default template. + + .NOTES + [Set the customization template for an OIDC subject claim for a repository] + (https://docs.github.com/rest/actions/oidc#set-the-customization-template-for-an-oidc-subject-claim-for-a-repository) + #> + [OutputType([void])] + [CmdletBinding(SupportsShouldProcess)] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Repository, + + # Whether to use the default subject claim template. + # When true, the include_claim_keys are ignored by the API. + [Parameter(Mandatory)] + [bool] $UseDefault, + + # Array of unique strings. Each claim key can only contain alphanumeric characters and underscores. + [Parameter(Mandatory)] + [string[]] $IncludeClaimKeys, + + # 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(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + # Required permissions: Actions repo (write) or repo + } + + process { + $body = @{ + use_default = $UseDefault + include_claim_keys = $IncludeClaimKeys + } + + $apiParams = @{ + Method = 'PUT' + APIEndpoint = "/repos/$Owner/$Repository/actions/oidc/customization/sub" + Body = $body + Context = $Context + } + + if ($PSCmdlet.ShouldProcess("OIDC subject claim for repository [$Owner/$Repository]", 'Set')) { + $null = Invoke-GitHubAPI @apiParams + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Actions/OIDC/Get-GitHubOidcClaim.ps1 b/src/functions/public/Actions/OIDC/Get-GitHubOidcClaim.ps1 new file mode 100644 index 000000000..38df17307 --- /dev/null +++ b/src/functions/public/Actions/OIDC/Get-GitHubOidcClaim.ps1 @@ -0,0 +1,76 @@ +function Get-GitHubOidcClaim { + <# + .SYNOPSIS + Get the supported OIDC claim keys for a GitHub instance + + .DESCRIPTION + Retrieves the list of supported OpenID Connect (OIDC) claim keys from the OIDC discovery endpoint + of a GitHub instance. This endpoint is public and requires no authentication. + + The claim keys returned can be used with Set-GitHubOidcSubjectClaim to customize the OIDC + subject claim template for organizations and repositories. + + .EXAMPLE + ```powershell + Get-GitHubOidcClaim + ``` + + Gets the supported OIDC claim keys for github.com. + + .EXAMPLE + ```powershell + Get-GitHubOidcClaim -Context $GitHubContext + ``` + + Gets the supported OIDC claim keys for the GitHub instance associated with the given context. + + .NOTES + [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) + + .LINK + https://psmodule.io/GitHub/Functions/Actions/OIDC/Get-GitHubOidcClaim + #> + [OutputType([string[]])] + [CmdletBinding()] + param( + # The context to run the command in. Used to determine the GitHub instance hostname. + # When not provided, defaults to github.com. + [Parameter()] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + } + + process { + $hostName = 'github.com' + if ($Context) { + if ($Context -is [string]) { + $resolved = Get-GitHubContext -Context $Context -ErrorAction SilentlyContinue + if ($resolved) { + $hostName = $resolved.HostName + } + } elseif ($Context.HostName) { + $hostName = $Context.HostName + } + } + + $issuerHost = if ($hostName -eq 'github.com') { + 'token.actions.githubusercontent.com' + } else { + "token.actions.$hostName" + } + + $discoveryUri = "https://$issuerHost/.well-known/openid-configuration" + Write-Debug "[$stackPath] - Discovery URI: [$discoveryUri]" + + $response = Invoke-RestMethod -Uri $discoveryUri -Method Get + $response.claims_supported + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Actions/OIDC/Get-GitHubOidcSubjectClaim.ps1 b/src/functions/public/Actions/OIDC/Get-GitHubOidcSubjectClaim.ps1 new file mode 100644 index 000000000..45a0a6e5e --- /dev/null +++ b/src/functions/public/Actions/OIDC/Get-GitHubOidcSubjectClaim.ps1 @@ -0,0 +1,85 @@ +function Get-GitHubOidcSubjectClaim { + <# + .SYNOPSIS + Get the customization template for an OIDC subject claim + + .DESCRIPTION + Gets the customization template for an OpenID Connect (OIDC) subject claim for an organization + or repository. + + .EXAMPLE + ```powershell + Get-GitHubOidcSubjectClaim -Owner 'PSModule' + ``` + + Gets the OIDC subject claim customization template for the 'PSModule' organization. + + .EXAMPLE + ```powershell + Get-GitHubOidcSubjectClaim -Owner 'PSModule' -Repository 'GitHub' + ``` + + Gets the OIDC subject claim customization template for the 'GitHub' repository. + + .OUTPUTS + System.Management.Automation.PSCustomObject + + .NOTES + [Get the customization template for an OIDC subject claim for an organization](https://docs.github.com/en/rest/actions/oidc?apiVersion=2022-11-28#get-the-customization-template-for-an-oidc-subject-claim-for-an-organization) + [Get the customization template for an OIDC subject claim for a repository](https://docs.github.com/en/rest/actions/oidc?apiVersion=2022-11-28#get-the-customization-template-for-an-oidc-subject-claim-for-a-repository) + + .LINK + https://psmodule.io/GitHub/Functions/Actions/OIDC/Get-GitHubOidcSubjectClaim + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] + [OutputType([pscustomobject])] + [CmdletBinding(DefaultParameterSetName = 'Get the customization template for an OIDC subject claim for an organization')] + param( + # The account owner of the repository or the organization name. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization')] + [Alias('User')] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ParameterSetName = 'Get the customization template for an OIDC subject claim for a repository', + ValueFromPipelineByPropertyName)] + [string] $Repository, + + # 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 { + $params = @{ + Context = $Context + } + + switch ($PSCmdlet.ParameterSetName) { + 'Get the customization template for an OIDC subject claim for an organization' { + $params['Organization'] = $Owner + Get-GitHubOidcSubjectClaimForOrganization @params + break + } + 'Get the customization template for an OIDC subject claim for a repository' { + $params['Owner'] = $Owner + $params['Repository'] = $Repository + Get-GitHubOidcSubjectClaimForRepository @params + break + } + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Actions/OIDC/Set-GitHubOidcSubjectClaim.ps1 b/src/functions/public/Actions/OIDC/Set-GitHubOidcSubjectClaim.ps1 new file mode 100644 index 000000000..b8a2b0453 --- /dev/null +++ b/src/functions/public/Actions/OIDC/Set-GitHubOidcSubjectClaim.ps1 @@ -0,0 +1,113 @@ +function Set-GitHubOidcSubjectClaim { + <# + .SYNOPSIS + Set the customization template for an OIDC subject claim + + .DESCRIPTION + Creates or updates the customization template for an OpenID Connect (OIDC) subject claim for an + organization or repository. + + For repositories, when UseDefault is true, the IncludeClaimKeys are ignored by the API. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaim -Owner 'PSModule' -IncludeClaimKeys @('repo', 'context') + ``` + + Sets the OIDC subject claim customization template for the 'PSModule' organization. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaim -Owner 'PSModule' -Repository 'GitHub' -IncludeClaimKeys @('repo', 'context') + ``` + + Sets the OIDC subject claim customization template for the 'GitHub' repository with custom claim keys. + + .EXAMPLE + ```powershell + Set-GitHubOidcSubjectClaim -Owner 'PSModule' -Repository 'GitHub' -UseDefault -IncludeClaimKeys @('repo') + ``` + + Resets the OIDC subject claim customization for the 'GitHub' repository to use the default template. + + .OUTPUTS + System.Void + + .NOTES + [Set the customization template for an OIDC subject claim for an organization](https://docs.github.com/en/rest/actions/oidc?apiVersion=2022-11-28#set-the-customization-template-for-an-oidc-subject-claim-for-an-organization) + [Set the customization template for an OIDC subject claim for a repository](https://docs.github.com/en/rest/actions/oidc?apiVersion=2022-11-28#set-the-customization-template-for-an-oidc-subject-claim-for-a-repository) + + .LINK + https://psmodule.io/GitHub/Functions/Actions/OIDC/Set-GitHubOidcSubjectClaim + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSShouldProcess', '', Scope = 'Function', + Justification = 'This check is performed in the private functions.' + )] + [OutputType([void])] + [CmdletBinding( + SupportsShouldProcess, + DefaultParameterSetName = 'Set the customization template for an OIDC subject claim for an organization' + )] + param( + # The account owner of the repository or the organization name. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization')] + [Alias('User')] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ParameterSetName = 'Set the customization template for an OIDC subject claim for a repository', + ValueFromPipelineByPropertyName)] + [string] $Repository, + + # Array of unique strings. Each claim key can only contain alphanumeric characters and underscores. + [Parameter(Mandatory)] + [string[]] $IncludeClaimKeys, + + # Whether to use the default subject claim template for the repository. + # When true, the IncludeClaimKeys are ignored by the API. + [Parameter(ParameterSetName = 'Set the customization template for an OIDC subject claim for a repository')] + [switch] $UseDefault, + + # 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 { + $params = @{ + Context = $Context + } + + switch ($PSCmdlet.ParameterSetName) { + 'Set the customization template for an OIDC subject claim for an organization' { + $params['Organization'] = $Owner + $params['IncludeClaimKeys'] = $IncludeClaimKeys + Set-GitHubOidcSubjectClaimForOrganization @params + break + } + 'Set the customization template for an OIDC subject claim for a repository' { + $params['Owner'] = $Owner + $params['Repository'] = $Repository + $params['IncludeClaimKeys'] = $IncludeClaimKeys + $params['UseDefault'] = $UseDefault.IsPresent + Set-GitHubOidcSubjectClaimForRepository @params + break + } + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Actions/OIDC/completers.ps1 b/src/functions/public/Actions/OIDC/completers.ps1 new file mode 100644 index 000000000..bc7e3a503 --- /dev/null +++ b/src/functions/public/Actions/OIDC/completers.ps1 @@ -0,0 +1,18 @@ +Register-ArgumentCompleter -CommandName Set-GitHubOidcSubjectClaim -ParameterName IncludeClaimKeys -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters + $pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } } + $params = @{ + Context = $fakeBoundParameters.Context + Verbose = $false + Debug = $false + } + $params | Remove-HashtableEntry -NullOrEmptyValues + $filteredOptions = Get-GitHubOidcClaim @params | Where-Object { $_ -like $pattern } + if (-not $filteredOptions) { + return $null + } + $filteredOptions | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/tests/Actions.Tests.ps1 b/tests/Actions.Tests.ps1 new file mode 100644 index 000000000..299e14f0c --- /dev/null +++ b/tests/Actions.Tests.ps1 @@ -0,0 +1,138 @@ +#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' } + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester grouping syntax: known issue.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingWriteHost', '', + Justification = 'Log outputs to GitHub Actions logs.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidLongLines', '', + Justification = 'Long test descriptions and skip switches' +)] +[CmdletBinding()] +param() + +BeforeAll { + $testName = 'ActionsTests' + $os = $env:RUNNER_OS + $guid = [guid]::NewGuid().ToString() +} + +Describe 'Actions' { + $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" + + Context 'OIDC' { + Context 'Get-GitHubOidcClaim' { + It 'Get-GitHubOidcClaim - No context - Returns claim keys for github.com' { + $result = Get-GitHubOidcClaim + LogGroup 'Result' { + Write-Host ($result | Out-String) + } + $result | Should -Not -BeNullOrEmpty + $result | Should -Contain 'sub' + $result | Should -Contain 'repository' + $result | Should -BeOfType [string] + } + } + } + + Context 'As using on ' -ForEach $authCases { + BeforeAll { + $context = Connect-GitHubAccount @connectParams -PassThru -Silent + LogGroup 'Context' { + Write-Host ($context | Format-List | Out-String) + } + if ($AuthType -eq 'APP') { + LogGroup 'Context - Installation' { + $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent + Write-Host ($context | Format-List | Out-String) + } + } + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" + + switch ($OwnerType) { + 'user' { + Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | + Remove-GitHubRepository -Confirm:$false + $repo = New-GitHubRepository -Name $repoName -Confirm:$false + } + 'organization' { + Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | + Remove-GitHubRepository -Confirm:$false + $repo = New-GitHubRepository -Organization $Owner -Name $repoName -Confirm:$false + } + } + LogGroup "Repository - [$repoName]" { + Write-Host ($repo | Select-Object * | Out-String) + } + } + + AfterAll { + switch ($OwnerType) { + 'user' { + Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | + Remove-GitHubRepository -Confirm:$false + } + 'organization' { + Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | + Remove-GitHubRepository -Confirm:$false + } + } + Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent + Write-Host ('-' * 60) + } + + Context 'OIDC' { + It 'Get-GitHubOidcClaim - With context - Returns claim keys' { + $result = Get-GitHubOidcClaim -Context $context + LogGroup 'Result' { + Write-Host ($result | Out-String) + } + $result | Should -Not -BeNullOrEmpty + $result | Should -Contain 'sub' + $result | Should -BeOfType [string] + } + + It 'Get-GitHubOidcSubjectClaim - Organization - Returns template' -Skip:($OwnerType -ne 'organization') { + $result = Get-GitHubOidcSubjectClaim -Owner $Owner -Context $context + LogGroup 'Result' { + Write-Host ($result | Format-List | Out-String) + } + $result | Should -Not -BeNullOrEmpty + $result.include_claim_keys | Should -Not -BeNullOrEmpty + } + + It 'Get-GitHubOidcSubjectClaim - Repository - Returns template' -Skip:($OwnerType -in ('repository', 'enterprise')) { + $result = Get-GitHubOidcSubjectClaim -Owner $Owner -Repository $repoName -Context $context + LogGroup 'Result' { + Write-Host ($result | Format-List | Out-String) + } + $result | Should -Not -BeNullOrEmpty + } + + It 'Set-GitHubOidcSubjectClaim - Organization - Sets template' -Skip:($OwnerType -ne 'organization') { + { + Set-GitHubOidcSubjectClaim -Owner $Owner -IncludeClaimKeys @('repo', 'context') -Context $context + } | Should -Not -Throw + } + + It 'Set-GitHubOidcSubjectClaim - Repository - Sets template with custom keys' -Skip:($OwnerType -in ('repository', 'enterprise')) { + { + Set-GitHubOidcSubjectClaim -Owner $Owner -Repository $repoName ` + -IncludeClaimKeys @('repo', 'ref') -Context $context + } | Should -Not -Throw + } + + It 'Set-GitHubOidcSubjectClaim - Repository - Sets template with UseDefault' -Skip:($OwnerType -in ('repository', 'enterprise')) { + { + Set-GitHubOidcSubjectClaim -Owner $Owner -Repository $repoName ` + -IncludeClaimKeys @('repo') -UseDefault -Context $context + } | Should -Not -Throw + } + } + } +}