Сборка в конвейере#
Все инструменты AFT рассчитаны на запуск без участия человека: параметры задаются манифестом, результат возвращается кодом выхода, отчёты пишутся в файлы. Поэтому полный цикл собирается в конвейер: проверить описание, собрать, проверить результат, найти уязвимости и опубликовать.
Порядок шагов#
Проверка манифеста идёт первой и не требует ни прав администратора, ни сборки:
aft-app validate app.yaml
Код возврата 0 означает, что ошибок нет, 1 - что манифест не принят. Проверка разбирает манифест теми же правилами, что и сборка, поэтому ловит опечатку в имени поля, значение неподходящего типа, одиночное значение там, где ожидается список, и секцию источника, не совпадающую с заявленным типом. В сообщении указывается путь до поля и номер строки, а при опечатке предлагается близкое по написанию имя. Шаг дешёвый и снимает большую часть ошибок до того, как будет занята сборочная машина.
Сборка меняет систему и требует прав администратора:
sudo aft-app build app.yaml
Результат ложится в каталог, заданный секцией export. Ненулевой код выхода
означает, что сборка не удалась.
Проверка результата выполняется анализатором. Он работает с уже установленным приложением, поэтому сборку сначала нужно установить из полученного репозитория:
sudo flatpak remote-add --if-not-exists --no-gpg-verify ci-repo ./repo
sudo flatpak install -y ci-repo ru.example.MyApp
aft-analyzer ru.example.MyApp --format=json --report=./report
Анализатор возвращает 0 при успехе, 1 при предупреждениях и 2 при ошибках. Флаг
--no-exit-code заставляет его всегда возвращать 0, если конвейер не должен
падать на предупреждениях. Набор проверок сужается флагом --checkers со
списком через запятую: Manifest, Desktop, Icon, AppStream, Export, Permission,
Binary, Xattr, Library, Environment, Signature, Bsign, DBus.
Поиск уязвимостей запускается отдельным инструментом или прямо из сборки:
aft-scanner scan ru.example.MyApp --fail-on=high --format=json,html \
--output-dir=./report
Встроенный в сборку вариант описывается секцией build.scan манифеста и
отрабатывает последним, уже после экспорта:
build:
scan:
enabled: true
failOn: high
strict: true
severities: [critical, high]
ignoreCves: [CVE-2023-0001]
Поле strict делает найденные уязвимости причиной неуспеха сборки. Без него
находки попадают в отчёт, но сборка считается успешной.
Состав ПО формируется сборкой автоматически, если включено поле build.sbom.
Получить состав уже установленного приложения отдельно можно так:
aft-flatpak-sbom ru.example.MyApp -o myapp.cdx.json
Подпись#
Подписей две, и они независимы.
Подпись репозитория ключом GPG задаётся полями export.gpgSign и
export.gpgHomedir. Без неё пользователю придётся подключать репозиторий с
отключённой проверкой.
Подпись исполняемых файлов средствами bsign нужна для замкнутой программной
среды Astra Linux и настраивается секцией build.bsign. Пароль ключа в
конвейере передаётся файлом, чтобы подпись не требовала ввода:
build:
bsign:
enabled: true
key: 0123456789ABCDEF0123456789ABCDEF01234567
passphraseFile: /run/secrets/bsign-pass
elfOnly: true
Файл с паролем не хранится в репозитории с исходниками, а подставляется механизмом секретов конвейера.
Воспроизводимость#
Плавающие версии делают сборку невоспроизводимой. Версия пакета закрепляется
полем source.repository.version, версия среды выполнения указывается точным
номером ветки, а не значением вроде stable.
Кэш скачанных пакетов лежит в каталоге build.cacheDir. На сборочной машине
его имеет смысл сохранять между запусками, чтобы не скачивать одно и то же, но
при закреплении версий кэш не подменяет запрошенную версию тем, что в нём уже
лежит.
Один манифест может описывать несколько сборок: документы разделяются строкой
--- и собираются по очереди. Это удобно, когда одно и то же приложение
собирается под несколько линий или архитектур, и позволяет держать все варианты
в одном файле.