Как создать конвейер автоматизированных сборок для проекта в Arduino Часть 2/2


Часть 1, Часть 2

Давайте добавим Arduino Zero. Модифицируем часть программы, которая устанавливает ядро AVR, и добавляем другой код:

# Установка ядер Arduino arduino-cli core install arduino:avr arduino-cli core install arduino:samd

Давайте также поменяем код для компиляции наших скетчей:

# Компилируем все файлы с расширениями *.ino для Arduino Uno for f in {,**/}*.ino ; do arduino-cli compile -b arduino:avr:uno $f arduino-cli compile -b arduino:samd:arduino_zero_native $f done

Так вы автоматически проверите код на разных платформах и увидите, появятся ли ошибки.

Если добавить изменения и отправить их в репозиторий на GitHub, а потом перейти на вкладку Actions (Действия), то вы увидите свой новенький рабочий поток и его выходные данные:

При нажатии на название сборки вы увидите что-то подобное:

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

Автоматизированные сборки PlatformIO

Скрипт выше будет работать и для скетчей, и для библиотек Arduino со скетчами-образцами. Он не подходит для проектов PlatformIO. Для проектов такого типа рекомендуется создавать автоматизированные сборки с помощью интерфейса командной строки PlatformIO вместо аналога в Arduino.

С таким подходом вы сделаете непрерывную интеграцию для любого типа проектов из PlatformIO, а не только для проектов из Arduino. И это его самое большое преимущество. В целом этапы схожи. Добавляем шаг в build.yml:

… steps: - name: Checkout uses: actions/[email protected] - name: Build on PlatformIO run: bash ci/build-platformio.sh

Теперь добавляем скрипт оболочки build-platformio.sh:

MyPlatformIOProject ├── .github │ └── workflows │ └── build.yml ├── ci │ └── build-platformio.sh …

А дальше следуем инструкции по установке PlatformIO:

#!/bin/bash # Немедленный выход, если у команды не нулевой статус set -e # Переход в рабочее пространство github cd $GITHUB_WORKSPACE # Устанавливаем PlatformIO CLI export PATH=$PATH:~/.platformio/penv/bin curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -o get-platformio.py python3 get-platformio.py

Теперь устанавливаем платформы для тестирования:

# Устанавливаем платформу Atmel AVR pio platform install "atmelavr"

Если вы корректно настроили platformio.ini, вам осталось пройти всего один шаг:

# Компилируем проект pio run

Как вариант — можно напрямую пойти в окружения, определённые в platformio.ini:

# Компилируем проект для Uno pio run -e uno

Вот и все. Процесс оказался ещё проще, чем при работе с Arduino CLI.

Укрепляем красивый стиль форматирования кода

Инструмент clang-format (CF) помогает проверять код на соответствие определенным правилам стиля форматирования в программах на C или C++.

Стилей программирования много — выбирайте тот, что вам ближе: LLVM, GNU, Google, Mozilla или Microsoft. Вы также можете настроить инструмент проверки CF, чтобы писать код в одном стиле. Просто выберите любой из них, если не можете решить. Наличие одного приоритетного стиля важнее, чем поиск идеального. Всегда можно изменить или переопределить его позже, а всю базу кода просто переформатировать.

Если вы работаете в VSC, вы можете добавить расширение, чтобы форматировать код при каждом сохранении файла. Тогда у вас больше не будет повода волноваться об этом. Все будет автоматизировано. Для других редакторов доступны похожие плагины. Я предлагаю добавлять в проект файл .clang-format:

MyArduinoLibrary ├── .clang-format …

Выберите основной стиль и конфигурируйте его в файле вместе с вашими конфигурационными опциями. Вот как выглядит мой .clang-format:

BasedOnStyle: Google Language: Cpp IndentWidth: 4 AlignConsecutiveMacros: true

Не стесняйтесь изучать остальные возможности clang-format. У этого инструмента есть что предложить.

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

Чтобы этого достичь, создаём новый шаг Check clang-format conformity в файле build.yml. Предлагаю добавить его прямо после шага проверки (Checkout):

… steps: - name: Checkout uses: actions/[email protected] - name: Check clang-format conformity run: bash ci/clang-lint.sh - name: Build on Arduino CLI run: bash ci/build-arduino.sh

Так запускается скрипт оболочки clang-lint.sh. Добавляем в файл несколько строчек для установки clang-format:

#!/bin/bash # Немедленный выход, если у команды не нулевой статус set -e # Включаем опцию оболочки globstar shopt -s globstar # Переходим в рабочее пространство github cd $GITHUB_WORKSPACE # Устанавливаем clang-format sudo apt-get -y install clang-format-10

Теперь делаем цикл по всем исходным файлам с кодом. Проверяем, правильно ли отформатировано их содержимое:

# Проверка вывода clang-format for f in {,**/}*.{h,c,hpp,cpp,ino} ; do if [ -f "$f" ]; then diff $f <(clang-format -assume-filename=main.cpp $f) 1>&2 fi done

Здесь есть одна главная строчка:

diff $f <(clang-format -assume-filename=main.cpp $f) 1>&2

Она запускает работу CF над файлом и сравнивает вывод с текущим содержимым файла. Если они одинаковые, значит файл отформатирован правильно. Если они отличаются, значит цель ещё не достигнута.

Вывод команды diff перенаправляется в stderr, а это значит, что любой вывод считается ошибочным. Если файл отформатирован правильно, у diff не будет вывода и не будет ошибок. Если вывод сборки будет неудачным, то вы увидите неверно форматированные строчки кода.

Очень рекомендую добавлять какой-либо вывод прямо после команды diff, чтобы лучше понимать, какие файлы проверяются. Например, вот так:

echo "Checking file ${f}" diff $f <(clang-format -assume-filename=main.cpp $f) 1>&2

Если вы знаете как обойти скрипты оболочки, то на выходе конвейера сборок вы получите кое-что интересное:

Мысли напоследок

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

Если к конвейеру автоматизированных сборок добавить юнит-тесты, он станет ещё более мощным дополнением при работе над программами. Интеграция и того, и другого в ваш поток — это всего одна команда в скрипте: pio test.

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


Перевод статьи Raphael Stäbler: How to Create an Automated Build Pipeline for Your Arduino Project


Поделиться статьей:


Вернуться к статьям

Комментарии

    Ничего не найдено.