本文将介绍利用Bat指令以及Git等工具实现自动化拉取远程分支,同时使用gradle自动编译打包发送邮件到指定邮箱的过程,实现自动化编译与通知功能,因为当时的需求只有自动打包与通知,所以也没有加入异常处理机制,日志记录也不完善,但是整体思路是一致的,其余的是体验上的加强。

前言

一些基础的东西这里将不作赘述,如git、gralde、bat指令等,以及过程中涉及的各个工具的环境搭建,这些都可以自行百度,资料非常多。

配置文件

为了使用上的便利,最好能提供给使用者自行配置具体项目具体参数的文件,毕竟不是所有人都了解bat,下面提供该编译工具配置所需要的git资源的样例:

git邮箱|git密码|git地址|git分支|该分支具体某次提交记录(放空默认最新)|git项目名

打包完成后邮件地址配置样例:


发件人邮箱  
发件人邮箱密码  
这是邮件标题  
这是具体邮件内容  
收件人1邮箱  
收件人2邮箱

自动编译bat文件内容

因为git内容比较多,所以具体的讲解我直接注释在代码里面,bat的注释以rem开头,其中一些重要命令也会稍加注释,如果有一些没有注释的又不清楚的可以百度了解一下。


@echo off & setlocal enabledelayedexpansion
COLOR 0A
:cloneBegin
rem 初始化参数.
set gitUser=””
set gitPwd=””
set gitUrl=””
set gitBranch=””
set gitCommit=””
set gitProjectName=””
set cloneStr=””
set /a index=0
set cloneRootPath=””
set cloneBranchPath=””
set cloneCommitPath=””
set currentGitName=””
set /a status=0
set /a mailIndex=0
rem 从git-config文件中逐行读取配置信息,并将项目及其依赖库拉去至本地.
for /f “tokens=1-6 delims==|” %%a in (git-config.txt) do (
rem 初始化参数.
set “gitUser=%%a”
set “gitPwd=%%b”
set “gitUrl=%%c”
set “gitBranch=%%d”
set “gitCommit=%%e”
rem 转义@字符.
set gitUser=!gitUser:@=%%40!
set gitUrl=!gitUrl:https://=!
set gitUrl=!gitUrl:http://=!
rem 生成git clone的指令.
set cloneStr=http://!gitUser!:!gitPwd!@!gitUrl! -b !gitBranch!
set “currentGitName=%%f”

echo !cloneStr!  

if !index! EQU 0 (  
    set "gitProjectName=%%f"  
    echo ***************!currentGitName! start clone...***************  
    rem *拉去主项目到当前目录下的项目名目录下.*  
    git clone !cloneStr! ./!gitProjectName!  
) else (  
    echo ***************!currentGitName! start clone...***************  
    cd !gitProjectName!  
    rem *拉去依赖项目到主项目目录下的依赖库名目录下.*  
    git clone !cloneStr! ./!currentGitName!  
    rem *dp0 表示当前该bat文件的目录下.*  
    cd %~dp0  
)  
rem *设置当前项目的build.gradle路径以及其分支名与提交记录路径.*  
if !index! EQU 0 (  
    set "cloneRootPath=%~dp0!gitProjectName!\build.gradle"  
    set "cloneBranchPath=%~dp0!gitProjectName!\.git\HEAD"  
    set "cloneCommitPath=%~dp0!gitProjectName!\.git\refs\heads\!gitBranch!"  
) else (  
    set "cloneRootPath=%~dp0!gitProjectName!\%%f"  
    set "cloneBranchPath=%~dp0!gitProjectName!\%%f\.git\HEAD"  
    set "cloneCommitPath=%~dp0!gitProjectName!\%%f\.git\refs\heads\!gitBranch!"  
)  
rem *判断当前项目是否拉取成功,其分支与当前所处提交记录是否正确*  
if exist !cloneRootPath! (  
    echo *******!currentGitName! clone complete...*******  
    find /i "!gitBranch!" !cloneBranchPath! && (  
        echo *******!currentGitName! clone branch correctly...*******  
        if "!gitCommit!"==" " (  
            echo *******!currentGitName! clone latest commit correctly...*******  
        )||(  
            find /i "!gitCommit!" !cloneCommitPath! && (  
                echo *******!currentGitName! clone seleteced commit correctly...*******  
            )||(  
                if !index! EQU 0 (  
                    cd %~dp0!gitProjectName!  
                ) else (  
                    cd %~dp0!gitProjectName!\!currentGitName!  
                )  
                rem *更改分支*  
                git reset --hard !gitCommit!  
                cd %~dp0  
                find /i "!gitCommit!" !cloneCommitPath! && (  
                    echo *******!currentGitName! clone seleteced commit correctly...*******  
                )||(  
                    echo *******!currentGitName! clone seleteced commit failed...*******  
                    rem rd /s /q %~dp0!gitProjectName!  
                    goto cloneError  
                )  
            )  
        )  
    )||(  
        echo *******!currentGitName! clone branch failed...*******  
        rem rd /s /q %~dp0!gitProjectName!  
        goto cloneError  
    )  
 ) else (  
    echo *******!gitProjectName! clone failed, please try again...*******  
    rem rd /s /q %~dp0!gitProjectName!  
    goto cloneError  
 )  
 set /a index+=1  

)
rem 编译项目.
if exist !cloneRootPath! (
cd !gitProjectName!
:buildApk
gradle assembleRelease
rem after call other batch such as gradle, turn echo off to make command disappear.
@echo off & setlocal enabledelayedexpansion
rem 编译完成的后续处理bat文件.
call build-after.bat
PAUSE
) else (
:cloneError
rem 错误处理,打印当前的信息判断是否配置错误,修改错误的配置信息后按回车重新开始编译.
echo *!gitProjectName! clone failed, there are your configs in !currentGitName! as follow:*
echo *gitUser=!gitUser!*
echo *gitPwd=!gitPwd!*
echo *gitUrl=!gitUrl!*
echo *gitBranch=!gitBranch!*
echo *gitCommit=!gitCommit!*
echo *repositoryName=!currentGitName!*
echo *please check for errors and correct them, press any key to reclone after all*
PAUSE
goto :cloneBegin
)
PAUSE
</code></pre>

