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

feat: support GitHub Enterprise Server environments #40

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ A GitHub Action to roughly calculate DORA lead time for changes This is not mean
- `owner-repo`: optional, string, defaults to the repo where the action runs. Can target another owner or org and repo. e.g. `'DeveloperMetrics/DevOpsMetrics'`, but will require authenication (see below)
- `default-branch`: optional, string, defaults to `main`
- `number-of-days`: optional, integer, defaults to `30` (days)
- commit-counting-method: #optional, defaults to 'last'. Accepts two values, 'last' - to start timing from the last commit of a PR, and 'first' to start timing from the first commit of a PR
- `commit-counting-method`: #optional, defaults to 'last'. Accepts two values, 'last' - to start timing from the last commit of a PR, and 'first' to start timing from the first commit of a PR
- `pat-token`: optional, string, defaults to ''. Can be set with GitHub PAT token. Ensure that `Read access to actions and metadata` permission is set. This is a secret, never directly add this into the actions workflow, use a secret.
- `actions-token`: optional, string, defaults to ''. Can be set with `${{ secrets.GITHUB_TOKEN }}` in the action
- `app-id`: optional, string, defaults to '', application id of the registered GitHub app
- `app-install-id`: optional, string, defaults to '', id of the installed instance of the GitHub app
- `app-private-key` optional, string, defaults to '', private key which has been generated for the installed instance of the GitHub app. Must be provided without leading `'-----BEGIN RSA PRIVATE KEY----- '` and trailing `' -----END RSA PRIVATE KEY-----'`.
- `app-private-key`: optional, string, defaults to '', private key which has been generated for the installed instance of the GitHub app. Must be provided without leading `'-----BEGIN RSA PRIVATE KEY----- '` and trailing `' -----END RSA PRIVATE KEY-----'`.
- `api-url`: optional, string, defaults to `${{ github.api_url }}` which should cover both github.com and GitHub Enterprise Server.

