运行 Docker 中 Android 的并行 Gitlab CI 作业

Running parallel Gitlab CI jobs for Android in Docker

我使用 Gitlab CI 在 Docker 容器中使用 fastlane 构建我的 Android 应用程序。我的应用程序有两种“风味”,我想在单独的 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 && $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 && $CI_COMMIT_REF_PROTECTED == "true"'
        when: never
      - when: on_success

(此管道中的其他工作会发布 git 标签的版本并上传到 Play 商店,但这些与此问题无关。)

以下是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 守护进程,这会导致另一个失败。

如何让这些作业能够运行并行?

您是否有足够的资源同时运行?尤其是内存可能是一个问题,因此 OS 将由于内存压力而杀死另一个容器。