jenkins自动化编译安卓apk包

2021-04-14

项目编译说明

Android 编译环境搭建及必要参数说明
1.开发平台:Linux 目标平台:android
2.安装依赖:Node,JDK, Android SDK,Gradle, Yarn, WatchMan
  
  【✅】Node:版本12以上

  【✅】JDK:1.8 

  【✅】SDK: (sdkversion:28 ;buildtoolsVersion:28.0.3)

  【✅】Gradle: B端版-4.10.3 C端版本--5.4.1

  【✅】Yarn: npm install -g yarn

  【✅】WatchMan

编译打包
  B端包含RN组件,每次打包前需要更新第三方库,需要执行一次yarn命令;C端不需要
  打包指令:cd进android工程后执行下面命令
    测试环境:./gradlew assemblenewtestDebug
    正式环境:./gradlew assembleproductionRelease

  编译成功后在{主项目}android/app/build/outputs/apk/{环境}/{模式}/ 下找到{环境}_v{版本}_{模式}.apk

安装依赖:

- JDK(略)
- Android SDK
- Nodejs
- Yarn
- Gradle
- WatchMan

一、通过sdk-tools部署安卓sdk

1、创建 Android SDK 目录

mkdir /data/android-sdk

2、下载 SDK tools

wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip

3、解压缩并移动文件

unzip sdk-tools-linux-4333796.zip && mv tools /data/android-sdk/

4、分配权限

chown -R 1000:1000 /home/jenkins/android-sdk/

5、查看所有平台 SDK

cd /data/android-sdk/tools/bin/
./sdkmanager --list

6、根据你的项目,下载对应的平台 SDK

echo "y" | ./sdkmanager "platform-tools" "build-tools;28.0.3" "platforms;android-28"

7、配置环境变量

vi /etc/profile

##########android-sdk############
export ANDROID_HOME=/data/android-sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
################################

二、部署nodejs 12

官网: https://nodejs.org/en/download/package-manager/

1、下载nodejs二进制包

mkdir -p /data
wget https://nodejs.org/dist/v12.1.0/node-v12.1.0-linux-x64.tar.gz \
    && tar xf node-v12.1.0-linux-x64.tar.gz \
    && mv node-v12.1.0-linux-x64/ /data/node-v12.1.0

2、配置环境变量

vi /etc/profile

##########Nodejs12###############
export NODE_HOME=/data/node-v12.1.0
export PATH=$NODE_HOME/bin:$PATH
################################

三、安装yarn

安装yarn

npm install -g yarn

安装CodePush脚手架(公司项目需要)

yarn global add react-native-update-cli
yarn add react-native-update

四、部署gradle

1. 下载指定安装的版本

假如安装版本是4.10.3

wget https://downloads.gradle-dn.com/distributions/gradle-4.10.3-all.zip

2. 新建存放版本目录并解压

mkdir /data/gradle
unzip -d /data/gradle gradle-4.10.3-all.zip

3. 配置环境变量

编辑配置文件
vi /etc/profile

export GRADLE_HOME=/data/gradle/gradle-4.10.3
export PATH=${GRADLE_HOME}/bin:${PATH}

临时切换版本使用

export PATH=$PATH:/data/gradle/gradle-5.4.1//bin

4. 配置国内镜像

这是可选项,按需操作。
可进行全局配置或者是单独项目配置,设置全局配置后,则不需要单独配置。

4.1 全局配置

新增并编辑文件

mkdir ~/.gradle/
vi ~/.gradle/init.gradle

新增以下内容并保存

