Skip to content

Commit 3a300ab

Browse files
authored
Merge pull request #28 from samsmithnz/OutputRefining
Updating markdown output
2 parents 4447d37 + e20bd6d commit 3a300ab

File tree

5 files changed

+87
-46
lines changed

5 files changed

+87
-46
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// "forwardPorts": [],
1414

1515
// Use 'postCreateCommand' to run commands after the container is created.
16-
// "postCreateCommand": "src/deploymentfrequency.ps1 -ownerRepo 'SamSmithnz/SamsFeatureFlags' -workflows 'Feature Flags CI/CD,CodeQL' -branch 'Main' -numberOfDays 30 -patToken $env:PATTOKEN",
16+
// "postCreateCommand": "src/deploymentfrequency.ps1 -ownerRepo 'SamSmithnz/SamsFeatureFlags' -workflows 'Feature Flags CI/CD,CodeQL' -branch 'Main' -numberOfDays 30 -patToken $env:PATTOKEN -showVerboseLogging $true",
1717

1818

1919
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.

.github/workflows/workflow.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ jobs:
3838
uses: actions/checkout@v3
3939
with:
4040
ref: ${{ github.ref }}
41+
42+
#basic tests
4143
- name: Test this repo
4244
uses: ./ # the ./ runs the action.yml in this repo
4345
with:
@@ -49,18 +51,22 @@ jobs:
4951
owner-repo: 'samsmithnz/DevOpsMetrics'
5052
default-branch: 'main'
5153
number-of-days: 30
54+
show-verbose-logging: 0
5255
- name: Test no workflow
5356
uses: ./
5457
with:
5558
workflows: ''
5659
owner-repo: 'samsmithnz/GitHubToAzureDevOps'
57-
60+
show-verbose-logging: 0
61+
62+
#authenication tests
5863
- name: Test elite repo with PAT Token
5964
uses: ./
6065
with:
6166
workflows: 'Feature Flags CI/CD'
6267
owner-repo: 'samsmithnz/SamsFeatureFlags'
63-
pat-token: "${{ secrets.PATTOKEN }}"
68+
pat-token: "${{ secrets.PATTOKEN }}"
69+
show-verbose-logging: 0
6470
- name: Test elite repo, multiple workflows, with PAT Token
6571
uses: ./
6672
with:

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ A GitHub Action to roughly calculate DORA deployment frequency. This is not mean
2323
- `actions-token`: optional, string, defaults to ''. Can be set with `${{ secrets.GITHUB_TOKEN }}` in the action
2424
- `app-id`: optional, string, defaults to '', application id of the registered GitHub app
2525
- `app-install-id`: optional, string, defaults to '', id of the installed instance of the GitHub app
26-
- `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-----'`.
26+
- `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-----'`.
27+
- `show-verbose-logging`: optional, bool, defaults to 0, if set to 1, will show more verbose logging information
2728

