Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
150 lines
5.9 KiB
PowerShell
150 lines
5.9 KiB
PowerShell
<#
|
|
.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
|