SuperAPI AI 工具集

github-actions-android

部署与运维

查看项目

更新于 10-16 10:54

技能介绍

用途

该技能面向在 GitHub Actions 中为 Android 应用做部署的场景,重点不在通用 CI,而在于签名、AAB 构建与上架商店。它与其他技能分工:通用 CI 交给 github-actions,应用开发交给 android-development,JVM 测试交给 android-unit-testing,应用内购买(billing)与上传不同,交给 play-billing。

需要先探测项目属于原生(gradlew)还是 Expo/React Native(eas.json),不要在没有必要时把 eas build 和 bundleRelease 混在同一个 job 里。

不可协商的规则

  • Play 接收的是 AAB(bundleRelease),不是 APK;APK 只用于 sideload 或 Firebase App Distribution。
  • Keystore 与密码只能放在 GitHub Secrets,绝不能把 .jks / .keystore 提交进 git。
  • Play App Signing 开启时,CI 使用 upload key。
  • Play 的 service account(JSON)放在 secret 中,遵循最小权限(Release to testing / production)。
  • versionCode 必须确定(使用版本化文件或 github.run_number,但要记录为单一来源)。
  • 自动 CI 使用 internal(或 alpha)轨道;production 需配合 environment: production 与 reviewer。

使用方式

原生项目 CI 示例

jobs:
  test:
    runs-on: ubuntu-latest
    permissions: { contents: read }
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "17"   # 项目对应的 JDK
          cache: gradle
      - run: chmod +x gradlew
      - run: ./gradlew --no-daemon lintDebug testDebugUnitTest

gradlew wrapper 是必需的,且使用与 compileOptions 相同的 JDK。插桩测试(connectedCheck / 模拟器)不放在默认 PR 流程中,应使用 Firebase Test Lab 或 workflow_dispatch 的 job(参见 android-instrumented-testing)。Gradle 缓存通过 setup-java 的 cache: gradle 实现。

签名

典型 secrets 包括 ANDROID_KEYSTORE_BASE64、ANDROID_KEYSTORE_PASSWORD、ANDROID_KEY_ALIAS、ANDROID_KEY_PASSWORD。在 release job 中解码 keystore(base64 -d),若写入磁盘需在结束时删除。release 的 signingConfigs 读取环境变量(ORG_GRADLE_PROJECT_… 或在 runner 上生成的 gradle.properties)。debug signing 只用于 debug,release 绝不使用 signingConfig signingConfigs.debug。

发布与 Play 示例

deploy-play:
  needs: test
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  runs-on: ubuntu-latest
  environment: internal   # 或 production
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-java@v4
      with: { distribution: temurin, java-version: "17", cache: gradle }
    - run: ./gradlew --no-daemon bundleRelease
    # Fastlane supply 或 Play Publisher action

可使用 Fastlane supply / upload_to_play_store 或仓库已有的 Play Publisher action。service account JSON 通过 PLAY_SERVICE_ACCOUNT_JSON 提供。轨道顺序为 internal → alpha/beta → production;可在 Console 中提升,或使用显式 lane,第一个 workflow 不要直接跳到 production。若团队对发布说明做版本管理,在 fastlane/metadata 中提供 en-US/pt-BR changelog。除上传商店外,还应上传 .aab artifact(upload-artifact),保留期设短。

版本管理

versionName 面向用户可见(产品的 semver / calver)。versionCode 必须始终递增。Play 发生冲突时 CI 应失败,而不是使用 --force。Flavors(prod/staging)需使用正确的 bundle 与 package name,不要把 debug 发布到 Play。

Expo / React Native

使用 EXPO_TOKEN(或项目支持时用 Expo OIDC)。通过 eas build --platform android --profile production 与 eas submit --platform android,或下载 AAB 后走同一套 supply 流程。eas.json 的 production profile 应先指向同一个 internal 轨道。如果二进制由 EAS 负责,不要在 Expo 根目录运行 gradlew。

反模式

  • 以“仅为 CI”为由提交 keystore
  • 把 APK 上传 Play Store
  • 没有 signingConfig 的 assembleRelease
  • 每次 push 都发布到 production 轨道
  • 每个改动的 PR 都跑模拟器
  • 复用拥有整个组织 owner 权限的 service account JSON

与其他技能的集成

Pipeline: github-actions;App: android-development;测试: android-unit-testing / android-instrumented-testing;iOS: github-actions-ios;上线: production-readiness。

完成标准

  • PR 中执行 lint + unit
  • 通过 secrets 用 upload key 签名 AAB
  • 上传到非 production 轨道(或受保护的 production)
  • versionCode 唯一且递增
  • git 中没有 keystore