Сборка и публикация Qt Android приложений через Gitlab CI

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, запущенную мной онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Над сервисом для построения CI/CD даже не задумывался, есть GitLab, что еще нужно? Первым шагом нужно создать файл .gitlab-ci.yaml в корне проекта. Далее я подробно разберу его содержимое, а для тех кто хочет посмотреть сразу все, в конце статьи есть ссылки на репозиторий. Тем кто хоть немного знаком с синтаксисом .gitlab-ci.yml должно быть все понятно.

Объявляем переменную для всего файла, она будет доступна как в самом файле, так и в переменных среды в контейнере.

variables:  
	PROJECT_NAME: TestFirebaseAll

Указываем шаги сборки, по дефолту есть build, test и deploy, которые выполняется в соответствующем порядке. Можно определить свои и вставить в нужные позиции.

stages:  
  - build  
  - deploy

Далее идет шаблон задачи (Job) для сборки, это всего лишь шаблон и как его использовать будет показано ниже. Cамое главное необходимо понять, что он не включается в шаги pipelane. Далее по строкам:

  • stage - определяем на каком шаге сборки нужно запускать задачу (у нас это build);

  • image - docker образ где все будет запускаться, туда же (в определенную папку, она и будет рабочей директорией) будет скопирован наш репозиторий;

  • variables - еще раз определяем переменную, но уже на уровне задачи, это нужно для переиспользования шаблона в будущем;

  • artifacts - наши собранные aad файлы нужно будет где-то хранить, наиболее простым решением будет использование артефактов, Указываем директорию, которую нужно будет сохранить в виде архива, он будет доступен для скачивания;

  • before_script - команды которые нужно выполнить перед началом основных задач (еще существует after_script), у нас это создание файла ключа для подписи aab файла (здесь используем еще одну переменную среды KEYSTORE_FILE, ее мы определили сами, как именно - далее);

  • script - собственно сама сборка проекта, здесь ничего интересного нет, команды взяты прямиком из Qt.

Здесь мне очень сильно помог репозиторий пользователя rabits, там лежат Dockerfile для сборки образов, где установлен Qt, есть как под desktop, так и android, естественно все есть на docker hub. Также есть замечательный репозиторий qtci, содержащий различные скрипты для использования qt в ci-ситемах.

.build_template:
  stage: build
  image: rabits/qt:5.15-android
  variables:
    ANDROID_ABIS: ""
  artifacts:
    name: aab-${ANDROID_ABIS}
    paths:
      - ./dist/build/outputs/bundle/
    expire_in: 1 week  
  before_script:
    - echo ${KEYSTORE_FILE} | base64 -d > ./release.keystore
  script:    
    - qmake ./app/${PROJECT_NAME}.pro -spec android-clang "CONFIG+=qtquickcompiler" ANDROID_ABIS="${ANDROID_ABIS}"
    - make
    - make INSTALL_ROOT=./dist install
    - sudo chown -R $(whoami) $ANDROID_HOME
    - androiddeployqt --input ./android-${PROJECT_NAME}-deployment-settings.json --output ./dist
      --aab --deployment bundled --gradle --jarsigner --sign ./release.keystore ${KEY_ALIAS} --storepass ${KEY_PASSWORD}INSTALL_ROOT=./dist install    - sudo chown -R $(whoami) $ANDROID_HOME    - androiddeployqt --input ./android-${PROJECT_NAME}-deployment-settings.json --output ./dist      --aab --deployment bundled --gradle --jarsigner --sign ./release.keystore ${KEY_ALIAS} --storepass ${KEY_PASSWORD}

И вот первая выполняемая задача, созданная на основе предыдущего шаблона. С помощью переопределенной переменой мы указываем под какую платформу будем собирать, у нас их две arm64-v8a и armeabi-v7a. Все файлы будут сохранены в артефактах и доступны для скачивания в интерфейсе GitLab.

build-v8a:
  extends: .build_template
  variables:
    ANDROID_ABIS: "arm64-v8a"
    
build-v7a:
  extends: .build_template
  variables:
    ANDROID_ABIS: "armeabi-v7a"

Далее идет еще один шаблон, для деплоя в Google Market. Для этого мы используем утилиту под названием fastlane. Это довольно мощная программа, позволяющая делать скриншоты программы, загружать их в Google Market, деплоить во все стадии разработки (внутреннее тестирование, закрытое тестирование, открытое тестирование и релиз) приложение и это все для Android и iOS!

.deploy_google:
  stage: deploy
  image: zl0i/fastlane-ci:latest
  before_script:
    - echo ${GOOGLE_SERVICE} | base64 -d > ./google_play_api_key.json

Для работы этой утилиты нужно создать Gemfile в корне проекта, а также папку fastlane с файлами Appfile и Fastfile.

