Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# GitHub Powershell Module

# GitHub PowerShell

The **GitHub PowerShell** module serves as a convenient API wrapper around [GitHub's REST API](https://docs.github.com/en/rest), making the functionalities and data available on GitHub accessible through PowerShell commands. This module is tailored for developers, administrators, and GitHub enthusiasts who are familiar with PowerShell and want to integrate or manage their GitHub repositories seamlessly.
Expand Down
2 changes: 1 addition & 1 deletion src/GitHub/GitHub.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
$scriptFilePath = $MyInvocation.MyCommand.Path

Write-Verbose "[$scriptFilePath] - Initializing GitHub module..." -Verbose
Write-Verbose "[$scriptFilePath] - Initializing GitHub module..."

Initialize-SecretVault -Name $script:SecretVault.Name -Type $script:SecretVault.Type

Expand Down
2 changes: 1 addition & 1 deletion src/GitHub/GitHub.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Author = 'Marius Storhaug'

# Version number of this module
ModuleVersion = '0.0.1'
ModuleVersion = '0.1.1'

# Description of the functionality provided by this module
Description = 'GitHub PowerShell Module'
Expand Down
29 changes: 29 additions & 0 deletions src/GitHub/private/Menu/Invoke-DrawMenu.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function Invoke-DrawMenu {
## supportfunction to the Menu function below
param (
$menuItems,
$menuPosition,
$menuTitel
)
$fcolor = $host.UI.RawUI.ForegroundColor
$bcolor = $host.UI.RawUI.BackgroundColor
$l = $menuItems.length + 1
Clear-Host
$menuwidth = $menuTitel.length + 4
Write-Host "`t" -NoNewline
Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor
Write-Host "`t" -NoNewline
Write-Host "* $menuTitel *" -fore $fcolor -back $bcolor
Write-Host "`t" -NoNewline
Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor
Write-Host ''
Write-Debug "L: $l MenuItems: $menuItems MenuPosition: $menuposition"
for ($i = 0; $i -le $l; $i++) {
Write-Host "`t" -NoNewline
if ($i -eq $menuPosition) {
Write-Host "$($menuItems[$i])" -fore $bcolor -back $fcolor
} else {
Write-Host "$($menuItems[$i])" -fore $fcolor -back $bcolor
}
}
}
29 changes: 29 additions & 0 deletions src/GitHub/private/Menu/Invoke-Meny.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function Menu {
## Generate a small "DOS-like" menu.
## Choose a menuitem using up and down arrows, select by pressing ENTER
param (
[array]$menuItems,
$menuTitel = 'MENU'
)
$vkeycode = 0
$pos = 0
Invoke-DrawMenu $menuItems $pos $menuTitel
while ($vkeycode -ne 13) {
$press = $host.ui.rawui.readkey('NoEcho,IncludeKeyDown')
$vkeycode = $press.virtualkeycode
Write-Host "$($press.character)" -NoNewline
if ($vkeycode -eq 38) { $pos-- }
if ($vkeycode -eq 40) { $pos++ }
if ($pos -lt 0) { $pos = 0 }
if ($pos -ge $menuItems.length) { $pos = $menuItems.length - 1 }
Invoke-DrawMenu $menuItems $pos $menuTitel
}
Write-Output $($menuItems[$pos])
}


<#
? What account do you want to log into? [Use arrows to move, type to filter]
> GitHub.com
GitHub Enterprise Server
#>
76 changes: 51 additions & 25 deletions src/GitHub/public/API/Invoke-GitHubAPI.ps1
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
function Invoke-GitHubAPI {
<#
.SYNOPSIS
Calls the GitHub API using the provided parameters.
.SYNOPSIS
Calls the GitHub API using the provided parameters.

.DESCRIPTION
This function is a wrapper around Invoke-RestMethod tailored for calling GitHub's API.
It automatically handles the endpoint URI construction, headers, and token authentication.
.DESCRIPTION
This function is a wrapper around Invoke-RestMethod tailored for calling GitHub's API.
It automatically handles the endpoint URI construction, headers, and token authentication.

.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET
.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET

Gets all open pull requests for the specified repository.
Gets all open pull requests for the specified repository.

.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' }
.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' }

Gets all open pull requests for the specified repository, filtered by the 'state' parameter.
Gets all open pull requests for the specified repository, filtered by the 'state' parameter.

.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } -Accept 'application/vnd.github.v3+json'
.EXAMPLE
Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } -Accept 'application/vnd.github.v3+json'

Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header.
#>
Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header.
#>
[CmdletBinding()]
param (
# The HTTP method to be used for the API request. It can be one of the following: GET, POST, PUT, DELETE, or PATCH.
Expand All @@ -42,15 +42,15 @@

# The 'Accept' header for the API request. If not provided, the default will be used by GitHub's API.
[Parameter()]
[string] $Accept,
[string] $Accept = 'application/vnd.github+json',

# Specifies the HTTP version used for the request.
[Parameter()]
$HttpVersion = '2.0',
[version] $HttpVersion = '2.0',

# Support Pagination Relation Links per RFC5988.
[Parameter()]
$FollowRelLink = $true,
[bool] $FollowRelLink = $true,

# The secure token used for authentication in the GitHub API. It should be stored as a SecureString to ensure it's kept safe in memory.
[Parameter()]
Expand All @@ -76,6 +76,23 @@

$URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '')

