ProjectJobs.psm1
# Gitlab Project Pipeline Jobs # Import-Module GitlabCli # import dependency if required function Get-JobDurationSummary () { param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [psobject[]] $Value, [Parameter(Mandatory=$true, Position=1)] [string] $Status ) begin { $ProjectJobs = @()} process { $ProjectJobs += $Value } end { ($ProjectJobs | Where-Object Status -eq $Status | Measure-Object -Property duration -Minimum -Maximum -Average | Select-Object -Property Average, Minimum, Maximum, Count) } } function ConvertTo-JobSummary { param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [psobject[]] $Value ) begin { $ProjectJobs = @()} process { $ProjectJobs += $Value } end { [PSCustomObject]@{ Success = $ProjectJobs | Get-JobDurationSummary -Status success Failed = $ProjectJobs | Get-JobDurationSummary -Status failed } } } function Find-GitlabProjectJobs() { param ( [Parameter(Mandatory=$false)] [string] $ProjectId = ".", [Parameter(Mandatory=$true, Position=0)] [datetime] $CompletedAfter, [Parameter(Mandatory=$true, Position=1)] [ValidateSet('test', 'deploy')] [string] $PipelineStage, [Parameter(Mandatory=$false, Position=2)] [string] $Branch = 'main', [Parameter(Mandatory=$false, Position=3)] [string] $HostEnv = 'test', [Parameter(Mandatory=$false, Position=4)] [switch] $IncludeJobSummary, [Parameter(Mandatory=$false, Position=5)] [string[]] $Scopes = @('success', 'failed') ) $ProjectPath = (Get-GitlabProject $ProjectId ).PathWithNamespace $JobStatus = "[$($Scopes -join ",")]".ToUpper() $StartCursor = "" $JobDetails = @() $page = 0 $found = $false while (-not $found) { $page++ $Data = Invoke-GitlabGraphQL -Query @" { project(fullPath: "$ProjectPath") { jobs(statuses: $JobStatus, after: "$StartCursor") { count pageInfo { hasNextPage startCursor endCursor } nodes { name refName finishedAt duration queuedDuration stage { name status } } } } } "@ $Jobs = $Data.Project.Jobs $JobDetails += $Jobs.nodes $found = ($JobDetails | Select-Object -Last 1).finishedAt -lt $CompletedAfter $StartCursor = $Jobs.pageInfo.hasNextPage ? $Jobs.pageInfo.endCursor : "" } $FilteredJobs = ($JobDetails | Where-Object { $_.finishedAt -gt $CompletedAfter -and $_.refName -ieq $Branch -and $_.name.Contains($HostEnv) -and $_.stage.name.Contains([string]$PipelineStage)} | ForEach-Object {[PSCustomObject]@{ Name = $_.name Ref = $_.refName Duration = $_.duration QueuedDuration = $_.queuedDuration FinishedAt = $_.finishedAt Stage = $_.stage.Name Status = $_.stage.status }}) $Response = [PSCustomObject]@{ Service = ($ProjectPath).Split('/')[-1] CompletedAfter = $CompletedAfter Jobs = $FilteredJobs } if ($IncludeJobSummary) { $Response | Add-Member -MemberType 'NoteProperty' -Name 'JobSummary' -Value $($FilteredJobs | ConvertTo-JobSummary) } $Response } Export-ModuleMember -Function Find-GitlabProjectJobs |