您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

Android 在jenkins自动打包

时间:2022-06-16 10:44:33  来源:  作者:运维蚂蚁

一、背景

由于公司的jenkins运行在k8s集群中,在jenkins打包时调用jenkins-slave 来工作,所以需先构建Android-jenkins-slave镜像。

jenkins-slave 在打包过程中会用到gradle和sdk,那么就牵涉到gradle插件和sdk持久化。

Android打包对资源要求较高,也可以单独建立jenkins工作节点,将Android打包调度到物理机节点进行。

二、NFS存储

//安装NFS服务端
[root@nfs-server ~]# yum install -y nfs-utils
[root@nfs-server ~]# mkdir -p /data/android
[root@nfs-server ~]# mkdir -p /data/gradle

[root@nfs-server ~]# vi /etc/exports
/data/android 192.168.10.0/24(rw,no_root_squash)
/data/gradle 192.168.10.0/24(rw,no_root_squash)

[root@nfs-server ~]# systemctl enable rpcbind.service
[root@nfs-server ~]# systemctl enable nfs-server.service

[root@nfs-server ~]# systemctl start rpcbind.service
[root@nfs-server ~]# systemctl start nfs-server.service
[root@nfs-server ~]# exportfs -r

//可能存在NFS无法访问,需提高权限
[root@nfs-server ~]#  chmod -R 777 /data/android /data/gradle

三、android-jenkins-slave镜像的Dockerfile

[root@mayi-ops jenkins-slave-android]# vim Dockerfile
FROM centos:7
LABEL mAIntainer dengyoucheng

COPY jdk-8u261-linux-x64.rpm /opt
COPY gradle-6.7.1-all.zip /opt
COPY sdk-tools-linux-3859397.zip /opt 
COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave

