diff --git a/src/classes/public/Environment/GitHubEnvironment.ps1 b/src/classes/public/Environment/GitHubEnvironment.ps1
index 799addd97..9fb960fe1 100644
--- a/src/classes/public/Environment/GitHubEnvironment.ps1
+++ b/src/classes/public/Environment/GitHubEnvironment.ps1
@@ -8,7 +8,16 @@
# The owner of the environment.
[string] $Owner
+ # URL to the owner/organization profile.
+ # Example: https://github.com/octocat
+ [string] $OwnerUrl
+
+ # URL to the repository.
+ # Example: https://github.com/octocat/Hello-World
+ [string] $RepositoryUrl
+
# URL of the environment.
+ # Example: https://github.com/octocat/Hello-World/settings/environments/123/edit
[string] $Url
# The date and time the environment was created.
@@ -34,6 +43,8 @@
$this.Name = $Object.name
$this.Owner = $Owner
$this.Repository = $Repository
+ $this.OwnerUrl = "https://$($Context.HostName)/$Owner"
+ $this.RepositoryUrl = "https://$($Context.HostName)/$Owner/$Repository"
$this.Url = "https://$($Context.HostName)/$Owner/$Repository/settings/environments/$($Object.id)/edit"
$this.CreatedAt = $Object.created_at
$this.UpdatedAt = $Object.updated_at
diff --git a/src/classes/public/GitHubFormatter.ps1 b/src/classes/public/GitHubFormatter.ps1
index 1fa06d0c5..b69263dad 100644
--- a/src/classes/public/GitHubFormatter.ps1
+++ b/src/classes/public/GitHubFormatter.ps1
@@ -28,6 +28,6 @@
{ $_ -ge 1MB } { return '{0:N2} MB' -f ($size / 1MB) }
{ $_ -ge 1KB } { return '{0:N2} KB' -f ($size / 1KB) }
}
- return "$size B"
+ return '{0:N2} B' -f $size
}
}
diff --git a/src/classes/public/GitHubPermissionDefinition.ps1 b/src/classes/public/GitHubPermissionDefinition.ps1
new file mode 100644
index 000000000..93ff6643f
--- /dev/null
+++ b/src/classes/public/GitHubPermissionDefinition.ps1
@@ -0,0 +1,46 @@
+class GitHubPermissionDefinition {
+ # The programmatic name of the permission as returned by the GitHub API
+ [string] $Name
+
+ # The human-friendly name of the permission as shown in the GitHub UI
+ [string] $DisplayName
+
+ # A brief description of what access the permission grants
+ [string] $Description
+
+ # A link to the relevant documentation or GitHub UI page
+ [uri] $URL
+
+ # The levels of access that can be granted for this permission
+ [string[]] $Options
+
+ # The type of permission (Fine-grained, Classic)
+ [string] $Type
+
+ # The scope at which this permission applies (Repository, Organization, User, Enterprise)
+ [string] $Scope
+
+ GitHubPermissionDefinition() {}
+
+ GitHubPermissionDefinition(
+ [string]$Name,
+ [string]$DisplayName,
+ [string]$Description,
+ [string]$URL,
+ [string[]]$Options,
+ [string]$Type,
+ [string]$Scope
+ ) {
+ $this.Name = $Name
+ $this.DisplayName = $DisplayName
+ $this.Description = $Description
+ $this.URL = [uri]$URL
+ $this.Options = $Options
+ $this.Type = $Type
+ $this.Scope = $Scope
+ }
+
+ [string] ToString() {
+ return $this.Name
+ }
+}
diff --git a/src/classes/public/Secrets/GitHubSecret.ps1 b/src/classes/public/Secrets/GitHubSecret.ps1
index 61b8c9160..27c73ead9 100644
--- a/src/classes/public/Secrets/GitHubSecret.ps1
+++ b/src/classes/public/Secrets/GitHubSecret.ps1
@@ -1,29 +1,29 @@
class GitHubSecret {
- # The key ID of the public key.
+ # The name of the secret.
[string] $Name
- # The scope of the variable, organization, repository, or environment.
+ # The scope of the secret, organization, repository, or environment.
[string] $Scope
- # The name of the organization or user the Public Key is associated with.
+ # The name of the organization or user the secret is stored in.
[string] $Owner
- # The name of the repository the Public Key is associated with.
+ # The name of the repository the secret is stored in.
[string] $Repository
- # The name of the environment the Public Key is associated with.
+ # The name of the environment the secret is stored in.
[string] $Environment
- # The date and time the variable was created.
+ # The date and time the secret was created.
[datetime] $CreatedAt
- # The date and time the variable was last updated.
+ # The date and time the secret was last updated.
[datetime] $UpdatedAt
- # The visibility of the variable.
+ # The visibility of the secret.
[string] $Visibility
- # The ids of the repositories that the variable is visible to.
+ # The ids of the repositories that the secret is visible to.
[GitHubRepository[]] $SelectedRepositories
GitHubSecret() {}
diff --git a/src/classes/public/Variables/GitHubVariable.ps1 b/src/classes/public/Variables/GitHubVariable.ps1
index 6af9e2c0a..412d31c15 100644
--- a/src/classes/public/Variables/GitHubVariable.ps1
+++ b/src/classes/public/Variables/GitHubVariable.ps1
@@ -8,13 +8,13 @@
# The scope of the variable, organization, repository, or environment.
[string] $Scope
- # The name of the organization or user the variable is associated with.
+ # The name of the organization or user the variable is stored in.
[string] $Owner
- # The name of the repository the variable is associated with.
+ # The name of the repository the variable is stored in.
[string] $Repository
- # The name of the environment the variable is associated with.
+ # The name of the environment the variable is stored in.
[string] $Environment
# The date and time the variable was created.
diff --git a/src/formats/GitHubEnvironment.Format.ps1xml b/src/formats/GitHubEnvironment.Format.ps1xml
index 1373b0c0f..6a8530fa0 100644
--- a/src/formats/GitHubEnvironment.Format.ps1xml
+++ b/src/formats/GitHubEnvironment.Format.ps1xml
@@ -32,10 +32,24 @@
- Repository
+
+ if ($Host.UI.SupportsVirtualTerminal -and
+ ($env:GITHUB_ACTIONS -ne 'true')) {
+ $PSStyle.FormatHyperlink($_.Repository,$_.RepositoryUrl)
+ } else {
+ $_.Repository
+ }
+
- Owner
+
+ if ($Host.UI.SupportsVirtualTerminal -and
+ ($env:GITHUB_ACTIONS -ne 'true')) {
+ $PSStyle.FormatHyperlink($_.Owner,$_.OwnerUrl)
+ } else {
+ $_.Owner
+ }
+
diff --git a/src/formats/GitHubPermissionDefinition.Format.ps1xml b/src/formats/GitHubPermissionDefinition.Format.ps1xml
new file mode 100644
index 000000000..756b42381
--- /dev/null
+++ b/src/formats/GitHubPermissionDefinition.Format.ps1xml
@@ -0,0 +1,46 @@
+
+
+
+
+ GitHubPermissionDefinitionTable
+
+ GitHubPermissionDefinition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Scope
+
+
+
+ if ($Host.UI.SupportsVirtualTerminal -and
+ ($env:GITHUB_ACTIONS -ne 'true') -and $_.Url) {
+ $PSStyle.FormatHyperlink($_.DisplayName, $_.Url)
+ } else {
+ $_.DisplayName
+ }
+
+
+
+ Description
+
+
+
+
+
+
+
+
diff --git a/src/functions/public/Auth/Context/Get-GitHubContext.ps1 b/src/functions/public/Auth/Context/Get-GitHubContext.ps1
index 9f0015551..6ff8aecc1 100644
--- a/src/functions/public/Auth/Context/Get-GitHubContext.ps1
+++ b/src/functions/public/Auth/Context/Get-GitHubContext.ps1
@@ -19,12 +19,12 @@
Justification = 'Encapsulated in a function. Never leaves as a plain text.'
)]
[OutputType([GitHubContext])]
- [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')]
+ [CmdletBinding(DefaultParameterSetName = 'Get default context')]
param(
# The name of the context.
[Parameter(
Mandatory,
- ParameterSetName = 'NamedContext'
+ ParameterSetName = 'Get a named context'
)]
[Alias('Name')]
[string] $Context,
@@ -32,7 +32,7 @@
# List all available contexts.
[Parameter(
Mandatory,
- ParameterSetName = 'ListAvailableContexts'
+ ParameterSetName = 'List all available contexts'
)]
[switch] $ListAvailable
)
@@ -45,11 +45,11 @@
process {
switch ($PSCmdlet.ParameterSetName) {
- 'NamedContext' {
- Write-Debug "NamedContext: [$Context]"
+ 'Get a named context' {
+ Write-Debug "Get a named context: [$Context]"
$ID = $Context
}
- 'ListAvailableContexts' {
+ 'List all available contexts' {
Write-Debug "ListAvailable: [$ListAvailable]"
$ID = '*'
}
@@ -85,7 +85,7 @@
throw "Unknown context type: [$($contextObj.Type)]"
}
}
- }
+ } | Sort-Object -Property Name
}
end {
@@ -93,4 +93,3 @@
}
}
#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '8.1.3' }
-
diff --git a/src/functions/private/Auth/Context/completers.ps1 b/src/functions/public/Auth/Context/completers.ps1
similarity index 92%
rename from src/functions/private/Auth/Context/completers.ps1
rename to src/functions/public/Auth/Context/completers.ps1
index 31f4d4436..fb204c67a 100644
--- a/src/functions/private/Auth/Context/completers.ps1
+++ b/src/functions/public/Auth/Context/completers.ps1
@@ -12,7 +12,8 @@
$contexts += 'Anonymous'
}
- $contexts += (Get-GitHubContext -ListAvailable -Verbose:$false).Name
+ $contexts += (Get-GitHubContext -ListAvailable -Verbose:$false -Debug:$false).Name
+ $contexts = $contexts | Sort-Object -Unique
$contexts | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
diff --git a/src/functions/public/Auth/Connect-GitHubApp_completer.ps1 b/src/functions/public/Auth/completer.ps1
similarity index 100%
rename from src/functions/public/Auth/Connect-GitHubApp_completer.ps1
rename to src/functions/public/Auth/completer.ps1
diff --git a/src/functions/public/Permission/Get-GitHubPermissionDefinition.ps1 b/src/functions/public/Permission/Get-GitHubPermissionDefinition.ps1
new file mode 100644
index 000000000..0019adf59
--- /dev/null
+++ b/src/functions/public/Permission/Get-GitHubPermissionDefinition.ps1
@@ -0,0 +1,104 @@
+function Get-GitHubPermissionDefinition {
+ <#
+ .SYNOPSIS
+ Retrieves GitHub permission definitions
+
+ .DESCRIPTION
+ Gets the list of GitHub permission definitions from the module's internal data store.
+ This includes fine-grained permissions for repositories, organizations, and user accounts.
+ The function supports filtering by permission type and scope to help you find specific permissions.
+
+ File path-specific permissions are excluded from this list as they are handled differently
+ by the GitHub API (they appear under the FilePaths property in installation data rather
+ than as named permissions).
+
+ .EXAMPLE
+ Get-GitHubPermissionDefinition
+
+ Gets all permission definitions.
+
+ .EXAMPLE
+ Get-GitHubPermissionDefinition -Type Fine-grained
+
+ Gets all fine-grained permission definitions.
+
+ .EXAMPLE
+ Get-GitHubPermissionDefinition -Scope Repository
+
+ Gets all permission definitions that apply to repository scope.
+
+ .EXAMPLE
+ Get-GitHubPermissionDefinition -Type Fine-grained -Scope Organization
+
+ Gets all fine-grained permission definitions that apply to organization scope.
+
+ .EXAMPLE
+ Get-GitHubPermissionDefinition -Name contents
+
+ Gets the specific permission definition for 'contents' permission.
+
+ .NOTES
+ This function provides access to a curated list of GitHub permission definitions maintained within the module.
+ The data includes permission names, display names, descriptions, available options, and scopes.
+
+ File path permissions are excluded from this list as they are handled differently by the GitHub API.
+ These permissions are user-specified paths with read/write access that appear in the FilePaths
+ property of GitHub App installation data, not as standard named permissions.
+
+ .LINK
+ https://psmodule.io/GitHub/Functions/Permission/Get-GitHubPermissionDefinition
+ #>
+ [OutputType([GitHubPermissionDefinition[]])]
+ [CmdletBinding()]
+ param(
+ # Filter by permission name (supports multiple values & wildcards)
+ [Parameter()]
+ [string[]] $Name = '*',
+
+ # Filter by permission display name (supports multiple values & wildcards)
+ [Parameter()]
+ [string[]] $DisplayName = '*',
+
+ # Filter by permission type (supports multiple values & wildcards)
+ [Parameter()]
+ [string[]] $Type = '*',
+
+ # Filter by permission scope (supports multiple values & wildcards)
+ [Parameter()]
+ [string[]] $Scope = '*'
+ )
+
+ begin {
+ $stackPath = Get-PSCallStackPath
+ Write-Debug "[$stackPath] - Start"
+ }
+
+ process {
+ try {
+ [scriptblock]$test = {
+ param(
+ [Parameter(Mandatory)][string] $Value,
+ [Parameter(Mandatory)][string[]] $Patterns
+ )
+ foreach ($p in $Patterns) {
+ if ($Value -like $p) { return $true }
+ }
+ return $false
+ }
+
+ $script:GitHub.Permissions | Where-Object {
+ (& $test -Value $_.Name -Patterns $Name) -and
+ (& $test -Value $_.DisplayName -Patterns $DisplayName) -and
+ (& $test -Value $_.Type -Patterns $Type) -and
+ (& $test -Value $_.Scope -Patterns $Scope)
+ }
+ } catch {
+ Write-Error "Failed to retrieve GitHub permission definitions: $($_.Exception.Message)"
+ throw
+ }
+ }
+
+ end {
+ Write-Debug "[$stackPath] - End"
+ }
+}
diff --git a/src/functions/public/Permission/completers.ps1 b/src/functions/public/Permission/completers.ps1
new file mode 100644
index 000000000..139a72e5f
--- /dev/null
+++ b/src/functions/public/Permission/completers.ps1
@@ -0,0 +1,35 @@
+Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -ParameterName Name -ScriptBlock {
+ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
+ $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
+
+ $script:GitHub.Permissions.Name | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
+ }
+}
+
+Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -ParameterName DisplayName -ScriptBlock {
+ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
+ $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
+
+ $script:GitHub.Permissions.DisplayName | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
+ }
+}
+
+Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -ParameterName Type -ScriptBlock {
+ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
+ $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
+
+ $script:GitHub.Permissions.Type | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
+ }
+}
+
+Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -ParameterName Scope -ScriptBlock {
+ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
+ $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
+
+ $script:GitHub.Permissions.Scope | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
+ }
+}
diff --git a/src/functions/public/Secrets/Remove-GitHubSecret.ps1 b/src/functions/public/Secrets/Remove-GitHubSecret.ps1
index 2d4f1a4b4..f5ea7b3eb 100644
--- a/src/functions/public/Secrets/Remove-GitHubSecret.ps1
+++ b/src/functions/public/Secrets/Remove-GitHubSecret.ps1
@@ -78,15 +78,38 @@
switch ($PSCmdlet.ParameterSetName) {
'ArrayInput' {
foreach ($item in $InputObject) {
- $params = @{
- Owner = $item.Owner
- Repository = $item.Repository
- Environment = $item.Environment
- Name = $item.Name
- Context = $item.Context
+ switch ($item.Scope) {
+ 'environment' {
+ $params = @{
+ Owner = $item.Owner
+ Repository = $item.Repository
+ Environment = $item.Environment
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubSecretFromEnvironment @params
+ }
+ 'repository' {
+ $params = @{
+ Owner = $item.Owner
+ Repository = $item.Repository
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubSecretFromRepository @params
+ }
+ 'organization' {
+ $params = @{
+ Owner = $item.Owner
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubSecretFromOwner @params
+ }
+ default {
+ throw "Secret '$($item.Name)' has unsupported Scope value '$scope'."
+ }
}
- $params | Remove-HashtableEntry -NullOrEmptyValues
- Remove-GitHubSecret @params
}
break
}
diff --git a/src/functions/public/Variables/Remove-GitHubVariable.ps1 b/src/functions/public/Variables/Remove-GitHubVariable.ps1
index ffe376cc3..578ad371c 100644
--- a/src/functions/public/Variables/Remove-GitHubVariable.ps1
+++ b/src/functions/public/Variables/Remove-GitHubVariable.ps1
@@ -84,15 +84,38 @@
switch ($PSCmdlet.ParameterSetName) {
'ArrayInput' {
foreach ($item in $InputObject) {
- $params = @{
- Owner = $item.Owner
- Repository = $item.Repository
- Environment = $item.Environment
- Name = $item.Name
- Context = $item.Context
+ switch ($item.Scope) {
+ 'environment' {
+ $params = @{
+ Owner = $item.Owner
+ Repository = $item.Repository
+ Environment = $item.Environment
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubVariableFromEnvironment @params
+ }
+ 'repository' {
+ $params = @{
+ Owner = $item.Owner
+ Repository = $item.Repository
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubVariableFromRepository @params
+ }
+ 'organization' {
+ $params = @{
+ Owner = $item.Owner
+ Name = $item.Name
+ Context = $Context
+ }
+ Remove-GitHubVariableFromOwner @params
+ }
+ default {
+ throw "Variable '$($item.Name)' has unsupported Scope value '$($item.Scope)'."
+ }
}
- $params | Remove-HashtableEntry -NullOrEmptyValues
- Remove-GitHubVariable @params
}
break
}
diff --git a/src/variables/private/GitHub.ps1 b/src/variables/private/GitHub.ps1
index 3891118b3..917d0be14 100644
--- a/src/variables/private/GitHub.ps1
+++ b/src/variables/private/GitHub.ps1
@@ -23,4 +23,1184 @@ $script:GitHub = [pscustomobject]@{
Config = $null
Event = $null
Runner = $null
+ Permissions = @(
+ # ------------------------------
+ # Repository Fine-Grained Permission Definitions
+ # ------------------------------
+ [GitHubPermissionDefinition]::new(
+ 'actions',
+ 'Actions',
+ 'Workflows, workflow runs and artifacts.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-actions',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'administration',
+ 'Administration',
+ 'Repository creation, deletion, settings, teams, and collaborators.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-administration',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'attestations',
+ 'Attestations',
+ 'Create and retrieve attestations for a repository.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-attestations',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'checks',
+ 'Checks',
+ 'Checks on code.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-checks',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'security_events',
+ 'Code scanning alerts',
+ 'View and manage code scanning alerts.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-code-scanning-alerts',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'codespaces',
+ 'Codespaces',
+ 'Create, edit, delete and list Codespaces.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-codespaces',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'codespaces_lifecycle_admin',
+ 'Codespaces lifecycle admin',
+ 'Manage the lifecycle of Codespaces, including starting and stopping.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-codespaces-lifecycle-admin',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'codespaces_metadata',
+ 'Codespaces metadata',
+ 'Access Codespaces metadata including the devcontainers and machine type.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-codespaces-metadata',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'codespaces_secrets',
+ 'Codespaces secrets',
+ 'Restrict Codespaces user secrets modifications to specific repositories.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-codespaces-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'statuses',
+ 'Commit statuses',
+ 'Commit statuses.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-commit-statuses',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'contents',
+ 'Contents',
+ 'Repository contents, commits, branches, downloads, releases, and merges.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-contents',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'repository_custom_properties',
+ 'Custom properties',
+ 'Read and write repository custom properties values at the repository level, when allowed by the property.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-custom-properties',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'vulnerability_alerts',
+ 'Dependabot alerts',
+ 'Retrieve Dependabot alerts.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-dependabot-alerts',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'dependabot_secrets',
+ 'Dependabot secrets',
+ 'Manage Dependabot repository secrets.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-dependabot-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'deployments',
+ 'Deployments',
+ 'Deployments and deployment statuses.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-deployments',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'discussions',
+ 'Discussions',
+ 'Discussions and related comments and labels.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-discussions',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'environments',
+ 'Environments',
+ 'Manage repository environments.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-environments',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'issues',
+ 'Issues',
+ 'Issues and related comments, assignees, labels, and milestones.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-issues',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'merge_queues',
+ 'Merge queues',
+ "Manage a repository's merge queues",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-merge-queues',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new( #Mandatory
+ 'metadata',
+ 'Metadata',
+ 'Search repositories, list collaborators, and access repository metadata.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-metadata',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'packages',
+ 'Packages',
+ 'Packages published to the GitHub Package Platform.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-packages',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'pages',
+ 'Pages',
+ 'Retrieve Pages statuses, configuration, and builds, as well as create new builds.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-pages',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'repository_projects',
+ 'Projects',
+ 'Manage classic projects within a repository.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-projects',
+ @(
+ 'read',
+ 'write',
+ 'admin'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'pull_requests',
+ 'Pull requests',
+ 'Pull requests and related comments, assignees, labels, milestones, and merges.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-pull-requests',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'repository_advisories',
+ 'Repository security advisories',
+ 'View and manage repository security advisories.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-repository-security-advisories',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'repo_secret_scanning_dismissal_requests',
+ 'Secret scanning alert dismissal requests',
+ 'View and manage secret scanning alert dismissal requests',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-secret-scanning-alert-dismissal-requests',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'secret_scanning_alerts',
+ 'Secret scanning alerts',
+ 'View and manage secret scanning alerts.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-secret-scanning-alerts',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'secret_scanning_bypass_requests',
+ 'Secret scanning push protection bypass requests',
+ 'Review and manage repository secret scanning push protection bypass requests.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-secret-scanning-push-protection-bypass-requests',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'secrets',
+ 'Secrets',
+ 'Manage Actions repository secrets.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'single_file',
+ 'Single file',
+ 'Manage just a single file.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-single-file',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'actions_variables',
+ 'Variables',
+ 'Manage Actions repository variables.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-variables',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'repository_hooks',
+ 'Webhooks',
+ 'Manage the post-receive hooks for a repository.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-webhooks',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'workflows',
+ 'Workflows',
+ 'Update GitHub Action workflow files.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#repository-permissions-for-workflows',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Repository'
+ ),
+
+ # ------------------------------
+ # Organization Fine-Grained Permission Definitions
+ # ------------------------------
+ [GitHubPermissionDefinition]::new(
+ 'organization_api_insights',
+ 'API Insights',
+ 'View statistics on how the API is being used for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-api-insights',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_administration',
+ 'Administration',
+ 'Manage access to an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-administration',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_user_blocking',
+ 'Blocking users',
+ 'View and manage users blocked by the organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-blocking-users',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_campaigns',
+ 'Campaigns',
+ 'Manage campaigns.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-campaigns',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_custom_org_roles',
+ 'Custom organization roles',
+ 'Create, edit, delete and list custom organization roles. View system organization roles.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-custom-organization-roles',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_custom_properties',
+ 'Custom properties',
+ 'Read and write repository custom properties values and administer definitions at the organization level.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-custom-properties',
+ @(
+ 'read',
+ 'write',
+ 'admin'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_custom_roles',
+ 'Custom repository roles',
+ 'Create, edit, delete and list custom repository roles.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-custom-repository-roles',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_events',
+ 'Events',
+ 'View events triggered by an activity in an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-events',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_copilot_seat_management',
+ 'GitHub Copilot Business',
+ 'Manage Copilot Business seats and settings',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-github-copilot-business',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'issue_fields',
+ 'Issue Fields',
+ 'Manage issue fields for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-issue-fields',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'issue_types',
+ 'Issue Types',
+ 'Manage issue types for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-issue-types',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_knowledge_bases',
+ 'Knowledge bases',
+ 'View and manage knowledge bases for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-knowledge-bases',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'members',
+ 'Members',
+ 'Organization members and teams.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-members',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_models',
+ 'Models',
+ 'Manage model access for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-models',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_network_configurations',
+ 'Network configurations',
+ 'View and manage hosted compute network configurations available to an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-network-configurations',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_announcement_banners',
+ 'Organization announcement banners',
+ 'View and modify announcement banners for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-announcement-banners',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_secret_scanning_bypass_requests',
+ 'Organization bypass requests for secret scanning',
+ 'Review and manage secret scanning push protection bypass requests.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-bypass-requests-for-secret-scanning',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_codespaces',
+ 'Organization codespaces',
+ 'Manage Codespaces for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-codespaces',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_codespaces_secrets',
+ 'Organization codespaces secrets',
+ 'Manage Codespaces Secrets for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-codespaces-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_codespaces_settings',
+ 'Organization codespaces settings',
+ 'Manage Codespaces settings for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-codespaces-settings',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_dependabot_secrets',
+ 'Organization dependabot secrets',
+ 'Manage Dependabot organization secrets.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-dependabot-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_code_scanning_dismissal_requests',
+ 'Organization dismissal requests for code scanning',
+ 'Review and manage code scanning alert dismissal requests.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-dismissal-requests-for-code-scanning',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_private_registries',
+ 'Organization private registries',
+ 'Manage private registries for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-organization-private-registries',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_personal_access_token_requests',
+ 'Personal access token requests',
+ 'Manage personal access token requests from organization members.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-personal-access-token-requests',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_personal_access_tokens',
+ 'Personal access tokens',
+ 'View and revoke personal access tokens that have been granted access to an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-personal-access-tokens',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_plan',
+ 'Plan',
+ "View an organization's plan.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-plan',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_projects',
+ 'Projects',
+ 'Manage projects for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-projects',
+ @(
+ 'read',
+ 'write',
+ 'admin'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'secret_scanning_dismissal_requests',
+ 'Secret scanning alert dismissal requests',
+ 'Review and manage secret scanning alert dismissal requests',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-secret-scanning-alert-dismissal-requests',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_secrets',
+ 'Secrets',
+ 'Manage Actions organization secrets.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_self_hosted_runners',
+ 'Self-hosted runners',
+ 'View and manage Actions self-hosted runners available to an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-self-hosted-runners',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'team_discussions',
+ 'Team discussions',
+ 'Manage team discussions and related comments.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-team-discussions',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_actions_variables',
+ 'Variables',
+ 'Manage Actions organization variables.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-variables',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'organization_hooks',
+ 'Webhooks',
+ 'Manage the post-receive hooks for an organization.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#organization-permissions-for-webhooks',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Organization'
+ ),
+
+ # ------------------------------
+ # User (Account) Fine-Grained Permission Definitions
+ # ------------------------------
+ [GitHubPermissionDefinition]::new(
+ 'blocking',
+ 'Block another user',
+ 'View and manage users blocked by the user.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-block-another-user',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'codespaces_user_secrets',
+ 'Codespaces user secrets',
+ 'Manage Codespaces user secrets.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-codespaces-user-secrets',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'copilot_messages',
+ 'Copilot Chat',
+ 'This application will receive your GitHub ID, your GitHub Copilot Chat session messages ' +
+ '(not including messages sent to another application), and timestamps of provided GitHub Copilot ' +
+ 'Chat session messages. This permission must be enabled for Copilot Extensions.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-copilot-chat',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'copilot_editor_context',
+ 'Copilot Editor Context',
+ 'This application will receive bits of Editor Context (e.g. currently opened file) whenever you send it a message through Copilot Chat.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-copilot-editor-context',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'emails',
+ 'Email addresses',
+ "Manage a user's email addresses.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-email-addresses',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'user_events',
+ 'Events',
+ "View events triggered by a user's activity.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-events',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'followers',
+ 'Followers',
+ "A user's followers",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-followers',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'gpg_keys',
+ 'GPG keys',
+ "View and manage a user's GPG keys.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-gpg-keys',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'gists',
+ 'Gists',
+ "Create and modify a user's gists and comments.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-gists',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'keys',
+ 'Git SSH keys',
+ 'Git SSH keys',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-git-ssh-keys',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'interaction_limits',
+ 'Interaction limits',
+ 'Interaction limits on repositories',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-interaction-limits',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'knowledge_bases',
+ 'Knowledge bases',
+ 'View knowledge bases for a user.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-knowledge-bases',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'user_models',
+ 'Models',
+ 'Allows access to GitHub Models.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-models',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'plan',
+ 'Plan',
+ "View a user's plan.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-plan',
+ @(
+ 'read'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'profile',
+ 'Profile',
+ "Manage a user's profile settings.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-profile',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'git_signing_ssh_public_keys',
+ 'SSH signing keys',
+ "View and manage a user's SSH signing keys.",
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-ssh-signing-keys',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'starring',
+ 'Starring',
+ 'List and manage repositories a user is starring.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-starring',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'watching',
+ 'Watching',
+ 'List and change repositories a user is subscribed to.',
+ 'https://docs.github.com/rest/overview/permissions-required-for-github-apps' +
+ '#user-permissions-for-watching',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'User'
+ ),
+
+ # ------------------------------
+ # Enterprise Fine-Grained Permission Definitions
+ # ------------------------------
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_custom_properties',
+ 'Custom properties',
+ 'View repository custom properties and administer definitions at the enterprise level.',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-custom-properties',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_organization_installation_repositories',
+ 'Enterprise organization installation repositories',
+ 'Manage repository access of GitHub Apps on Enterprise-owned organizations',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-enterprise-organization-installation-repositories',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_organization_installations',
+ 'Enterprise organization installations',
+ 'Manage installation of GitHub Apps on Enterprise-owned organizations',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-enterprise-organization-installations',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_organizations',
+ 'Enterprise organizations',
+ 'Create and remove enterprise organizations',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-enterprise-organizations',
+ @(
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_people',
+ 'Enterprise people',
+ 'Manage user access to the enterprise',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-enterprise-people',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ ),
+ [GitHubPermissionDefinition]::new(
+ 'enterprise_sso',
+ 'Enterprise single sign-on',
+ 'View and manage enterprise single sign-on configuration',
+ 'https://docs.github.com/enterprise-cloud@latest/rest/overview/permissions-required-for-github-apps' +
+ '#enterprise-permissions-for-enterprise-single-sign-on',
+ @(
+ 'read',
+ 'write'
+ ),
+ 'Fine-grained',
+ 'Enterprise'
+ )
+ )
}
diff --git a/tests/GitHubFormatter.Tests.ps1 b/tests/GitHubFormatter.Tests.ps1
index 63f55c7c3..7c9455acf 100644
--- a/tests/GitHubFormatter.Tests.ps1
+++ b/tests/GitHubFormatter.Tests.ps1
@@ -7,11 +7,7 @@
[CmdletBinding()]
param()
-# This test file validates size property standardization across GitHub classes
-# It focuses on unit conversion and formatting expectations rather than live API calls
-
Describe 'Size Property Standardization Tests' {
-
Context 'Unit Conversion Logic' {
It 'Validates KB to Bytes conversion formula' {
# Test the conversion used in GitHubRepository and GitHubOrganization
@@ -41,23 +37,19 @@ Describe 'Size Property Standardization Tests' {
}
Context 'Expected Format Output Patterns' {
- It 'Validates expected format patterns for size display' {
- # These tests verify the expected output patterns without requiring the actual formatter
- # They document what the GitHubFormatter::FormatFileSize method should produce
-
- $testCases = @(
- @{ Bytes = 0; ExpectedPattern = '\d+\s+B' } # "0 B"
- @{ Bytes = 512; ExpectedPattern = '\d+\s+B' } # "512 B"
- @{ Bytes = 1024; ExpectedPattern = '\d+\.\d{2} KB' } # "1.00 KB"
- @{ Bytes = 1048576; ExpectedPattern = '\d+\.\d{2} MB' } # "1.00 MB"
- @{ Bytes = 1073741824; ExpectedPattern = '\d+\.\d{2} GB' } # "1.00 GB"
- @{ Bytes = 110592; ExpectedPattern = '\d+\.\d{2} KB' } # "108.00 KB"
- )
-
- foreach ($case in $testCases) {
- # Document expected pattern - actual formatting tested in integration tests
- $case.ExpectedPattern | Should -Match '\w+' # Verify pattern is non-empty
- }
+ $testCases = @(
+ @{ Bytes = 0; ExpectedPattern = '\d+[.,]\d{2}\s{2}B' } # "0.00 B"
+ @{ Bytes = 512; ExpectedPattern = '\d+[.,]\d{2}\s{2}B' } # "512.00 B"
+ @{ Bytes = 1024; ExpectedPattern = '\d+[.,]\d{2} KB' } # "1.00 KB"
+ @{ Bytes = 1048576; ExpectedPattern = '\d+[.,]\d{2} MB' } # "1.00 MB"
+ @{ Bytes = 1073741824; ExpectedPattern = '\d+[.,]\d{2} GB' } # "1.00 GB"
+ @{ Bytes = 110592; ExpectedPattern = '\d+[.,]\d{2} KB' } # "108.00 KB"
+ )
+
+ It 'Validates formatter output pattern for bytes' -ForEach $testCases {
+ # Test the formatter against the expected pattern
+ $result = [GitHubFormatter]::FormatFileSize($Bytes)
+ $result | Should -Match $ExpectedPattern
}
}
diff --git a/tests/Permissions.Tests.ps1 b/tests/Permissions.Tests.ps1
new file mode 100644
index 000000000..043358796
--- /dev/null
+++ b/tests/Permissions.Tests.ps1
@@ -0,0 +1,211 @@
+#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' }
+
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSUseDeclaredVarsMoreThanAssignments', '',
+ Justification = 'Pester grouping syntax: known issue.'
+)]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSAvoidUsingConvertToSecureStringWithPlainText', '',
+ Justification = 'Used to create a secure string for testing.'
+)]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSAvoidUsingWriteHost', '',
+ Justification = 'Log outputs to GitHub Actions logs.'
+)]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSAvoidLongLines', '',
+ Justification = 'Long test descriptions and skip switches'
+)]
+[CmdletBinding()]
+param()
+
+Describe 'Permissions' {
+ $authCases = . "$PSScriptRoot/Data/AuthCases.ps1"
+
+ Context 'As using on ' -ForEach $authCases {
+ BeforeAll {
+ $context = Connect-GitHubAccount @connectParams -PassThru -Silent
+ LogGroup 'Context' {
+ Write-Host ($context | Format-List | Out-String)
+ }
+ }
+
+ AfterAll {
+ Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent
+ Write-Host ('-' * 60)
+ }
+
+ Context 'For Apps' -Skip:($AuthType -ne 'APP') {
+ BeforeAll {
+ $installationContext = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent
+ LogGroup 'Context - Installation' {
+ Write-Host ($installationContext | Format-List | Out-String)
+ }
+ }
+
+ It 'App context should have Permissions property populated' -Skip:($AuthType -ne 'APP') {
+ $installationContext.Permissions | Should -Not -BeNullOrEmpty
+ $installationContext.Permissions | Should -BeOfType [pscustomobject]
+ }
+
+ It 'All app installation permissions should exist in permission catalog and be valid options' -Skip:($AuthType -ne 'APP') {
+ $catalog = Get-GitHubPermissionDefinition
+ $catalogNames = $catalog.Name
+
+ # Flatten context permission hashtable/object into name/value pairs (value is access level like read/write/admin)
+ $granted = @()
+ $installationContext.Permissions.PSObject.Properties | ForEach-Object {
+ if ($_.Name -eq 'metadata') { return } # metadata is mandatory; still in catalog but just proceed normally
+ $granted += [pscustomobject]@{ Name = $_.Name; Level = [string]$_.Value }
+ }
+
+ # Unknown permissions (present in context but not in catalog)
+ $unknown = $granted | Where-Object { $_.Name -notin $catalogNames }
+ if ($unknown) {
+ throw "Unknown permission(s) detected in app installation: $($unknown.Name -join ', ')"
+ }
+
+ # For each granted permission ensure level is one of the catalog options
+ foreach ($g in $granted) {
+ $def = $catalog | Where-Object Name -EQ $g.Name
+ $def | Should -Not -BeNullOrEmpty
+ $def.Options | Should -Contain $g.Level
+ }
+ }
+
+ It 'Permission catalog should contain all permissions granted to the app installation' -Skip:($AuthType -ne 'APP') {
+ $catalog = Get-GitHubPermissionDefinition
+ $missing = @()
+ $installationContext.Permissions.PSObject.Properties | ForEach-Object {
+ if ($_.Name -notin $catalog.Name) {
+ $missing += $_.Name
+ }
+ }
+ if ($missing.Count -gt 0) {
+ throw "Missing permission definitions for: $($missing -join ', ')"
+ }
+ }
+ }
+ }
+
+ Context 'Get-GitHubPermissionDefinition' {
+ It 'Should return all permission definitions when called without parameters' {
+ $result = Get-GitHubPermissionDefinition
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ ($result | Measure-Object).Count | Should -BeGreaterThan 0
+ }
+
+ It 'Should return only Fine-grained permissions when filtered by Type' {
+ $result = Get-GitHubPermissionDefinition -Type Fine-grained
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ $result | ForEach-Object { $_.Type | Should -Be 'Fine-grained' }
+ }
+
+ It 'Should return only Repository permissions when filtered by Scope' {
+ $result = Get-GitHubPermissionDefinition -Scope Repository
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ $result | ForEach-Object { $_.Scope | Should -Be 'Repository' }
+ }
+
+ It 'Should return only Organization permissions when filtered by Scope' {
+ $result = Get-GitHubPermissionDefinition -Scope Organization
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ $result | ForEach-Object { $_.Scope | Should -Be 'Organization' }
+ }
+
+ It 'Should return only User permissions when filtered by Scope' {
+ $result = Get-GitHubPermissionDefinition -Scope User
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ $result | ForEach-Object { $_.Scope | Should -Be 'User' }
+ }
+
+ It 'Should filter by both Type and Scope when both are specified' {
+ $result = Get-GitHubPermissionDefinition -Type Fine-grained -Scope Repository
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType [GitHubPermissionDefinition]
+ $result | ForEach-Object {
+ $_.Type | Should -Be 'Fine-grained'
+ $_.Scope | Should -Be 'Repository'
+ }
+ }
+
+ It 'Should include expected properties for each permission' {
+ $result = Get-GitHubPermissionDefinition | Select-Object -First 1
+ $result.Name | Should -Not -BeNullOrEmpty
+ $result.DisplayName | Should -Not -BeNullOrEmpty
+ $result.Description | Should -Not -BeNullOrEmpty
+ $result.URL | Should -Not -BeNullOrEmpty
+ $result.Options | Should -Not -BeNullOrEmpty
+ $result.Type | Should -Not -BeNullOrEmpty
+ $result.Scope | Should -Not -BeNullOrEmpty
+ }
+
+ It 'Should include the contents permission for repositories' {
+ $result = Get-GitHubPermissionDefinition | Where-Object { $_.Name -eq 'contents' }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Name | Should -Be 'contents'
+ $result.DisplayName | Should -Be 'Contents'
+ $result.Scope | Should -Be 'Repository'
+ $result.Type | Should -Be 'Fine-grained'
+ $result.Options | Should -Contain 'read'
+ $result.Options | Should -Contain 'write'
+ }
+
+ It 'Should include the members permission for organizations' {
+ $result = Get-GitHubPermissionDefinition | Where-Object { $_.Name -eq 'members' }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Name | Should -Be 'members'
+ $result.DisplayName | Should -Be 'Members'
+ $result.Scope | Should -Be 'Organization'
+ $result.Type | Should -Be 'Fine-grained'
+ $result.Options | Should -Contain 'read'
+ $result.Options | Should -Contain 'write'
+ }
+
+ It 'Should include profile permission for users' {
+ $result = Get-GitHubPermissionDefinition | Where-Object { $_.Name -eq 'profile' }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Name | Should -Be 'profile'
+ $result.DisplayName | Should -Be 'Profile'
+ $result.Scope | Should -Be 'User'
+ $result.Type | Should -Be 'Fine-grained'
+ $result.Options | Should -Contain 'write'
+ }
+ }
+
+ Context 'GitHubPermission Class' {
+ BeforeAll {
+ $permission = [GitHubPermissionDefinition]@{
+ Name = 'test'
+ DisplayName = 'Test Permission'
+ Description = 'A test permission'
+ URL = 'https://docs.github.com/test'
+ Options = @('read', 'write')
+ Type = 'Fine-grained'
+ Scope = 'Repository'
+ }
+ }
+
+ It 'Should create a GitHubPermission object with all properties' {
+ $permission | Should -Not -BeNullOrEmpty
+ $permission.Name | Should -Be 'test'
+ $permission.DisplayName | Should -Be 'Test Permission'
+ $permission.Description | Should -Be 'A test permission'
+ $permission.URL | Should -Be 'https://docs.github.com/test'
+ $permission.Options | Should -Contain 'read'
+ $permission.Options | Should -Contain 'write'
+ $permission.Type | Should -Be 'Fine-grained'
+ $permission.Scope | Should -Be 'Repository'
+ }
+
+ It 'Should have a meaningful ToString() method' {
+ $result = $permission.ToString()
+ $result | Should -Be 'test'
+ }
+ }
+}
diff --git a/tests/Secrets.Tests.ps1 b/tests/Secrets.Tests.ps1
index 48bff8af7..48e06423d 100644
--- a/tests/Secrets.Tests.ps1
+++ b/tests/Secrets.Tests.ps1
@@ -215,14 +215,18 @@ Describe 'Secrets' {
}
}
- It 'Remove-GitHubSecret' {
+ It 'Remove-GitHubSecret via pipeline - using pipeline' {
$testSecretName = "$secretName`TestSecret*"
+ LogGroup 'Create secret(s) for pipeline removal' {
+ $create = Set-GitHubSecret @scope -Name "$secretName`TestSecretPipeline" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
+ }
LogGroup 'Before remove' {
$before = Get-GitHubSecret @scope -Name $testSecretName
Write-Host "$($before | Format-List | Out-String)"
}
LogGroup 'Remove' {
- $before | Remove-GitHubSecret
+ Get-GitHubSecret @scope -Name $testSecretName | Remove-GitHubSecret
}
LogGroup 'After remove' {
$after = Get-GitHubSecret @scope -Name $testSecretName
@@ -231,6 +235,26 @@ Describe 'Secrets' {
$after.Count | Should -Be 0
}
+ It 'Remove-GitHubSecret via pipeline - using variable' {
+ $pipelineTestSecretName = "$secretName`PipelineTest"
+ LogGroup 'Create test secret for pipeline removal' {
+ $createResult = Set-GitHubSecret @scope -Name $pipelineTestSecretName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get secret for pipeline removal' {
+ $secretToRemove = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($secretToRemove | Format-List | Out-String)"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $secretToRemove | Remove-GitHubSecret } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
+
Context 'SelectedRepository' {
It 'Get-GitHubSecretSelectedRepository - gets a list of selected repositories' {
LogGroup "SelectedRepositories - [$orgSecretName]" {
@@ -402,18 +426,42 @@ Describe 'Secrets' {
}
}
- It 'Remove-GitHubSecret' {
+ It 'Remove-GitHubSecret via pipeline - using pipeline' {
+ LogGroup 'Create secret(s) for pipeline removal' {
+ $create = Set-GitHubSecret @scope -Name "$secretName`PipelineRemoval" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
+ }
$before = Get-GitHubSecret @scope -Name "*$os*"
LogGroup 'Secrets - Before' {
Write-Host "$($before | Format-Table | Out-String)"
}
- $before | Remove-GitHubSecret
+ Get-GitHubSecret @scope -Name "*$os*" | Remove-GitHubSecret
$after = Get-GitHubSecret @scope -Name "*$os*"
LogGroup 'Secrets -After' {
Write-Host "$($after | Format-Table | Out-String)"
}
$after.Count | Should -Be 0
}
+
+ It 'Remove-GitHubSecret via pipeline - using variable' {
+ $pipelineTestSecretName = "$secretName`PipelineTest"
+ LogGroup 'Create test secret for pipeline removal' {
+ $createResult = Set-GitHubSecret @scope -Name $pipelineTestSecretName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get secret for pipeline removal' {
+ $secretToRemove = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($secretToRemove | Format-List | Out-String)"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $secretToRemove | Remove-GitHubSecret } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
}
Context 'Environment' -Skip:($OwnerType -in ('repository', 'enterprise')) {
@@ -512,18 +560,43 @@ Describe 'Secrets' {
}
}
- It 'Remove-GitHubSecret' {
+ It 'Remove-GitHubSecret via pipeline - using pipeline' {
+ LogGroup 'Create secret(s) for pipeline removal' {
+ $create = Set-GitHubSecret @scope -Name "$secretName`PipelineRemoval" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
+ }
LogGroup 'Secrets - Before' {
$before = Get-GitHubSecret @scope -Name "*$os*"
Write-Host "$($before | Format-Table | Out-String)"
}
- $before | Remove-GitHubSecret
+ Get-GitHubSecret @scope -Name "*$os*" | Remove-GitHubSecret
LogGroup 'Secrets - After' {
$after = Get-GitHubSecret @scope -Name "*$os*"
Write-Host "$($after | Format-Table | Out-String)"
}
$after.Count | Should -Be 0
}
+
+ It 'Remove-GitHubSecret via pipeline - using variable' {
+ $pipelineTestSecretName = "$secretName`PipelineTest"
+ LogGroup 'Create test secret for pipeline removal' {
+ $createResult = Set-GitHubSecret @scope -Name $pipelineTestSecretName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get secret and test whitespace handling' {
+ $secretToRemove = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($secretToRemove | Format-List | Out-String)"
+ Write-Host "Testing that environment secrets with valid Environment property work correctly"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $secretToRemove | Remove-GitHubSecret } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubSecret @scope -Name $pipelineTestSecretName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
}
}
}
diff --git a/tests/Variables.Tests.ps1 b/tests/Variables.Tests.ps1
index 2b039ce31..0599ac435 100644
--- a/tests/Variables.Tests.ps1
+++ b/tests/Variables.Tests.ps1
@@ -240,22 +240,43 @@ Describe 'Variables' {
}
}
- It 'Remove-GitHubVariable' {
- $testVarName = "$variableName`TestVariable*"
- LogGroup 'Before remove' {
- $before = Get-GitHubVariable @scope -Name $testVarName
- Write-Host "$($before | Format-List | Out-String)"
+ It 'Remove-GitHubVariable via pipeline - using pipeline' {
+ LogGroup 'Create variable(s) for pipeline removal' {
+ $create = Set-GitHubVariable @scope -Name "$variableName`PipelineRemoval" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
}
- LogGroup 'Remove' {
- $before | Remove-GitHubVariable
+ $before = Get-GitHubVariable @scope -Name "*$os*"
+ LogGroup 'Variables - Before' {
+ Write-Host "$($before | Format-Table | Out-String)"
}
- LogGroup 'After remove' {
- $after = Get-GitHubVariable @scope -Name $testVarName
- Write-Host "$($after | Format-List | Out-String)"
+ Get-GitHubVariable @scope -Name "*$os*" | Remove-GitHubVariable
+ $after = Get-GitHubVariable @scope -Name "*$os*"
+ LogGroup 'Variables -After' {
+ Write-Host "$($after | Format-Table | Out-String)"
}
$after.Count | Should -Be 0
}
+ It 'Remove-GitHubVariable via pipeline - using variable' {
+ $pipelineTestVariableName = "$variableName`PipelineTest"
+ LogGroup 'Create test variable for pipeline removal' {
+ $createResult = Set-GitHubVariable @scope -Name $pipelineTestVariableName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get variable for pipeline removal' {
+ $variableToRemove = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($variableToRemove | Format-List | Out-String)"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $variableToRemove | Remove-GitHubVariable } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
+
Context 'SelectedRepository' -Tag 'Flaky' {
It 'Get-GitHubVariableSelectedRepository - gets a list of selected repositories' {
LogGroup "SelectedRepositories - [$orgVariableName]" {
@@ -433,18 +454,42 @@ Describe 'Variables' {
}
}
- It 'Remove-GitHubVariable' {
+ It 'Remove-GitHubVariable via pipeline - using pipeline' {
+ LogGroup 'Create variable(s) for pipeline removal' {
+ $create = Set-GitHubVariable @scope -Name "$variableName`PipelineRemoval" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
+ }
$before = Get-GitHubVariable @scope -Name "*$os*"
LogGroup 'Variables - Before' {
Write-Host "$($before | Format-Table | Out-String)"
}
- $before | Remove-GitHubVariable
+ Get-GitHubVariable @scope -Name "*$os*" | Remove-GitHubVariable
$after = Get-GitHubVariable @scope -Name "*$os*"
LogGroup 'Variables -After' {
Write-Host "$($after | Format-Table | Out-String)"
}
$after.Count | Should -Be 0
}
+
+ It 'Remove-GitHubVariable via pipeline - using variable' {
+ $pipelineTestVariableName = "$variableName`PipelineTest"
+ LogGroup 'Create test variable for pipeline removal' {
+ $createResult = Set-GitHubVariable @scope -Name $pipelineTestVariableName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get variable for pipeline removal' {
+ $variableToRemove = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($variableToRemove | Format-List | Out-String)"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $variableToRemove | Remove-GitHubVariable } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
}
Context 'Environment' -Skip:($OwnerType -in ('repository', 'enterprise')) {
@@ -560,18 +605,43 @@ Describe 'Variables' {
}
}
- It 'Remove-GitHubVariable' {
+ It 'Remove-GitHubVariable via pipeline - using pipeline' {
+ LogGroup 'Create variable(s) for pipeline removal' {
+ $create = Set-GitHubVariable @scope -Name "$variableName`PipelineRemoval" -Value 'PipelineTestValue'
+ Write-Host "$($create | Format-List | Out-String)"
+ }
LogGroup 'Variables - Before' {
$before = Get-GitHubVariable @scope -Name "*$os*"
Write-Host "$($before | Format-Table | Out-String)"
}
- $before | Remove-GitHubVariable
+ Get-GitHubVariable @scope -Name "*$os*" | Remove-GitHubVariable
LogGroup 'Variables - After' {
$after = Get-GitHubVariable @scope -Name "*$os*"
Write-Host "$($after | Format-Table | Out-String)"
}
$after.Count | Should -Be 0
}
+
+ It 'Remove-GitHubVariable via pipeline - using variable' {
+ $pipelineTestVariableName = "$variableName`PipelineTest"
+ LogGroup 'Create test variable for pipeline removal' {
+ $createResult = Set-GitHubVariable @scope -Name $pipelineTestVariableName -Value 'PipelineTestValue'
+ Write-Host "$($createResult | Format-List | Out-String)"
+ }
+ LogGroup 'Get variable and test whitespace handling' {
+ $variableToRemove = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($variableToRemove | Format-List | Out-String)"
+ Write-Host "Testing that environment variables with valid Environment property work correctly"
+ }
+ LogGroup 'Remove via pipeline' {
+ { $variableToRemove | Remove-GitHubVariable } | Should -Not -Throw
+ }
+ LogGroup 'Verify removal' {
+ $after = Get-GitHubVariable @scope -Name $pipelineTestVariableName
+ Write-Host "$($after | Format-List | Out-String)"
+ $after | Should -BeNullOrEmpty
+ }
+ }
}
}
}