# $AccessTokenAsPlainText = ConvertFrom-SecureString $AccessToken -AsPlainText
# # Swap out this by using the -Authentication Bearer -Token $AccessToken
# switch -Regex ($AccessTokenAsPlainText) {
# '^ghp_|^github_pat_' {
# $headers.authorization = "token $AccessTokenAsPlainText"
# }
# '^ghu_|^gho_' {
# $headers.authorization = "Bearer $AccessTokenAsPlainText"
# }
# default {
# $tokenPrefix = $AccessTokenAsPlainText -replace '_.*$', '_*'
# $errorMessage = "Unexpected AccessToken format: $tokenPrefix"
# Write-Error $errorMessage
# throw $errorMessage
# }
# }

$APICall = @{
Uri = $URI
Method = $Method
Expand All @@ -88,9 +105,19 @@
StatusCodeVariable = 'StatusCode'
ResponseHeadersVariable = 'ResponseHeaders'
}
Remove-HashTableEntries -Hashtable $APICall -NullOrEmptyValues
$APICall | Remove-HashTableEntries -NullOrEmptyValues

if ($Body) {
$Body | Remove-HashTableEntries -NullOrEmptyValues

# Use body to create the query string for GET requests
if ($Method -eq 'GET') {
$queryParams = ($Body.GetEnumerator() |
ForEach-Object { "$([System.Web.HttpUtility]::UrlEncode($_.Key))=$([System.Web.HttpUtility]::UrlEncode($_.Value))" }) -join '&'
if ($queryParams) {
$APICall.Uri = $APICall.Uri + '?' + $queryParams
}
}
if ($Body -is [string]) {
$APICall.Body = $Body
} else {
Expand All @@ -101,12 +128,11 @@
try {
Invoke-RestMethod @APICall | Write-Output
Write-Verbose ($StatusCode | ConvertTo-Json -Depth 100)
Write-Verbose ($ResponseHeaders | ConvertTo-Json -Depth 100)
} catch [System.Net.WebException] {
Write-Error "[$functionName] - WebException - $($_.Exception.Message)"
throw $_
Write-Verbose ($responseHeaders | ConvertTo-Json -Depth 100)
} catch {
Write-Error "[$functionName] - GeneralException - $($_.Exception.Message)"
throw $_
Write-Error "[$functionName] - Status code - [$StatusCode]"
$err = $_ | ConvertFrom-Json -Depth 10
Write-Error "[$functionName] - $($err.Message)"
Write-Error "[$functionName] - For more info please see: [$($err.documentation_url)]"
}
}
34 changes: 34 additions & 0 deletions src/GitHub/public/Actions/Disable-GitHubWorkflow.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Function Disable-GitHubWorkflow {
<#
.NOTES
https://docs.github.com/en/rest/reference/actions#disable-a-workflow
#>
[CmdletBinding()]
param (
[Parameter()]
[string] $Owner = (Get-GitHubConfig -Name Owner),

[Parameter()]
[string] $Repo = (Get-GitHubConfig -Name Repo),

[Parameter(
Mandatory,
ValueFromPipelineByPropertyName
)]
[string[]] $ID
)

begin {}

process {
$inputObject = @{
APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/disable"
Method = 'PUT'
}

Invoke-GitHubAPI @inputObject | Out-Null

}

end {}
}
34 changes: 34 additions & 0 deletions src/GitHub/public/Actions/Enable-GitHubWorkflow.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Function Enable-GitHubWorkflow {
<#
.NOTES
https://docs.github.com/en/rest/reference/actions#enable-a-workflow
#>
[CmdletBinding()]
param (
[Parameter()]
[string] $Owner = (Get-GitHubConfig -Name Owner),

[Parameter()]
[string] $Repo = (Get-GitHubConfig -Name Repo),

[Parameter(
Mandatory,
ValueFromPipelineByPropertyName
)]
[string[]] $ID
)

begin {}

process {
$inputObject = @{
APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/enable"
Method = 'PUT'
}

Invoke-GitHubAPI @inputObject | Out-Null

}

end {}
}
59 changes: 59 additions & 0 deletions src/GitHub/public/Actions/Get-GitHubWorkflow.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
function Get-GitHubWorkflow {
<#
.SYNOPSIS
Lists the workflows in a repository.

.DESCRIPTION
Anyone with read access to the repository can use this endpoint.
If the repository is private you must use an access token with the repo scope.
GitHub Apps must have the actions:read permission to use this endpoint.

.EXAMPLE
Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world'

Gets all workflows in the 'octocat/hello-world' repository.

.EXAMPLE
Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world' -Name 'hello-world.yml'

Gets the 'hello-world.yml' workflow in the 'octocat/hello-world' repository.

.NOTES
https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#list-repository-workflows
#>
[CmdletBinding(DefaultParameterSetName = 'ByName')]
param (
[Parameter()]
[string] $Owner = (Get-GitHubConfig -Name Owner),

[Parameter()]
[string] $Repo = (Get-GitHubConfig -Name Repo),

[Parameter(ParameterSetName = 'ByName')]
[string] $Name,

[Parameter(ParameterSetName = 'ByID')]
[string] $ID,

[Parameter()]
[int] $PerPage = 100
)

begin {}

process {

$body = @{
per_page = $PerPage
}

$inputObject = @{
APIEndpoint = "/repos/$Owner/$Repo/actions/workflows"
Method = 'GET'
Body = $body
}

Invoke-GitHubAPI @inputObject | Select-Object -ExpandProperty workflows | Write-Output

}
}
55 changes: 55 additions & 0 deletions src/GitHub/public/Actions/Get-GitHubWorkflowRun.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Function Get-GitHubWorkflowRun {
<#
.NOTES
https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-workflow
https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository
#>
[CmdletBinding(DefaultParameterSetName = 'Repo')]
param (
[Parameter()]
[string] $Owner = (Get-GitHubConfig -Name Owner),

[Parameter()]
[string] $Repo = (Get-GitHubConfig -Name Repo),

[Parameter(ParameterSetName = 'ByName')]
[string] $Name,

[Parameter(ParameterSetName = 'ByID')]
[string] $ID,

[Parameter()]
[int] $PerPage = 100
)

begin {}

process {

$body = @{
per_page = $PerPage
}

if ($Name) {
$ID = (Get-GitHubWorkflow -Owner $Owner -Repo $Repo -Name $Name).id
}

if ($ID) {
$Uri = "/repos/$Owner/$Repo/actions/workflows/$ID/runs"
} else {
$Uri = "/repos/$Owner/$Repo/actions/runs"
}

$inputObject = @{
APIEndpoint = $Uri
Method = 'GET'
Body = $body
}

Invoke-GitHubAPI @inputObject | Select-Object -ExpandProperty workflow_runs | Write-Output

}

end {}

}
Loading