Технологии

Публикация Allure-отчетов в условиях ограниченности CI/CD

Привет! Меня зовут Николай, я SDET‑разработчик в тестировании в SimbirSoft. В своей статье хочу поделиться опытом публикации Allure‑отчётов, рассказать о плюсах, минусах и подводных камнях различных подходов. Эта статья подойдет QA‑ и DevOps‑специалистам, которые столкнулись с проблемой публикации Allure‑отчетов из‑за ограничений используемой на проекте CI/CD‑системы. Для полного понимания материала нужны базовые навыки установки ПО на Linux, общее представление о том, что такое Allure и как он работает, понимание принципов работы артефактов сборок в CI/CD‑системе, а также базовые знания о контейнеризации с помощью Docker. Введение Казалось бы, публикация Allure‑отчёта в 2025 году — задача из разряда «ну что тут вообще может пойти не так?». Большинство CI/CD‑инструментов уже умеют работать с отчётами — либо «из коробки», либо через плагины. Но что, если ваш CI/CD не поддерживает публикацию Allure‑отчётов? Или, например, вы используете только GitLab? Разберём, какие есть варианты решения. Для начала создадим простой базовый пайплайн, на котором потом будем экспериментировать: image: maven:3.9.6-eclipse-temurin-22 # Образ с Java + Maven stages: - compile - test - report - pages default: tags: - docker compile_code: # Сборка проекта stage: compile script: - mvn compile run_test: # Запуск тестов stage: test script: - mvn test artifacts: paths: - target/allure-results # Сохраняем файлы Allure как артефакты when: always expire_in: 7 days allow_failure: true Gitlab Pages Поговорим о том, как использовать встроенный в GitLab функционал Pages. Он позволяет публиковать статические сайты прямо на своём домене — просто через пайплайн. Чтобы проверить, включён ли Pages, загляните в панель администратора → Features. Если опция выключена, нужно немного подправить конфигурацию. Откройте файл gitlab.rb и найдите строки, отвечающие за активацию Pages — pages_external_url и gitlab_pages['enable']. Закомментированные строки раскомментируйте и задайте им нужные значения: pages_external_url — укажите URL вашего GitLab; gitlab_pages['enable'] — поменяйте значение с false на true. После этого Pages заработает, и можно переходить к настройке деплоя: Сохраняем изменения и запускаем реконфигурацию GitLab: sudo gitlab‑ctl reconfigure Пока система обновляется, можно заняться DNS. Добавьте A‑запись для вашего домена — без неё Pages не сможет корректно опубликовать сайт. Особенность GitLab Pages в том, что при запуске статичных сайтов он создаёт поддомен с названием текущей группы или пользователя (подробнее об этом можно почитать здесь). Например, если ваш GitLab доступен по адресу gitlab.example.com, то сайт с отчётом Allure будет развёрнут по адресу ИМЯ_ГРУППЫ.gitlab.example.com. Настроить DNS можно самостоятельно или передать это DevOps‑инженеру. После этого проверяем, что всё работает. Для этого создадим простой пайплайн: он запустит автотесты, сгенерирует отчёт и передаст его в папку public — именно её Pages использует по умолчанию для сборки сайта. generate_report: # Создание отчета Allure stage: report script: - mvn allure:report artifacts: paths: - target/allure-report when: always expire_in: 30 days pages: # Публикация отчета через Pages stage: pages script: - mkdir public - cp -r target/allure-report/* public/ artifacts: paths: - public expire_in: 30 days После чего в разделе Deploy→Pages можно увидеть ссылку на активную страницу Allure‑отчета. Поздравляю — теперь мы можем публиковать наши отчёты, используя функционал GitLab Pages. Удобно, просто и наглядно. Но, как это часто бывает, у простоты есть обратная сторона. Если сравнить такой подход с полноценными решениями CI/CD, которые умеют публиковать Allure‑отчёты «по‑взрослому», мы сразу заметим главный недостаток — отсутствие истории прогонов. Сейчас при каждом запуске автотестов мы создаём новую веб‑страницу с отчётом, и предыдущие результаты остаются за кадром. То есть история не хранится, и динамику по проекту отследить невозможно. Решить проблему можно двумя способами. Первый, более «в лоб», вариант — использовать git внутри контейнера и после каждой сборки пушить отчёты в отдельный репозиторий. Далее из него отчёты подтягиваются в job'ы Pages. Метод рабочий, но, скажем честно, изящным его не назовёшь. Надёжность, удобство и безопасность такого подхода вызывают вопросы, а количество потенциальных точек отказа явно выше, чем хотелось бы. Второй способ — аккуратнее и технологичнее. Мы можем использовать Job Artifacts API и при помощи curl скачивать артефакты из job'ы, которая генерирует файлы отчёта после последней сборки пайплайна. Для этого понадобится выполнить два подготовительных шага. Первое — создать personal access token с правами read_api. Сделать это просто: переходим в Preferences → Access Tokens, нажимаем Add new token, заполняем поля, ставим галочку напротив read_api и создаём токен. После этого останется лишь корректно прописать запрос — и отчёты начнут подтягиваться автоматически, без лишних телодвижений и костылей. Дальше копируем токен — сделать это нужно сразу, потом он больше не отобразится. Теперь переходим в проект с автотестами: Settings → CI/CD → Variables. Создаём новую переменную API_TOKEN и обязательно ставим чекбоксы для сокрытия значений в логах — всё‑таки токен содержит чувствительные данные. Теперь добавим к нашему пайплайну новую job'у — она и будет работать с артефактами через API. download_artifacts: # Скачиваем артефакты через GitLab Artifacts API stage: artifact script: - 'curl --location --output artifacts.zip --header "PRIVATE-TOKEN: $ API_TOKEN " " https://ССЫЛКА_НА_ВАШ_GITLAB/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/main/download?job=generate_report "' - unzip artifacts.zip - cp -r target/allure-report/history target/allure-results artifacts: paths: - target/allure-results when: always expire_in: 7 days allow_failure: true dependencies: - run_test Работает это довольно просто. В заголовке curl‑запроса мы передаём поле PRIVATE‑TOKEN: $API_TOKEN, в котором хранится наш access token. Дальше с его помощью скачиваем zip‑архив с артефактами — то есть с Allure‑отчётом — из предыдущего запуска пайплайна с нужной job'ой. После этого распаковываем архив и копируем папку history в артефакты текущего прогона. Всё — теперь в Pages у тебя будут не просто отчёты «на сейчас», а полноценная история с трендами и динамикой по проекту. Если коротко про плюсы и минусы: Плюсы: Не нужно внедрять дополнительные технологии или инструменты в окружение проекта. Всё работает средствами GitLab. Минусы: Есть нюансы с публикацией отчётов по разным веткам. Для этого придётся немного поиграться с настройками Pages и, возможно, завести отдельные поддомены. Со временем архив с историей будет расти, поэтому стоит заранее продумать автоматическую очистку, чтобы не тратить место впустую. В целом — решение не идеальное, но рабочее и вполне аккуратное. Особенно если хочется сохранить историю Allure без тяжёлых костылей и внешних сервисов. Allure Server Allure Server — это готовое решение для публикации отчётов автотестов, которое работает на базе Docker. По сути, он берёт на себя всё, что обычно приходится делать вручную: публикует отчёты, сохраняет историю и автоматически её чистит. Удобно, надёжно и без танцев с Pages. Чтобы начать работу, достаточно скачать и развернуть образ Allure Server. Делается это в пару шагов — просто выполняешь команды: docker pull kochetkovma/allure‑server:2.13.9 docker run ‑p 8081:8080 ‑d ‑rm ‑name allure‑server ‑v /allure‑server‑data:/allure kochetkovma/allure‑server:2.13.9 В команде docker run необходимо в параметры передать порт, на котором будет доступен сервер и путь, по которому будут сохранятся отчеты. После чего по адресу«IP_сервера:ПОРТ/ui» будет доступен наш Allure-сервер и его интерфейс. На главной странице Allure Server ты увидишь список отчётов и удобную навигацию по разделам. Интерфейс здесь довольно дружелюбный — можно вручную загрузить results или готовые reports, сгенерировать отчёт на основе загруженных данных, а при необходимости удалить лишние результаты, чтобы не засорять хранилище. Дальше загляни в раздел Swagger — там собраны все доступные методы API. Нас в первую очередь интересуют два из них: /api/results и /api/report. Первый отвечает за загрузку результатов, второй — за генерацию отчёта. Скопируй их и добавь в новую job'у, которая будет отправлять результаты и запускать сборку отчёта автоматически. Так мы избавимся от ручных действий и получим полностью автоматизированный процесс публикации отчётов. allure_report: # Отправка results на Allure server stage: send_report before_script: - apt-get update && apt-get install -y zip jq - zip -r -j allure-result.zip target/allure-results/* script: # Загружаем results на сервер Allure и получаем UUID - | export RESPONSE=$(curl -X POST 'ССЫЛКА_НА_ВАШ_СЕРВЕР/api/result' \ -H "accept: /" \ -H "Content-Type: multipart/form-data" \ -F " allureResults=@allure-result.zip ;type=application/x-zip-compressed") # Создаем отчет на основе полученного UUID - | curl --location --request POST 'ССЫЛКА_НА_ВАШ_СЕРВЕР/api/report' \ -H "Content-Type: application/json" \ --data-raw "{ \"reportSpec\": { \"path\": [ \"${CI_PROJECT_NAME}\", \"${TEST_INTG_GROUP}\" ], \"executorInfo\": { \"buildName\": \"${CI_JOB_URL}\" } }, \"results\": [\"${UUID}\" ], \"deleteResults\": true }" | jq '.latest' dependencies: - run_test Первый запрос отвечает за отправку results, ответом на который будет сообщение следующего вида: [ { "uuid": "string", "size": ”number”, "created": "date" } ] Из ответа сервера нам нужно вытащить значение uuid — оно понадобится для второго запроса, который запускает генерацию отчёта. В теле этого запроса стоит заполнить поля json реальными данными, например, подставив системные переменные из GitLab CI. После того как пайплайн отработает, можно перейти на главную страницу сервера — в разделе Reports появится свежий отчёт. Всё просто и наглядно. Теперь коротко про плюсы и минусы. Плюсы: — Настраивается быстро, запускается ещё быстрее. — Не требует дополнительных преобразований — достаточно отправить zip‑архив с results, и сервер сделает всё сам. Минусы: — Не лучший вариант, если над автотестами работают несколько команд: все отчёты будут отображаться на одной главной странице. — Без дополнительной защиты доступ к серверу может получить любой, кто знает его адрес — этот момент точно стоит продумать заранее. В остальном решение лёгкое в развёртывании и отлично подходит для небольших команд или внутренних проектов, где важна простота и скорость. Allure–docker–service Если говорить о Allure‑docker‑service, то он представляет гораздо больший функционал в отличие от Allure Server. Сам сервис представляет из себя два контейнера, связанных между собой, поэтому запускать такое проще через compose. version: '3' services: allure: image: "frankescobar/allure-docker-service" environment: CHECK_RESULTS_EVERY_SECONDS: 3 KEEP_HISTORY: 1 ports: - "3000:5050" volumes: - ${PWD}/allure-results:/app/allure-results - ${PWD}/allure-reports:/app/default-reports healthcheck: test: ["CMD", "curl", "-f", " http://IP_АДРЕС_СЕРВЕРА:5050 "] interval: 30s timeout: 10s retries: 5 allure-ui: image: "frankescobar/allure-docker-service-ui" environment: ALLURE_DOCKER_PUBLIC_API_URL: "http:// IP_АДРЕС_СЕРВЕРА:5050" ports: - "5252:5252" depends_on: allure: condition: service_healthy Важно помнить: контейнер с UI нужно запускать только после того, как поднимется основной сервис. Иначе вместо красивого интерфейса ты увидишь ошибку. Чтобы этого избежать, укажи зависимость через depends_on — это гарантирует правильный порядок запуска. В параметрах первого сервиса задай порт, на котором он будет работать, и пути для хранения файлов. Для второго — порт и адрес основного сервиса, чтобы они могли «общаться» между собой. Если всё настроено корректно, то при переходе по адресу первого сервиса тебя встретит страница Swagger, а по адресу второго — уже знакомый UI‑интерфейс Allure Server. Всё просто, если не спешить и следовать шагам по порядку. Как и в случае с Allure Server, здесь тоже можно загрузить отчёт вручную. Но есть и приятные бонусы, например, возможность выгрузить готовый отчёт в формате HTML и отправить его по почте. Удобно, когда нужно быстро поделиться результатами без доступа к серверу. Однако есть одно отличие: этот сервис не принимает zip‑архив с результатами напрямую. Вместо этого данные нужно передавать в теле запроса в формате JSON. Структура у него следующая: { "results": [ { "file_name": "example1", "content_base64": "Y29udGVudCBleGFtcGxlMQ==" }, { "file_name": "example2", "content_base64": "Y29udGVudCBleGFtcGxlMg==" }, { "file_name": "example3", "content_base64": "Y29udGVudCBleGFtcGxlMw==" } ] } Поле results — это массив, где каждый элемент содержит два значения: file_name и content_base64. Первое — это имя файла, второе — его содержимое, закодированное в base64. Чтобы сформировать корректный JSON, нужно подготовить скрипт, который пройдётся по файлам и соберёт эти данные в нужном формате. Автор исходного решения использовал для этого небольшой скрипт на Python, но мы пойдём чуть дальше — напишем этот скрипт прямо в нашем пайплайне. Так всё будет происходить автоматически, без лишних ручных шагов. send_allure_results: stage: report script: - | # Установка необходимых пакетов apt-get update && apt-get install -y jq # Переход в директорию с результатами cd target/allure-results || exit # Генерация списка файлов files=$(ls -1F | grep -v '/') # Исключаем директории # Подготовим временный файл для JSON temp_json="$(mktemp)" # Собираем Json масив array='[]' for file in $files; do # Кодируем файл в base64 encoded_content=$(base64 "$file") # Создаем новый элемент массива new_element="{ \"file_name\": \"$file\", \"content_base64\": \"$encoded_content\"}" # Добавляем элемент в массив array=$(jq ". += [$new_element]" <<< "$array") done # Готовим финальный JSON final_json=$(jq '. |= { "results": . }' <<< "$array") echo "$final_json" > "$temp_json" # Сохраняем JSON в файл # Отпрака запроса на сервер curl -v \ -H "Content-Type: application/json" \ --data-binary "@$temp_json" \ dependencies: - run_test allow_failure: true В параметрах запроса передаётся id проекта — туда и отправятся результаты автотестов. Дополнительно указываем force_project_creation=true на случай, если проекта для отчётов ещё не существует. После выполнения запроса можно перейти на страницу отчёта в сервисе — и там уже будет готовая визуализация результатов. Всё настроено, всё работает, можно смотреть статистику и делиться ссылкой с командой. Плюсы: Можно повысить безопасность за счёт добавления аккаунтов и ролей. Удобный интерфейс: легко переключаться между разными отчётами. Хорошо подходит для больших команд. Расширенный функционал — всё под рукой. Минусы: Настройка и запуск посложнее, чем у других решений. Требуется отдельный скрипт для формирования JSON с results. Заключение Если подвести итог, то у каждого подхода есть своя логика и область применения. GitLab Pages подойдёт, когда хочется обойтись без внедрения новых технологий в проект. Но нужно быть готовым: чтобы добиться хотя бы части возможностей официальных интеграций Allure, придётся немало поработать с пайплайнами. Allure Server — отличный выбор, если нужен отчёт «здесь и сейчас». Он лёгок в настройке и использовании, но в плане безопасности и масштабируемости есть ограничения, особенно для больших команд. Allure Docker Service — самое близкое к полноценной интеграции Allure‑решение. Он гибкий, функциональный и подходит для серьёзных проектов, хотя и требует немного больше внимания при настройке. Главное — выбрать инструмент под свои задачи, а не под описание в документации. Тогда и отчёты будут радовать, и настройка не станет головной болью. Спасибо за внимание! Больше авторских материалов для SDET‑специалистов от моих коллег читайте в соцсетях SimbirSoft — ВКонтакте и Telegram.

Фильтры и сортировка