Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 [Feature]: Adding function for secrets #299

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions .github/workflows/Process-PSModule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ jobs:
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
with:
SkipTests: SourceCode
3 changes: 0 additions & 3 deletions CodingStandard.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ Additions or adjustments to those defaults are covered in this document to ensur
- Do **not** declare `DefaultParameterSetName = '__AllParameterSets'`.
- Only specify a `DefaultParameterSetName` if it is actually different from the first parameter set.

- **One API Call = One Function**
- If you find that a single function is handling multiple distinct API calls, split it into multiple functions.

- **Public vs. Private**
1. **Public Functions**
- Support pipeline input if appropriate.
Expand Down
26 changes: 13 additions & 13 deletions Coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
</tr>
<tr>
<td>Covered functions</td>
<td>160</td>
<td>176</td>
</tr>
<tr>
<td>Missing functions</td>
<td>855</td>
<td>839</td>
</tr>
<tr>
<td>Coverage</td>
<td>15.76%</td>
<td>17.34%</td>
</tr>
</table>

Expand Down Expand Up @@ -293,7 +293,7 @@
| `/repos/{owner}/{repo}/actions/jobs/{job_id}/logs` | | :x: | | | |
| `/repos/{owner}/{repo}/actions/jobs/{job_id}/rerun` | | | | :x: | |
| `/repos/{owner}/{repo}/actions/oidc/customization/sub` | | :x: | | | :x: |
| `/repos/{owner}/{repo}/actions/organization-secrets` | | :x: | | | |
| `/repos/{owner}/{repo}/actions/organization-secrets` | | :white_check_mark: | | | |
| `/repos/{owner}/{repo}/actions/organization-variables` | | :x: | | | |
| `/repos/{owner}/{repo}/actions/permissions` | | :x: | | | :x: |
| `/repos/{owner}/{repo}/actions/permissions/access` | | :x: | | | :x: |
Expand Down Expand Up @@ -424,16 +424,16 @@
| `/repos/{owner}/{repo}/deployments/{deployment_id}/statuses` | | :x: | | :x: | |
| `/repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}` | | :x: | | | |
| `/repos/{owner}/{repo}/dispatches` | | | | :white_check_mark: | |
| `/repos/{owner}/{repo}/environments` | | :x: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}` | :x: | :x: | | | :x: |
| `/repos/{owner}/{repo}/environments` | | :white_check_mark: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: |
| `/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies` | | :x: | | :x: | |
| `/repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}` | :x: | :x: | | | :x: |
| `/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules` | | :x: | | :x: | |
| `/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/apps` | | :x: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}` | :x: | :x: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}/secrets` | | :x: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}/secrets` | | :white_check_mark: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key` | | :x: | | | |
| `/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}` | :x: | :x: | | | :x: |
| `/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}` | :white_check_mark: | :x: | | | :white_check_mark: |
| `/repos/{owner}/{repo}/environments/{environment_name}/variables` | | :x: | | :x: | |
| `/repos/{owner}/{repo}/environments/{environment_name}/variables/{name}` | :x: | :x: | :x: | | |
| `/repos/{owner}/{repo}/events` | | :x: | | | |
Expand Down Expand Up @@ -606,13 +606,13 @@
| `/user` | | :white_check_mark: | :white_check_mark: | | |
| `/user/blocks` | | :white_check_mark: | | | |
| `/user/blocks/{username}` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: |
| `/user/codespaces` | | :x: | | :x: | |
| `/user/codespaces/secrets` | | :x: | | | |
| `/user/codespaces/secrets/public-key` | | :x: | | | |
| `/user/codespaces/secrets/{secret_name}` | :x: | :x: | | | :x: |
| `/user/codespaces` | | :white_check_mark: | | :x: | |
| `/user/codespaces/secrets` | | :white_check_mark: | | | |
| `/user/codespaces/secrets/public-key` | | :white_check_mark: | | | |
| `/user/codespaces/secrets/{secret_name}` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: |
| `/user/codespaces/secrets/{secret_name}/repositories` | | :x: | | | :x: |
| `/user/codespaces/secrets/{secret_name}/repositories/{repository_id}` | :x: | | | | :x: |
| `/user/codespaces/{codespace_name}` | :x: | :x: | :x: | | |
| `/user/codespaces/{codespace_name}` | :white_check_mark: | :white_check_mark: | :x: | | |
| `/user/codespaces/{codespace_name}/exports` | | | | :x: | |
| `/user/codespaces/{codespace_name}/exports/{export_id}` | | :x: | | | |
| `/user/codespaces/{codespace_name}/machines` | | :x: | | | |
Expand Down
89 changes: 89 additions & 0 deletions src/functions/public/Secrets/Get-GitHubPublicKey.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
function Get-GitHubPublicKey {
<#
.SYNOPSIS
Gets a public key.

.DESCRIPTION
Gets your public key, which you need to encrypt secrets. You need to encrypt a secret before you can create or update secrets.

.EXAMPLE
Get-GitHubPublicKey

Gets a public key for the authenticated user.

.EXAMPLE
Get-GitHubPublicKey -Organization 'PSModule'

Gets a public key for the 'PSModule' organization.

.EXAMPLE
Get-GitHubPublicKey -Owner 'PSModule' -Repository 'GitHub' -Type 'codespaces'

Gets a public key for the 'GitHub' repository in the 'PSModule' organization for codespaces.

.OUTPUTS
[PSObject[]]

.LINK
https://psmodule.io/GitHub/Functions/Secrets/Get-GitHubPublicKey/
#>
[OutputType([psobject[]])]
[CmdletBinding(DefaultParameterSetName = 'AuthenticatedUser')]
param (
# The account owner of the repository. The name is not case sensitive.
[Parameter(ParameterSetName = 'Repository', Mandatory)]
[Parameter(ParameterSetName = 'Organization', Mandatory)]
[Alias('Organization', 'User')]
[string] $Owner,

# The name of the repository. The name is not case sensitive.
[Parameter(ParameterSetName = 'Repository', Mandatory)]
[string] $Repository,

# The context to run the command in. Used to get the details for the API call.
[Parameter()]
[ValidateSet('actions', 'codespaces')]
[string] $Type = 'actions',

# 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 = (Get-GitHubContext)
)

begin {
$stackPath = Get-PSCallStackPath
Write-Debug "[$stackPath] - Start"
$Context = Resolve-GitHubContext -Context $Context
Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT
}

process {
switch ($PSCmdlet.ParameterSetName) {
'Organization' {
$APIEndpoint = "/orgs/$Owner/$Type/secrets/public-key"
break
}
'Repository' {
$APIEndpoint = "/repos/$Owner/$Repository/$Type/secrets/public-key"
break
}
'AuthenticatedUser' {
$APIEndpoint = '/user/codespaces/secrets/public-key'
break
}
}

$inputObject = @{
Method = 'GET'
APIEndpoint = $APIEndpoint
Context = $Context
AuthType = $AuthType
}
Invoke-GitHubAPI @inputObject | Select-Object -ExpandProperty Response
}

end {
Write-Debug "[$stackPath] - End"
}
}
113 changes: 113 additions & 0 deletions src/functions/public/Secrets/Get-GitHubSecret.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
function Get-GitHubSecret {
<#
.SYNOPSIS
Retrieve GitHub Secret(s) without revealing encrypted value(s).

.DESCRIPTION
Retrieves GitHub secrets from a repository, organization, or environment without exposing
the actual secret values. Supports multiple contexts such as Actions, Codespaces, and
Organization secrets.

The function returns an array of PSObjects containing metadata about the secrets.

.EXAMPLE
Get-GitHubSecret -Owner PSModule -Repo Demo -Type actions

Retrieves all Actions secrets from the 'Demo' repository under the 'PSModule' organization.

.EXAMPLE
Get-GitHubSecret -Owner PSModule -Type organization

Retrieves all organization-level secrets under the 'PSModule' organization.

.EXAMPLE
Get-GitHubSecret -Owner PSModule -Repo Demo -Environment Staging

Retrieves all secrets for the 'Staging' environment in the 'Demo' repository under 'PSModule'.

.OUTPUTS
[PSObject[]]

.LINK
https://psmodule.io/GitHub/Functions/Secrets/Get-GitHubSecret/
#>
[OutputType([psobject[]])]
[CmdletBinding(DefaultParameterSetName = 'AuthorizedUser', SupportsPaging)]
param (
# The account owner of the repository. The name is not case sensitive.
[Parameter(ParameterSetName = 'Environment')]
[Parameter(ParameterSetName = 'Organization', Mandatory)]
[Parameter(ParameterSetName = 'Repository', Mandatory)]
[Alias('Organization', 'User')]
[string] $Owner,

# The name of the repository. The name is not case sensitive.
[Parameter(ParameterSetName = 'Environment', Mandatory)]
[Parameter(ParameterSetName = 'Repository', Mandatory)]
[string] $Repository,

# The name of the repository environment.
[Parameter(ParameterSetName = 'Environment', Mandatory)]
[string] $Environment,

# The name of the secret.
[Parameter()]
[string] $Name,

# The type of secret to retrieve.
# Can be either 'actions', 'codespaces', or 'organization'.
[Parameter()]
[ValidateSet('actions', 'codespaces', 'organization')]
[string] $Type = 'actions',

# 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 = (Get-GitHubContext)
)

begin {
$stackPath = Get-PSCallStackPath
Write-Debug "[$stackPath] - Start"
# $Context = Resolve-GitHubContext -Context $Context
# Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT
}

process {
$inputObject = @{
Method = 'GET'
APIEndpoint = switch ($PSCmdlet.ParameterSetName) {
'Environment' {
"/repos/$Owner/$Repository/environments/$Environment/secrets"
break
}
'Organization' {
"/orgs/$Owner/$Type/secrets"
break
}
'Repository' {
$Type -eq 'organization' ?
"/repos/$Owner/$Repository/actions/organization-secrets" :
"/repos/$Owner/$Repository/$Type/secrets"
break
}
'AuthorizedUser' {
'user/codespaces/secrets'
}
}
Context = $Context
}

# There is no endpoint for /repos/$Owner/$Repository/actions/organization-secrets/$Name
if ($Type -ne 'organization' -and -not [string]::IsNullOrWhiteSpace($Name)) {
$inputObject.APIEndpoint += "/$Name"
}

$response = Invoke-GitHubAPI @inputObject | Select-Object -ExpandProperty Response
[bool]$response.PSObject.Properties['secrets'] ? $response.secrets : $response
}

end {
Write-Debug "[$stackPath] - End"
}
}
Loading
Loading