2829
To test the current repo (same as where the action runs)
2930
```
@@ -85,4 +86,4 @@ Number of days: 30
8586
Authentication detected: GITHUB APP TOKEN
8687
Rate limit consumption: 10 / 5000
8788
Deployment frequency over last 30 days, is 1.2 per day, with a DORA rating of 'Elite'
88-
```
89+
```

action.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ inputs:
3131
app-private-key:
3232
description: 'private key which has been generated for the installed instance of the GitHub app'
3333
default: ""
34+
show-verbose-logging:
35+
description: 'show more details of the calculation and processing'
36+
default: 0 # (0 == false)
3437
runs:
3538
using: "composite"
3639
steps:
3740
- name: Run DORA deployment frequency
3841
shell: pwsh
3942
run: |
40-
$result = ${{ github.action_path }}/src/deploymentfrequency.ps1 -ownerRepo "${{ inputs.owner-repo }}" -workflows "${{ inputs.workflows }}" -branch "${{ inputs.default-branch }}" -numberOfDays ${{ inputs.number-of-days }} -patToken "${{ inputs.pat-token }}" -actionsToken "${{ inputs.actions-token }}" -appId "${{ inputs.app-id }}" -appInstallationId "${{ inputs.app-install-id }}" -appPrivateKey "${{ inputs.app-private-key }}"
43+
$result = ${{ github.action_path }}/src/deploymentfrequency.ps1 -ownerRepo "${{ inputs.owner-repo }}" -workflows "${{ inputs.workflows }}" -branch "${{ inputs.default-branch }}" -numberOfDays ${{ inputs.number-of-days }} -patToken "${{ inputs.pat-token }}" -actionsToken "${{ inputs.actions-token }}" -appId "${{ inputs.app-id }}" -appInstallationId "${{ inputs.app-install-id }}" -appPrivateKey "${{ inputs.app-private-key }}" -showVerboseLogging ${{ inputs.show-verbose-logging }}
4144
Write-Host "::set-output name=result::$result"
4245
Write-Output $result >> $env:GITHUB_STEP_SUMMARY
43-
44-
46+

src/deploymentfrequency.ps1

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Param(
88
[string] $actionsToken = "",
99
[string] $appId = "",
1010
[string] $appInstallationId = "",
11-
[string] $appPrivateKey = ""
11+
[string] $appPrivateKey = "",
12+
[bool] $showVerboseLogging = $false
1213
)
1314

1415
#The main function
@@ -20,24 +21,29 @@ function Main ([string] $ownerRepo,
2021
[string] $actionsToken = "",
2122
[string] $appId = "",
2223
[string] $appInstallationId = "",
23-
[string] $appPrivateKey = "")
24+
[string] $appPrivateKey = "",
25+
[bool] $showVerboseLogging = $false)
2426
{
2527

2628
#==========================================
2729
#Input processing
2830
$ownerRepoArray = $ownerRepo -split '/'
2931
$owner = $ownerRepoArray[0]
3032
$repo = $ownerRepoArray[1]
31-
Write-Output "Owner/Repo: $owner/$repo"
3233
$workflowsArray = $workflows -split ','
33-
Write-Output "Workflows: $workflows"
34-
Write-Output "Branch: $branch"
35-
$numberOfDays = $numberOfDays
36-
Write-Output "Number of days: $numberOfDays"
34+
$numberOfDays = $numberOfDays
35+
#Write-Output "showVerboseLogging: $showVerboseLogging"
36+
if ($showVerboseLogging -eq $true)
37+
{
38+
Write-Output "Owner/Repo: $owner/$repo"
39+
Write-Output "Workflows: $workflows"
40+
Write-Output "Branch: $branch"
41+
Write-Output "Number of days: $numberOfDays"
42+
}
3743

3844
#==========================================
3945
# Get authorization headers
40-
$authHeader = GetAuthHeader $patToken $actionsToken $appId $appInstallationId $appPrivateKey
46+
$authHeader = GetAuthHeader $patToken $actionsToken $appId $appInstallationId $appPrivateKey $showVerboseLogging
4147

4248
#==========================================
4349
#Get workflow definitions from github
@@ -61,22 +67,26 @@ function Main ([string] $ownerRepo,
6167

6268
#Extract workflow ids from the definitions, using the array of names. Number of Ids should == number of workflow names
6369
$workflowIds = [System.Collections.ArrayList]@()
70+
$workflowNames = [System.Collections.ArrayList]@()
6471
Foreach ($workflow in $workflowsResponse.workflows){
6572

6673
Foreach ($arrayItem in $workflowsArray){
6774
if ($workflow.name -eq $arrayItem)
6875
{
69-
#Write-Output "'$($workflow.name)' matched with $arrayItem"
70-
$result = $workflowIds.Add($workflow.id)
71-
if ($result -lt 0)
76+
#This looks odd: but assigning to a (throwaway) variable stops the index of the arraylist being output to the console. Using an arraylist over an array has advantages making this worth it for here
77+
if (!$workflowIds.Contains($workflow.id))
7278
{
73-
Write-Output "unexpected result"
79+
$result = $workflowIds.Add($workflow.id)
80+
}
81+
if (!$workflowNames.Contains($workflow.name))
82+
{
83+
$result = $workflowNames.Add($workflow.name)
7484
}
7585
}
76-
else
77-
{
78-
#Write-Output "'$($workflow.name)' DID NOT match with $arrayItem"
79-
}
86+
# else
87+
# {
88+
# Write-Output "'$($workflow.name)' DID NOT match with $arrayItem"
89+
# }
8090
}
8191
}
8292

@@ -149,8 +159,10 @@ function Main ([string] $ownerRepo,
149159
{
150160
$rateLimitResponse = Invoke-RestMethod -Uri $uri3 -ContentType application/json -Method Get -Headers @{Authorization=($authHeader["Authorization"])} -SkipHttpErrorCheck -StatusCodeVariable "HTTPStatus"
151161
}
152-
Write-Output "Rate limit consumption: $($rateLimitResponse.rate.used) / $($rateLimitResponse.rate.limit)"
153-
162+
if ($showVerboseLogging -eq $true)
163+
{
164+
Write-Output "Rate limit consumption: $($rateLimitResponse.rate.used) / $($rateLimitResponse.rate.limit)"
165+
}
154166

155167
#==========================================
156168
#Calculate deployments per day
@@ -230,22 +242,22 @@ function Main ([string] $ownerRepo,
230242

231243
if ($dateList.Count -gt 0 -and $numberOfDays -gt 0)
232244
{
233-
Write-Output "Deployment frequency over last $numberOfDays days, is $displayMetric $displayUnit, with a DORA rating of '$rating'"
234-
return Format-OutputMarkdown -workflowIds $workflowIds -displayMetric $displayMetric -displayUnit $displayUnit -numberOfDays $numberOfDays -numberOfUniqueDates $uniqueDates.Length.ToString() -color $color -rating $rating
235-
245+
if ($showVerboseLogging -eq $true)
246+
{
247+
Write-Output "Deployment frequency over last $numberOfDays days, is $displayMetric $displayUnit, with a DORA rating of '$rating'"
248+
}
249+
return Format-OutputMarkdown -workflowNames $workflowNames -displayMetric $displayMetric -displayUnit $displayUnit -repo $ownerRepo -branch $branch -numberOfDays $numberOfDays -numberOfUniqueDates $uniqueDates.Length.ToString() -color $color -rating $rating
236250
}
237251
else
238252
{
239-
$output = "Deployment frequency: no data to display for this workflow and time period"
240-
Write-Output $output
241-
return $output
253+
return Format-NoOutputMarkdown -workflows $workflows -numberOfDays $numberOfDays
242254
}
243255
}
244256

245257
#Generate the authorization header for the PowerShell call to the GitHub API
246258
#warning: PowerShell has really wacky return semantics - all output is captured, and returned
247259
#reference: https://stackoverflow.com/questions/10286164/function-return-value-in-powershell
248-
function GetAuthHeader ([string] $patToken, [string] $actionsToken, [string] $appId, [string] $appInstallationId, [string] $appPrivateKey)
260+
function GetAuthHeader ([string] $patToken, [string] $actionsToken, [string] $appId, [string] $appInstallationId, [string] $appPrivateKey, [bool] $showVerboseLogging = $false)
249261
{
250262
#Clean the string - without this the PAT TOKEN doesn't process
251263
$patToken = $patToken.Trim()
@@ -255,24 +267,36 @@ function GetAuthHeader ([string] $patToken, [string] $actionsToken, [string] $ap
255267
#Write-Host "patToken is something: $(![string]::IsNullOrEmpty($patToken))"
256268
if (![string]::IsNullOrEmpty($patToken))
257269
{
258-
Write-Host "Authentication detected: PAT TOKEN"
270+
if ($showVerboseLogging -eq $true)
271+
{
272+
Write-Host "Authentication detected: PAT TOKEN"
273+
}
259274
$base64AuthInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$patToken"))
260275
$authHeader = @{Authorization=("Basic {0}" -f $base64AuthInfo)}
261276
}
262277
elseif (![string]::IsNullOrEmpty($actionsToken))
263278
{
264-
Write-Host "Authentication detected: GITHUB TOKEN"
279+
if ($showVerboseLogging -eq $true)
280+
{
281+
Write-Host "Authentication detected: GITHUB TOKEN"
282+
}
265283
$authHeader = @{Authorization=("Bearer {0}" -f $base64AuthInfo)}
266284
}
267285
elseif (![string]::IsNullOrEmpty($appId)) # GitHup App auth
268286
{
269-
Write-Host "Authentication detected: GITHUB APP TOKEN"
287+
if ($showVerboseLogging -eq $true)
288+
{
289+
Write-Host "Authentication detected: GITHUB APP TOKEN"
290+
}
270291
$token = Get-JwtToken $appId $appInstallationId $appPrivateKey
271292
$authHeader = @{Authorization=("token {0}" -f $token)}
272293
}
273294
else
274295
{
275-
Write-Host "No authentication detected"
296+
if ($showVerboseLogging -eq $true)
297+
{
298+
Write-Host "No authentication detected"
299+
}
276300
$base64AuthInfo = $null
277301
$authHeader = $null
278302
}
@@ -340,19 +364,27 @@ function Get-JwtToken([string] $appId, [string] $appInstallationId, [string] $ap
340364
}
341365

342366
# Format output for deployment frequency in markdown
343-
function Format-OutputMarkdown([array] $workflowIds, [string] $rating, [string] $displayMetric, [string] $displayUnit, [string] $numberOfDays, [string] $numberOfUniqueDates, [string] $color)
367+
function Format-OutputMarkdown([array] $workflowNames, [string] $rating, [string] $displayMetric, [string] $displayUnit, [string] $repo, [string] $branch, [string] $numberOfDays, [string] $numberOfUniqueDates, [string] $color)
344368
{
345-
$workflowNames = $workflowIds -join ", "
346369
$encodedDeploymentFrequency = [uri]::EscapeUriString($displayMetric + " " + $displayUnit)
347370

348-
$markdown = "## DORA Metric: Deployment Frequency`r`n" +
349-
"![Deployment Frequency](https://img.shields.io/badge/frequency-" + $encodedDeploymentFrequency + "-" + $color + "?logo=github&label=Deployment%20frequency)`r`n" +
350-
"**Definition:** For the primary application or service, how often is it successfully deployed to production.`n" +
351-
"**Results:** Deployment frequency over last **$numberOfDays days** is **$displayMetric $displayUnit**, with a DORA rating of **$rating**.`n" +
352-
"- Workflow(s) used: $workflowNames`n" +
353-
"- Active days of deployment: $numberOfUniqueDates days`n"
371+
$markdown = "![Deployment Frequency](https://img.shields.io/badge/frequency-" + $encodedDeploymentFrequency + "-" + $color + "?logo=github&label=Deployment%20frequency)`r`n" +
372+
"**Definition:** For the primary application or service, how often is it successfully deployed to production.`n" +
373+
"**Results:** Deployment frequency is **$displayMetric $displayUnit** with a **$rating** rating, over the last **$numberOfDays days**.`n" +
374+
"**Details**:`n" +
375+
"- Repository: $repo using $branch branch`n" +
376+
"- Workflow(s) used: $($workflowNames -join ", ")`n" +
377+
"- Active days of deployment: $numberOfUniqueDates days`n" +
378+
"---"
379+
return $markdown
380+
}
354381

382+
function Format-NoOutputMarkdown([string] $workflows, [string] $numberOfDays)
383+
{
384+
$markdown = "![Deployment Frequency](https://img.shields.io/badge/frequency-none-lightgrey?logo=github&label=Deployment%20frequency)`r`n`n" +
385+
"No data to display for $ownerRepo for workflow(s) $workflows over the last $numberOfDays days`n`n" +
386+
"---"
355387
return $markdown
356388
}
357389

358-
main -ownerRepo $ownerRepo -workflows $workflows -branch $branch -numberOfDays $numberOfDays -patToken $patToken -actionsToken $actionsToken -appId $appId -appInstallationId $appInstallationId -appPrivateKey $appPrivateKey
390+
main -ownerRepo $ownerRepo -workflows $workflows -branch $branch -numberOfDays $numberOfDays -patToken $patToken -actionsToken $actionsToken -appId $appId -appInstallationId $appInstallationId -appPrivateKey $appPrivateKey -showVerboseLogging $showVerboseLogging

0 commit comments

Comments
 (0)