GitHub запускает свои щупальца в CI/CD и менеджмент артефактов

    В мае 2019 года GitHub анонсировала выход сервиса Package Registry. Вслед за этим, уже в августе, была анонсирована поддержка CI/CD в Actions.


    В статье я расскажу, что это за сервисы и как это можно использовать на примере небольшого пет-проекта на GitHub.



    Что это за сервисы такие?


    GitHub Actions это платформа которая позволяет управлять жизненным циклом ПО, исходный код которого размещен на GitHub. По факту, TravisCI, CircleCI и многие другие бесплатные CI/CD платформы получили нового конкурента в лице Actions.


    GitHub Package Registry является центральным репозиторием артефактов, в данный момент существует поддержка пяти различных типов артефактов.


    Поддерживаемые типы артефактов в Actions


    Поддержка в Actions Аналог Язык
    NPM-пакеты https://www.npmjs.com/ Javascript
    Docker-образы https://hub.docker.com/ -
    Maven-артефакты https://mvnrepository.com/ Java
    NuGet-пакеты https://www.nuget.org/ .NET
    Ruby-гемы https://rubygems.org/ Ruby

    Это удобная возможность иметь все артефакты в одном месте, ведь не всегда целесообразно разворачивать свой сервер Nexus или Artifactory.


    GitHub все больше становится похожим на GitLab, а где-то даже уже и превзошел оппонента, например в GitLab пока еще нет поддержки NuGet-пакетов и Ruby-гемов. По факту, если раньше для опенсорс проектов приходилось подключать внешние интеграции к GitHub, то сейчас все яйца в одной корзине. Тут уж пусть каждый сам решает хорошо это или плохо, но как минимум это удобно.


    Как попробовать?


    В данный момент оба сервиса находятся в бета-режиме, зарегистрироваться в бета-тесте можно на этих страницах.


    Миграция с других сервисов очень простая, я мигрировал несколько своих пет-проектов с TravisCI и DockerHub на Actions и Package Registry соответственно.


    Покажу как это выглядит на одном из примеров. Проект самый обычный, я писал о нем в этой статье. Ничего сверхсложного, обычный LaTeX-код, с помощью которого собираются артефакты (2 PDF файла), они публикуются в релизах GitHub. Для того чтобы не скачивать кучу LaTeX-пакетов я написал Dockerfile, чтобы можно было удобно работать из-под любой ОС.


    Package Registry


    Для того чтобы начать работать с Package Registry вместо DockerHub нужно сделать всего два простых шага.
    Создаем токен в настройках GitHub (у токена должны быть права на запись и чтение артефактов).



    Страница создания токена


    И далее можем аутентифицироваться с созданным токеном и пушить артефакты, вот так все просто:


    docker login docker.pkg.github.com --username amet13
    docker tag docker-latex:0.0.1 docker.pkg.github.com/amet13/master-thesis/docker-latex:0.0.1
    docker push docker.pkg.github.com/amet13/master-thesis/docker-latex:0.0.1

    Обратите внимание, я специально указал свой никнейм на GitHub в нижнем регистре, иначе вы получите ошибку от Docker:


    Error parsing reference: "docker.pkg.github.com/Amet13/master-thesis/docker-latex:0.0.1" is not a valid repository/tag: invalid reference format: repository name must be lowercase

    А вот как это выглядит в веб-интерфейсе GitHub:



    Страница Package Registry для Docker-образов


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


    Actions


    С Actions немного посложнее, но тем кто когда-либо работал с любой другой CI/CD системой не составит труда разобраться. Конфигурация в Actions описывается декларативным YAML, хотя до этого использовался HCL.


    Немного базовых понятий (я намеренно не буду переводить определения, по-моему тут итак все ясно):


    • Workflow — процесс который управляем жизненным циклом ПО (build, test, package, release, deploy) для репозитория
    • Workflow file — файл в котором описывается Workflow, находится он в корне репозитория в каталоге .github/workflows/
    • Job — это каждый запуск Workflow, Job запускаются по триггеру, в один момент времени может быть запущено много Job
    • Step — в каждой Job есть Step, на каждом Step можно запускать команды или Actions
    • Action — заранее написанный кем-либо "плагин", список многих Actions можно найти в репозитории awesome-actions
    • Virtual environment — окружение на котором работает Job (по факту это виртуальная машина на Windows, macOS или Linux)
    • Runner — это развернутое окружение для запуска Job, в один момент времени на Runner может работать только один Job
    • Event — событие которое запускает Workflow, например Push, Pull Request, Webhook, Cron-джоба и т.д.
    • Artifact — артефакты (бинарники, изображения, логи и т.д.)


    Так выглядит страница со списком Job в Workflow


    Ограничения и запреты:


    • 20 Workflows на один репозиторий
    • 1000 API-запросов в час для всех Actions в репозитории
    • максимальное время работы Job — 6 часов
    • параллельно может работать 20 Jobs в репозитории (для всех Workflow)
    • запрещено использовать Actions для майнинга криптовалют и serverless-вычислений

    Самая актуальная документация доступна по этой ссылке.



    А вот так выглядят логи одной из Job


    Пример


    Вернемся к примеру, вот как выглядит мой конфиг, разберем его подробнее по частям.


    Указываем имя для Workflow и описываем на какой триггер он должен срабатывать (список всех триггеров описан в документации):


    name: master-thesis
    on: [push]

    На каком Virtual Environment запускаем Job:


    jobs:
      build:
        # ubuntu-latest, ubuntu-18.04, or ubuntu-16.04
        # windows-latest, windows-2019, or windows-2016
        # macOS-latest or macOS-10.14
        runs-on: ubuntu-latest

    Первый шаг, в name: указываем название Step'а (не обязательно), а в uses: какой Action хотим использовать, в данном случае клонировать репозиторий:


        steps:
        - name: Checkout repo
          uses: actions/checkout@v1

    На следующем шаге мы не используем Action, а только набор своих команд где логинимся в Package Registry, собираем Docker-образ и пушим его в репозиторий образов. В блоке env: задаем переменные окружения, одну из них берем из секретов:


        - name: Build docker image and push it to the registry
          env:
            GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
            DOCKER_IMAGE_ORIGIN: "docker.pkg.github.com/amet13/master-thesis/docker-latex"
    
          run: |
    
            # Pull submodules
            git submodule init
            git submodule update --remote
    
            # Login to GitHub Packages and build Docker image
            docker login docker.pkg.github.com -u amet13 -p ${GITHUB_TOKEN}
            docker pull ${DOCKER_IMAGE_ORIGIN}:latest
            docker build -t ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} .
    
            # Generate PDF artifacts
            docker run --rm -i \
              -v ${PWD}:/master-thesis:Z ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} \
              bash -c "latexmk -xelatex -synctex=1 -jobname=master-thesis main.tex"
            docker run --rm -i \
              -v ${PWD}:/master-thesis:Z ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} \
              bash -c "cd presentation/ && latexmk -xelatex -synctex=1 -jobname=presentation main.tex"
    
            # Publish Docker image to GitHub Packages (with latest tag)
            docker tag ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA} ${DOCKER_IMAGE_ORIGIN}:latest
            docker push ${DOCKER_IMAGE_ORIGIN}:${GITHUB_SHA}
            docker push ${DOCKER_IMAGE_ORIGIN}:latest

    Уверен, что в ближайшем будущем уже появится Action который позволит автоматически тегировать и пушить образы вместо ручного прописывания команд Docker.



    Добавление секрета содержащего GitHub-токен


    Следующим шагом после сборки PDF-файлов необходимо создать релиз на GitHub и включить в этот релиз собранные артефакты. Для автоматического создания релиза используем сторонний Action, в котором в блоке if: можно указать условие запуска шага — только при создании тега:


        - name: Create GitHub release with artifacts
          uses: softprops/action-gh-release@v1
          if: startsWith(github.ref, 'refs/tags/')
          with:
            files: |
              master-thesis.pdf
              presentation/presentation.pdf
            name: "Build ${GITHUB_SHA}"
          env:
            GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

    Итоги


    Несмотря на бета-статус, оба сервиса работают хорошо, уверен что допилят много вещей.
    В некоторых моментах бывает неудобно, глобальных переменных нет, но это обходится костылями.


    Мне понравился подход GitHub к отказу от HCL в пользу YAML. Также понравилась поддержка многих типов хостов, вполне щадящие лимиты (пока что), посмотрим как оно будет дальше. В целом, для несложных пайплайнов в публичных репозиториях на GitHub, такая связка подойдет очень хорошо.


    Перевод этой статьи уже на medium.

    • +50
    • 10.8k
    • 4
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 4

      +2
      Добротно написано, премного благодарен
        0
        Я поигрался — мне не зашло. ИМХО, GitHub перемудрил сам себя. Могли просто повторить функциональность Travis CI + добавить какие-то плюшки — и было бы то, что нужно.
          0
          Неактивно пользую Circle CI (Travis CI как-то не зашел) и пока мигрировать не планирую. Посмотрю как оно будет развиваться… продукт то теперь мелкософтовский — подспудно ожидаю каких-то подлянок, но это личное…
            0
            Мне понравился подход GitHub к отказу от HCL в пользу YAML.

            steps:
              - name: Set up NodeJS
                uses: actions/setup-node@v1
              - name: Checkout sources
                uses: actions/checkout@v1

            Ну такое себе, списки в ямле совсем ненаглядные — все пункты сливаются в единое полотно.


            Эх, а как бы это выглядело в tree:


            step
                name \Set up NodeJS
                uses \actions/setup-node@v1
            step
                name \Checkout sources
                uses \actions/checkout@v1

            Only users with full accounts can post comments. Log in, please.