Недавно для QtProtobuf я озадачился настройкой босяцкого CI для верификации "запросов на слияние" aka pull requests, ну и конечно для того, чтобы вставить модный бэйдж в README проекта. На выбор были GitHub Actions и Travis CI. Честно скажу, я не задавался целью искать, сравнивать, анализировать, хотелось простоты и быстрого решения совсем несложной задачи. Сначала я разобрался с CI для GitHub Actions, и настроил билд и верификацию юниттестов через docker контейнер. Но ввиду уймы ограничений GitHub Actions оказался попросту непригодным для верификации проекта в Windows. Пришлось обратиться к Travis CI.


КДПВ_not_found.png


На момент написания статьи в Travis CI красавался вот такой дисклеймер:


Windows builds are in early access stage. Please head to the Travis CI Community forum to get help or post ideas.

Это вызывало опасения, поскольку изначально я пытался настроить все через docker-контейнер и подсунуть его в GitHub Actions, но эта затея провалилась из-за ограничений по размеру, типу контейнеров и т.п. в GitHub.


К делу


Для начала работы вам нужно авторизовать Travis CI в GitHub, после чего в настройках вашего профиля появится приложение Travis CI. Что удобно вы можете определить репозитории, к которым Travis CI может иметь доступ:



Следующим шагом будет настройка триггеров Travis CI. Эта процедура уже делается из панели администрирования самого Travis CI, на момент написания статьи были доступны следующие триггеры:


  • Запуск по push на любой бранч проекта
  • Запуск при создании запросов на слияние
  • Запуск по времени (cron)

В принципе достойный набор для построения CI.


После выбора триггеров для запуска билдов, необходимо создать .travis.yml, с описанием процедуры построения и, в зависимости от имеющихся триггеров, поместить этот файл в репозиторий. Сразу озадачила разрозненная и несистематизированная документация самого Travis CI касательно .travis.yml, но при желании разобраться можно.


Основная задача, которая стояла — это подготовка окружения для сборки, поскольку сама сборка и верификация это дело CMake.


Описываем процедуру сборки в .travis.yml


Для начала нужно выбрать операционную систему, которая запускается как виртуальная машина на серверах Travis CI, и язык программирования.


os: windows
language: C++
...

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


Следующим шагом нужно скачать и установить необходимые зависимости. Для QtProtobuf, такими являются:


  • Qt 5.12.3 или выше
  • cmake-3.1 или выше
  • Strawberry perl 5.28 или выше
  • GoLang 1.10 или выше
  • Yasm 1.3 или выше
  • Visual Studio Compiler 14.16.x

И тут Travis CI сильно подсобил. Среди предустановленных пакетов оказался не только Git и MSVC, но и cmake, wget и chocolatey. В прицнипе при наличии chocolatey, дальнейшая установка зависимостей значительно облегчена. Правда, для меня осталось загадкой, почему в chocolatey до сих пор не завезли Qt.


Для начала скачиваем полный инсталлер Qt из официального репозитория:


...
before_install:
  - wget -q https://download.qt.io/official_releases/qt/5.13/5.13.2/qt-opensource-windows-x86-5.13.2.exe
...

Примечание: При загрузке wget вываливает огромное количество логов с прогрессом скачивания. Travis CI как и GitHub имеет ограничение на размер лога сборки, поэтому следует избегать ненужных логов. Опция -q aka --quite скрывает вывод логов у wget.

Делаем установку необходимых зависимостей:


...
install:
  - choco install golang
  - choco install yasm
  - ./qt-opensource-windows-x86-5.13.2.exe --script ./.ci/qt_installer_windows.qs
...

С установкой GoLang и Yasm думаю не должно быть вопросов. А вот запуску инсталлера Qt, я уделю больше внимания.


QtInstallerFramework поддерживает автоматизацию процесса установки путем написания скриптов.


Готовые скрипты для инсталляции той или иной версии Qt достаточно просто гуглятся, я лишь дам ссылку на имеющийся у меня и обращу внимание на выбор компонент для установки:


...
Controller.prototype.ComponentSelectionPageCallback = function() {
    var widget = gui.currentPageWidget();
    widget.deselectAll();
    widget.selectComponent("qt.qt5.5132.win32_msvc2017");

    gui.clickButton(buttons.NextButton);
}
...

Здесь я отключаю все checkbox компоненты вызовом widget.deselectAll(); и включаю необходимый для постройки "qt.qt5.5132.win32_msvc2017". Тут имеются 2 аспекта, которые важны при написании этой процедуры:


  • selectComponent работает также как и графический компонент, а потому зависимости и подкомпоненты выбираются по той же логике, как если бы мы выбрали их в графическом интерфейсе. Именно поэтому не нужно переживать по-поводу разрешения зависимостей.
  • Названия компонент можно посмотреть в "вербальном" режиме установки. Для этого я в одну из итераций выполнил widget.selectAll(); и запустил установку скомандой - ./qt-opensource-windows-x86-5.13.2.exe --verbose --script ./.ci/qt_installer_windows.qs. В логах вы с легкостью можете найти все необходимые вам компоненты и модерировать их установку при помощи widget.selectComponent/widget.deselectComponent.

И последний важный момент, который я затрону в этом tutorial — это окружение для сборки. Из-за того, что установка зависимостей и сборка происходят в рамках одного shell, после уставновки Go и Yasm в нашем shell нет прописаного PATH до исполняемых файлов. Поэтому необходимо вручную прописать PATH, GOROOT перед простраением:


script:
...
  - setx path "%path%;C:\Qt\5.13.2\msvc2017\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
  - set GOROOT="c:\Go"
  - set PATH="%PATH%;C:\Qt\5.13.2\msvc2017\bin;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools"
  - cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.13.2\msvc2017;C:\Go\bin;C:\ProgramData\chocolatey\lib\yasm\tools" ..  
...

Еще хочется обратить внимание на то, что в CMAKE_PREFIX_PATH по аналогии необходимо прописать путь до Go и Yasm для корректной работы функции find_program.


Возможно позже я соберусь описать создание docker-контейнера для сборки с Qt на борту.


Все скрипты можно найти тут