跳过主要内容
CI/CD

Automatic Capacitor Android build with GitLab

如何在5分钟内使用fastlane和GitLab为您的Android Ionic应用设置CI/CD管道

文章来源

马丁·多纳迪尤

作者

瓦莱里亚

审阅者

乔丹

编辑器

自动Capacitor Android 构建与 GitLab

自动 Android 构建与 GitLab CI

Setting up CI/CD for Capacitor apps can be complex and time-consuming. Here’s what you need to know:

前提条件

开始之前,您需要设置:

  • GitLab 账户(具有管理员权限)
  • 已在 Google Play 商店发布并正确签名的应用
  • Android 签名密钥和 keystore 文件
  • Google Cloud Console 项目(已启用 Play StoreAPI)
  • 具有适当权限的服务账户
  • 对 GitLab CI/CD 工作流程的理解
  • 了解Fastlane配置
  • 维护和调试管道的时间

Capgo通过Capgo构建

跳过Fastlane、Gradle runner、keystore和上传脚本的维护 Capgo构建 从您的CI/CD管道中运行已有的签名原生Android构建:

  • 与您的管道兼容: Trigger Capgo Build from GitLab CI, GitHub Actions, Jenkins, or local scripts after your web build and npx cap sync.
  • 从CI密钥中签名:在CI密钥中保留Android密钥库、密钥别名、密码和Play Console服务账户JSON
  • 无原生运行器维护:Capgo构建提供维护的Android构建环境,因此您不需要管理SDK镜像、Gradle缓存问题或Fastlane通道
  • artifact和提交: 下载已签名的artifact用于QA或通过Capgo CLI提交发布版本。

定价

  • Capgo计划从每月12美元开始
  • 包括OTA更新和约每月15个原生构建
  • 额外的构建分钟按分钟计费通过信用额度

在CI/CD中设置Capgo构建

手动设置指南

以下是您需要做的事情:

请遵循以下步骤

  1. 复制Fastlane文件
  2. 在GitLab中存储您的机密信息
  3. 创建 & 存储您的 Google Play 服务帐号密钥
  4. 存储您的 Android 签名密钥
  5. 设置您的 GitLab 工作流 .yml 文件

1. 复制 Fastlane 文件

Fastlane 是一款 Ruby 库,用于自动化常见的移动开发任务。使用 Fastlane,您可以配置自定义的“道线”,这些道线包含一系列的“动作”,这些动作执行您通常使用 Android Studio 执行的任务。您可以使用 Fastlane 做很多事情,但在本教程中,我们将仅使用一小部分核心动作。

创建一个 Fastlane 文件夹,位于您的项目根目录,并复制以下文件: Fastlane

default_platform(:android)

KEYSTORE_KEY_ALIAS = ENV["KEYSTORE_KEY_ALIAS"]
KEYSTORE_KEY_PASSWORD = ENV["KEYSTORE_KEY_PASSWORD"]
KEYSTORE_STORE_PASSWORD = ENV["KEYSTORE_STORE_PASSWORD"]

platform :android do
    desc "Deploy a beta version to the Google Play"
    private_lane :verify_changelog_exists do |version_code: |
      changelog_path = "android/metadata/en-US/changelogs/#{version_code}.txt"
      UI.user_error!("Missing changelog file at #{changelog_path}") unless File.exist?(changelog_path)
      UI.message("Changelog exists for version code #{version_code}")
    end

    private_lane :verify_upload_to_staging do |version_name: |
      UI.message "Skipping staging verification step"
    end
    lane :beta do
				keystore_path = "#{Dir.tmpdir}/build_keystore.keystore"
				File.write(keystore_path, Base64.decode64(ENV['ANDROID_KEYSTORE_FILE']))
				json_key_data = Base64.decode64(ENV['PLAY_CONFIG_JSON'])
				previous_build_number = google_play_track_version_codes(
					package_name: ENV['DEVELOPER_PACKAGE_NAME'],
					track: "internal",
					json_key_data: json_key_data,
				)[0]

				current_build_number = previous_build_number + 1
				sh("export NEW_BUILD_NUMBER=#{current_build_number}")
        gradle(
          task: "clean bundleRelease",
          project_dir: 'android/',
          print_command: false,
          properties: {
            "android.injected.signing.store.file" => "#{keystore_path}",
            "android.injected.signing.store.password" => "#{KEYSTORE_STORE_PASSWORD}",
            "android.injected.signing.key.alias" => "#{KEYSTORE_KEY_ALIAS}",
            "android.injected.signing.key.password" => "#{KEYSTORE_KEY_PASSWORD}",
						'versionCode' => current_build_number
          })
        upload_to_play_store(
					package_name: ENV['DEVELOPER_PACKAGE_NAME'],
					json_key_data: json_key_data,
          track: 'internal',
          release_status: 'completed',
          skip_upload_metadata: true,
          skip_upload_changelogs: true,
          skip_upload_images: true,
          skip_upload_screenshots: true,
        )
    end
    lane :build do
      gradle(
        task: "clean bundleRelease",
        project_dir: 'android/',
        print_command: false,
        properties: {
          "android.injected.signing.store.file" => "#{keystore_path}",
          "android.injected.signing.store.password" => "#{KEYSTORE_STORE_PASSWORD}",
          "android.injected.signing.key.alias" => "#{KEYSTORE_KEY_ALIAS}",
          "android.injected.signing.key.password" => "#{KEYSTORE_KEY_PASSWORD}",
        })
    end
    lane :prod_release do
      build_gradle = File.read("../android/app/build.gradle")

      verify_changelog_exists(version_code: build_gradle.match(/versionCode (\d+)/)[1])
      verify_upload_to_staging(version_name: build_gradle.match(/versionName '([\d\.]+)'/)[1])

      supply(
        track_promote_to: 'beta',
        skip_upload_apk: true,
        skip_upload_aab: true,
        skip_upload_metadata: false,
        skip_upload_changelogs: false,
        skip_upload_images: false,
        skip_upload_screenshots: false
      )
    end
