跳过主要内容
CI/CD

Automatic Capacitor Android build with GitHub actions

如何在 5 分钟内使用 fastlane 和 GitHub Actions 为您的 Android Capacitor 应用设置 CI/CD pipeline

马丁·多纳迪厄

马丁·多纳迪厄

内容营销

Automatic Capacitor Android build with GitHub actions

为 Capacitor 应用设置 CI/CD 可能会很复杂和耗时。以下是您需要知道的内容:

我们现在建议使用 Capgo 构建与 Capgo CLI 用于本机 Capacitor 构建。 本 Fastlane 指南保留用于维护现有 GitHub Actions pipeline 的团队,但新 Android 构建应使用 Capgo CLI 以免自己维护 Fastlane、Gradle 运行器、密钥库和上传脚本。

前置条件

开始之前,您需要设置:

  • 一个具有管理员访问权限的GitHub账户
  • 已在Google Play Store上发布并正确签名的应用
  • Android签名密钥和keystore文件
  • Google Cloud Console项目,已启用Play StoreAPI
  • 具有适当权限的服务账户
  • GitHub Actions工作流程的理解
  • Fastlane配置的知识
  • 维护和调试管道所需的时间

Capgo Build for CI/CD by Capgo

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

  • 与您的 pipeline 一起工作: 在 Capgo 构建之后从 GitHub Actions、GitLab CI、Jenkins 或本地脚本中触发 Capgo 构建 npx cap sync.
  • 从 CI 秘密中签名: 在您的 CI 秘密中保留 Android 密钥库、密钥别名、密码和 Play Console 服务帐号 JSON
  • 无本机运行器维护: Capgo 构建提供维护的 Android 构建环境,因此您不需要管理 SDK 镜像、Gradle 缓存问题或 Fastlane 通道
  • 工件和提交: 下载用于 QA 的签名工件或通过 Capgo CLI 提交发布构建

定价

  • Capgo 计划从 $12/月开始
  • 包含 OTA 更新和每月约 15 个本机构建
  • 额外的构建分钟通过信用额度按分钟计费

设置 Capgo 构建在 CI/CD 中

手动设置指南

以下是您需要做的事情:

GitHub 动作定价

价格 GitHub 动作

GitHub 动作根据您的仓库类型提供免费分钟数:

  • 公共仓库:每月 2,000 分钟
  • 私有仓库:每月 2,000 分钟(Linux 运行器)

对于私有项目,成本约为每分钟 $0.008。典型的构建时间为 3-5 分钟。

手动设置步骤

  1. 创建 Android Keystore
  2. 设置 Google Play 服务帐号
  3. 设置 Fastlane
  4. 配置 GitHub 秘密
  5. 创建 GitHub Actions 工作流

1. 创建 Android Keystore

在发布 Android 应用之前,您需要创建一个 keystore 文件。这是一个一次性设置。

使用 keytool 生成 Keystore

在您的终端中运行以下命令:

keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

您将被要求输入:

  • Keystore 密码: 选择一个强大的密码(您将需要它作为 KEYSTORE_STORE_PASSWORD)
  • 密钥密码: 选择一个强大的密码(你将需要这个作为 KEYSTORE_KEY_PASSWORD)
  • 你的姓名、组织等: 填写你的详细信息

重要注意事项

  • 安全保存这些值:

    • 密钥库文件位置(例如 my-release-key.keystore)
    • 密钥别名(例如 my-key-alias) - 你将需要这个作为 KEYSTORE_KEY_ALIAS
    • 密钥库密码 - 你将需要这个作为 KEYSTORE_STORE_PASSWORD
    • 密钥密码 - 你将需要这个作为 KEYSTORE_KEY_PASSWORD
  • 备份密钥库文件: 如果你丢失了它,你就无法更新你的发布应用

  • 保密: 不要将密钥库文件提交到git

  • 安全存储: 在安全的位置保留多个备份

备选方案:使用现有的密钥库

如果你已经发布了你的应用,你必须使用最初使用的同一个密钥库。你可以在这里找到它:

  • 在你第一次构建应用的本地机器上
  • 在你的Play Console → 设置 → 应用签名(如果使用Google Play App Signing)

2. 设置Google Play Service Account

为了允许GitHub Actions 将构建上传到Google Play,你需要一个服务账户。

步骤 2.1:创建Google Cloud Project

  1. 前往 Google Cloud Console
  2. 创建新项目或选择现有项目
  3. 注意项目 ID

步骤 2.2:启用 Google Play Developer API

  1. 在 Google Cloud Console 中,前往 APIs & ServicesLibrary
  2. 搜索“Google Play Android Developer API”
  3. 点击 启用

步骤 2.3:创建 Service Account

  1. 前往 身份与管理服务账号
  2. 点击 创建服务账号
  3. 输入信息:
    • 名称: github-actions-uploader
    • 描述:“GitHub 的服务账号用于上传构建”
  4. 点击 创建并继续
  5. 暂时跳过角色赋予(点击 继续然后 完成)

步骤 2.4: 创建服务帐户密钥

  1. 点击新创建的服务帐户
  2. 前往 密钥 选项卡
  3. 点击 添加密钥创建新密钥
  4. 选择 JSON 格式
  5. 点击 创建
  6. 将下载一个 JSON 文件 - 请安全保存稍后会用到