编译后bat文件内容

该文件在上一个bat文件末尾自动调用,也可在编译后直接运行,判断是否编译成功,若编译成功则调用blat工具发送邮件到指定给指定的收件人。


@echo off & setlocal enabledelayedexpansion   
set status=0  
set sendUser=""  
set sendPwd=""  
set mailTitle=""  
set mailContent=""  
set /a mailIndex=0  
cd %~dp0  
rem *从git-config文件中读取主项目名.*  
for /f "tokens=1-6 delims==|" %%a in (git-config.txt) do (  
    if !status! EQU 0 (  
        set status=1  
        rem *判断主项目名是否编译成功.*  
        if exist %~dp0%%f\app\build\outputs\apk\app-release.apk (  
            echo *******%%f build success*******  
            rem *生成当前时间.*  
            set time=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%  
            rem *重命名生成的apk文件,并将其移至指定目录.*  
            ren %~dp0%%f\app\build\outputs\apk\app-release.apk %%f_1.0.0_!time!.apk  
            move %~dp0%%f\app\build\outputs\apk\%%f_1.0.0_!time!.apk %~dp0  
            rd /s /q %~dp0%%f  
            rem *逐行读取邮件配置文件内容,最后调用blat发送邮件给每个收件人.*  
            for /f "" %%a in (mail-config.txt) do (  
                if !mailIndex! EQU 0 (  
                    set "sendUser=%%a"  
                )  
                if !mailIndex! EQU 1 (  
                    set "sendPwd=%%a"  
                )  
                if !mailIndex! EQU 2 (  
                    set "mailTitle=%%a"  
                )  
                if !mailIndex! EQU 3 (  
                    set "mailContent=%%a"  
                )  
                if !mailIndex! GTR 3 (  
                    blat -body "!mailContent!" -to %%a -s "!mailTitle!" -u !sendUser! -pw !sendPwd! -charset UTF-8  
                )  
                set /a mailIndex+=1  
            )  
        ) else (  
            echo *******%%f build failed*******  
            echo *******please check for errors and correct them, press any key to rebuild after all*******  
            PAUSE  
        )  
    )  
)  
PAUSE  

总结

写这个自动化编译工具时自己对bat语言一无所知,gradle、blat这些工具也是边做边学,但是主要难度还是在于bat的编写上,有时候一条语句就要琢磨个半天,而且由于所花时间有限,写的工具只能算是勉强能用,若要谈到良好的体验那肯定是差之甚远,有兴趣的朋友可以自己拿去优化优化然后分享出来,也可以大家一起交流讨论。