Initial commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
JIRA_BASE_URL=https://jira.a1.by
|
||||||
|
JIRA_PROJECT=VDEV
|
||||||
|
JIRA_USER=your-user-name
|
||||||
|
JIRA_TOKEN=l72382b4ruo8mdp1c6mvcsg8h4kbf9ij497i2vtdqa0sfbaduoeqkcs
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
.env
|
||||||
|
.DS_Store
|
||||||
|
*.csv
|
||||||
|
*.json
|
||||||
|
__pycache__/
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# Jira Ticket Analysis
|
||||||
|
|
||||||
|
Исполняемый скрипт `jira_analyze.py` анализирует тикеты Jira по проекту `VDEV` на `https://jira.a1.by`.
|
||||||
|
|
||||||
|
Токен не хранится в файлах проекта. Перед запуском задайте его через переменную окружения:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export JIRA_TOKEN='your-token-here'
|
||||||
|
export JIRA_USER='Serhei_T'
|
||||||
|
./jira_analyze.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Шаблон переменных окружения есть в `.env.example`. Файл `.env` добавлен в `.gitignore`.
|
||||||
|
|
||||||
|
Можно также создать локальный `.env`, скрипт загрузит его автоматически:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
После этого откройте `.env` и замените `JIRA_TOKEN=your-token-here` на реальный токен. Для этой Jira используется Basic Auth, поэтому также должен быть заполнен `JIRA_USER`.
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./jira_analyze.py --project VDEV
|
||||||
|
./jira_analyze.py --project VDEV --stale-days 14
|
||||||
|
./jira_analyze.py --jql 'project = VDEV AND statusCategory != Done ORDER BY updated DESC'
|
||||||
|
./jira_analyze.py --csv-out jira-dev.csv --json-out jira-dev.json
|
||||||
|
./jira_analyze.py --html-quarter-out dev-q1-q2-2026.html
|
||||||
|
./jira_analyze.py --html-sprint-quarter-out vdev-sprints-quarters.html
|
||||||
|
```
|
||||||
|
|
||||||
|
Для вашей задачи по завершенным спринтам 2026 используйте готовую команду:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./vdev_sprint_report_2026.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Она создаст файл `vdev-sprints-2026.html` и не будет сканировать все тикеты проекта.
|
||||||
|
|
||||||
|
Что считает скрипт:
|
||||||
|
|
||||||
|
- общее количество тикетов;
|
||||||
|
- количество resolved и unresolved;
|
||||||
|
- долю закрытых тикетов;
|
||||||
|
- распределение по статусам, типам, приоритетам, исполнителям, компонентам и меткам;
|
||||||
|
- созданные и закрытые тикеты по месяцам;
|
||||||
|
- незакрытые тикеты без обновлений дольше `--stale-days`;
|
||||||
|
- незакрытые тикеты с просроченным `duedate`.
|
||||||
|
|
||||||
|
HTML-отчет по кварталам:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./jira_analyze.py --html-quarter-out dev-q1-q2-2026.html --report-year 2026 --quarters 1,2 --closed-status 'Закрыт'
|
||||||
|
```
|
||||||
|
|
||||||
|
Для HTML-отчета без `--jql` скрипт сам использует запрос:
|
||||||
|
|
||||||
|
```jql
|
||||||
|
project = VDEV AND status = "Закрыт" AND resolutiondate >= "2026-01-01" AND resolutiondate < "2026-07-01" ORDER BY resolutiondate ASC
|
||||||
|
```
|
||||||
|
|
||||||
|
В HTML попадает:
|
||||||
|
|
||||||
|
- выполненные задачи по Q1 и Q2 2026;
|
||||||
|
- фактические и плановые часы из Jira time tracking;
|
||||||
|
- отклонение факт-план;
|
||||||
|
- средний цикл выполнения от `created` до `resolutiondate`;
|
||||||
|
- разбивка по командам через `components`, если компонент не заполнен - через `assignee`;
|
||||||
|
- проблемные сигналы: нет часов, нет оценки, закрыто после срока, длинный цикл, высокий приоритет, блокирующие метки, нет компонента;
|
||||||
|
- рекомендации по корректировкам для команд.
|
||||||
|
|
||||||
|
HTML-отчет по спринтам с января по сегодня:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./jira_analyze.py --html-sprint-quarter-out vdev-sprints-quarters.html --sprints-from 2026-01-01 --sprints-to 2026-06-15
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт использует Jira Agile API:
|
||||||
|
|
||||||
|
- находит boards проекта `VDEV`;
|
||||||
|
- выгружает только завершенные `closed` спринты, пересекающиеся с периодом;
|
||||||
|
- выгружает задачи каждого спринта;
|
||||||
|
- оставляет закрытые задачи через `statusCategory = Done`, `resolutiondate` или статус из `--closed-status`;
|
||||||
|
- раскладывает спринты по кварталам по `completeDate`, затем `endDate`, затем `startDate`;
|
||||||
|
- считает закрытые фичи, задачи и баги в каждом квартале;
|
||||||
|
- дедуплицирует задачу внутри квартала, если она встретилась в нескольких спринтах/boards.
|
||||||
|
|
||||||
|
Категории типов:
|
||||||
|
|
||||||
|
- `Фичи`: Jira-типы с `Feature`, `Story`, `фич`, `истор`;
|
||||||
|
- `Задачи`: Jira-типы с `Task`, `задач`;
|
||||||
|
- `Баги`: Jira-типы с `Bug`, `Defect`, `дефект`, `ошиб`;
|
||||||
|
- остальное попадает в `Прочее`.
|
||||||
|
|
||||||
|
Если нужно ограничить отчет конкретной Agile board:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./jira_analyze.py --html-sprint-quarter-out vdev-sprints-quarters.html --board-id 123
|
||||||
|
```
|
||||||
|
|
||||||
|
Параметры по умолчанию:
|
||||||
|
|
||||||
|
- `--base-url https://jira.a1.by`;
|
||||||
|
- `--project VDEV`;
|
||||||
|
- `--page-size 100`;
|
||||||
|
- `--stale-days 30`.
|
||||||
Executable
+1280
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Jira VDEV Sprint Quarterly Statistics</title>
|
||||||
|
<style>
|
||||||
|
:root { --bg: #f5f7fb; --card: #ffffff; --ink: #182033; --muted: #69758f; --line: #e2e7f0; --accent: #2251ff; }
|
||||||
|
body { margin: 0; background: var(--bg); color: var(--ink); font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; }
|
||||||
|
header { padding: 32px; color: white; background: linear-gradient(135deg, #14213d, #2251ff); }
|
||||||
|
main { max-width: 1240px; margin: 0 auto; padding: 24px; }
|
||||||
|
h1 { margin: 0 0 8px; font-size: 30px; }
|
||||||
|
h2 { margin: 0 0 14px; font-size: 20px; }
|
||||||
|
.meta { color: rgba(255,255,255,.78); }
|
||||||
|
.grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 16px; }
|
||||||
|
.card { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 18px; box-shadow: 0 8px 24px rgba(28, 39, 69, .06); }
|
||||||
|
.metric { color: var(--muted); font-size: 13px; }
|
||||||
|
.value { margin-top: 8px; font-size: 28px; font-weight: 750; }
|
||||||
|
table { width: 100%; border-collapse: collapse; }
|
||||||
|
th, td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
|
||||||
|
th { background: #eef2ff; color: #27345c; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; }
|
||||||
|
section { margin-bottom: 16px; }
|
||||||
|
.empty { color: var(--muted); margin: 0; }
|
||||||
|
@media (max-width: 860px) { .grid { grid-template-columns: 1fr; } header { padding: 24px; } main { padding: 16px; } }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>Статистика закрытых фич, задач и багов по спринтам</h1>
|
||||||
|
<div class="meta">Проект VDEV · период 2026-01-01 - 2026-06-15 · boards: Continuous Improvement Board, my board, Scope Belta Board, Scope VOKA Board, VDEV DevOps Kanban, актуальные тикеты · сформировано 2026-06-15 23:53</div>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<section class="grid">
|
||||||
|
<div class="card"><div class="metric">Спринтов в периоде</div><div class="value">0</div></div>
|
||||||
|
<div class="card"><div class="metric">Закрытых задач</div><div class="value">0</div></div>
|
||||||
|
<div class="card"><div class="metric">Фактические часы</div><div class="value">0.0</div></div>
|
||||||
|
<div class="card"><div class="metric">Кварталов</div><div class="value">0</div></div>
|
||||||
|
</section>
|
||||||
|
<section class="card"><h2>Итоги по кварталам</h2><p class="empty">Нет данных</p></section>
|
||||||
|
<section class="card"><h2>Разбивка по спринтам</h2><p class="empty">Нет данных</p></section>
|
||||||
|
<section class="card"><h2>Закрытые задачи</h2><p class="empty">Нет закрытых фич/задач/багов</p></section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
"${SCRIPT_DIR}/jira_analyze.py" \
|
||||||
|
--html-sprint-quarter-out "${SCRIPT_DIR}/vdev-sprints-2026.html" \
|
||||||
|
--sprints-from 2026-01-01 \
|
||||||
|
--sprints-to 2026-06-15
|
||||||
Reference in New Issue
Block a user