To test the current repo (same as where the action runs)
```yml
Expand Down
7 changes: 5 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: 'DORA lead time for changes'
description: 'A GitHub Action to roughly calculate DORA lead time for changes'
author: developermetrics.org
author: developermetrics.org
branding:
icon: activity
color: gray-dark
Expand Down Expand Up @@ -39,6 +39,9 @@ inputs:
app-private-key:
description: 'private key which has been generated for the installed instance of the GitHub app'
default: ""
api-url:
description: 'the URL of the GitHub API'
default: ${{ github.api_url }}
outputs:
markdown-file:
description: "The markdown that will be posted to the job summary, so that the markdown can saved and used other places (e.g.: README.md)"
Expand All @@ -50,7 +53,7 @@ runs:
id: lead-time
shell: pwsh
run: |
$result = ${{ github.action_path }}/src/leadtimeforchanges.ps1 -ownerRepo "${{ inputs.owner-repo }}" -workflows "${{ inputs.workflows }}" -branch "${{ inputs.default-branch }}" -numberOfDays ${{ inputs.number-of-days }} -commitCountingMethod ${{ inputs.commit-counting-method }} -patToken "${{ inputs.pat-token }}" -actionsToken "${{ inputs.actions-token }}" -appId "${{ inputs.app-id }}" -appInstallationId "${{ inputs.app-install-id }}" -appPrivateKey "${{ inputs.app-private-key }}"
$result = ${{ github.action_path }}/src/leadtimeforchanges.ps1 -ownerRepo "${{ inputs.owner-repo }}" -workflows "${{ inputs.workflows }}" -branch "${{ inputs.default-branch }}" -numberOfDays ${{ inputs.number-of-days }} -commitCountingMethod ${{ inputs.commit-counting-method }} -patToken "${{ inputs.pat-token }}" -actionsToken "${{ inputs.actions-token }}" -appId "${{ inputs.app-id }}" -appInstallationId "${{ inputs.app-install-id }}" -appPrivateKey "${{ inputs.app-private-key }}" -apiUrl "${{ inputs.api-url }}"
$filePath="dora-lead-time-markdown.md"
Set-Content -Path $filePath -Value $result
"markdown-file=$filePath" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
Expand Down
22 changes: 12 additions & 10 deletions src/leadtimeforchanges.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Param(
[string] $actionsToken = "",
[string] $appId = "",
[string] $appInstallationId = "",
[string] $appPrivateKey = ""
[string] $appPrivateKey = "",
[string] $apiUrl = "https://api.github.com"
)

#The main function
Expand All @@ -22,7 +23,8 @@ function Main ([string] $ownerRepo,
[string] $actionsToken = "",
[string] $appId = "",
[string] $appInstallationId = "",
[string] $appPrivateKey = "")
[string] $appPrivateKey = "",
[string] $apiUrl = "https://api.github.com")
{

#==========================================
Expand All @@ -48,7 +50,7 @@ function Main ([string] $ownerRepo,

#Get pull requests from the repo
#https://developer.GitHub.com/v3/pulls/#list-pull-requests
$uri = "https://api.github.com/repos/$owner/$repo/pulls?state=all&head=$branch&per_page=100&state=closed";
$uri = "$apiUrl/repos/$owner/$repo/pulls?state=all&head=$branch&per_page=100&state=closed";
if (!$authHeader)
{
#No authentication
Expand All @@ -72,7 +74,7 @@ function Main ([string] $ownerRepo,
if ($mergedAt -ne $null -and $pr.merged_at -gt (Get-Date).AddDays(-$numberOfDays))
{
$prCounter++
$url2 = "https://api.github.com/repos/$owner/$repo/pulls/$($pr.number)/commits?per_page=100";
$url2 = "$apiUrl/repos/$owner/$repo/pulls/$($pr.number)/commits?per_page=100";
if (!$authHeader)
{
#No authentication
Expand Down Expand Up @@ -109,7 +111,7 @@ function Main ([string] $ownerRepo,

#==========================================
#Get workflow definitions from github
$uri3 = "https://api.github.com/repos/$owner/$repo/actions/workflows"
$uri3 = "$apiUrl/repos/$owner/$repo/actions/workflows"
if (!$authHeader) #No authentication
{
$workflowsResponse = Invoke-RestMethod -Uri $uri3 -ContentType application/json -Method Get -SkipHttpErrorCheck -StatusCodeVariable "HTTPStatus"
Expand Down Expand Up @@ -156,7 +158,7 @@ function Main ([string] $ownerRepo,
$totalWorkflowHours = 0

#Get workflow definitions from github
$uri4 = "https://api.github.com/repos/$owner/$repo/actions/workflows/$workflowId/runs?per_page=100&status=completed"
$uri4 = "$apiUrl/repos/$owner/$repo/actions/workflows/$workflowId/runs?per_page=100&status=completed"
if (!$authHeader)
{
$workflowRunsResponse = Invoke-RestMethod -Uri $uri4 -ContentType application/json -Method Get -SkipHttpErrorCheck -StatusCodeVariable "HTTPStatus"
Expand Down Expand Up @@ -208,7 +210,7 @@ function Main ([string] $ownerRepo,

#==========================================
#Show current rate limit
$uri5 = "https://api.github.com/rate_limit"
$uri5 = "$apiUrl/rate_limit"
if (!$authHeader)
{
$rateLimitResponse = Invoke-RestMethod -Uri $uri5 -ContentType application/json -Method Get -SkipHttpErrorCheck -StatusCodeVariable "HTTPStatus"
Expand Down Expand Up @@ -341,7 +343,7 @@ function ConvertTo-Base64UrlString(
}
}

function Get-JwtToken([string] $appId, [string] $appInstallationId, [string] $appPrivateKey)
function Get-JwtToken([string] $appId, [string] $appInstallationId, [string] $appPrivateKey, [string] $apiUrl )
{
# Write-Host "appId: $appId"
$now = (Get-Date).ToUniversalTime()
Expand Down Expand Up @@ -376,7 +378,7 @@ function Get-JwtToken([string] $appId, [string] $appInstallationId, [string] $ap
catch { throw New-Object System.Exception -ArgumentList ("GitHub App authenication error: Signing with SHA256 and Pkcs1 padding failed using private key $($rsa): $_", $_.Exception) }
$jwt = $jwt + '.' + $sig
# send headers
$uri = "https://api.github.com/app/installations/$appInstallationId/access_tokens"
$uri = "$apiUrl/app/installations/$appInstallationId/access_tokens"
$jwtHeader = @{
Accept = "application/vnd.github+json"
Authorization = "Bearer $jwt"
Expand Down Expand Up @@ -410,4 +412,4 @@ function GetFormattedMarkdownForNoResult([string] $workflows, [string] $numberOf
return $markdown
}

main -ownerRepo $ownerRepo -workflows $workflows -branch $branch -numberOfDays $numberOfDays -commitCountingMethod $commitCountingMethod -patToken $patToken -actionsToken $actionsToken -appId $appId -appInstallationId $appInstallationId -appPrivateKey $appPrivateKey
main -ownerRepo $ownerRepo -workflows $workflows -branch $branch -numberOfDays $numberOfDays -commitCountingMethod $commitCountingMethod -patToken $patToken -actionsToken $actionsToken -appId $appId -appInstallationId $appInstallationId -appPrivateKey $appPrivateKey -apiUrl $apiUrl