Сборка артефакта

GitBeginner
Практиковаться сейчас

Введение

В предыдущей лабораторной работе вы узнали о «контроле качества» (CI). Теперь перейдём к следующему этапу: упаковке.

Представьте программное обеспечение как продукт на фабрике. После прохождения всех проверок качества его нужно положить в коробку, запечатать и промаркировать, прежде чем отправить заказчикам. В мире программного обеспечения такой «коробкой» часто служит Docker-контейнер.

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

Именно воспроизводимость является ключевой идеей. При развёртывании нужно использовать известный результат сборки, а не заново собирать код по-разному на каждой целевой машине.

GitHub предоставляет реестр под названием GitHub Container Registry (GHCR).

В этой лабораторной работе вы научите своего робота-помощника:

  • Упаковывать приложение в Docker-контейнер.
  • Помечать его тегом версии.
  • Отправлять (push) его на склад GitHub автоматически.

Предварительные требования

Мы продолжим использовать репозиторий github-actions-basics.

Создайте Dockerfile

Прежде чем робот сможет упаковать приложение, ему нужны инструкции. В Docker эти инструкции записывают в специальный файл Dockerfile.

Перейдите в каталог проекта.

cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics

Примечание: замените your-username своим именем пользователя GitHub.

Создайте файл с именем Dockerfile (с прописной буквы D и без расширения) со следующим содержимым.

cat > Dockerfile << EOF
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
EOF

Вот что именно этот список инструкций велит роботу сделать:

  • FROM node:16-alpine: начать с лёгкой базовой системы, в которой уже установлен Node.js;
  • WORKDIR /app: создать рабочую папку внутри контейнера;
  • COPY ...: скопировать файлы проекта в контейнер;
  • RUN npm install: установить необходимые зависимости внутри контейнера;
  • CMD ...: при запуске контейнера запустить приложение.

Теперь добавьте этот файл в репозиторий и отправьте изменения на GitHub.

git add Dockerfile
git commit -m "Add Dockerfile"
git push

Создайте рабочий процесс публикации

Теперь создадим новый рабочий процесс для упаковки и отправки приложения. Назовём его docker-publish.yml.

Создайте файл:

touch .github/workflows/docker-publish.yml

Откройте его в nano.

nano .github/workflows/docker-publish.yml

Добавьте следующую конфигурацию. Здесь мы вводим новое понятие — permissions (разрешения).

name: Docker Publish

on:
  push:
    branches: ["master", "main"]

permissions:
  contents: read
  packages: write

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

Зачем нужны разрешения?

По умолчанию робот имеет ограниченный доступ из соображений безопасности. Поскольку мы хотим, чтобы робот загружал данные в вашу учётную запись GitHub (в раздел «packages»), ему нужно явно предоставить ключ от склада. Именно это делает параметр packages: write.

Это хороший пример принципа минимально необходимых привилегий при проектировании конвейера. Рабочие процессы должны получать только те разрешения, которые нужны для выполняемой задачи.

Сохраните файл и выйдите из nano (Ctrl+X, Y, Enter).

Добавьте этапы сборки и отправки

Теперь проверим самую важную часть — сборку и отправку образа.

Мы воспользуемся двумя официальными инструментами Docker (actions):

  1. docker/login-action: для входа в склад;
  2. docker/build-push-action: для сборки контейнера и его отправки.

Этот этап соединяет CI и доставку. После успешного прохождения тестов конвейер создаёт версионированный артефакт, который другие системы смогут развернуть позже без повторной сборки из исходного кода.

Снова откройте .github/workflows/docker-publish.yml.

nano .github/workflows/docker-publish.yml

Добавьте следующие этапы в задание build-and-push:

- name: Log in to the Container registry
  uses: docker/login-action@v2
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
  uses: docker/build-push-action@v4
  with:
    context: .
    push: true
    tags: ghcr.io/${{ github.repository }}/app:latest

Разберём специальные переменные:

  • ghcr.io: адрес «склада» GitHub;
  • ${{ github.actor }}: переменная, которая автоматически подставляет ваше имя пользователя GitHub;
  • ${{ secrets.GITHUB_TOKEN }}: специальный временный пароль, который GitHub создаёт для робота. Вам ничего не нужно делать — всё работает автоматически. Этот токен позволяет роботу безопасно войти в систему без ручного ввода пароля;
  • tags: метка для контейнера. Она имеет формат: Адрес склада / Ваше имя / Имя репозитория / Имя приложения : Версия.

Сохраните файл и выйдите из nano.

Теперь отправьте этот рабочий процесс на GitHub, чтобы запустить процесс.

git add .
git commit -m "Add Docker publishing workflow"
git push

Проверьте артефакт

Теперь ваш робот усердно работает: настраивает сервер, входит в систему, собирает контейнер и отправляет его.

  1. Откройте свой репозиторий на GitHub.
  2. Перейдите на вкладку Actions.
  3. Нажмите запуск рабочего процесса «Docker Publish».
  4. Дождитесь, пока этапы станут зелёными.

Docker Publish

После успешного завершения этапа «Build and push Docker image» ваш пакет окажется на складе. Давайте найдём его.

  1. Перейдите на главную страницу репозитория, на вкладку Code.
  2. Посмотрите на боковую панель справа. Вы должны увидеть раздел Packages.
  3. В этом разделе появится новый пакет.

Нажмите имя пакета, чтобы просмотреть его сведения. Это готовый артефакт. Любой пользователь с доступом к вашему репозиторию (или любой пользователь, если репозиторий общедоступен) теперь сможет скачать и запустить ваше приложение с помощью этого образа.

GitHub Packages

Итоги

В этой лабораторной работе вы создали полный конвейер доставки.

Вы научились:

  • Упаковке: создавать Dockerfile, чтобы помещать приложение в контейнер;
  • Разрешениям: предоставлять рабочему процессу доступ на запись в раздел packages;
  • Хранению: использовать GitHub Container Registry (GHCR) для хранения образов;
  • Автоматизации: автоматически собирать и отправлять код с помощью стандартных actions.

Теперь ваш робот-помощник умеет проверять код (CI) и отправлять код в виде артефактов. В следующей лабораторной работе мы рассмотрим безопасную работу с конфиденциальной информацией, например паролями.