← CI/CD: практика
12 мин · просто · Урок 4 из 10

Артефакты: передать файлы между стадиями

Почему файл из build не виден в test и как artifacts решают эту проблему. Собираем папку public и забираем её из следующей стадии.

Проблема чистого контейнера

Каждый job стартует в свежем контейнере: раннер поднимает образ, клонирует репозиторий на нужный коммит, выполняет команды и гасит всё обратно. Соседний job получит такой же новый контейнер и такой же чистый клон.

Отсюда следствие, на которое натыкаются все: файл, созданный в build, в test не существует. Дело не в правах и не в путях: файла физически нет, контейнер другой.

Проверьте на своём проекте:

stages:
  - build
  - test

build-site:
  stage: build
  script:
    - mkdir -p public
    - cp index.html style.css public/

check-build:
  stage: test
  script:
    - test -f public/index.html

build пройдёт, test упадёт: public/index.html в его контейнере нет.

artifacts

Артефакт — это файлы, которые GitLab забирает из контейнера после job и хранит у себя. Следующие стадии получают их автоматически, распакованными в рабочую папку.

build-site:
  stage: build
  script:
    - mkdir -p public
    - cp index.html style.css public/
  artifacts:
    paths:
      - public

Одна секция, и test зеленеет: в его контейнере появилась папка public, приехавшая из предыдущей стадии.

В paths перечисляют файлы и папки. Пути считаются от корня репозитория, поддерживаются маски вроде dist/*.js.

Скачать артефакт руками

Артефакты доступны и человеку. На странице пайплайна справа кнопка Download artifacts, у каждого job своя. Внутри zip с тем, что перечислено в paths.

Это первое, куда стоит лезть при разборе «на CI собралось не то»: скачали артефакт, посмотрели, что в нём реально лежит.

Артефакты не бесплатны

Они занимают место в хранилище проекта, а на бесплатном тарифе оно ограничено. Поэтому у артефактов есть срок жизни:

  artifacts:
    paths:
      - public
    expire_in: 1 hour

По умолчанию на GitLab.com артефакты живут 30 дней. В учебном проекте ставьте expire_in: 1 hour: файлы доедут до следующей стадии и не будут копиться месяц.

Одно исключение стоит знать: артефакты последнего успешного пайплайна на каждой ветке хранятся всегда, независимо от expire_in. Так что последняя зелёная сборка у вас останется в любом случае.

Отчёты вместо файлов

У artifacts есть второй режим, reports. Это те же файлы, но GitLab понимает их формат и рисует результат в интерфейсе:

  artifacts:
    reports:
      junit: report.xml

Так тесты показываются вкладкой с падениями в merge request, а не строкой в логе. Для нашего сайта это не нужно, но полезно знать, что artifacts умеет отдавать данные прямо в интерфейс.

Что важно запомнить

Каждый job получает свой чистый контейнер, файлы между стадиями сами не передаются.

artifacts.paths забирает файлы после job и раздаёт их следующим стадиям.

Артефакт можно скачать zip-архивом со страницы пайплайна. Это главный инструмент разбора «а что там собралось».

expire_in ограничивает срок хранения и бережёт место в проекте.

Дальше финал: превращаем папку public в сайт по своему адресу.

Прошли материал до конца? Отметьте урок пройденным.