Важная часть профессионального программирования — это конвейеры автоматизации сборок. Вы, конечно, можете считать несерьезным свое увлечение проектами на Arduino. Но давайте представим, что вы создаёте библиотеку Arduino для других пользователей. Может быть, это даже целый проект с открытым кодом, который рано или поздно станет полезным целому сообществу.
Конвейер автоматизации сборок выступает как непрерывная интеграция. Так вы гарантируете определенный уровень качества своего проекта. Открою два ответа на вопрос о том, как именно вам поможет непрерывная интеграция:
Первый пункт особенно помогает проектам Arduino, когда нужна гарантия совместимости с целым набором разных микроконтроллеров. Второй станет важным для вас, как только вы расширите свою команду и пригласите одного и более товарищей. Жизнь каждого в команде станет намного проще, если у вас будет понятный стиль программирования на всем проекте. И это еще не все — непрерывная интеграция может намного больше, в том числе:
Последнее касается того, что обычно документация нечасто обновляется надлежащим образом. Вы можете создать лучшую библиотеку, но если вы не собираетесь её описать, люди, скорее всего, не станут ею пользоваться.
Ваш проект на Arduino — это всего лишь папка со скетчем Arduino внутри:
MyArduinoProject
└── MyArduinoProject.ino
Если вам достаточно малого, то непрерывная интеграция и не нужна. Тем не менее от экспериментов с ней хуже не будет. Если вы хотите перейти на продвинутый уровень, подумайте над настройкой проекта на PlatformIO.
Среда PlatformIO хорошо интегрируется с Visual Studio Code и стала отличной альтернативой окружению Arduino IDE. В неё встроена поддержка многих микроконтроллеров и вы даже сможете выйти за границы экосистемы Arduino, но это уже отдельная тема. Стандартный проект в PlatformIO состоит из двух частей:
MyPlatformIOProject
├── platformio.ini
└── src
└── main.cpp
Тем не менее вы не ограничены этими файлами, это только начальная точка. По мере продвижения проект может вырасти во что-то большее, чем только два файла. И это уже определённо вариант для применения непрерывной интеграции.
Может быть, вы работаете не только над личным проектом, а над целой библиотекой Arduino, чтобы потом поделиться результатами в сообществе. В таком случае непрерывная интеграция — отличный вариант. Стандартная библиотека в Arduino, скорее всего, будет выглядеть так:
MyArduinoLibrary
├── examples
│ └── HelloWorld
│ └── HelloWorld.ino
├── library.properties
└── src
├── MyArduinoLibrary.cpp
└── MyArduinoLibrary.h
У вас есть минимум: один заглавный файл, один файл имплементации, а также один или больше скетчей Arduino.
А потом вы захотите убедиться, что ваша библиотека совместима с максимальным количеством плат Arduino. И вот тут конвейер автоматизированной сборки действительно пригодится.
Дальше я буду предполагать, что ваш проект хранится в системе контроля версий git и опубликован на GitHub. Если вы еще не публиковали там ничего, я очень рекомендую этот сервис для всех ваших проектов в программировании.
В нашем случае GitHub подходит потому, что мы собираемся пользоваться его рабочими процессами, которые позволяют создавать конвейерные сборки без дополнительных внешних сервисов. Похожим образом можно работать и на других платформах, например GitLab, или используя инструменты непрерывной интеграции, такие как Travis или CircleCI. Я советую вам посмотреть все возможности, чтобы найти те, которые вам подойдут. Я остановился на GitHub.
Применяя рабочие процессы GitHub, мы будем работать с виртуальной машиной последней версии Ubuntu и выполнять стек предварительно определенных задач, когда бы ни вносились изменения в код. Звучит ошеломительно. И пока будут происходить интересные события, мы будем собирать кусочки шаг за шагом.
Виртуальная машина работает на серверах GitHub. Всё, что нам нужно сделать, — создать конфигурационный файл внутри директории проекта .github/workflows
. Давайте назовем его build.yml
:
MyArduinoLibrary
├── .github
│ └── workflows
│ └── build.yml
…
У файла будет такое содержимое:
name: build
on: [pull_request, push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/[email protected]
В нём есть параметр имени name
— он может быть любым от самого короткого build
и до изощренного My awesome automated build
. Я возьму вариант попроще. Команда on: [pull_request, push]
говорит GitHub выполнять этот процесс всякий раз, когда происходит добавление обновлений в репозиторий или создается новый запрос на добавление изменений. Есть и другие события, а также сложносоставные триггеры, но это другой разговор.
Весь написанный нами процесс происходит на последней Ubuntu, и выполняется проверка кода. Последний шаг важен, потому что код должен попасть в рабочий поток.
После проверки добавим еще один шаг в build.yml
:
…
steps:
- name: Checkout
uses: actions/[email protected]
- name: Build on Arduino CLI
run: bash ci/build-arduino.sh
Этот шаг называется Build on Arduino CLI
, и он запускает скрипт оболочки ci/build-arduino.sh
. А теперь мы создадим такой файл в папке проекта:
MyArduinoLibrary
├── .github
│ └── workflows
│ └── build.yml
├── ci
│ └── build-arduino.sh
…
Этот скрипт установит Arduino CLI на нашу виртуальную машину и скомпилирует код для нескольких плат Arduino. Если компиляция падает, автоматизированный конвейер сборок тоже ломается. А если компиляция проходит успешно, это значит, что код корректен для всех протестированных платформ Arduino.
Для установки Arduino CLI мы будем следовать гайду:
#!/bin/bash
# Немедленный выход, если у команды не нулевой статус
set -e
# Включает опцию оболочки globstar
shopt -s globstar
# Переход в рабочее пространство github
cd $GITHUB_WORKSPACE
# Создаем директории
mkdir $HOME/Arduino
mkdir $HOME/Arduino/libraries
# Устанавливаем Arduino IDE
export PATH=$PATH:$GITHUB_WORKSPACE/bin
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
arduino-cli config init
arduino-cli core update-index
Добавляем ядро Arduino AVR:
# Установка ядра Arduino AVR
arduino-cli core install arduino:avr
До компиляции кода осталось немного. Если ваш проект — это библиотека, вам надо сначала подключить ее к директории библиотек Arduino. Иначе компилятор не сможет найти ваш код.
# Подключаем библиотеку Arduino
ln -s $GITHUB_WORKSPACE $HOME/Arduino/libraries/CI_Test_Library
А теперь компилируем скетчи для ядра AVR. Компиляция для Uno:
# Компилируем все файлы с расширением *.ino для Arduino Uno
for f in {,**/}*.ino ; do
arduino-cli compile -b arduino:avr:uno $f
done
Вот и всё. С этой установкой можно создать конвейер сборок, который автоматически компилирует все Arduino Sketches для Arduino Uno по каждому пакету изменений или запросу на их проверку в репозитории на GitHub.
Добавлять другие платформы очень просто, ведь вам всего-то нужно скопировать и изменить код, который устанавливает новые ядра и компилирует ваш проект.
Продолжение следует…
Перевод статьи Raphael Stäbler: How to Create an Automated Build Pipeline for Your Arduino Project
Комментарии