Android项目jenkins多分支流水脚本线构建总结(三)

研究了一周的jenkins自动化构建,这篇记录下过程中出现的问题,本且脚本存挡,以后就可以直接复制粘贴了。

我这儿就接上上次构建说了,整个自动化流程就是 构建——加固——发送邮件——apk存档。这个流程中我上两篇已经详细
介绍了构建加固,以及发送邮件。

第一个问题,在我360加固中,360加固程序我放在github上,有1.0和2.0两个版本,1.0为完整版本,2.0是我删除了部分java相关代码。我自己使用用的2.0,因为1.0完整包有点慢,下载耗时太多。2.0版本加固没有问题,但是无法自动签名,所以我在加固后自行签名了下,在这儿补上签名脚本。

#!/bin/bash
set -x
function echoHelp() {
  echo "Usage: $0 <ApkFile>"
}
#判断当前脚本第一个参数是否为空,为空则关闭脚本
if [[ ! -n $1 ]]; then
  echoHelp
  exit 0 
fi
# 脚本第一个参数,要签名的apk路径
file=$1
# 我的签名路径名称密码都配置在此文件中加载加载进来
source `dirname $0`/signature.properties
# 循环查找Android优化工具zipalign,并进行优化
zipalignexe=`find $ANDROID_HOME/build-tools -name "zipalign*" |sort |tail -n 1`
if [[ -n $1 ]]; then
  unaligned=${file}unaligned
  mv $file $unaligned && $zipalignexe -p 4 $unaligned $file && rm $unaligned
fi
#循环查找Android签名工具apksigner
apksignerexe=`find $ANDROID_HOME/build-tools -name "apksigner" |sort |tail -n 1`
#开始签名  请自动配置路径,名称和密码
$apksignerexe sign --ks "`dirname $0`/$storeFile" --ks-pass pass:$storePass \
  --ks-key-alias $keyAlias -key-pass pass:$keyPass \
  --v1-signing-enabled true \
  --v2-signing-enabled true \
  $file

重点来了,坑一

我用上边脚本循环查找apksigner,最终找到路劲为 /local/android-sdk-linux/build-tools/29.0.0-preview/apksigner
这个29.0.0preview下面签名后的包没法用,大家注意,很坑

我build-tools下面包为

jenkins 流水线 archiveArtifacts jenkins 流水线 shell构建_Android签名脚本


我删掉29.0.0-preview,再签名,ok完美,木有任何问题。

gitlab自动化触发Jenkins分支流水线扫描

到上边签名完成,整体脚本和构建已经经完成,但是不知道大家注意没有,Jenkins分支流水线没有设置Build Triggers webhook的地方,只有定时自动扫描,这种自己用的很不爽。我希望能设置webhook,我们每次push代码能触发实时构建。
经过网上查找资料,看到一位大神找到一种方式在此记录下:

在项目webhook设置url 的格式为 http://{Jenkins的host}/git/notifyCommit?url={Multibranch Pipeline里面配置的项目地址}。

至此Jenkins自动化构建完美收官,下面贴出自己的构建脚本,方便以后

pipeline {

    agent {
        label '修改为自己镜像'
    }
    options {
        timeout(time: 1, unit: 'HOURS')
    }
    stages {

        stage('Build') {
            steps {
                sh "./gradlew clean assembleRelease testTestRelease"
            }
        }

        stage ('Publish') {
            when {
                expression { BRANCH_NAME ==~ /release\/.*/ }
            }
            steps {
                sh "./gradlew -Ppublish assembleRelease"
            }
        }

        stage ('Enhance') {
            when {
                expression { BRANCH_NAME ==~ /release\/.*/ }
            }
            steps {
                sh "./buildsystem/jiagu.sh"
                emailext(
                        subject: "Android加固成功",
                        mimeType: "text/html",
                        attachmentsPattern: "build/jiagu/archives/*",
                        body: enhanceEmailBody(),
                        to: "修改为要发送的邮箱,多个用英文逗号隔开",
                        recipientProviders: [[$class: 'CulpritsRecipientProvider'],
                                         [$class: 'DevelopersRecipientProvider'],
                                         [$class: 'RequesterRecipientProvider']]
                )
            }
        }
    }
    post {
        success {
            archiveArtifacts 'build/jiagu/archives/*'
        }

    }
}

def enhanceEmailBody() {
    return """<p>Android加固成功。</p>
           <p>更新日志:<br/>
           ${getChangeString().replaceAll("\\\\\\\\n", "")}</p>
           <p>附件说明如下:</p>
             <ol>
               <li>文件名带jiagu的,是加固后的包,用于分发。</li>
               <li>文件名不带jiagu的,与mapping开头的txt文件,用于生成补丁。</li>
               <li>git-info.txt文件为本次构建代码的最新git信息。</li>
             </ol>
           </p>
           """
}

加固脚本

#!/bin/bash

cd `dirname $0`/../
projectDir=`pwd`
buildDir="$projectDir/build"

# release Official apk
cd $buildDir
touch timestampFile
echo "Build release official apk"
cd $projectDir
# invoke gradlew to build the official apk
./gradlew releaseOfficial || exit 1
# find the target apk
targetApk=`find $projectDir/release -name "*.apk" -newer $buildDir/timestampFile`
if [ ! -n "$targetApk" ]; then
  echo "Apk is not changed. Exit"
  exit 0
fi

# download the program
cd ~/
jgCacheDir=".android/jiagu"
jgVersion="1.0"
jgFolder=360-jiagu-$jgVersion
jgZipName=$jgFolder.zip
if [ ! -d "$jgCacheDir" ]; then
  mkdir -p ${jgCacheDir}
fi
cd $jgCacheDir

if test -e "$jgZipName"; then
  zflag=" -z $jgZipName"
else
  zflag=""
fi
echo "zflag = "
echo zflag
curl -L -e ";auto" -o $jgZipName https://github.com/smallTrong/360jiagu/archive/2.0.zip

# extract
cd $buildDir
echo "Extract jiagu.zip"
unzip -oq ~/$jgCacheDir/$jgFolder -d .
if [ ! -d "jiagu" ]; then
  mv 360* jiagu
else
  cp -rf $jgFolder/* jiagu/
fi
#cd jiagu && ./init.sh || exit 1

cd $buildDir/jiagu
cd ..
chmod -R 777 jiagu
cd jiagu

# login

java -jar jiagu.jar -login 360加固账号 密码
# remove unnecessary service config
java -jar jiagu.jar -config -
# process

mkdir -p output

for file in `find output -name "*.apk"`; do
  rm $file;
done
echo "Start process $targetApk"
java -jar jiagu.jar -jiagu $targetApk output || exit 1
enhancedApk=`find output -name "*.apk"`

# sign
echo "Sign $enhancedApk"
$projectDir/buildsystem/signIOP.sh $enhancedApk

# cp the archives to folder
if [ ! -d "archives" ]; then
  mkdir archives
else
  rm archives/*
fi
cp $enhancedApk archives/
for file in `find $projectDir/release -type f -newer $buildDir/timestampFile`; do
  cp $file archives/
done
git log -n 1 > archives/git-info.txt

签名脚本本文章上边已有