思考
采用docker编译我们可以在本地不配置任何环境,只要安装docker,并下载docker镜像就好了。我在其他机器想编译,那我只需要把镜像pull下来,运行就好了。如果没有我们想要的镜像,我们可以自己配置,然后上传到docker hub,留着以后什么时候需要就下载。
构建docker环境
这里使用dockerfile来构建android的编译环境。如果不想自己构建,也可以直接用我构建好的镜像:registry.cn-hangzhou.aliyuncs.com/lm93129/android_env:v1
FROM ubuntu:18.10
MAINTAINER Yang zixi
ENV ANDROID_HOME="/opt/android-sdk" \
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
# 获取最新版本的sdktools地址:https://developer.android.com/studio/index.html
ENV ANDROID_SDK_TOOLS_VERSION="4333796"
# 设置本地语言
ENV LANG="en_US.UTF-8" \
LANGUAGE="en_US.UTF-8" \
LC_ALL="en_US.UTF-8"
RUN apt-get clean && apt-get update -qq && apt-get install -qq -y apt-utils locales && locale-gen $LANG
ENV DEBIAN_FRONTEND="noninteractive" \
TERM=dumb \
DEBIAN_FRONTEND=noninteractive
# 设置android环境变量
ENV ANDROID_SDK_HOME="$ANDROID_HOME"
ENV PATH="$PATH:$ANDROID_SDK_HOME/emulator:$ANDROID_SDK_HOME/tools/bin:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools:$ANDROID_NDK:$FLUTTER_HOME/bin:$FLUTTER_HOME/bin/cache/dart-sdk/bin"
WORKDIR /tmp
# 安装一些依赖包,这里由于我个人需要,所以多安装了一些,可以根据自己的实际情况,少安装一些包
RUN apt-get update -qq > /dev/null && \
apt-get install -qq locales > /dev/null && \
locale-gen "$LANG" > /dev/null && \
apt-get install -qq --no-install-recommends \
build-essential \
autoconf \
curl \
git \
lib32stdc++6 \
lib32z1 \
lib32z1-dev \
libc6-dev \
libgmp-dev \
libmpc-dev \
libmpfr-dev \
libxslt-dev \
libxml2-dev \
m4 \
ncurses-dev \
ocaml \
openjdk-8-jdk \
openssh-client \
pkg-config \
software-properties-common \
unzip \
wget \
zip \
zlib1g-dev > /dev/null
# 安装SDK
RUN echo "Installing sdk tools ${ANDROID_SDK_TOOLS_VERSION}" && \
wget --quiet --output-document=sdk-tools.zip \
"https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS_VERSION}.zip" && \
mkdir --parents "$ANDROID_HOME" && \
unzip -q sdk-tools.zip -d "$ANDROID_HOME" && \
rm --force sdk-tools.zip && \
# 安装sdk中的组件,可以根据需要自行修改
mkdir --parents "$ANDROID_HOME/.android/" && \
echo '### User Sources for Android SDK Manager' > \
"$ANDROID_HOME/.android/repositories.cfg" && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager --licenses > /dev/null && \
echo "Installing platforms" && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"platforms;android-28" \
"platforms;android-27" \
"platforms;android-26" \
"platforms;android-25" > /dev/null && \
echo "Installing platform tools " && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"platform-tools" > /dev/null && \
echo "Installing build tools " && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"build-tools;28.0.3" "build-tools;28.0.2" > /dev/null && \
echo "Installing extras " && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"extras;android;m2repository" \
"extras;google;m2repository" > /dev/null && \
echo "Installing play services " && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"extras;google;google_play_services" \
"extras;m2repository;com;android;support;constraint;constraint-layout;1.0.2" > /dev/null && \
echo "Installing Google APIs" && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager \
"add-ons;addon-google_apis-google-24" \
"add-ons;addon-google_apis-google-23" > /dev/null && \
yes | "$ANDROID_HOME"/tools/bin/sdkmanager --licenses
# 设置Jenkins的环境
RUN mkdir -p /var/lib/jenkins/workspace
RUN mkdir -p /home/jenkins
RUN chmod 777 /home/jenkins
RUN chmod 777 /var/lib/jenkins/workspace
RUN chmod 777 $ANDROID_HOME/.android
保存上面的代码为Dockerfile,然后运行docker build -t android_builder:v1 .
就可以构建镜像。构建过程,需要下载谷歌的东西,所以国内网络可能会有问题,请注意网络,或者自行再构建过程中加入代理,我这里使用国外的服务器构建的,所以没有该问题。
这个镜像可以根据需要自己进行扩展,比如我这里只有android25-28的。如果你需要其他的,也可以自己再加。
使用方法
直接使用镜像
我们可以将android项目目录挂载到容器中,然后运行命令即可。例如:
docker run -it --rm -v /home/android:/home/builder/workdir -u 0:0 android_builder:v1 /bin/bash
然后进入/home/builder/workdir中运行构建命令即可,上面使用了--rm命令,所以再容器关闭后会自动销毁。
Jenkins中使用镜像
直接贴上pipeline的代码,其中镜像可以挂载/root/.gradle目录,可以实现不需要每次都下载依赖。然后关于蒲公英的上传,这里只是做了一个示例。这个脚本里面还可以再扩展下,比如构建完成之后钉钉通知下载app之类的
pipeline {
environment {
CI = 'true'
}
agent {
docker {
image 'registry.cn-hangzhou.aliyuncs.com/lm93129/android_env:v1'
args '-v /docker/ci-cache/.gradle:/root/.gradle'
}
}
parameters {
listGitBranches branchFilter: '*', credentialsId: 'gitlab', defaultValue: 'master', name: 'prj_tag', quickFilterEnabled: false, remoteURL: 'http://gitlab.com.cn/asoco/xxxx.git', selectedValue: 'NONE', sortMode: 'DESCENDING_SMART', tagFilter: '*', type: 'PT_BRANCH'
}
stages {
stage('构建') {
steps {
echo '开始构建'
git credentialsId: 'gitlab', url: 'http://gitlab.com.cn/asoco/xxxx.git'
sh 'git checkout ${prj_tag}'
sh '/bin/bash gradlew assembleRelease'
echo '构建成功'
}
}
stage('代码扫描') {
steps {
echo '开始代码扫描'
sh './gradlew sonarqube'
echo '代码扫描结束'
}
}
stage('apk上传') {
steps {
echo '上传代码到蒲公英'
sh "curl -F "file=@/tmp/*.apk" -F "uKey=" -F "_api_key=" https://qiniu-storage.pgyer.com/apiv1/app/upload "
}
}
}
post {
failure {
echo '失败'
}
success {
archiveArtifacts artifacts: 'app/build/outputs/apk/release/*.apk', fingerprint: true
}
}
}