Работа с файлами, артефактами и отпечатками

Рейтинг: 64.6% · 12 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Работа с файлами, артефактами и отпечатками

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками (вы здесь)
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Сборка прошла зелёным, на экране build 393 - и через минуту рабочая папка агента вычищена. Бинарь, который ты только что собрал, исчез. А тебе он нужен: отдать на деплой, скачать руками, прогнать на тесте. Или другая боль - стейдж "Build" собрал jar на одном агенте, а стейдж "Test" поднялся на другом, и там этого jar нет вообще, ведь у каждого агента своя файловая система. В этом уроке разберём, как Jenkins работает с файлами внутри пайплайна, как сохранять результаты сборки наружу и как по отпечатку находить, где именно твой артефакт был использован.

Файлы внутри сборки: рабочая директория и шаги чтения/записи

Каждый jenkins build живёт в своём workspace - рабочей директории на агенте. Туда клонируется код, туда падают результаты компиляции. Пока сборка идёт, ты можешь читать и писать файлы прямо из пайплайна, не вызывая голый shell.

Базовый набор шагов:
  • readFile - прочитать файл в строку
  • writeFile - записать строку в файл
  • fileExists - проверить, что файл есть (вернёт true/false)

Код: Выделить всё

pipeline {
    agent any
    stages {
        stage('Prepare') {
            steps {
                script {
                    // записываем номер сборки в файл
                    writeFile file: 'build-info.txt',
                              text: "build ${env.BUILD_NUMBER}\n"

                    // читаем обратно
                    def info = readFile('build-info.txt').trim()
                    echo "Прочитали: ${info}"

                    if (fileExists('pom.xml')) {
                        echo 'Это maven-проект'
                    }
                }
            }
        }
    }
}
Эти шаги выполняются на агенте и читают именно его файловую систему. Запомни главное ограничение: workspace - вещь временная. Между сборками он может быть очищен, а при работе на эфемерных pod-агентах в Kubernetes исчезает вместе с подом сразу после прогона. Поэтому всё, что должно пережить сборку, надо явно сохранить.

Изображение

stash и unstash: передача файлов между стейджами и агентами

Самая частая засада многоагентных пайплайнов: собрал на одном, тестируешь на другом, а файлов нет. Решение - jenkins stash. Шаг stash упаковывает выбранные файлы в архив и складывает его на контроллере. Потом на любом другом агенте шаг unstash распаковывает их обратно в workspace.

Код: Выделить всё

pipeline {
    agent none
    stages {
        stage('Build') {
            agent { label 'maven' }
            steps {
                sh 'mvn -B clean package'
                // прячем собранный jar для следующих стейджей
                stash name: 'app-jar', includes: 'target/*.jar'
            }
        }
        stage('Test') {
            agent { label 'tester' }
            steps {
                // достаём jar на другом агенте
                unstash 'app-jar'
                sh 'java -jar target/app.jar --selftest'
            }
        }
    }
}
Здесь

Код: Выделить всё

agent none
на уровне pipeline означает, что глобального агента нет, и каждый стейдж выбирает свой через

Код: Выделить всё

agent { label ... }
. stash переносит jar между ними прозрачно.

У stash есть параметры

Код: Выделить всё

includes
и

Код: Выделить всё

excludes
(Ant-glob, как везде в Jenkins). Имя в обязательно - именно по нему unstash находит архив.

Важные грабли: stash едет через контроллер и хранится у него в памяти/на диске. Это не транспорт для гигабайтных артефактов. Держи стэши маленькими - конфиги, один-два бинаря, отчёты. Тяжёлые сборки (целые node_modules, докер-слои) гоняй через внешнее хранилище или registry, а не через stash. По умолчанию стэши удаляются в конце сборки. Если хочешь, чтобы при рестарте отдельного стейджа они были доступны, включи опцию:

Код: Выделить всё

options {
    preserveStashes(buildCount: 5)
}
archiveArtifacts и junit: сохраняем результаты наружу

