美文网首页
Android持续集成:Jenkins+Gradle+360加固

Android持续集成:Jenkins+Gradle+360加固

作者: 郭某人1 | 来源:发表于2019-05-22 19:42 被阅读0次

    Gradle脚本

    一. 在Project下新建一个目录reinforce,将360加固相关文件导入

    图片.png
    import java.util.zip.ZipEntry
    import java.util.zip.ZipOutputStream
    
    ext {
        BASE = getBasePath()
    
        JAR = BASE + "jiagu.jar"
        JAVA_JAR = "-jar"
    
        NAME = ""//360加固账号
        PASSWORD = ""//360加固密码
    
        CHANNEL_CONFIG = BASE + "channel.txt"//保存渠道配置
        OUTPUT_PATH = "build/outputs/" + BUILD_TYPE.toLowerCase() + "/"
        //根目录下的build目录  : 加固后所有apk的保存路径
    }
    
    def getKeyPath() {
        if ("true".equals(IS_JENKINS)) {
            if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
                println "jenkins debug 构建"
                return "/var/lib/jenkins/jobs/android/workspace/***/debug.keystore"
            } else {
                println "jenkins release 构建"
                return "/var/lib/jenkins/jobs/android/workspace/***/***.keystore"
            }
        } else {
            if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
                return "/Users/ningkang/StudioProjects/app-hongcai/hongcai/debug.keystore"
            } else {
                return "/Users/ningkang/StudioProjects/app-hongcai/hongcai/hongcai-release.keystore"
            }
        }
    }
    
    def getKeyPassword() {
        if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
            println "debug keypassword"
            return "hongcaitest"
        } else {
            println "release keypassword"
            return RELEASE_STORE_PASSWORD
        }
    }
    
    
    def getAliasPassword() {
        if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
            println "debug aliaspassword"
            return "hongcaitest"
        } else {
            println "release aliaspassword"
            return RELEASE_KEY_PASSWORD
        }
    }
    
    def getAlias() {
        if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
            println "debug alias"
            return "debug.keystore"
        } else {
            println "release alias"
            return "hongcai"
        }
    }
    
    def getApkFilePath() {
        if ("true".equals(IS_JENKINS)) {
            return "/var/lib/jenkins/jobs/android/workspace/hongcai/build/outputs/apk/office/"
        } else {
            return "hongcai/build/outputs/apk/"
        }
    }
    
    def getBasePath() {
        if ("true".equals(IS_JENKINS)) {
            println "BasePath:  /var/lib/jenkins/jobs/android/workspace/reinforce/"
            return "/var/lib/jenkins/jobs/android/workspace/reinforce/"
        } else {
            println "BasePath:  /Users/ningkang/StudioProjects/app-hongcai/reinforce/"
            return "/Users/ningkang/StudioProjects/app-hongcai/reinforce/"
        }
    
    }
    
    def getAssembleType() {
        if ("debug".equalsIgnoreCase(BUILD_TYPE)) {
            return "assembleDebug"
        } else {
            return "assembleRelease"
        }
    }
    
    class ApkFile {
        String channel
        File file
    }
    
    /**
     * 查找所有apk
     * @param buildType release 或者 debug
     * @return ArrayList <ApkFile>
     */
    def findApkFiles(String buildType) {
    
        println "findApkFiles buildType: " + buildType
        println "apkFilePath:" + getApkFilePath()
    
        File apkDir = new File(getApkFilePath())
        File[] channelDirs = apkDir.listFiles()
    
        println "channelDirs.length:" + channelDirs.length
    
        List<ApkFile> apkFiles = new ArrayList<>()
    
        if ("true".equals(IS_JENKINS)) {
            for (int i = 0; i < channelDirs.length; i++) {
                File channelDir = channelDirs[i]
                ApkFile apkFile = new ApkFile()
                File[] files = channelDir.listFiles()
                println "channelDirs" + channelDir.name
                if (files == null || files.length == 0) {
                    continue
                }
    
                File lastFile = files[0]
                if (!lastFile.name.endsWith(".apk")) {
                    continue
                }
                apkFile.file = lastFile
                apkFiles.add(apkFile)
                println "apk:" + lastFile.name
            }
        } else {
            for (int i = 0; i < channelDirs.length; i++) {
                File channelDir = channelDirs[i]
                ApkFile apkFile = new ApkFile()
                apkFile.channel = channelDir.name
                File[] files = new File(channelDir, "/" + buildType.toLowerCase()).listFiles()
                if (files == null || files.length == 0) {
                    continue
                }
                File lastFile = files[0]
                if (!lastFile.name.endsWith(".apk")) {
                    continue
                }
                apkFile.file = lastFile
                apkFiles.add(apkFile)
                println "apk:" + lastFile.name
            }
        }
        println "apkFiles:" + apkFiles.size()
    
        return apkFiles
    }
    
    /**
     * 360加固
     * @param apk 加固的原始apk File
     * @param outputPath 输出目录
     * @param channel 原始渠道(baidu,yyb,...)
     */
    def reinforce(apk, outputPath) {
    
        println "reinforce apk:" + apk
        println "reinforce outputPath:" + outputPath
    
        //jiagu.db中缓存了多渠道信息,如果不删除会合并到当前多渠道配置
        def db = new File(BASE + "jiagu.db")
        if (db.exists()) {
            if (!db.delete()) {
                throw new RuntimeException("delete jiagu.db failure!")
            }
        }
    
        // 1. login
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, '-login', NAME, PASSWORD]
        }
    
        // 2. import sign
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, "-importsign", getKeyPath(), getKeyPassword(), getAlias(), getAliasPassword()]
        }
    
        // 3. show sign
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, "-showsign"]
        }
    
        // 4.import channel
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, "-importmulpkg", CHANNEL_CONFIG]
        }
    
        //5.import channel
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, "-showmulpkg"]
        }
    
        // 6. jiagu apk
        exec {
            executable = 'java'
            args = [JAVA_JAR, JAR, '-jiagu', apk, outputPath, "-autosign", "-automulpkg"]
        }
    
    }
    
    /** * 删除一些临时文件 * @param outputDir apk保存目录 */
    def filterApk(File outputDir) {
        println "*************** filter apk ***************"
        File[] files = outputDir.listFiles()
        for (int i = 0; i < files.length; i++) {
            File file = files[i]
            String fileName = file.getName()
            if (fileName.endsWith("jiagu_sign.apk") || fileName.endsWith("temp.apk") || !fileName.endsWith("_sign.apk")) {
                file.delete()
            }
        }
    }
    
    /** * 修改所有apk文件名 * @param outputDir apk保存目录 */
    def renameApk(File outputDir) {
        println "*************** rename apk ***************"
        File[] files = outputDir.listFiles()
        for (int i = 0; i < files.length; i++) {
            File file = files[i]
            String fileName = file.getName()
            String[] prefixArr = fileName.split("-")
            String[] suffixArr = fileName.split("_")
            String rename = prefixArr[0] + "-" + BUILD_TYPE.toLowerCase() + "_" + prefixArr[1] + "-" + suffixArr[suffixArr.length - 2] + ".apk"
            file.renameTo(file.getParent() + "/" + rename)
            println "rename apk: " + fileName + " --> " + rename
        }
    }
    
    /**
     * zip压缩apk保存目录,生成 build/outputs/-x.x.x.zip * @param outputDir apk保存目录
     */
    def compressDir(File outputDir) {
        println "*************** compress apk output dir ***************"
        File zipFile = new File(outputDir.getParent() + "/" + outputDir.getName() + ".zip")
        if (zipFile.exists()) {
            zipFile.delete()
        }
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))
        File[] files = outputDir.listFiles()
        for (int i = 0; i < files.length; i++) {
            File file = files[i]
            byte[] bf = new byte[8192]
            FileInputStream fis = new FileInputStream(file)
            zos.putNextEntry(new ZipEntry(file.getName()))
            int len
            while ((len = fis.read(bf)) > 0) {
                zos.write(bf, 0, len)
            }
            zos.flush()
            fis.close()
        }
        zos.close()
    }
    
    //构建发布到生产环境的所有渠道apk,生成压缩文件 hongcai-x.x.x.zip
    task packageRelease {
        dependsOn(getAssembleType()) doLast {
            List<ApkFile> apkFiles = findApkFiles(BUILD_TYPE)
            if (apkFiles.size() == 0) {
                throw new RuntimeException("no apk files has found!")
            }
            File outputDir = new File(OUTPUT_PATH)
            if (outputDir.exists()) {
                outputDir.delete()
            }
            outputDir.mkdirs()
            for (int i = 0; i < apkFiles.size(); i++) {
                ApkFile apkFile = apkFiles.get(i)
                reinforce(apkFile.file, outputDir.getPath())
            }
            filterApk(outputDir)
            renameApk(outputDir)
            compressDir(outputDir)
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Android持续集成:Jenkins+Gradle+360加固

          本文链接:https://www.haomeiwen.com/subject/cqmpoftx.html