Skip to content

Instantly share code, notes, and snippets.

@jdhitsolutions
Created March 7, 2024 17:59
Show Gist options
  • Select an option

  • Save jdhitsolutions/30cd246fd99dd442e4a75ddf0261c2ce to your computer and use it in GitHub Desktop.

Select an option

Save jdhitsolutions/30cd246fd99dd442e4a75ddf0261c2ce to your computer and use it in GitHub Desktop.

Revisions

  1. jdhitsolutions created this gist Mar 7, 2024.
    113 changes: 113 additions & 0 deletions Get-GHIssueStats.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,113 @@
    #requires -version 7.4

    <#
    This function requires the gh.exe command line tool.
    You many encounter API rate restrictions under heavy use.
    #>

    #load the custom formatting file
    Update-FormatData $PSScriptRoot\ghLabelStatus.format.ps1xml

    Function Get-ghIssueLabelCount {
    [cmdletbinding()]
    [OutputType('ghLabelStatus')]
    [alias('ghlc')]
    Param(
    [Parameter(
    Position = 0,
    Mandatory,
    ValueFromPipeline,
    HelpMessage = 'Specify the Github owner and repo in the format: owner/repo. You might need to match casing with GitHub.'
    )]
    [ValidateNotNullOrEmpty()]
    [ValidatePattern('\w+/\w+$', ErrorMessage = 'Please use the format OWNER/Repository. e.g. jdhitsolutions/psreleasetools')]
    [string]$Repository,

    [Parameter(HelpMessage = 'Specify the first X number of issue labels sorted by count in descending order.')]
    [ValidateScript({ $_ -gt 0 }, ErrorMessage = 'Enter a value greater than 0.')]
    [int]$First = 25,

    [Parameter(HelpMessage = 'Specify the number of issues to analyze')]
    [ValidateScript({ $_ -gt 0 }, ErrorMessage = 'Enter a value greater than 0.')]
    [int]$Limit = 1000
    )

    Begin {
    Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)"
    Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)"
    Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Using host: $($Host.Name)"
    $ReportDate = Get-Date
    } #begin

    Process {
    Try {
    $gh = Get-Command -Name gh.exe -ErrorAction Stop
    Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Using $( gh.exe --version | Select-Object -First 1)"
    Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Processing $Limit issues from $Repository"

    <#
    gitHub issue Available JSON fields:
    assignees
    author
    body
    closed
    closedAt
    comments
    createdAt
    id
    labels
    milestone
    number
    projectCards
    projectItems
    reactionGroups
    state
    title
    updatedAt
    url
    #>
    $ghData = gh.exe issue list --repo $Repository --limit $Limit --json 'id,title,labels' | ConvertFrom-Json
    Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $($ghData.count) items"
    } #Try
    Catch {
    Write-Warning 'This command requires the gh.exe command-line utility.'
    } #Catch

    If ($ghData.count -gt 0) {
    Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Getting top $First issue labels"
    $data = $ghData.labels |
    Group-Object -Property Name -NoElement |
    Sort-Object Count, Name -Descending |
    Select-Object -First $First

    foreach ($Item in $data) {
    #create a custom object
    if ($item.Name -match '\s') {
    $escName = '%22{0}%22' -f ($item.Name -replace '\s', '+')
    $uri = "https://github.com/$Repository/issues?q=is%3Aissue+is%3Aopen+label%3A$escName"
    }
    else {
    $uri = "https://github.com/$Repository/issues?q=is%3Aissue+is%3Aopen+label%3A$($Item.Name)"
    }
    [PSCustomObject]@{
    PStypeName = 'ghLabelStatus'
    Count = $Item.Count
    PctTotal = ($item.Count / $ghData.Count) * 100
    Label = $Item.Name
    LabelUri = $uri
    Repository = $Repository
    IssueCount = $ghData.Count
    ReportDate = $ReportDate
    }
    }
    } #if data found
    else {
    Write-Warning "No open issues found in $Repository"
    }
    } #process

    End {
    Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)"
    } #end

    } #close Get-ghIssueLabelCount
    47 changes: 47 additions & 0 deletions ghLabelReport.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    #requires -version 7.4

    #a control script to generate a markdown report.

    #ghLabelReport.ps1
    Param(
    [Parameter(
    Position = 0,
    Mandatory,
    ValueFromPipeline,
    HelpMessage = 'Specify the Github owner and repo in the format: owner/repo. You might need to match casing with GitHub.'
    )]
    [ValidateNotNullOrEmpty()]
    [ValidatePattern('\w+/\w+$', ErrorMessage = 'Please use the format OWNER/Repository. e.g. jdhitsolutions/psreleasetools')]
    [string]$Repository,

    [Parameter(HelpMessage = 'Specify the first X number of issue labels sorted by count in descending order.')]
    [ValidateScript({ $_ -gt 0 }, ErrorMessage = 'Enter a value greater than 0.')]
    [int]$First = 25,

    [Parameter(HelpMessage = 'Specify the number of issues to analyze')]
    [ValidateScript({ $_ -gt 0 }, ErrorMessage = 'Enter a value greater than 0.')]
    [int]$Limit = 1000

    )

    #dot source the required function
    . $PSScriptRoot\Get-ghIssueStats.ps1

    $data = Get-ghIssueLabelCount @PSBoundParameters

    if ($data) {
    $repoIssues = "https://github.com/$($data[0].Repository)/issues"
    $md = [System.Collections.Generic.List[string]]::New()
    $md.Add("# Label Report for [$($data[0].Repository)]($repoIssues)`n")
    $md.Add("This is the breakdown of labels based on __$($data[0].IssueCount)__ open issues. Total percentages might be more than 100% as issues can have multiple labels.`n")
    $md.Add("Count| Percent of Total | Label|")
    $md.Add("|-----|-----|-----|")
    foreach ($item in $data) {
    $md.Add("| $($item.count) | $([math]::Round($item.PctTotal,2)) | [$($item.Label)]($($item.LabelUri))|")
    }

    $md.Add("`n_$($data[0].ReportDate)_")
    }

    #write the markdown to the pipeline
    $md
    112 changes: 112 additions & 0 deletions ghLabelStatus.format.ps1xml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    <!--
    Format type data generated 12/04/2023 12:58:47 by PROSPERO\Jeff
    This file was created using the New-PSFormatXML command that is part
    of the PSScriptTools module.
    https://github.com/jdhitsolutions/PSScriptTools
    -->
    <Configuration>
    <ViewDefinitions>
    <View>
    <!--Created 12/04/2023 12:58:47 by PROSPERO\Jeff-->
    <Name>default</Name>
    <ViewSelectedBy>
    <TypeName>ghLabelStatus</TypeName>
    </ViewSelectedBy>
    <GroupBy>
    <ScriptBlock>"{0} [{1}]" -f $_.Repository,$_.ReportDate</ScriptBlock>
    <Label>Repository</Label>
    </GroupBy>
    <TableControl>
    <!--Delete the AutoSize node if you want to use the defined widths.-->
    <AutoSize />
    <TableHeaders>
    <TableColumnHeader>
    <Label>Count</Label>
    <Width>8</Width>
    <Alignment>right</Alignment>
    </TableColumnHeader>
    <TableColumnHeader>
    <Label>PctTotal</Label>
    <Width>8</Width>
    <Alignment>right</Alignment>
    </TableColumnHeader>
    <TableColumnHeader>
    <Label>Label</Label>
    <Width>15</Width>
    <Alignment>left</Alignment>
    </TableColumnHeader>
    </TableHeaders>
    <TableRowEntries>
    <TableRowEntry>
    <TableColumnItems>
    <TableColumnItem>
    <PropertyName>Count</PropertyName>
    </TableColumnItem>
    <TableColumnItem>
    <ScriptBlock>"{0:p2}" -f ($_.Count/$_.IssueCount)</ScriptBlock>
    </TableColumnItem>
    <TableColumnItem>
    <PropertyName>Label</PropertyName>
    </TableColumnItem>
    </TableColumnItems>
    </TableRowEntry>
    </TableRowEntries>
    </TableControl>
    </View>
    <View>
    <!--Created 12/04/2023 15:18:46 by PROSPERO\Jeff-->
    <Name>uri</Name>
    <ViewSelectedBy>
    <TypeName>ghLabelStatus</TypeName>
    </ViewSelectedBy>
    <GroupBy>
    <ScriptBlock>
    $link = $PSStyle.FormatHyperlink($_.Repository,"https://github.com/$($_.Repository)/issues")
    "$($PSStyle.Foreground.Yellow +$PSStyle.Italic)$link$($PSStyle.Reset) [$($_.ReportDate)]"
    </ScriptBlock>
    <Label>Repository</Label>
    </GroupBy>
    <TableControl>
    <!--Delete the AutoSize node if you want to use the defined widths.-->
    <AutoSize />
    <TableHeaders>
    <TableColumnHeader>
    <Label>Count</Label>
    <Width>8</Width>
    <Alignment>right</Alignment>
    </TableColumnHeader>
    <TableColumnHeader>
    <Label>PctTotal</Label>
    <Width>8</Width>
    <Alignment>right</Alignment>
    </TableColumnHeader>
    <TableColumnHeader>
    <Label>Label</Label>
    <Width>14</Width>
    <Alignment>left</Alignment>
    </TableColumnHeader>
    </TableHeaders>
    <TableRowEntries>
    <TableRowEntry>
    <TableColumnItems>
    <TableColumnItem>
    <PropertyName>Count</PropertyName>
    </TableColumnItem>
    <TableColumnItem>
    <ScriptBlock>"{0:p2}" -f ($_.Count/$_.IssueCount)</ScriptBlock>
    </TableColumnItem>
    <TableColumnItem>
    <ScriptBlock>
    $link = $PSStyle.FormatHyperlink($_.Label,$_.LabelUri)
    "$($PSStyle.Foreground.Yellow +$PSStyle.Italic)$link$($PSStyle.Reset)"
    </ScriptBlock>
    </TableColumnItem>
    </TableColumnItems>
    </TableRowEntry>
    </TableRowEntries>
    </TableControl>
    </View>
    </ViewDefinitions>
    </Configuration>