Про CI/CD

Прочитал студентам проповедь про CI/CD в embedded, поделюсь и тут:

Как учат нас всякие нормативные документы — возьмем, например «авиационный» стандарт DO-178B или в русском переводе — КТ-178B — «интеграция» — это процесс, в рамках которого «исполняемый код загружается в целевой вычислитель» (раздел 5.4) — то есть примерно то, когда вы в Riot выполняете команду make flash или в каком-нибудь красивом IDE типа Keil или IAR (ну или в крайнем случае Arduino IDE) нажимаете кнопку «Run», которая делает то же самое — ваш проект компилируется и загружается в подключенное к вашему компьютеру через отладчик устройство. Это может быть устроено немного более сложно, но пока такого представления об этом всем достаточно.

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

Исходя из результатов испытаний вы понимаете, что программа работает неправильно, возвращаетесь к кодированию — и все повторяется заново, стандарт описывает это словами «Процессы жизненного цикла ПО могут иметь итерационный характер, то есть, могут повторяться» — примерно так, как это показано для «компоненты Z» на этом рисунке:

«Наивный» подход к разработке ПО (свойственный инженерам-электронщикам, кстати говоря) — это то, что показано для «компоненты W» — формулируем требования, выдаем их кодеру, он пишет код, потом заливаем его в целевое устройство, …, PROFIT! Проблема в том, что он… не работает, но при этом широко применяется, вот довольно яркое описание принятых у электронщиков рабочих процессов в программировании:

Качество кода? Ревью? Разделение задач? система контроля версий? Да о чем вы! Высрал бинарник в пизженом кейле и отдал на производство. Человек ушел, работы не приняли, новый начинает с нуля все заново.

https://mbr.livejournal.com/606449.html

Так вот, «непрерывная интеграция» — это в точности то, что сделано в Riot’овских тестах, запускающихся на базе iotlab:

— основная «ветка» безо всякого участия программиста компилируется (это результат «процесса кодирования», пункт 5.3.2 в документе), причем «эталонным» компилятором (я видел, как некоторые проекты «ломались» от смены версий gcc);
— выполняется «процесс интеграции» (раздел 5.4);
— дальше проводится то, что в КТ-178 называется словом «испытания» (программисты скорее будут использовать слово «тестирование») — «выхлоп» программы сравнивается с ожидаемым.

Хочу обратить внимание, что верификация этим не исчерпывается, это немного более сложная штука, но как минимум часть задач верификации тестированием закрывается. Главное — то, что все это делается полностью автоматически, и программист не может намеренно «обойти» эти процессы, потому такая интеграция и называется «непрерывной».

Ну а так как результаты испытаний — это, в том числе, и входные данные для процессов разработки («устранение ошибок – это мероприятия процессов разработки») — то они становятся такими же «непрерывными» — как для «компоненты Z» на рисунке перемежаются «кодирование» и «интеграция» (а то и вовсе по результатам очередной интеграции и испытаний мы возвращаемся к разработке требований и перепроектированию).

В embedded это все особенно ярко видно, потому что «целевой вычислитель» — вот он у вас, в руках или на столе в виде отладочной платы.

Понятно, что все эти вещи можно делать разными средствами — да хоть даже «вручную» — написал код, выполнил команду make или нажал Compile, отдал получившийся бинарник тестировщику (и все это еще оформить документально журналом по принципу «сделал — запиши, не сделал — запиши два раза» — в принципе, и такие «процессы» возможны), но если можно автоматизировать эту работу — то почему бы и нет? Заодно в какой-то степени из процесса испытаний исключается человеческий фактор, все, что можно проверить автоматически — будет проверено, в идеале — для каждого существенного изменения в вашем гитлабовском репозитории (а контроль версий на языке тех же стандартов входит в то, что называется «управлением конфигурациями»).

Собственно, именно это и называется «непрерывной интеграцией», а вовсе не бездумное использование GitLab, Docker и прочих Ansible — важны не инструменты, а то, что вы с помощью этих инструментов делаете. Более того, если строго следовать требованиям КТ-178 — то используемые в процессе валидации инструменты должны быть «квалифицированы», то есть разработаны в рамках предъявляемых стандартом требований. Разумеется, такие программные продукты тоже есть, стоят дорого, как и все авиационное — но возможно, и с ними в жизни придется встретиться.