步骤 2.5: 在 Play Console 中授权

  1. 前往 Google Play Console
  2. 前往 设置API 权限
  3. 服务帐号, 点击 授权访问 为您的服务帐号
  4. 应用权限 选项卡中,添加您的应用
  5. 帐号权限 选项卡中,授予这些权限:
    • 查看应用信息和下载大批量报告(只读)
    • 创建、编辑和删除草稿应用
    • 发布应用到测试轨道
    • 发布应用到生产、排除和其他轨道
  6. 点击 邀请用户
  7. 点击 发送邀请

步骤 2.6:验证 JSON Key

下载的 JSON 文件应如下所示:

{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "...",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
  "client_email": "github-actions-uploader@your-project-id.iam.gserviceaccount.com",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "..."
}

您将在 GitHub 秘密设置步骤中将其转换为 base64。

3. 设置 Fastlane

创建 fastlane 在您的项目根目录下创建一个文件夹并添加一个 Fastfile 内容如下:

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'])
        
        # Get previous build number and increment
        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}")
        
        # Build the app
        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
        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
end

4. 配置GitHub机密

现在您已经拥有了您的密钥库和服务帐户 JSON,您需要将它们安全地存储在GitHub中。

步骤 4.1:访问GitHub机密

  1. 前往您的仓库在GitHub
  2. 点击 设置机密和变量操作
  3. 点击 新建仓库机密

步骤 4.2: 添加必需的密钥

逐一添加这些密钥:

__CAPGO_KEEP_0__

  1. 下载步骤 2.4 中的服务帐户 JSON 文件
  2. 将其转换为 base64:

在 macOS/Linux 上:

base64 service_account_key.json | pbcopy

在 Windows (PowerShell) 上:

[Convert]::ToBase64String([IO.File]::ReadAllBytes("service_account_key.json")) | Set-Clipboard
  1. 创建一个新密钥 PLAY_CONFIG_JSON 并粘贴 base64 字符串

__CAPGO_KEEP_0__

  1. 将您的 keystore 转换为 base64:

在 macOS/Linux 上:

base64 my-release-key.keystore | pbcopy

在 Windows (PowerShell) 中:

[Convert]::ToBase64String([IO.File]::ReadAllBytes("my-release-key.keystore")) | Set-Clipboard
  1. 创建一个名为 ANDROID_KEYSTORE_FILE 并粘贴 base64 字符串

__CAPGO_KEEP_0__

创建一个名为你在生成密钥库时使用的别名的新密钥 (例如, my-key-alias)

创建一个名为你在生成密钥库时设置的密钥密码的新密钥

创建一个名为你在生成密钥库时设置的密钥库密码的新密钥

创建一个名为你在生成密钥库时设置的密钥库密码的新密钥

创建一个名为你的应用包名的新密钥 (例如,

你可以在这里找到你的包名

在这里找到你的包名 com.example.app)

在这里找到你的包名 android/app/build.gradle under applicationId

步骤 4.3: 验证所有机密

确保您已配置以下 6 个机密:

  • ✅ PLAY_CONFIG_JSON
  • ✅ ANDROID_KEYSTORE_FILE
  • ✅ KEYSTORE_KEY_ALIAS
  • ✅ KEYSTORE_KEY_PASSWORD
  • ✅ KEYSTORE_STORE_PASSWORD
  • ✅ DEVELOPER_PACKAGE_NAME

5. 创建 GitHub Actions 工作流

创建 .github/workflows/build-upload-android.yml:

name: Build and Deploy Android App

on:
  push:
    tags:
      - '*'

jobs:
  build_android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      
      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: npm
          
      - name: Install dependencies
        run: npm ci
        
      - name: Cache Gradle
        uses: actions/cache@v5
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
            
      - name: Build app
        run: npm run build
        
      - name: Sync Capacitor
        run: npx cap sync
        
      - name: Setup Java
        uses: actions/setup-node@v5
        with:
            distribution: 'zulu'
            java-version: '17'
            
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.0'
          bundler-cache: true
          
      - name: Run Fastlane
        uses: maierj/fastlane-action@v3.1.0
        env:
          PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
          ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
          DEVELOPER_PACKAGE_NAME: ${{ secrets.DEVELOPER_PACKAGE_NAME }}
          KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
          KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
          KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
        with:
          lane: android beta
          
      - name: Upload artifact
        uses: actions/upload-artifact@v2
        with:
          name: android-release
          path: ./android/app/build/outputs/bundle/release/app-release.aab
          retention-days: 10

如何工作

  1. 创建一个 Git 标签来触发工作流
  2. GitHub Actions 为您的应用程序构建
  3. Fastlane 将其上传到 Google Play beta 频道
  4. 您的应用程序将自动更新

构建时间和成本

  • 构建时间:3-5 分钟
  • 私有仓库的成本:约 $0.04/次
  • 开源项目免费

CI/CD 设置指南

替代CI/CD平台

实时更新和部署

资源

Keep going from Automatic Capacitor Android build with GitHub actions

如果您正在使用 Automatic Capacitor Android build with GitHub actions 来规划CI/CD自动化,将其与 Capgo CI/CD 在Capgo CI/CD中, Capgo原生构建 为产品工作流程中的Capgo原生构建 Capgo集成 为产品工作流程中的Capgo集成 CI/CD集成 CI/CD集成的实现细节,以及 GitHub动作集成 for the implementation detail in GitHub Actions Integration.

Capacitor应用的实时更新

当一个web层bug处于活跃状态时,通过Capgo将修复推送到用户,而不是等待几天的应用商店审批。用户在后台接收更新,而原生变化保持在正常的审批路径中。

立即开始

最新博客

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