GitHub Actions: знакомство и первые шаги

Мы уже многому научились из предыдущих трех статей цикла публикаций о GIT: создавать локальные репозитории, управлять ими, создавать удаленные репозитории на GitHub, связывать репозитории между собой. Настало время пойти дальше и автоматизировать процесс доставки вашего проекта из GitHub на продакшн сервер.

В этой статье мы начнем с основ — разберемся в том, что такое GitHub Actions и какие концепции в нем присутствуют, познакомимся с понятиями workflow, jobs и steps.

Что такое GitHub Actions?

GitHub Actions — это сервис GitHub, который позволяет автоматизировать, в общем-то, любой процесс связанный с деплоем кода на продакшн сервер. Код проекта выполняется на виртуальных серверах GitHub и далее может быть доставлен туда, куда вам нужно.

GitHub Actions имеет множество готовых решений начиная от уже написанных темплейтов по прогонки тестов, до шаблонов выкладки кода на продакшн. Сам сервис располагается на GitHub в верхней панели инструментов в вашем репозитории:

При первом переходе во вкладку Actions — вам будет предложено выбрать одно из готовых решений или создать workflow самостоятельно. Так как мы знакомимся с этой технологией — выбираем пункт самостоятельного создания workflow. После выбора этого пункта откроется окно редактора:

Здесь нас интересует верхняя строка, указывающая на расположение файла, где прописывается workflow: /.GitHub/workflows/.yml. Почти вся работа над workflow будет происходить в yml файлах, расположенных прямо в вашем репозитории. Нужно создать следующую структуру директорий: в корне проекта создается скрытая директория .GitHub, в ней создается директория workflows и уже в ней располагаются yml файлы с workflow.

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

Понятия GitHub Actions

Workflow — это последовательность выполнения задач или поток выполнения действий. Задачи внутри workflow называется jobs (работы), но обычно их не переводят, а так и называют — джобы. Джобы состоят из шагов (steps), которые содержат основные инструкции для выполнения workflow.

Вся эта многоуровневая конструкция легко и органично отражается в yml файлах. Это мы увидим чуть позже. Workflow обычно выполняет какую-то большую задачу, например, тестирование проекта или его деплой. Workflow может быть множество, они могут выполнять параллельно, а могут последовательно, так же как и джобы.

У Workflow множество опций срабатывания: он может быть вызван автоматически, вручную, может выполняться периодически по расписанию. Опции запуска workflow настраиваются индивидуально. Для начала работы с workflow, информации достаточно. Перейдем к практике и напишем простой тренировочный workflow в онлайн редакторе на GitHub.

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

Первые шаги работы с workflow

Откроем онлайн редактор на GitHub и начнем писать наш первый workflow. Он будет состоять из одной джобы и одного шага. Главное здесь — понять устройство и иерархию элементов workflow.

Вот так будет выглядеть наш учебный workflow:

name: Print workflow #Название workflow
on: workflow_dispatch #Триггер, который будет вызывать workflow

jobs: #Начало секции джобов
  print_hello: #Название джоба
    runs-on: ubuntu-latest #Среда выполнения джоба
    
    steps: #Начало секции шагов
      - name: Print hello #Название шага
        run: echo "Hello world!" #Команда, которая будет выполнена в терминале

В этом workflow можно выделить три логических блока:

  1. Настройки самого workflow:
    • name — название workflow, которое будет отражено в дашборде GitHub;
    • on — условие срабатывания workflow. Сейчас у нас установлено значение workflow_dispatch — ручной запуск workflow. Обычно это значение установлено как push — автоматическое выполнение workflow при загрузке файлов в репозиторий;
  2. Jobs — настройка джобов:
    • print_hello — название джобы. В данном случае — это print_hello;
    • runs-on — инструкция, указывающая на какой ОС запускать джобу. В данном случае джоба будет выполняться на Ubuntu последней версии.
  3. Steps — настройка шагов выполнения джобы:
    • name — название шага;
    • run — действие, которое будет выполнено в терминале Linux. В нашем случае мы вызываем команду echo, которая выводит в терминал «Hello world!».

