Запуск параллельных заданий Gitlab CI для Android в Docker

#android #docker #continuous-integration #gitlab #fastlane

# #Android #docker #непрерывная интеграция #gitlab #fastlane

Вопрос:

Я использую Gitlab CI для создания своего приложения для Android с использованием fastlane внутри контейнера Docker. В моем приложении есть два «варианта», которые я хочу создать в отдельных заданиях CI. Вот соответствующая часть .gitlab-ci.yml :

 default:
  image: registry.example.com/group/project:29-android-fastlane-debian
  tags:
    - docker
  before_script:
    - ruby -v # Print out ruby version for debugging
    - bundle install

build_flavor1_debug:
  stage: build
  script:
    - bundle exec fastlane build release:"false" --env flavor1
  artifacts:
    paths:
      - app/build/outputs/bundle/
  rules:
      - if: '$CI_COMMIT_TAG amp;amp; $CI_COMMIT_REF_PROTECTED == "true"'
        when: never
      - when: on_success

build_flavor2_debug:
  stage: build
  script:
    - bundle exec fastlane build release:"false" --env flavor2
  artifacts:
    paths:
      - app/build/outputs/bundle/
  rules:
      - if: '$CI_COMMIT_TAG amp;amp; $CI_COMMIT_REF_PROTECTED == "true"'
        when: never
      - when: on_success
 

(Другие задания в этом конвейере выполняют сборки релизов для тегов git и загружают их в Play Store, но они не имеют отношения к этой проблеме.)

Вот соответствующие части Fastfile :

 # All flavors we know about. If one is not specified, run them all
flavors = {
  "flavor1" => "com.example.flavor1.app",
  "flavor2" => "com.example.flavor2.app"
}

# If set to a single flavor, make it the only one in the array
if ENV["FLAVOR_NAME"]
  flavors = flavors.slice(ENV["FLAVOR_NAME"])
end

UI.user_error!("Unknown flavor '#{ENV["FLAVOR_NAME"]}' selected") if flavors.empty?

platform :android do

  desc "Build the application"
  lane :build do |options|
    setup(options)

    flavors.each { |flavor_name, flavor_package|
      build_flavor(
        flavor: flavor_name,
        release: options[:release]
      )
    }
  end

end
 

Использование --env флага загружает .env файл с соответствующей FLAVOR_NAME переменной, установленной для одновременного запуска только одного варианта.

Это работало нормально, когда я запускал сборки последовательно, но это занимает слишком много времени. Я изменил конфигурацию Gitlab Runner, чтобы разрешить одновременное выполнение до 8 заданий, и теперь я получаю следующую ошибку:

 The message received from the daemon indicates that the daemon has disappeared.
Build request sent: Build{id=111291aa-90bc-45c3-8fb4-9a271d4663f4, currentDir=/builds/group/project}
Attempting to read last messages from the daemon log...
Daemon pid: 1100
  log file: /root/.gradle/daemon/6.5/daemon-1100.out.log
----- Last  20 lines from daemon log file - daemon-1100.out.log -----

[SNIP] - No useful logs here...

----- End of the daemon log -----
FAILURE: Build failed with an exception.
* What went wrong:
Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)
 

Иногда это происходит на задании одного варианта, а иногда и на другом. Если я вручную повторно запускаю неудачное задание, оно всегда выполняется успешно.

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

Как я могу заставить эти задания выполняться параллельно?

Комментарии:

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

2. Попробуйте выполнить сборку с --no-daemon помощью, режим демона бесполезен в контейнере.

3. @Xiaofeng Я попробую, но, согласно документации Gradle, этот флаг больше не имеет никакого значения. Также смотрите github.com/gradle/gradle/issues/2824#issuecomment-326282674

4. Достаточно ли у вас ресурсов для одновременных запусков? Особенно проблемой может быть память.

5. @JanGaraj У меня на компьютере 32 ГБ, и Docker разрешено использовать до 24 ГБ.

Ответ №1:

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