allprojects{
    repositories {
        def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/repository/public/'
        def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter/'
        def ALIYUN_GOOGLE_URL = 'https://maven.aliyun.com/repository/google/'
        def ALIYUN_GRADLE_PLUGIN_URL = 'https://maven.aliyun.com/repository/gradle-plugin/'
        all { ArtifactRepository repo ->
            if(repo instanceof MavenArtifactRepository){
                def url = repo.url.toString()
                if (url.startsWith('https://repo1.maven.org/maven2/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
                    remove repo
                }
                if (url.startsWith('https://jcenter.bintray.com/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
                    remove repo
                }
                if (url.startsWith('https://dl.google.com/dl/android/maven2/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_GOOGLE_URL."
                    remove repo
                }
                if (url.startsWith('https://plugins.gradle.org/m2/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_GRADLE_PLUGIN_URL."
                    remove repo
                }
            }
        }
        maven { url ALIYUN_REPOSITORY_URL }
        maven { url ALIYUN_JCENTER_URL }
        maven { url ALIYUN_GOOGLE_URL }
        maven { url ALIYUN_GRADLE_PLUGIN_URL }
    }
}

4.2 项目单独配置

在项目中找到文件build.gradle,并修改

buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google/' }
        maven { url 'https://maven.aliyun.com/repository/jcenter/'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'

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

allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google/' }
        maven { url 'https://maven.aliyun.com/repository/jcenter/'}
    }
}

五、部署watchman(公司项目需要)

官网:https://facebook.github.io/watchman/docs/install.html

1、下载watchman二进制包

wget https://github.com/facebook/watchman/releases/download/v2021.04.05.00/watchman-v2021.04.05.00-linux.zip

2、解压

unzip watchman-v2021.04.05.00-linux.zip \
    && cd watchman-v2021.04.05.00-linux

3、复制文件到目录并赋权

mkdir -p /usr/local/{bin,lib} /usr/local/var/run/watchman
cp bin/* /usr/local/bin
cp lib/* /usr/local/lib
chmod 755 /usr/local/bin/watchman
chmod 2777 /usr/local/var/run/watchman

编译打包

更新依赖node_modules

cd /usr/local/src/demo/imapp_rn/
yarn config set ignore-engines true && yarn config set registry https://registry.npm.taobao.org && yarn --prefer-offline

调用npx jetify将所有node_modules迁移到AndroidX

npx jetify

测试环境打包apk

gradle clean assemblenewtestDebug --no-daemon --stacktrace

# 输出路径
android/app/build/outputs/apk/newtest/debug

生产环境打包apk

gradle clean --no-daemon assembleproductionRelease --stacktrace

# 输出路径
android/app/build/outputs/apk/production/release

jenkins pipeline

pipeline {
    agent {
        label 'apk-slave'
    }
    options {
        ansiColor('xterm')
        buildDiscarder(logRotator(daysToKeepStr: '1', numToKeepStr: '3'))
    }
    tools {
        jdk 'jdk_1.8_202'
        git 'git_2.19.1'
    }

    parameters{
        listGitBranches(
            remoteURL: 'http://apk.demo.com/demo.git',
            branchFilter: '.*',
            tagFilter: '*',
            defaultValue: 'master',
            name: 'BRANCH_OR_TAG',
            type: 'PT_BRANCH_TAG',
            selectedValue: 'TOP',
            sortMode: 'DESCENDING_SMART',
            quickFilterEnabled: 'true',
            credentialsId: 'gitlab_username_password_credential')
    }

    environment {
        GIT = 'http://apk.demo.com/demo.git'
        FILENAME='demo.apk'
        BUILD_ARG = sh(script: """echo ${NEWENV} | awk -F '-' '{if (\$1=="prd") {print "assembleproductionRelease"} else {print "assemblenewtestDebug"}}' """, returnStdout: true).trim()
        OUTPUTS_DIR = sh(script: """echo ${NEWENV} | awk -F '-' '{if (\$1=="prd") {print "production/release"} else {print "newtest/debug"}}' """, returnStdout: true).trim()
        PROJECT = sh(script: """echo ${GIT} | awk -F '/' '{print \$NF}' | awk -F '.' '{print \$1}' | awk -F '-' '{if (\$1=="${IMAGE_GROUP}") {print \$0} else {print "${IMAGE_GROUP}-"\$0}}'| tr "[:upper:]" "[:lower:]" """, returnStdout: true).trim()
        ENV = sh(script: "echo ${JOB_BASE_NAME} | awk -F '-' '{print \$1}'", returnStdout: true).trim()
        NEWENV = sh(script: """echo ${JOB_BASE_NAME} | awk -F '-' '{if (\$1=="test") {print "new"\$1} else {print \$1}}' """, returnStdout: true).trim()
        CHECK_TAG = sh(script: "echo ${BRANCH_OR_TAG} | awk -F '/' '{if (\$3) print \$3; else print \$1}'", returnStdout: true).trim()  // 分支或tag
    }
    stages {
        stage ('代码获取') {
            steps {
              echo "\033[46;30m************************************************ 拉取代码开始 ************************************************\033[0m"
              git credentialsId: 'gitlab_username_password_credential', url: "${GIT}"
              sh '[ -n "${CHECK_TAG}" ] &&  git checkout ${CHECK_TAG} ||  { echo -e "切换至指定的tag的版本,tag:${CHECK_TAG} 不存在或为空,请检查输入的tag!" && exit 111; }'
              sh "git pull origin ${CHECK_TAG} || true"
              buildName "${CHECK_TAG}"
              echo "\033[46;30m************************************************ 拉取代码结束 ************************************************\033[0m"
            }
        }


        stage ('编译打包'){
          steps{
            withEnv(["PATH+NODE_HOME=/data/node-v12.1.0/bin","PATH+GRADLE_HOME=/data/gradle/gradle-4.10.3/bin"]) {
              echo "\033[46;30m************************************************ 编译打包开始 ************************************************\033[0m"
              sh "[ -d 'node_modules' ] && echo 'Directory Exists' || mkdir node_modules && mount --bind /data/modules_mount/node_modules node_modules"
              sh "yarn config set ignore-engines true && yarn config set registry https://registry.npm.taobao.org && yarn --prefer-offline && npx jetify"
              sh 'cd android && gradle clean ${BUILD_ARG} --no-daemon --stacktrace'
              echo "\033[46;30m************************************************ 编译打包结束 ************************************************\033[0m"
            }
          }
        }

    
    }

    post {
       always {
                script{
                    sh "umount node_modules" // 解除目录挂载
                    deleteDir() // 清理工作目录
                }
        }
    }

}

参考链接

https://www.androidos.net.cn/doc/2021/2/14/86.html
https://www.jianshu.com/p/551a3d3debc9
https://www.cnblogs.com/gj5379/p/10827748.html
https://blog.csdn.net/wc1695040842/article/details/102230401
https://blog.csdn.net/gxl3999/article/details/44282469


标题:jenkins自动化编译安卓apk包
作者:fish2018
地址:http://seczh.com/articles/2021/04/14/1618382331649.html