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,125 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Velocity-Analyse ueber 12 Monate fuer alle pathOS Teams
|
||||
#>
|
||||
|
||||
$JiraUrl = "https://arija.jaas.service.deutschebahn.com"
|
||||
$ApiBase = "$JiraUrl/rest"
|
||||
$OutputDir = "project-audit\data\jira-velocity"
|
||||
|
||||
$TeamProjects = @(
|
||||
@{ key = "O2C404"; name = "Team 404" }
|
||||
@{ key = "O2CCIB"; name = "Team CIB" }
|
||||
@{ key = "O2CZERO"; name = "Team Zero" }
|
||||
@{ key = "O2COS"; name = "OPs Squad" }
|
||||
@{ key = "O2CDEVOPS"; name = "DevOps" }
|
||||
)
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
Write-Host "============================================================"
|
||||
Write-Host " pathOS Velocity-Analyse (12 Monate)"
|
||||
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 { return $null }
|
||||
}
|
||||
|
||||
$AllResults = @()
|
||||
|
||||
foreach ($Team in $TeamProjects) {
|
||||
$Key = $Team.key
|
||||
$Name = $Team.name
|
||||
Write-Host ""
|
||||
Write-Host ">> $Name ($Key)" -ForegroundColor Yellow
|
||||
|
||||
# Alle resolved/done Issues der letzten 12 Monate
|
||||
$Jql = "project = $Key AND status in (Fertig, Done, Closed, Resolved) AND resolved >= -365d ORDER BY resolved ASC"
|
||||
$Issues = @()
|
||||
$Start = 0
|
||||
do {
|
||||
$Uri = "$ApiBase/api/2/search?jql=$([Uri]::EscapeDataString($Jql))&startAt=$Start&maxResults=100&fields=summary,status,issuetype,resolutiondate,created"
|
||||
$Result = Invoke-JiraApi $Uri
|
||||
if ($null -eq $Result) { break }
|
||||
$Issues += $Result.issues
|
||||
$Start += 100
|
||||
Write-Host " $($Issues.Count) / $($Result.total)..." -NoNewline
|
||||
} while ($Issues.Count -lt $Result.total -and $Issues.Count -lt 3000)
|
||||
Write-Host ""
|
||||
Write-Host " $($Issues.Count) resolved Issues (12 Monate)" -ForegroundColor Green
|
||||
|
||||
# Nach Monat gruppieren
|
||||
$ByMonth = @{}
|
||||
$BugsByMonth = @{}
|
||||
$EnablerByMonth = @{}
|
||||
foreach ($I in $Issues) {
|
||||
$ResDate = $I.fields.resolutiondate
|
||||
if (-not $ResDate) { $ResDate = $I.fields.created }
|
||||
if ($ResDate) {
|
||||
try {
|
||||
$Date = [DateTime]::Parse($ResDate)
|
||||
$MK = $Date.ToString("yyyy-MM")
|
||||
$ByMonth[$MK] = ($ByMonth[$MK]) + 1
|
||||
$Type = $I.fields.issuetype.name
|
||||
if ($Type -eq "Bug" -or $Type -eq "Fehler") { $BugsByMonth[$MK] = ($BugsByMonth[$MK]) + 1 }
|
||||
if ($Type -eq "Enabler") { $EnablerByMonth[$MK] = ($EnablerByMonth[$MK]) + 1 }
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
# Ergebnis sammeln
|
||||
foreach ($MK in ($ByMonth.Keys | Sort-Object)) {
|
||||
$Total = $ByMonth[$MK]
|
||||
$Bugs = if ($BugsByMonth[$MK]) { $BugsByMonth[$MK] } else { 0 }
|
||||
$Enablers = if ($EnablerByMonth[$MK]) { $EnablerByMonth[$MK] } else { 0 }
|
||||
$AllResults += [PSCustomObject]@{
|
||||
Team = $Name
|
||||
Key = $Key
|
||||
Month = $MK
|
||||
Total = $Total
|
||||
Bugs = $Bugs
|
||||
Enabler = $Enablers
|
||||
BugRate = if ($Total -gt 0) { [Math]::Round(($Bugs / $Total) * 100, 0) } else { 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# CSV speichern
|
||||
$AllResults | Export-Csv "$OutputDir\velocity-12m.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation
|
||||
|
||||
# Markdown
|
||||
$Md = @()
|
||||
$Md += "# Velocity-Analyse pathOS (12 Monate)"
|
||||
$Md += ""
|
||||
$Md += "> Exportiert: $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
|
||||
$Md += ""
|
||||
$Md += "| Team | Monat | Gesamt | Bugs | Enabler | Bug% |"
|
||||
$Md += "|------|-------|--------|------|---------|------|"
|
||||
foreach ($R in $AllResults) {
|
||||
$Md += "| $($R.Team) | $($R.Month) | $($R.Total) | $($R.Bugs) | $($R.Enabler) | $($R.BugRate)% |"
|
||||
}
|
||||
$Md -join "`n" | Out-File "$OutputDir\velocity-12m.md" -Encoding UTF8
|
||||
|
||||
# Zusammenfassung pro Team
|
||||
Write-Host ""
|
||||
Write-Host "=== Zusammenfassung ==="
|
||||
foreach ($Team in $TeamProjects) {
|
||||
$TeamData = $AllResults | Where-Object { $_.Key -eq $Team.key }
|
||||
$TotalAll = ($TeamData | Measure-Object -Property Total -Sum).Sum
|
||||
$TotalBugs = ($TeamData | Measure-Object -Property Bugs -Sum).Sum
|
||||
$AvgMonth = if ($TeamData.Count -gt 0) { [Math]::Round($TotalAll / $TeamData.Count, 0) } else { 0 }
|
||||
Write-Host " $($Team.name): $TotalAll Issues (12M), Avg $AvgMonth/Monat, $TotalBugs Bugs ($([Math]::Round($TotalBugs/$TotalAll*100,0))%)"
|
||||
}
|
||||
|
||||
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