Привет! Меня зовут Дмитрий Круцких, я Flutter-тимлид в компании Surf. Сегодня расскажу, как написать простейший GitHub Action, используя язык программирования Dart.
GitHub Actions — сервис автоматизации рабочих процессов, или CI/CD. Настроенный CI/CD приносит проектам ряд бенефитов. Например, мы можем переложить на плечи автоматики:
проверку статическим анализатором изменений, вносимых в кодовую базу,
валидацию стиля написания кода,
запуск всех видов автоматического тестирования.
Эта статья пригодится тем, кто пишет на Dart, уже работает с GitHub Actions, но столкнулся с проблемой: в GitHub Marketplace нет необходимой функциональности.
Расскажу, как на языке Dart написать собственный скрипт для GitHub Actions. Благодаря этому вам не нужно будет переключаться с языка на язык, чтобы настраивать CI/CD: просто берите привычный вам Dart и делайте всё на нём.
GitHub Actions: пошаговая схема создания
Для начала освежим теорию.
Actions — отдельные команды, самый маленький кирпичик в процессе автоматизации. Actions можно повторно использовать в разных проектах. Они могут быть трех видов:
составной список действий (по сути это простой переиспользуемый набор действий),
Job складывается из Actions. В общем случае jobs не зависят друг от друга и могут запускаться параллельно на нескольких машинах. При необходимости между ними можно определить зависимости.
Workflow (рабочий процесс) формируется из одной или нескольких job.
Всё это описывается в yaml-файле который располагается в папке .github/workflows репозитория.
Рассмотрим простейший файл, описывающий процесс автоматизации:
name: Dart Code Metrics
on: [push] # запускаем при каждой выгрузке в репозиторий
jobs:
check:
name: dart-code-metrics-action
runs-on: ubuntu-latest
steps:
# скачиваем исходники воспользовавшись actions/checkout
- uses: actions/checkout@v2
# запускаем dart-code-metrics-action передав ему GitHub токен
- name: dart-code-metrics
uses: dart-code-checker/dart-code-metrics-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
Наша цель — написать тот самый Action, кирпичик, который можно встроить в виде шага в подобный рабочий процесс.
Реализация действия
Мы будем запускать наш код в виртуальной машине Dart, поэтому нам подойдет вариант с докер-контейнером.
Проект нашего action будет иметь примерно такую структуру:
.
action_app
bin
main.dart
pubspec.yaml
action.yaml
Dockerfile
README.md
Код действия располагается в файле main.dart. Простейший action выглядит примерно так:
import 'dart:io';
import 'package:github_actions_toolkit/github_actions_toolkit.dart';
void main(List<String> arguments) async {
try {
// `name` input defined in `action.yaml` file
final name = Input('name', isRequired: true, canBeEmpty: false);
log.info('Hello ${name.value} !');
} catch (error) {
log.error(error.toString());
exitCode = 1;
}
}
Точкой входа, как и во всех приложения командной строки на Dart, является функция main. Тело функции необходимо обернуть в блок try-catch, чтобы в случае ошибок сборка в GitHub прерывалась (иначе она всегда будет считаться успешной).
Мы воспользовались пакетом github_action_toolkit для чтения параметров и вывода сообщения в лог.
В корне репозитория создадим action.yaml
name: Hello
description: Greet someone
inputs:
name: # id of input
description: Who to greet
required: true
default: "World"
runs:
using: "docker"
image: "Dockerfile"
Файл action.yaml содержит метаданные: по его наличию GitHub понимает, что в папке расположен код действия, которое можно загрузить и выполнить. Указываем, что действие основано на докер-контейнере, и даём точку входа: файл Dockerfile.
Также в action.yaml указывается набор входных и выходных параметров. В нашем случае мы ожидаем, что в действие передадут имя для приветствия. Более подробную информацию по возможностям файла метаданных смотрите в документации.
Добавляем Dockerfile:
FROM google/dart:latest
COPY action_app/ /action_app/
RUN cd /action_app \
&& pub get \
&& dart run /action_app/bin/main.dart
Файл содержит команды докеру. За основу берем публичный образ от Google с самой свежей версией языка Dart. Далее копируем код действия, который расположен в папке action_app. Вызываем команду получения зависимостей, которые требуются для работы приложения. В завершение запускаем код приложения, точка входа которого находится в main.dart.
Результат работы нашего примера
Полезные ссылки
Github_actions_toolkit — Dart-пакет для удобной работы с логированием, получением входных аргументов Inputs и публикацией результатов Outputs.
Dart Code Metrics Action — action для запуска статического анализатора для языка Dart.
«Используем бесплатные возможности Github Actions для CI/CD на Flutter-проекте» — гайд по GitHub Actions от моего коллеги по Surf Евгения Сатурова.
Surf Gear — опенсорсный репозиторий Surf. Либы, стандарты, тулзы и прочие полезности, которые мы используем для разработки на Flutter.
Больше полезного про Flutter — в телеграм-канале Surf Flutter Team. Публикуем кейсы, лучшие практики, новости и вакансии Surf, а также проводим прямые эфиры. Присоединяйтесь!