The GitHub REST API is an essential tool to automate your GitHub repositories. You can use it to create issues, manage branches, create dashboards, or many other things.
We can use PowerShell to automate all these tasks and create applications that automate to work for us. Let's see how to start.
For using the Rest API with PowerShell, we need to authenticate to the Rest API. You cannot do it using a Login/Password, it will not work, and you will get a 4XX HTTP error.
There are 3 ways to authenticate to the Rest API, access token, GitHub App, and inside GitHub Action.
Access token
Access token is the simple way to authenticate to the Rest API. You simply need to go to your GitHub account settings then Developer Settings (or simply go to this URI), and then create an access token. You can either choose the classic tokens (no restriction) or the fine-grained token where you can use fine-tuned permissions.
I will create a classic token with the repo:status and write:discussion privileges.
To use the token follow the script here
# This script illustrates how you can log in and perform a get action to Github Rest API with an access token
# This script lists all repository names for a given organization
param(
# The access token to the GitHub Rest API
[Parameter(Mandatory=$true)]
[string]
$accessToken,
[Parameter(Mandatory=$true)]
[string]
$orgaName
)
$authenticationToken = [System.Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$accessToken"))
$headers = @{
"Authorization" = [String]::Format("Basic {0}", $authenticationToken)
"Content-Type" = "application/json"
}
$reposAPIUri = "https://api.github.com/orgs/$($orgaName)/repos"
$githubRepositories = Invoke-RestMethod -Method get -Uri $reposAPIUri -Headers $headers
foreach ($respository in $githubRepositories) {
write-host $respository.name
}
The token is encoded in Base64
Then formatted to give something like
Authorization Basic
End added to the http header for in the invoke-RestMethod cmdlet
GitHub App
Authentication with a GitHub App is more complex. First, you need to create a GitHub App by following the instructions on this page. Once you have created your GitHub App you will need to create a client secret and a private key. Download the private key on your computer. And finally note the App ID.
You will also need to install the application in your account and get the instance ID.
To authenticate with a GitHub app you will need to authenticate first with the certificate and then generate a token to access the API.
The certificate and the App ID will be used to create a JSON Web Token. This JWT will be used to create a JIT token for the GitHub Rest API request.
To create the SWT I need a tool, there are no native tools to create a JWT in PwSh now, but you can use the powershell-jwt module as I did here (install-module -name powershell-jwt)
With the access token, you can query the API by using the Authorization="token $token", note that you can also ask for a specific version of the API by using the X-GitHub-Api-Version
Note also that GitHub recommends using Accept="application/vnd.github+json" when interacting with the API.
# This script illustrates how you can log in and perform a get action to Github Rest API with a GitHub App
# this script list all issues
param(
# The access token to the GitHub Rest API
[Parameter(Mandatory=$true)]
[string]
$pathToGitHubAppKey,
[Parameter(Mandatory=$true)]
[string]
$instanceID,
[Parameter(Mandatory=$true)]
[string]
$appID,
[Parameter(Mandatory=$true)]
[string]
$organisation,
[Parameter(Mandatory=$true)]
[string]
$repository
)
# Get the private key content
$apiPemData = Get-Content -Path $pathToGitHubAppKey
$apiSecret = [System.Text.Encoding]::UTF8.GetBytes($apiPemData)
$exp = [int][double]::parse((Get-Date -Date $((Get-Date).addseconds(300).ToUniversalTime()) -UFormat %s))
$iat = [int][double]::parse((Get-Date -Date $((Get-Date).ToUniversalTime()) -UFormat %s))
# create a Json Web Tokken using new-jwt from the powershell-jwt module
$jwt = New-JWT -Algorithm "RS256" -Issuer $appID -ExpiryTimestamp $exp -SecretKey $apiSecret -PayloadClaims @{ "iat" = $iat}
# request a new tokken
$headers = @{
"Accept" = "application/vnd.github+json"
"Authorization" = "Bearer $jwt"
}
$res = Invoke-WebRequest -Uri "https://api.github.com/app/installations/$($instanceID)/access_tokens" -Headers $headers -Method Post
$json_res = ConvertFrom-Json($res.Content)
$token = $json_res.token
# Querry the API to list all issues in a repository
$reposAPIUri = "https://api.github.com/repos/$'$organisation)/$($repository)/issues"
$headers = @{
Accept="application/vnd.github+json"
Authorization="token $token"
"X-GitHub-Api-Version" = "2022-11-28"
}
$issuesList = Invoke-WebRequest -Uri $reposAPIUri -Headers $headers
$issuesObject = ConvertFrom-Json($issuesList.content)
foreach ($issue in $issuesObject) {
$issue.title
}
GitHub Action workflow
The last way to authenticate to the Rest API is to run your PowerShell script in GitHub Action. You can use the Token method or the GitHub method to authenticate to GitHub Rest API. But GitHub doesn’t recommend that.
When you create a workflow for GithHub Action, GitHub creates a token, GITHUB_TOKEN, that you can use in your script.
The first step is to create the workflow with the main.yaml file
name: Windows-wks
on: [push, pull_request]
jobs:
validate:
runs-on: windows-latest
permissions:
issues: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v1
- name: Perform_Tests
shell: pwsh
run: .\githubAction-login.ps1
In the Job, you can setup permissions for the built-in token
permissions:
issues: write
Then I add the token to an environment variable
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
So, I can use it in the script like this
$stringTokken = $Env:GH_TOKEN
$headers = @{
"Accept" = "application/vnd.github+json"
"Authorization" = "Bearer $stringTokken"
}
$reposAPIUri = "https://api.github.com/repos/<ORGA>/<REPOS>/issues"
$githubRepositories = Invoke-RestMethod -Method get -Uri $reposAPIUri -Headers $headers
foreach ($respository in $githubRepositories) {
write-host $respository.name
}
You can use the token as is, no need to encode it
Top comments (0)