reports/src/jira_export.php

143 lines
5.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

global$config; #!/usr/bin/env php
<?php
/**
* @var array $config
* @var array $teams
* @var string[] $holidays
*/
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Nechaev\Reports\StatusHelper;
require __DIR__ . '/../init.php';
require __DIR__ . '/functions.php';
// --- 1. Обработка параметров командной строки ---
$options = getopt('', ['start-date:', 'end-date:']);
if (empty($options['start-date']) || empty($options['end-date'])) {
echo "Использование: php jira_export.php --start-date=ГГГГ-ММ-ДД --end-date=ГГГГ-ММ-ДД\n";
exit(1);
}
$startDate = $options['start-date'];
$endDate = $options['end-date'];
// Валидация формата дат
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $startDate) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $endDate)) {
die("Ошибка: даты должны быть в формате ГГГГ-ММ-ДД\n");
}
// Извлекаем настройки из конфига
$jiraUrl = $config['jira']['url'];
$apiToken = $config['jira']['apiToken'];
$maxResults = $config['export']['maxResults'];
// --- 2. Инициализация клиента Guzzle ---
$client = new Client([
'base_uri' => $jiraUrl,
'headers' => [
'Authorization' => 'Bearer ' . $apiToken,
'Accept' => 'application/json',
],
]);
foreach ($teams as $team => $teamData) {
echo "Расчет для команды {$team}\n";
$filename = "{$team}_tasks_{$startDate}_to_{$endDate}.csv";
// --- 3. Подготовка JQL-запроса ---
// Запрос ищет задачи, у которых статус изменился на "Done" в указанный период.
$jql = "project in (".$teamData['projects'].") AND issuetype in standardIssueTypes() AND issuetype not in (Epic, \"Admin work\") AND resolutiondate > \"{$startDate}\" AND resolutiondate < \"{$endDate}\"";
$params = [
'jql' => $jql,
'maxResults' => $maxResults,
'fields' => 'issuetype,key,summary,assignee,resolution,aggregatetimeoriginalestimate,aggregateprogress,resolutiondate',
];
try {
// --- 4. Обработка пагинации ---
// Если задач больше, чем maxResults, Jira вернет только часть.
// Мы будем запрашивать страницы до тех пор, пока не получим все.
$allIssues = [];
$startAt = 0;
$totalFetched = 0;
do {
$response = $client->get('rest/api/2/search', [
'query' => $params + ['startAt' => $startAt]
]);
$data = json_decode($response->getBody(), true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception("Ошибка декодирования JSON-ответа от Jira.");
}
$issues = $data['issues'] ?? [];
$allIssues = array_merge($allIssues, $issues);
// Обновляем счетчики для следующей итерации
$totalFetched += count($issues);
$startAt += count($issues);
echo "Получено задач: {$totalFetched} из {$data['total']}\n";
} while ($startAt < ($data['total'] ?? 0));
if (!empty($allIssues)) {
// Убираем дубликаты, там где изменения не требуются
$allIssues = filterByResolution($allIssues);
// Убираем задачи, исполнители на которых не исполнители
$allIssues = filterByExecutors($allIssues, array_keys($teamData['executors']));
//file_put_contents($filename.".json", json_encode($allIssues, JSON_PRETTY_PRINT));die();
echo "Убрали лишнее, осталось ".count($allIssues)."\n";
$task = null;
foreach ($allIssues as $i => $issue) {
$statuses = getStatusForIssue($issue['key'], $client);
//$allIssues[$i]['countStatuses'] = $statuses;
$firstDateInStatus = array_map(function($value) {
return is_array($value) && count($value) > 1 ? $value[1] : null;
}, $statuses);
$countStatus = array_map(function($value) {
return is_array($value) && count($value) > 1 ? $value[0] : null;
}, $statuses);
$task = new \Nechaev\Reports\Task(
$issue["fields"]["issuetype"]["name"],
$issue['key'],
$issue["fields"]["summary"],
$issue["fields"]["assignee"]["name"],
$issue["fields"]["aggregatetimeoriginalestimate"],
$issue["fields"]["aggregateprogress"]["progress"],
StatusHelper::getDataByStatus($firstDateInStatus, StatusHelper::getInWorkStatuses()),
$issue["fields"]["resolutiondate"],
StatusHelper::getDataByStatus($countStatus, StatusHelper::getInReviewStatuses()),
StatusHelper::getDataByStatus($countStatus, StatusHelper::getInTestingStatuses()),
);
file_put_contents($filename, $task, FILE_APPEND | LOCK_EX);
}
// --- 5. Сохранение в файл ---
echo "Данные успешно сохранены в файл: {$filename}\n";
} else {
echo "За указанный период завершенных задач не найдено.\n";
}
} catch (GuzzleException | Exception $e) {
echo "Ошибка: " . $e->getMessage() . "\n";
}
}