1. 授权认证
  2. 获取用户个人信息
  3. 项目协同
  4. 代码托管
  5. 持续集成
  6. 制品仓库
  7. 测试管理
  1. 项目协同
  2. 代码仓库
  3. DevOps 实践之旅
  4. 一分钟开始持续集成之旅
  5. 持续部署
  6. 制品库

Java + Android 在持续集成中的实践

Android 生态走过了快 10 年的光阴,如今已经更迭到了 Android 11 版本。一个完整的 Android APP 生命周期包括了:开发、测试、签名、发布 等过程。如何快速进行迭代,如何进行工程化,相信也是目前 Android 开发者日常会遇到的问题。

本文将演示 “Java - Android” 项目如何在 DevOps 中进行实践,实现自动化的 编译构建/签名/上传到 Generic 制品库进行发布 过程。

准备阶段

本地环境需要:

  1. Git
  2. Java
  3. Gradle
  4. Android SDK

以及一个 CODING DevOps 账号

初始化代码

使用 Android Studio 创建一个简单的 Android Hello World 项目并上传至 git 仓库。可参考以下的示例项目

示例代码目录结构

.
├── Jenkinsfile
├── README.md
├── app
│   ├── 步骤ild.gradle
│   ├── proguard-rules.pro
│   └── src                                            // android 的核心代码文件
│       ├── androidTest.java.com.example.java_android
│       │   └── ExampleInstrumentedTest.java              
│       ├── main
│       │   ├── AndroidManifest.xml
│       │   ├── java.com.example.java_android
│       │   │   └── MainActivity.java
│       │   └── res
│       │       
│       └── test.java.com.example.java_android         // 单元测试文件
│           └── ExampleUnitTest.java
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

编译构建

Android Studio

默认推荐使用 gradle 进行依赖管理和构建。

其中根目录下的 build.gradle 有项目所包含的依赖,以及依赖拉取的来源。