#init
RUN yum -y install wget && \
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak && \
    wget -O /etc/yum.repos.d/CentOS-Base.repo <http://mirrors.aliyun.com/repo/Centos-7.repo> && \
    yum makecache && \
    yum -y install epel-release && \
    yum -y install gcc gcc-c++ jq.NET-tools git unzip && \
    yum clean all && \
    rm -rf /var/cache/yum/* && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    mkdir -p /opt/android/sdk && \
    mkdir -p /usr/share/jenkins && \
    chmod +x /usr/bin/jenkins-slave

#install JAVA
RUN yum -y install /opt/jdk-8u261-linux-x64.rpm
ENV JAVA_HOME /usr/java/jdk1.8.0_261-amd64
ENV JRE_HOME  ${JAVA_HOME}/jre
ENV CLASSPATH .$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin

#install sdk
#./sdkmanager --list查看有哪些版本
RUN unzip  /opt/sdk-tools-linux-3859397.zip -d /opt/android/sdk && \
    mkdir /root/.android/ && touch /root/.android/repositories.cfg && \
    cd /opt/android/sdk/tools/bin && \
    ./sdkmanager --list
ENV ANDROID_HOME /root/.android
ENV PATH $PATH:$ANDROID_HOME:$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools
ENV ANDROID_ROOT /opt/android/sdk 
ENV PATH $PATH:$ANDROID_ROOT/tools:$ANDROID_ROOT/tools/bin
# sdkmanagerSDK指定目录,可以持久化存储
# yes | ./sdkmanager --licenses && \
# yes | ./sdkmanager "build-tools;33.0.0" "platforms;android-33" "build-tools;30.0.2" "platforms;android-30" "platform-tools" --sdk_root=/root/.android

#install gradle
RUN cd /opt/ && \
    unzip gradle-6.7.1-all.zip && \
    mv gradle-6.7.1 gradle
ENV PATH $PATH:/opt/gradle/bin

WORKDIR /opt
ENTRYPOINT ["jenkins-slave"]

三、pipeline 脚本(测试脚本)

//*************************************************
// Author       : mayi-ops
// Last modified: 2021-01-06
// wechat:        a403182580
// Description  : 安卓打包脚本
//*************************************************

//定义java-slave的yaml
def podTemplate = """
kind: Pod
metadata:
  name: android-slave
spec:
  containers:
  - name: jnlp
    image: "${registry}/library/jenkins-slave-android:1.3"
    imagePullPolicy: Always
    volumeMounts:
      - name: docker-cmd
        mountPath: /usr/bin/docker
      - name: docker-sock
        mountPath: /var/run/docker.sock
      - name: gradlecache
        mountPath: /root/.gradle
      - name: androidcache
        mountPath: /root/.android
  volumes:
    - name: docker-cmd
      hostPath:
        path: /usr/bin/docker
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock
    - name: gradlecache
      nfs:
        server: ${nfsip}
        path: ${gradle_cache}
    - name: androidcache
      nfs:
        server: ${nfsip}
        path: ${android_cache}
"""

//pipeline构建过程
pipeline {
    agent {
        //根据yaml创建salve
        kubernetes {
            label "android-slave"
            yaml podTemplate
        }
    }
    //变量
    environment {
        DingTalkHook = "<https://oapi.dingtalk.com/robot/send?access_token=**********>"
    }
    stages { 
        //如果是非admin、打包、打包部署,才会打包
        stage('拉取代码') {
            steps{
                script {
                    /* 获取git地址 */
                    if ( env.GitAddress ){
                        if ( env.GitAddress == '' ) {
                            echo "请输入git分支!"
                        }
                    }else{
                        echo "请输入gitlab项目地址。"
                        exit 0
                    }
                       
                    /* 代码分支 */
                    //输入分支:参数化构建过程->字符参数->名称:codeBranch->默认值:fat
                    if ( env.codeBranch ){
                        if ( env.codeBranch == '' ){
                            echo "请输入git分支!"
                        }
                    }else{
                        echo "没输入分支,默认使用master"
                        env.codeBranch = "master"
                    }
                    echo "git:"+env.GitAddress
                    echo "Branch:"+env.codeBranch

                    //拉取业务代码
                    checkout([  
                        $class: 'GitSCM',
                        branches: [[name: "${codeBranch}"]],
                        doGenerateSubmoduleConfigurations: false,
                        extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'code']],
                        submoduleCfg: [],
                        userRemoteConfigs: [[credentialsId: "build_auth", url: "${GitAddress}"]]
                    ])
                }
            }
        }
        
        stage('android打包'){
            steps{
                script {
                    dir("code"){
                        /* 打包脚本 */
                        sh "java -version"
                        sh "adb version"
                        sh "gradle -v"

                        echo "=================gradle打包中==============================="
                        sh "gradle assembleRelease"
                        
                        echo "=================gradle打包完成============================="
                        sh "cp App/build/outputs/apk/*/*.apk /root/ttt.apk"

                        echo "=================gradle clean=============================="
                        //sh "gradle clean"
                    }
                }
            }
        }
        
        stage('push APK'){
            steps{
                script {
                    env.Apkurl = sh returnStdout: true, script: """curl -F "file=@/root/ttt.apk" -F "uKey=${env.USER_KEY}" -F "_api_key=${env.API_KEY}" <https://qiniu-storage.pgyer.com/apiv1/app/upload|jq|grep> appQRCodeURL|awk -F'"' '{print \$4}'"""
                    echo "蒲公英二维码地址: "+env.Apkurl
                }
            }
        }
    }
    //使用post 插件必须使用pipeline,不能使用podTemplate插件
    post {
        //安装插件 HTTP Request Plugin和 Post build task
        success{
            script {
                //打包成功
                def ReqBody = """{
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "APK打包信息",
                        "text": "## 【${env.objectname}】打包成功 ✅ \n>- **打包分支:${env.codeBranch}**\n>- **扫描二维码下载APK:**\n>- ![screenshot](${env.Apkurl}) \n>- 构建日志: [点击查看详情](${env.BUILD_URL}console)"
                    },
                    "at": {
                        "isAtAll": true
                    }
                }"""
                httpRequest acceptType: 'APPLICATION_JSON_UTF8', 
                    consoleLogResponseBody: false, 
                    contentType: 'APPLICATION_JSON_UTF8', 
                    httpMode: 'POST', 
                    ignoreSslErrors: true, 
                    requestBody: ReqBody, 
                    responseHandle: 'NONE', 
                    url: "${env.DingTalkHook}",
                    quiet: true         
            }
        }
        failure{
            script {
                //打包失败
                def ReqBody = """{
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "APK打包信息",
                        "text": "## 【${env.objectname}】打包失败 ❌ \n>- **打包分支:${env.codeBranch}**\n>- 构建日志: [点击查看详情](${env.BUILD_URL}console)"
                    },
                    "at": {
                        "isAtAll": true
                    }
                }"""
                httpRequest acceptType: 'APPLICATION_JSON_UTF8', 
                    consoleLogResponseBody: false, 
                    contentType: 'APPLICATION_JSON_UTF8', 
                    httpMode: 'POST', 
                    ignoreSslErrors: true, 
                    requestBody: ReqBody, 
                    responseHandle: 'NONE', 
                    url: "${env.DingTalkHook}",
                    quiet: true         
            }
        }
    }
}