После написания workflow, его нужно сохранить путем создания коммита, так как по факту мы пишем простой yml-файл, который нужно сохранить в директорию проекта .GitHub/workflows/, чтобы workflow сработал:

Далее возвращаемся во вкладку Actions, которая теперь выглядит по другому:

Теперь слева мы видим список workflow, а в центральной части отражается условие выполнения workflow. В нашем случае, мы указали условию on свойство workflow_dispatch, что означает ручной запуск, именно поэтому у нас есть кнопка запуска workflow. После нажатия на кнопку Run workflow, мы можем переместиться в раздел All workflow и увидеть статус выполнения, запущенного workflow:

Если кликнуть по названию workflow — откроются развернутые сведения о выполненных джобах и шагах. Обратите внимание, на строки выделенные красным квадратом:

На скриншоте выделен шаг с названием Print Hello, командой, которая выполнялась и результатом выполнения этой команды. Напомним, что мы выполняли инструкцию run, которая запускала команду echo «Hello world».

Хорошо, первые шаги сделаны. Усложним немного наш workflow и добавим несколько новых джобов и шагов, а также познакомимся поближе с механизмом выполнения джобов.

Знакомимся с потоком выполнения джобов

Добавим в workflow еще несколько простых джобов, которые также будут выводить информацию в терминал:

name: Print workflow #Название workflow
on: workflow_dispatch #Триггер, который будет вызывать workflow

jobs: #Начало секции джобов

  print_hello: #Начало секции первой джобы
    runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print hello #Название шага
        run: echo "Hello world!" #Команда, которая будет выполнена в терминале

  print_full_technical_info: #Начало секции второй джобы
        runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print full_tech_info #Название шага
        run: sudo lshw #Команда, которая будет выполнена в терминале

  print_short_technical_info: #Начало секции третий джобы
    runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print short_tech_info #Название шага
        run: sudo lshw -short #Команда, которая будет выполнена в терминале

Сохранив изменения, запустив workflow и, перейдя в раздел отражения статусов workflow — мы увидим, что все джобы успешно отработали за 3c.:

Если вы перейдете во внутрь джобы — вы увидите результат работы команд в терминале. Ознакомьтесь с результатом работы команды sudo lshw -short (джоба print_short_technical_info) — команда выводит в терминал сведения о VM, на которой выполняется джоба. По умолчанию джобы выполняются параллельно и независимо друг от друга.

Мы можем управлять поведением выполнения джобов, чтобы выстроить джобы в один общий поток — нужно добавить инструкцию needs: на уровень условий выполнения джобы:

name: Print workflow #Название workflow
on: workflow_dispatch #Триггер, который будет вызывать workflow

jobs: #Начало секции джобов

  print_hello: #Начало секции первой джобы
    runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print hello #Название шага
        run: echo "Hello world!" #Команда, которая будет выполнена в терминале

  print_full_technical_info: #Начало секции второй джобы
       needs: print_hello  
    runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print full_tech_info #Название шага
        run: sudo lshw #Команда, которая будет выполнена в терминале

  print_short_technical_info: #Начало секции третий джобы
    needs: print_full_technical_info   
    runs-on: ubuntu-latest #Среда выполнения джоба
    steps: #Начало секции шагов
      - name: Print short_tech_info #Название шага
        run: sudo lshw -short #Команда, которая будет выполнена в терминале

В дашборде GitHub такой поток связанных задач, будет выглядеть вот так:

Если любая джоба в таком зависимом потоке завершится с ошибкой — другие джобы выполнены не будут. Такие же зависимые цепочки можно выстраивать и с целыми workflow. В зависимом от выполнения другого workflow файле указывается такая конструкция:

name: Release #Наименования текущего workflow
on: #Секция условий выполнения текущего workflow
  workflow_run: #Условия запуска текущего workflow
    workflows: ["Run Tests"] #Workflow, который запускается первым 
    branches: [main] #Ветка, в которой запускается первый workflow
    types: #Тип результата выполнения первого workflow
      - completed #Триггер статуса выполнения первого workflow

Отлично, теперь мы знаем как работает workflow, джобы и шаги. Настало время познакомиться с еще одной концепцией GitHub Action — экшенами.