buildscript {

    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.2'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Android 应用

一般以 Apk 的形式输出。

在项目根目录下执行 ./gradlew assembleRelease 即可编译输出未签名的 apk 文件,更多的用法可参见Android 开发者官方网站

运行示例:

运行后生成物:

APK 签名

为什么要为 APK 签名

  • 应用升级:当安装应用的更新时,系统会比较新版本和现有版本中的证书。如果证书匹配,则系统允许更新。如果使用不同的证书为新版本签名,您必须为应用分配另一个软件包名称。在此情况下,用户会将新版本作为全新应用进行安装。
  • 应用模块化:Android 允许通过同一证书签名的多个 APK 在同一个进程中运行(如果应用请求这样做),以便系统将其视为单个应用。这样一来,您便可以按模块部署您的应用,并且用户可以独立更新每个模块。
  • 通过权限共享代码/数据:Android 提供了基于签名的权限执行机制,以便一个应用可以将功能提供给使用指定证书签名的另一个应用。通过使用同一个证书为多个 APK 签名并使用基于签名的权限检查功能,您的应用可以采用安全的方式共享代码和数据。

如何生成 APK 签名

确保本地有 java 环境,在命令行运行 keytool 生成 Android 签名证书。

例如:

keytool -genkeypair -alias android.test -keyalg RSA -validity 36500 -keystore java-android.p12 -storetype pkcs12

其中 android.test 是证书的别名。请记住,后续要使用。

运行后会让输入证书的密码等信息

最终会在当前文件夹下面生成名为 java-android.p12 的证书文件。

使用 Android Studio 进行签名非常快捷,可参考官方《使用 Android Studio 对应用进行签名》

Android Studio 主要用于本地手动签名,自动化签名的过程将会直接集成到 CI 中,详情见后续步骤六。

使用 CODING 制品库存储管理 APK

目前,APK 没有一个统一的存储方式,没有好的追溯方式,不便于使用或者管理。

Generic 制品库

CODING 提供了 Generic 制品库,可以提供自定义的 Tag 作为版本标签,可以对 APK 文件进行管理和版本追溯。

  1. 创建一个 Generic 制品库

  1. 使用页面上传功能上传 APK 文件

  1. 查看版本列表管理历史版本

使用 CODING 持续集成实现自动化

上述步骤,编译、签名和上传 APK 文件其实都是重复劳动动作。下面介绍一下如何使用持续集成来实现自动化,代替人工执行这些重复操作。

  1. 在 CODING 中创建一个项目并推送代码到仓库,可以参考示例项目
  1. 在持续集成->构建计划 中新建一个构建计划,推荐使用 Java-Android 模版进行创建。

JenkinsFile

pipeline {
  agent any
  stages {
    stage("检出") {
      steps {
        checkout(
          [$class: 'GitSCM',
          branches: [[name: env.GIT_BUILD_REF]],
          userRemoteConfigs: [[
            url: env.GIT_REPO_URL,
              credentialsId: env.CREDENTIALS_ID
            ]]]
        )
      }
    }

    // 下述演示的过程依赖于此示例仓库 https://coding-public.coding.net/p/java_android/git
    // 您可以根据自己的实际情况调整构建过程

    // 步骤二
    stage('构建') {
      steps {
        // 清理旧的生成物
        sh "./gradlew clean && rm -rf ./app/build/"
        // 编译构建产出
        sh "./gradlew assembleRelease"
      }
    }
    // 步骤三
    stage("APK 签名") {
      steps {
        signAndroidApks(
          keyStoreId: env.ANDROID_CREDENTIAL_ID,          // 凭据ID,凭据证书的使用详见步骤六
          keyAlias: env.ANDROID_CREDENTIAL_ALIAS,         // 证书别名,在生成证书时输入的别名
          apksToSign: "app/build/outputs/apk/**/*.apk",   // 需要签名的 APK 的路径
          archiveSignedApks: true,                        // Jenkins 能力,可以在构建产物中输出签名后的 APK
          archiveUnsignedApks: true,                      // Jenkins 能力,可以在构建产物中输出未签名的 APK
          skipZipalign: true                              // 跳过 zipalign 过程
        )
      }
    }
    // 步骤四
    stage('上传到 Generic') {
      steps {
        codingArtifactsGeneric(
          credentialsId: "${env.CODING_ARTIFACTS_CREDENTIALS_ID}",    // 默认的制品库凭据ID,CI 内置的环境变量
          withBuildProps: true,                                       // 默认值,是否上传附加属性
          files: "app/build/outputs/apk/**/*.apk",                    // 需要上传的文件路径
          repoName: "${env.GENERIC_REPO_NAME}",                       // 已创建的 Generic 制品库名称
          version: "${CI_BUILD_NUMBER}"                               // 制品版本,可根据需要自定义,这里默认为 CI 构建的序号
        )
      }
    }
  }
}

使用凭据管理统一管理安卓证书

团队合作中,共享安全证书会有安全和效率问题,以文件形式储存的证书也不易于管理。

CODING 的凭据管理功能,提供了统一管理证书的能力,使用人仅需知道公开的 credentialId 即可在 CI 中使用凭据。

如何使用凭据

  1. 在 项目设置->开发者选项->凭据管理 处,点击录入凭据,上传步骤三中生成的证书文件,点击保存。

  1. 在使用 Java-Android 模版创建构建计划时,直接在选择凭据的下拉框中选择刚创建好的凭据,点击选择并授权。

  1. 构建计划创建完成后,选择的凭据会授权至新建的构建计划,并新增环境变量 ANDROID_CREDENTIAL_ID,填入所选的 credentialId。

  2. 点击立即构建后,CI 就会自动化地进行编译构建、APK 签名和上传签名后 APK 至 Generic 制品库的操作。

总结

至此,我们已经把整个 Android 开发流程中重要的操作步骤完全自动化流水线化,这极大地简化了人工操作,让开发者能更好的从繁琐的开发流程中脱离出来,专注于代码功能的迭代研发。

目前 CODING 已经在持续集成中内置了上述的整个流程,可以通过简单的配置即可快速使用,轻量易于上手。

完整的代码例子可参见示例项目

上一篇Ruby + Sinatra 构建应用
最近更新
感谢反馈有用
感谢反馈没用