<# .SYNOPSIS Exportiert Jira-Daten aller pathOS Team-Boards #> $JiraUrl = "https://arija.jaas.service.deutschebahn.com" $ApiBase = "$JiraUrl/rest" $OutputDir = "project-audit\data\jira-teams" $TeamProjects = @( @{ key = "O2C404"; name = "Team 404 (Portal)" } @{ key = "O2CCIB"; name = "Team CIB (Prozesse/Backend)" } @{ key = "O2CZERO"; name = "Team Zero (TAF/TAP)" } @{ key = "O2COS"; name = "OPs Squad (Infrastruktur)" } @{ key = "O2CSYS"; name = "STeam/System (ehem.)" } @{ key = "O2CQST"; name = "QA/Test" } @{ key = "O2CDEVOPS"; name = "DevOps" } ) [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Write-Host "============================================================" Write-Host " pathOS Team-Boards Jira Export" Write-Host "============================================================" $Token = Read-Host "Jira PAT" $Headers = @{ "Authorization" = "Bearer $Token"; "Content-Type" = "application/json" } New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null function Invoke-JiraApi($Uri) { try { $R = Invoke-WebRequest -Uri $Uri -Headers $Headers -UseBasicParsing -ErrorAction Stop return ($R.Content | ConvertFrom-Json) } catch { Write-Host " FEHLER: $($_.Exception.Message)" -ForegroundColor Red return $null } } $Summary = @() foreach ($Team in $TeamProjects) { $Key = $Team.key $Name = $Team.name Write-Host "" Write-Host ">> $Name ($Key)" -ForegroundColor Yellow # Projekt-Info $Proj = Invoke-JiraApi "$ApiBase/api/2/project/$Key" if ($null -eq $Proj) { Write-Host " Nicht gefunden oder kein Zugriff" -ForegroundColor Red; continue } Write-Host " Projekt: $($Proj.name)" # Issues (letzte 90 Tage) $Jql = "project = $Key AND updated >= -90d ORDER BY updated DESC" $Issues = @() $Start = 0 do { $Uri = "$ApiBase/api/2/search?jql=$([Uri]::EscapeDataString($Jql))&startAt=$Start&maxResults=100&fields=summary,status,issuetype,assignee,labels,components,fixVersions,priority,created,updated,sprint" $Result = Invoke-JiraApi $Uri if ($null -eq $Result) { break } $Issues += $Result.issues $Start += 100 } while ($Issues.Count -lt $Result.total -and $Issues.Count -lt 500) Write-Host " $($Issues.Count) Issues (90 Tage)" # Analyse $ByType = $Issues | Group-Object { $_.fields.issuetype.name } $ByStatus = $Issues | Group-Object { $_.fields.status.name } $Done = ($Issues | Where-Object { $_.fields.status.name -eq "Fertig" -or $_.fields.status.name -match "Done|Closed|Resolved" }).Count $InProgress = ($Issues | Where-Object { $_.fields.status.name -match "Implementation|In Bearbeitung|In Progress|Review|Validierung" }).Count $Open = $Issues.Count - $Done - $InProgress $TeamInfo = [PSCustomObject]@{ Team = $Name Key = $Key Total = $Issues.Count Done = $Done InProgress = $InProgress Open = $Open Features = ($ByType | Where-Object { $_.Name -eq "Feature" }).Count Enabler = ($ByType | Where-Object { $_.Name -eq "Enabler" }).Count Bugs = ($ByType | Where-Object { $_.Name -match "Bug|Fehler" }).Count Tasks = ($ByType | Where-Object { $_.Name -eq "Aufgabe" }).Count } $Summary += $TeamInfo Write-Host " Fertig: $Done | In Arbeit: $InProgress | Offen: $Open" # Issues als CSV speichern $CsvData = $Issues | ForEach-Object { [PSCustomObject]@{ Key = $_.key Typ = $_.fields.issuetype.name Status = $_.fields.status.name Prioritaet = if ($_.fields.priority) { $_.fields.priority.name } else { "" } Zusammenfassung = $_.fields.summary Assignee = if ($_.fields.assignee) { $_.fields.assignee.displayName } else { "" } Labels = if ($_.fields.labels) { $_.fields.labels -join ", " } else { "" } Erstellt = $_.fields.created Aktualisiert = $_.fields.updated } } $CsvData | Export-Csv "$OutputDir\$Key-issues.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation $Issues | ConvertTo-Json -Depth 10 | Out-File "$OutputDir\$Key-issues.json" -Encoding UTF8 } # Zusammenfassung Write-Host "" Write-Host ">> Zusammenfassung" -ForegroundColor Yellow $Summary | Format-Table -AutoSize $Md = @() $Md += "# Jira Team-Boards Analyse pathOS" $Md += "" $Md += "> Exportiert: $(Get-Date -Format 'yyyy-MM-dd HH:mm')" $Md += "" $Md += "| Team | Key | Issues (90d) | Fertig | In Arbeit | Offen | Features | Enabler | Bugs | Tasks |" $Md += "|------|-----|-------------|--------|-----------|-------|----------|---------|------|-------|" foreach ($T in $Summary) { $Md += "| $($T.Team) | $($T.Key) | $($T.Total) | $($T.Done) | $($T.InProgress) | $($T.Open) | $($T.Features) | $($T.Enabler) | $($T.Bugs) | $($T.Tasks) |" } $Md += "" # Assignee-Analyse (wer arbeitet wo) $Md += "## Assignees pro Team" foreach ($Team in $TeamProjects) { $Key = $Team.key $JsonPath = "$OutputDir\$Key-issues.json" if (Test-Path $JsonPath) { $Issues = Get-Content $JsonPath -Raw | ConvertFrom-Json $Assignees = $Issues | Where-Object { $_.fields.assignee } | Group-Object { $_.fields.assignee.displayName } | Sort-Object Count -Descending if ($Assignees.Count -gt 0) { $Md += "" $Md += "### $($Team.name) ($Key)" foreach ($A in $Assignees) { $Md += "- $($A.Name): $($A.Count) Issues" } } } } $Md -join "`n" | Out-File "$OutputDir\team-summary.md" -Encoding UTF8 $Summary | Export-Csv "$OutputDir\team-summary.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation Write-Host "" Write-Host "============================================================" -ForegroundColor Green Write-Host " FERTIG! Ergebnisse in $OutputDir" -ForegroundColor Green Write-Host "============================================================" -ForegroundColor Green