GitHub Actions: избавление от рутины

После обилия теории пора потренироваться в настройке GitHub Actions. Сделать это можно, настроив workflow для совсем простенького приложения.
Фреймворк Flask для этого подойдёт.

Почему вдруг Flask?

Flask — популярный фреймворк для проектов на Python, но, в отличие от Django, этот микрофреймворк при установке выглядит гораздо проще и компактнее. За компактность надо платить: в стартовой конфигурации Flask гораздо менее функционален, чем Django. После установки у Flask нет базы данных и ORM для работы с ней, нет системы форм, нет админки — нет почти ничего, что по умолчанию встроено в Django.
При развёртывании Flask будет установлено основное программное ядро, система обработки запросов, консольное приложение (подобное manage.py в Django), сервер разработчика и ещё несколько базовых вещей. Всё остальное устанавливает разработчик исходя из потребностей. В результате работа с Flask будет несколько сложнее, но настроить его можно гораздо гибче, и он больше приспособлен для нестандартных проектов.

Пишем проект за семь минут

Сейчас ваша задача — поработать с GitHub Actions, а не с проектом. Для такой тренировки лучше взять простое лёгкое приложение, потому наш выбор — Flask.
Не будем слишком требовательны к тестовому проекту: пусть в ответ на запрос к корневому URL он просто возвращает фразу «У меня получилось!».
Создайте на GitHub новый репозиторий с именем flask-app, клонируйте его себе на локальный компьютер и перейдите в него, дальнейшие команды нужно выполнять в репозитории.
Создайте и активируйте виртуальное окружение, установите в него фреймворк Flask:
Скопировать кодBASH
python3 -m venv flask_env && . flask_env/bin/activate pip install flask
Готово: установлен Flask и все необходимые зависимости.
Добавьте в корневую директорию файл hello.py с таким кодом:
Скопировать кодPYTHON
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'У меня получилось!' if __name__ == '__main__': app.run(debug=True, host='0.0.0.0')
В первых строках в код импортируется класс Flask из пакета flask и создаётся экземпляр этого класса. С помощью магического метода __name__ в конструктор этого класса передаётся имя файла hello.py. Таким образом, теперь экземпляр app — это наше приложение.
В следующей строке на app навешивается декоратор @app.route, он связывает URL главной страницы '/' с функцией hello_world(), точно как path() в Джанго. А функция hello_world() возвращает строку «У меня получилось!».
Проект готов! Всегда бы так.

Подключение репозитория к GitHub Actions

Для подключения GitHub Actions нужно в репозитории проекта создать папку .github/workflows и сохранить в ней yaml-файл с инструкциями. Можно создать директорию и файл вручную, а можно нажать ссылку в веб-интерфейсе GitHub — и GitHub всё сделает сам.
В файле .yaml декларативно описывается workflow, процесс автоматизации — пошаговые команды и условия их выполнения. Синтаксис этого описания очень похож на Docker.
В директории .github/workflows можно создать несколько файлов .yaml (или .yml) и описать в них разные workflow. Названия этих файлов могут быть любыми, но лучше давать осмысленные имена.

Настройка workflow через GitHub

Зайдите в свой репозиторий на GitHub и перейдите во вкладку Actions:
image
Нажмите ссылку set up a workflow yourself: будет создана директория .github/workflows с шаблоном main.yml. В этом файле вы опишете workflow для нового проекта.
Workflow — это набор команд, которые выполнятся в виртуальном окружении после того, как произойдёт какое-то событие-триггер (например, когда разработчик запушит код в репозиторий).
Комментарии в файлах .yml обозначаются символом решётки в начале строки, как и в Python. Отступами обозначается иерархия кода, вложенность элементов.
GitHub Actions создал предварительно заполненный шаблон:
image

Workflow

Любой workflow должен содержать, как минимум, имя name, ивент on (событие-триггер, после которого сработает workflow) и jobs — список действий, которые выполняются после срабатывания события on.
На верхнем уровне указан ключ name со значением CI — это название вашего workflow.

Ключ 'on': спусковой крючок для запуска workflow

Ключ on описывает триггер — событие, которое должно произойти, чтобы workflow начал выполняться. В шаблоне указан ивент push — это событие git push, а branches — это ветка, в которую он должен быть сделан, чтобы workflow запустился; можно указать и несколько веток. Workflow, описаный в шаблоне, сработает при пуше в ветку master.
В том же блоке on описан второй триггер: пулл-реквест в ветку мастер. В отличие от push, триггер на pull request сработает когда кто-то сделает запрос за изменение кода в ветке master. В этом случае, например, можно проверить, что предполагаемые изменения не содержат синтаксических ошибок и код написан по PEP8, а так же проходит все тесты, но не деплоить его.
В роли триггеров могут выступать и другие события, подробно о них можно почитать в документации GitHub Actions.

Ключ 'jobs': список заданий для workflow

Ключ jobs объединяет поименованные блоки команд, задачи, которые будут выполняться при запуске workflow. Таких блоков может быть несколько, например — build, tests, deploy, happyend.
Каждая задача-job описывается набором параметров.
Ключ name — это имя задачи.
Каждый job запускается в изолированном окружении, которое создаёт сервис GitHub Actions. Настройки окружения определяются в ключе runs-on. Это аналогично инструкции FROM в Dockerfile, там это называлось «базовый образ», а в терминологии GitHub Actions это называется «раннер» (runner). В шаблоне указана последняя версия Ubuntu.
Посмотрите, какие можно установить варианты окружения: поставьте курсор после ключа runs-on и нажмите Control+Space: система подсказок покажет вам доступные варианты. Эта комбинация клавиш применима ко всем ключам. Полезная штука.
Под ключом steps записывается перечень шагов, команд, которые будут выполнены на этом шаге. Начало каждого шага обозначается символом -.
Каждому шагу можно дать имя name, оно описывает смысл шага. В ключе run хранится команда, которая будет выполнена в терминале окружения.
Вместо run можно применять uses — для вызова actions. Actions — это скрипты, которые можно написать заранее и вызывать по имени из разных workflow. Про actions можно почитать здесь: https://docs.github.com/en/actions/creating-actions/about-actions#types-of-actions .

Добавление директории workflow в Git

Сделайте коммит, чтобы директория .github/workflows попала в Git. Нажмите зеленую кнопку Start commit справа-вверху, дайте имя коммиту и нажмите Commit new file:
image

Запуск workflow

Чтобы запустить workflow из примера — надо сделать push в master, тогда сработает инструкция on — и jobs начнут выполняться.
Создайте файл requirements.txt и укажите там единственную зависимость: flask. Можно создать этот файл через консоль:
Скопировать кодBASH
pip freeze > requirements.txt
Выполните команду git push. Файл requirements.txt запушился в Git, и workflow должен был сработать.
В интерфейсе GitHub перейдите во вкладку Actions:
image
Нажмите на результат выполнения workflow, он назван именем вашего коммита. В левой панели — название вашего workflow и вложенные в него jobs. Клик по названию откроет результаты выполнения задания.
image
Все steps успешно выполнились, всё работает.
В следующем уроке вы напишете собственный workflow для тестового Flask-приложения.