Экшены

До этого в шагах мы использовали инструкцию run для вызова Linux команд. Однако в рамках шагов можно использовать готовые модули или решения, написанные другими пользователями для выполнения каких-то типовых задач. Такие готовые решения в GitHub называются actions или экшены. Они распространяются бесплатно и находятся в GitHub Marketplace.

Покажем на реальном примере, как искать и использовать экшены. Одна из распространенных задач — это загрузка репозитория на VM. По умолчанию у виртуальных машин GitHub нет доступа к репозиторию — его нужно разрешить. Для этого используют готовый экшен: actions/checkout@v3. Вызываются экшены через инструкцию uses.

Переходим в маркетплейс и вводим в поиск checkout. Мы получили список доступных экшенов с совпадением по искомой фразе:

Обратите внимание, что экшены могут быть разработаны и опубликованы как профессиональными командами разработчиков, например, первый экшен написан самой командой разработчиков экшенов, а другие разработаны пользователями. При клике по нужному вам экшену — откроется страница с информацией о нем:

Вначале дается справочная информация, а затем примеры применения. Как видно из примера, экшены используются с инструкцией uses. В коде такая конструкция может выглядеть так:

name: Print workflow
on: workflow_dispatch

jobs:
  checkout:
    runs-on: ubuntu-latest
    steps:
      - name: checkout_repo
        uses: actions/checkout@v3

Вообще в GitHub Marketplace есть огромное количество разнообразных экшенов на все случаи жизни. Вот, например, наша задача доставить код нашего проекта на VPS. Для этой задачи также существует готовое решение. Мы изучили много нового материала — время подвести промежуточный итог.

О GitHub Actions и его концепциях в двух словах

GitHub Actions — это сервис автоматизации тестирования и доставки кода на продакшен. Пайплайн доставки кода, в терминологии GitHub — workflow, описывается в yml-файле и размещается непосредственно в рабочем репозитории в директории .GitHub/workflows/[work flow name].yml.

На уровне workflow определяется название workflow и триггер — условие, при котором будет срабатывать workflow. В коде эта инструкция выглядит так:

name: test_workflow #Название workflow
on: push #Триггер исполнения workflow. В данном случае workflow будет вызван автоматически при загрузке или обновления кода в репозитории.

Workflow состоит из jobs (джобы) — это логический уровень задачи. На уровне jobs определяется ОС, в среде которой будет выполняться задача и определяются шаги, которые содержат команды — инструкция run или экшены — инструкция uses. В коде это может выглядеть так:

name: print hello and checkout repo workflow
on: push

jobs:

  print_hello:
    runs-on: ubuntu-latest
    steps:
      - name: Print hello
        run: echo "Hello world!"

  checkout_repo:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

По умолчанию джобы и workflow выполняются параллельно на разных VM GitHub. Этим поведением можно управлять и выстраивать цепочки. Для последовательного и связанного выполнения джобов, в зависимых джобах используется инструкция needs: [waiting job]. Вот пример связанных джобов:

jobs:

  print_hello:
    runs-on: ubuntu-latest
    steps:
      - name: Print hello
        run: echo "Hello world!"

  checkout_repo:
    needs: print_hellow
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v3

Теперь мы умеем писать простые workflow, состоящие из несложных джобов. В следующей статье ма познакомимся еще с несколькими важными концепциями GitHub Actions: переменные, контексты и секреты, а после будем деплоить проект на VPS.

Перед прочтением следующей статьи, мы рекомендуем ознакомиться с предыдущими материалами:

Git: установка, настройка, инициализация репозитория

Разбираемся с основами git: устанавливаем git на Linux, создаем репозиторий и делаем первые коммиты.

Git: коммиты, ветки и перемещение между ними

Рассматриваем подробно работу с коммитами, ветками и перемещением между ними.

Git: работа с GitHub

Уходим в облака: знакомимся с gitHub и делаем первые шаги на пути к облачному хранению репозиториев. Вы узнаете, как загружать локальные репозитории в github и, как синхронизировать удаленные и локальные репозитории.