end

在 GitLab CI/CD 变量中存储您的机密信息

GitLab 提供了一个存储加密 CI/CD 变量的方式,类似于 GitHub 的仓库机密。要安全地存储您的敏感信息。

  1. 前往您的 GitLab 项目的设置。
  2. 导航到 CI/CD > 变量
  3. 添加以下变量:
  • ANDROID_KEYSTORE_FILE: base64 编码的 .jks.keystore 用于签署您的Android构建文件的文件。这将是与您的上传密钥相关联的keystore文件(如果使用Play App Signing),或您的应用签名密钥。
  • KEYSTORE_KEY_PASSWORD:与keystore文件相关联的密码
  • KEYSTORE_KEY_ALIAS:密钥存储别名
  • KEYSTORE_STORE_PASSWORD:私钥密码
  • DEVELOPER_PACKAGE_NAME:您的Android应用ID,如com.example.app
  • PLAY_CONFIG_JSON:服务账户密钥JSON的base64编码

创建Google Play服务账户密钥

要生成 PLAY_CONFIG_JSON 密钥,请遵循以下步骤:

  1. 前往 Google Cloud Console
  2. 创建一个新项目或选择一个现有的项目
  3. 启用 Google Play Android Developer API
  4. 创建一个服务帐户:
    • 前往 “IAM & Admin” > “服务帐户”
    • 点击 “创建服务帐户”
    • 为其命名并添加描述
    • 点击 “创建并继续”
    • 跳过角色赋予并点击 “完成”
  5. 生成 JSON 密钥:
    • 在列表中找到您的服务帐户
    • 点击三点菜单 > “管理密钥”
    • 点击 “添加密钥” > “创建新密钥”
    • 选择 JSON 格式
    • 点击 “创建”
  6. 在 Play Console 中为您的应用授予服务帐户访问权限:
    • 前往 Play Console
    • 导航到 “用户和权限”
    • 点击 “邀请新用户”
    • 输入服务帐户电子邮件(以 @*.iam.gserviceaccount.com 结尾)
    • 授予 “发布到生产环境” 权限
    • 点击 “邀请用户”
  7. 将 JSON 密钥转换为 base64:
    base64 -i path/to/your/service-account-key.json | pbcopy
  8. 将 base64 编码的字符串添加为 PLAY_CONFIG_JSON GitLab

设置 GitLab CI/CD Pipeline

创建一个 .gitlab-ci.yml 文件,放在项目的根目录中,来定义 CI/CD pipeline。以下是如何结构化你的 pipeline 的示例:


image: mingc/android-build-box:latest

stages:
  - build
  - upload_to_capgo
  - build_and_upload_android

build:
  stage: build
  tags:
    - saas-linux-xlarge-amd64
  cache:
    - key:
        files:
          - bun.lockb
      paths:
        - .node_modules/
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - node_modules/
      - dist/
  only:
    - master

upload_to_capgo:
  stage: upload_to_capgo
  tags:
    - saas-linux-xlarge-amd64
  script:
    - npx @capgo/cli@latest bundle upload -a $CAPGO_TOKEN -c dev
  dependencies:
    - build
  when: manual
  only:
    - master

build_and_upload_android:
  tags:
    - saas-linux-xlarge-amd64
  stage:    build_and_upload_android
  cache:
    - key:
        files:
          - android/gradle/wrapper/gradle-wrapper.properties
      paths:
        - ~/.gradle/caches/
  script:
    - npx cap sync android
    - npx cap copy android
    - bundle exec fastlane android beta # We do create a tag for the build to trigger XCode cloud builds
  dependencies:
    - build
  when: manual
  only:
    - master

触发 Pipeline

当你推送一个新的标签到 GitLab 仓库时,GitLab CI/CD 将自动触发定义的 pipeline,pipeline 将使用 Fastlane 来构建和部署你的 Android 应用。

确保根据你的项目结构和需求调整路径和依赖项。这一设置将帮助你在 GitLab CI/CD 中自动部署 Android 应用。

结论

通过使用 mingc/android-build-box Docker 镜像配置 GitLab CI/CD,你可以自动化 Android 应用构建过程,使你的开发流程更加高效和可靠。这一自动化将释放你的时间,让你专注于应用开发的核心方面,从而帮助你更高效地交付高质量的 Android 应用。

Keep going from Automatic Capacitor Android build with GitLab

如果你正在使用 Automatic Capacitor Android build with GitLab 来规划 CI/CD 自动化,连接它 Capgo CI/CD 为产品工作流程在 Capgo CI/CD 中 Capgo 原生构建 为产品工作流程在 Capgo 原生构建 中 Capgo 集成 为产品工作流程在 Capgo 集成 中 CI/CD 集成 为 CI/CD 集成的实现细节 GitHub 动作集成 为 GitHub 动作集成的实现细节

实时更新 Capacitor 应用

当 web 层 bug 活跃时,通过 Capgo 将修复推送给用户,而不是等待几天的应用商店审批。用户在后台接收更新,而原生更改仍在正常审批路径中。

来自马丁的人性化支持

立即开始

最新博客文章

Capgo 给您需要创建真正专业的移动应用所需的最佳见解。