stash живёт внутри одной сборки. А что отдать наружу, чтобы скачать через UI или забрать на деплой? Для этого есть jenkins artifacts и шаг archiveArtifacts. Он копирует файлы из workspace в постоянное хранилище сборки на контроллере, и они доступны на странице build 393 как ссылки для скачивания - переживают очистку workspace.

Код: Выделить всё

stage('Archive') {
    steps {
        archiveArtifacts artifacts: 'target/*.jar',
                         fingerprint: true,
                         onlyIfSuccessful: true
    }
}
Разбор параметров jenkins archiveartifacts:
  • artifacts - glob-маска файлов (можно несколько через запятую)
  • fingerprint: true - снять отпечаток (об этом ниже)
  • onlyIfSuccessful: true - архивировать только если сборка успешна
  • allowEmptyArchive: true - не падать, если по маске ничего не нашлось
  • excludes - что исключить из маски
Отдельная история - результаты тестов. Для них есть специальный шаг junit: он парсит XML-отчёты в формате JUnit (Surefire, pytest-junit, любой совместимый), строит графики трендов и помечает упавшие тесты прямо в UI.

Код: Выделить всё

stage('Test') {
    steps {
        sh 'mvn -B test'
    }
    post {
        always {
            junit testResults: '**/target/surefire-reports/*.xml',
                  allowEmptyResults: true
        }
    }
}
junit ставят в

Код: Выделить всё

post { always { ... } }
, чтобы отчёт собрался даже когда тесты упали - иначе при падении шаг до публикации просто не дойдёт. Параметр

Код: Выделить всё

allowEmptyResults: true
спасает, когда отчётов может не быть.

Отпечатки (fingerprints): где использован мой артефакт

Теперь самое недооценённое - jenkins fingerprint. Отпечаток это MD5-хэш файла, который Jenkins запоминает вместе со ссылкой, в какой сборке и какого job этот файл появлялся или использовался. Включив

Код: Выделить всё

fingerprint: true
при архивации, ты потом можешь открыть артефакт и увидеть всю его трассировку: вот сборка А его произвела, вот сборки Б и В его подтянули.

Зачем это на практике. Представь, что job "library" собирает common.jar, а пять других job'ов его потребляют. Прилетел баг. По отпечатку common.jar ты мгновенно видишь, какие именно сборки и каких версий тянули проблемный файл, и кого надо пересобрать. Без отпечатков пришлось бы вручную сопоставлять версии по логам.

Снять отпечаток можно не только при архивации, но и отдельным шагом:

Код: Выделить всё

fingerprint 'target/*.jar'
Чтобы трассировка была сквозной, отпечаток снимают и у производителя (через archiveArtifacts с fingerprint: true), и у потребителя (шагом fingerprint после того как файл оказался в workspace). Тогда на странице "See fingerprints" выстроится полная цепочка использования между job'ами.

Очистка и передача дальше по пайплайну

Workspace надо подчищать, особенно на долгоживущих статических агентах, где мусор копится между сборками. Простой способ - плагин Workspace Cleanup и шаг

Код: Выделить всё

cleanWs()
:

Код: Выделить всё

post {
    always {
        cleanWs()
    }
}
На эфемерных pod-агентах в Kubernetes отдельная очистка обычно не нужна: под умирает после прогона и уносит workspace с собой. Это, кстати, аргумент в пользу таких агентов - меньше борьбы с грязным окружением.

Передача артефакта дальше по конвейеру - это связка из уже разобранного. Внутри одной сборки гоняй файлы через stash/unstash. Наружу и в следующие job'ы (например, отдельный pipeline деплоя через

Код: Выделить всё

build job: 'deploy', ...
) отдавай через archiveArtifacts с отпечатком - дочерний job скачает артефакт по Copy Artifact или прямой ссылке и снимет свой fingerprint. Для тяжёлых бинарей в 2026 норма - не Jenkins, а внешний artifact-репозиторий (Nexus, Artifactory) или OCI-registry, а Jenkins лишь дирижирует.