#Gemfile
source "https://rubygems.org"
gem "fastlane"

Appfile содержит путь к json-файлу с ключами сервисного аккаунта для деплоя в Google Market, а также название вашего пакета приложения (package name). Сервисный аккаунт Google дает нам права производить различные операции в Google Console, как создать такой аккаунт написано здесь. В итоге у нас должен появится json файл, скачиваем его к себе (но не в корень проекта, он не должен быть в гите).

#Appfile
json_key_file("./google_play_api_key.json") 
package_name("com.zloi.firebase.test") #Здесь нужно указать свой package

Fastfile содержит описание задач, более подробно можно посмотреть в документации, но вкратце desc - то что будет выводиться в консоль после успешного завершения задачи, lane - ключевое слово, то что идет после двоеточия название задачи (необходимо для запуска), ключевое слово do и дальше описание что нужно сделать. Стоить отметить, что fastlane также умеет собирать проекты и инкриминировать номер версии. В данном случае мы загружаем наш собранный aab файл в стадию внутреннего тестирования. Остальные задачи толкают с внутреннего тестирования на открытое и так далее, вплоть до релиза.

#Fastfile
default_platform(:android)

platform :android do

  desc "Submit a new Internal Build to Play Store"
  lane :internal do
    upload_to_play_store(track: 'internal', aab: './dist/build/outputs/bundle/release/dist-release.aab')
  end

  desc "Promote Internal to Alpha"
  lane :promote_internal_to_alpha do
    upload_to_play_store(track: 'internal', track_promote_to: 'alpha')
  end

  desc "Promote Alpha to Beta"
  lane :promote_alpha_to_beta do
    upload_to_play_store(track: 'alpha', track_promote_to: 'beta')
  end

  desc "Promote Beta to Production"
  lane :promote_beta_to_production do
    upload_to_play_store(track: 'beta', track_promote_to: 'production')
  end
end

А вот сами задачи GitLab CI на основе предыдущего шаблона, автоматически выполняется только публикация на внутреннее тестирование, остальные в ручном режиме (в интерфейсе GitLab). Стоит отметить, что артефакты автоматически загружаются в рабочую директорию перед запуском.

deploy_android_internal:
  extends: .deploy_google
  script:
    - bundle exec fastlane internal

deploy_android_alfa:
  extends: .deploy_google
  script:
    - bundle exec fastlane promote_internal_to_alpha
  when: manual

deploy_android_beta:
  extends: .deploy_google
  script:
    - bundle exec fastlane promote_alpha_to_beta
  when: manual

deploy_android_production:
  extends: .deploy_google
  script:
    - bundle exec fastlane promote_beta_to_production
  when: manual

Теперь нужно настроить наш репозиторий, мы должны добавить 4 ключа в переменные GitLab CI, причем google_play_api_key.json и release.keystore нужно преобразовать в base64 строку. В итоге у нас должно появится что-то подобное. При создании переменных не забудте снять отметки с Protect variable и поставить на Mask variable.

Вот и все! Можно пушить в наш репозиторий и наслаждаться автоматической сборкой и размещением в Google Market. Естественно можно улучшить pipelane и добавить прохождение тестов, в том числе на Firebase Test Lab и много чего еще. Стоит отметить, что сама сборка занимает не мало времени (около 12 минут), docker-образ с Qt и нужными ndk/sdk весит 1,67 ГБ, также артефакты обычно весят не мало (а бесплатное место на GitLab ограничено), поэтому лучше сделать запуск pipelane по присвоению тэгу.

Весь код целиком можно посмотреть по ссылкам ниже, это небольшой проект, созданный для изучения функций Firebase и интеграции их в Qt Android.

GitHub - основной репозиторий.

GitLab - настроен автоматический импорт для запуска pipelane.

Очень буду рад если подскажете как внедрить сборку под iOS. Консруктивная критика всегда приветствуется.

Источник: https://habr.com/ru/post/599033/


Интересные статьи

Интересные статьи

Многие из вас прекрасно знают, что такое Google Ассистент. Это голосовой помощник, подобный Siri, Алисе, Алексе и другим. Когда пользователь что-то говорит, Google Ассистент понимает это с помощью nat...
В наше время в каждом доме по кластеру kubernetes, выкатка приложений в кластер осуществляется по тегу. Образ выкатываемого приложения отправляется c тегом в репозиторий ...
Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox. В данной статье проникаем в систему через SQL инъекцию, копаемся в истории командной строки и повышаем ...
Компании растут и меняются. Если для небольшого бизнеса легко прогнозировать последствия любых изменений, то у крупного для такого предвидения — необходимо изучение деталей.
Статей с подобным заголовком достаточно много, поэтому постараюсь избежать банальных тем. Надеюсь, что даже очень опытные разработчики найдут здесь что-то полезное для себя. В данной статье б...