Migrate all repos into monorepo context folders
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.
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
<#
|
||||
.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
|
||||
Reference in New Issue
Block a user