Tags:jenkins   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
使用 Jenkins 与 KubeVela 实现应用的持续交付
KubeVela 打通了应用与基础设施之间的交付管控的壁垒,相较于原生的 Kubernetes 对象,KubeVela 的 Application 更好地简化抽象了开发者需要关心的配置,将复杂的基础设施能力及...【详细内容】
2023-10-19  Search: jenkins  点击:(265)  评论:(0)  加入收藏
Jenkins+Docker一键打包部署Vue项目步骤详解
一、服务器环境配置&emsp;前面说明了服务器Nginx的安装和配置,这里稍微有些不同,但是因为此文是用Nginx镜像和前端镜像页面同时部署的方式来打包发布的,所以这里不再需要建立 /...【详细内容】
2023-09-15  Search: jenkins  点击:(185)  评论:(0)  加入收藏
Jenkins的四种安装部署方式以及Jenkins的基本配置
一、Jenkins简介Jenkins是一个开源的自动化服务器,用于实现持续集成和持续交付的流程。它提供了一种易于使用且可扩展的方式来构建、测试和部署软件。Jenkins的核心思想是通...【详细内容】
2023-08-16  Search: jenkins  点击:(504)  评论:(0)  加入收藏
jenkins中部署VUE
一、安装nodejs插在 系统管理-》插件管理 中 安装nodejs插件二、配置nodejs插件在jenkins全局工具配置中,配置nodejs,如下图 三、编写docker文件FROM nginx RUN rm /etc/ngin...【详细内容】
2023-02-21  Search: jenkins  点击:(202)  评论:(0)  加入收藏
k8s-jenkins安装
1.创建namespaceapiVersion: v1kind: Namespacemetadata:name: jenkins2.创建deployomentapiVersion: apps/v1kind: Deploymentmetadata:name: jenkinsspec:replicas: 1sele...【详细内容】
2022-07-06  Search: jenkins  点击:(291)  评论:(0)  加入收藏
Android 在jenkins自动打包
一、背景由于公司的jenkins运行在k8s集群中,在jenkins打包时调用jenkins-slave 来工作,所以需先构建android-jenkins-slave镜像。jenkins-slave 在打包过程中会用到gradle和sd...【详细内容】
2022-06-16  Search: jenkins  点击:(698)  评论:(0)  加入收藏
Jenkins基于Nginx实现域名访问,反向代理详细配置总结
背景:运维思路来讲,前两篇文章详细介绍到jenkins部署,仅仅是对于体验于学习,但运维任重而道远,往往生产不可轻易暴露自己的IP,因此前面我们学习到的IP+端口号的方式就不合适了,基于...【详细内容】
2022-04-29  Search: jenkins  点击:(805)  评论:(0)  加入收藏
如何在Jenkins上自动化部署Vue,手把手教你
第一步、部署环境1、安装nodeJs1、下载nodewget https://nodejs.org/dist/v16.8.0/node-v16.8.0-linux-x64.tar.xz2、解压压缩包xz -d node-v8.11.2-linux-x64.tar.xztar -x...【详细内容】
2021-09-06  Search: jenkins  点击:(335)  评论:(0)  加入收藏
Windows环境下安装Jenkins
前提条件:已成功安装JDK。官网下载地址: https://www.jenkins.io/download 二、安装1、jenkins安装包安装(1)直接双击运行已经下载好的jenkins.msi安装包 (2)点击"运行" (3)点击"Nex...【详细内容】
2021-06-23  Search: jenkins  点击:(407)  评论:(0)  加入收藏
jenkins+Acunetix实现自动化安全测试
目前主流的开发采用的是devops模式(开发、测试、运维一体化)。随着互联网安全要求越来越高,对网络安全就越发变得重要了。传统的测试工程师主要是对功能、接口、性能方面做测试...【详细内容】
2021-06-23  Search: jenkins  点击:(462)  评论:(0)  加入收藏
▌简易百科推荐
Android Emulator黑屏怎么办 Android模拟器黑屏解决方法
Android Emulator黑屏问题困扰了非常多的玩家,Android Emulator作为一款安卓模拟器,可以让你在电脑上运行和浏览安卓应用程序,但是程序本身不是很稳定,很容易会出现黑屏,启动不了...【详细内容】
2024-03-04  18183游戏网    Tags:Android Emulator   点击:(45)  评论:(0)  加入收藏
Android开发中常见的Hook技术有哪些?
Hook技术介绍Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事...【详细内容】
2023-12-25  沐雨花飞蝶  微信公众号  Tags:Android   点击:(91)  评论:(0)  加入收藏
在Android应用开发中使用NFC功能
NFC介绍NFC是指“近场通讯”(Near Field Communication),它是一种短距离无线通信技术,允许设备在非接触或极短距离内进行通信。NFC通常用于移动支付、门禁系统、智能标签和其他...【详细内容】
2023-12-22  沐雨花飞蝶  微信公众号  Tags:Android   点击:(104)  评论:(0)  加入收藏
关于Android图像Bitmap类,你要知道的一切
Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色...【详细内容】
2023-12-19  沐雨花飞蝶  微信公众号  Tags:Android   点击:(102)  评论:(0)  加入收藏
Android开发中如何进行单元测试?
单元测试介绍单元测试是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是函数或方法)是否按预期工作。单元测试通常由开发人员编写,旨在隔离和测试代码的特定部...【详细内容】
2023-12-11  沐雨花飞蝶  微信公众号  Tags:Android   点击:(170)  评论:(0)  加入收藏
一篇聊聊Jetpack Room实现数据存储持久性
Room介绍Room 是 Android Jetpack 组件库中的一部分,它是用于在 Android 应用中进行本地数据库访问和管理的库。Room 提供了一个抽象层,使开发者能够更轻松地访问 SQLite 数据...【详细内容】
2023-12-08  沐雨花飞蝶  微信公众号  Tags:Jetpack   点击:(149)  评论:(0)  加入收藏
了解Android系统架构中的HAL硬件抽象层
在Android系统中,HAL的存在使得不同厂商的硬件可以统一被上层的应用程序调用,从而提高了系统的兼容性和可移植性。HAL还可以帮助开发者更方便地开发应用程序,因为他们不需要为...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:Android   点击:(212)  评论:(0)  加入收藏
我们一起聊聊 IntentService 与 Service 的区别?
Service介绍Service组件是Android应用开发中的四大组件之一,用于在后台执行长时间运行的操作或处理远程请求。它可以在没有用户界面的情况下执行任务,并且可以与其他应用组件...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:IntentService   点击:(178)  评论:(0)  加入收藏
Android数据对象序列化原理与应用
序列化与反序列化「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换...【详细内容】
2023-11-14  沐雨花飞蝶  微信公众号  Tags:Android   点击:(279)  评论:(0)  加入收藏
你了解Android中的SELinux吗?
SELinux介绍SELinux(Security-Enhanced Linux)是一种安全增强的Linux操作系统,它通过强制访问控制(MAC)机制来提供更高级别的系统安全保护。相比于传统的Linux访问控制机制(DAC),SEL...【详细内容】
2023-11-09  沐雨花飞蝶  微信公众号  Tags:Android   点击:(272)  评论:(0)  加入收藏
站内最新
站内热门
站内头条