Для сравнения: в GitLab CI ту же роль играют

Код: Выделить всё

artifacts:
и в .gitlab-ci.yml, а в GitHub Actions -

Код: Выделить всё

actions/upload-artifact
и

Код: Выделить всё

download-artifact
. Идея одна и та же, разнятся только синтаксис и место хранения.

Типичные грабли
  • Гоняешь сотни мегабайт через stash и удивляешься, что контроллер тормозит. stash - для мелочи, не для тяжёлых сборок.
  • archiveArtifacts без

    Код: Выделить всё

    allowEmptyArchive
    валит сборку, когда маска ничего не нашла (опечатка в пути к target).
  • junit вне

    Код: Выделить всё

    post { always }
    - при падении тестов отчёт не публикуется, и в UI пусто.
  • Забыл

    Код: Выделить всё

    fingerprint: true
    и потом не можешь понять, какая сборка тянула битый jar.
  • Ждёшь файлы на втором агенте без unstash - их там нет, у каждого агента свой workspace.
  • Путаешь stash и archiveArtifacts: первый живёт внутри сборки, второй сохраняется наружу надолго.
Мини-лаба

Собери пайплайн с

Код: Выделить всё

agent none
и тремя стейджами:
  • Build на одном агенте: создай

    Код: Выделить всё

    writeFile
    файл version.txt с

    Код: Выделить всё

    env.BUILD_NUMBER
    , собери любой jar (или просто

    Код: Выделить всё

    sh 'echo test > app.jar'
    ), сделай stash обоих файлов.
  • Test на другом агенте: unstash, проверь

    Код: Выделить всё

    fileExists('app.jar')
    , прочитай version.txt через readFile.
  • Archive: archiveArtifacts с

    Код: Выделить всё

    fingerprint: true
    , добавь junit с фейковым XML-отчётом в post.
Прогони, открой страницу сборки, скачай артефакт, найди ссылку "See fingerprints" и убедись, что отпечаток снят.

Контрольные вопросы
  • Чем stash принципиально отличается от archiveArtifacts и когда какой использовать?
  • Почему шаг junit ставят в блок post { always }, а не просто после тестов?
  • Что даёт параметр fingerprint: true и какую задачу решают отпечатки между разными job?
  • Почему передавать гигабайтные бинари через stash - плохая идея, и чем заменить?
Итог

Файлы в Jenkins живут в workspace и по умолчанию недолговечны. readFile/writeFile/fileExists работают с ними внутри стейджа, stash/unstash переносят между агентами в рамках сборки, archiveArtifacts сохраняет результаты наружу, junit публикует тесты, а fingerprint даёт сквозную трассировку артефакта по всем job. Освой эту связку - и build 393 перестанет терять твои бинари, а ты всегда будешь знать, где какой артефакт всплыл.
👍3 ❤️3 🔥1 😄 🤔1
Аватара пользователя
SparkUser
Сообщения: 1
Зарегистрирован: 27 май 2026, 01:08

Re: Работа с файлами, артефактами и отпечатками

Сообщение SparkUser »

Вот про junit в post always прям спасибо, у меня отчёты не публиковались когда тесты падали и я неделю не мог понять почему UI пустой. Оказалось ставил шаг просто после sh.
👍1 ❤️ 🔥1 😄 🤔2
Аватара пользователя
wasmadmin
Сообщения: 1
Зарегистрирован: 04 июн 2026, 07:14

Re: Работа с файлами, артефактами и отпечатками

Сообщение wasmadmin »

А есть разница между fingerprint: true в archiveArtifacts и отдельным шагом fingerprint? Я так понял первое для того кто произвёл файл, второе для того кто потребил, чтобы цепочка между джобами сошлась?
👍1 ❤️2 🔥 😄 🤔
Ответить
← Предыдущая глава
Переменные среды, withEnv и рабочие пространства
Следующая глава →
Сборка проектов в конвейере: Maven, Gradle, npm

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость