關於Jenkins和Gradle 和Git一些相互操作: 獲取分支的當前分支名?

一、背景
因爲代碼都遷移到了Gitlab,所以Jenkins編譯的時候我們都需要將之前的SVN信息換成現在的Git信息。最近編譯一個Lib庫的時候,因爲團隊規定上傳Release版本的AAR到Maven的話,必須需要在Jenkins上編譯而且Git Branch 必須是master分支才能夠上傳到Maven。 
因此我們就需要在Gradle腳本中,獲取Git Branch ,Git Commit等相關信息。但是在獲取Git Branch的時候出現了問題,在本地Android Studio編譯的時候能夠獲取到Git Branch的名字,但是使用Jenkins編譯的時候,一直獲取不到信息。

下面是我寫的一份gradle文件,用於獲取Git和Jenkins的相關信息

/**
 * 獲取Git 分支名
 */
def getGitBranch() {
    return 'git symbolic-ref --short -q HEAD'.execute().text.trim()
}

/**
 * 獲取Git 版本號
 */
def getGitSHA() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 獲取Git Tag
 */
def getGitTag() {
    return 'git describe --tags'.execute([], project.rootDir).text.trim()
}

/**
 * 獲取Git 提交次數
 */
def getGitCommitCount() {
    return 100 + Interger.parse('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
}

/**
 * 判斷是否有jenkins
 */
boolean isInJenkins() {
    Map<String, String> map = System.getenv()
    if (map == null) {
        return false
    }
    String str = map.get("Path")
    if (str != null) {
        //it's windows
        return false
    } else {
        str = ""
        Iterator it = map.iterator()
        while (it.hasNext()) {
            str += it.next()
        }
        return str.contains("jenkins")
    }
}
/**
 * 獲取jenkins任務名
 */
def getJenkinsName() {
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.name = env.JOB_URL
        String[] stringArray = ext.name.split("/")
        if (stringArray.length > 0) {
            return stringArray[stringArray.length - 1]
        } else {
            return "Local"
        }
    } else {
        return "Local"
    }
}

/**
 * 獲取Jenkins Build 號
 * @return
 */
def getJenkinsBuildCode() {
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.buildNumber = env.BUILD_NUMBER?.toInteger()
        return "$buildNumber"
    } else {
        return 0
    }
}

/**
 * 定義幾個變量,在build.gradle裏面引用
 */
ext {
    gitTag = getGitTag()
    gitBranch = getGitBranch()
    gitSHA = getGitSHA()
    jenkinsRevision = getJenkinsBuildCode()
    jenkinsName = getJenkinsName()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
其中的方法,getGitBranch方法在Android Studio編譯的時候,能夠正常獲取到Git分支名。

    println "pom_version_type = " + pom_version_type
    println "jenkinsName = " + jenkinsName
    println "gitBranch = " + gitBranch
1
2
3
我在進行編譯的時候,是會通過如上代碼打印出Git Branch的信息。

在Android Studio 本地編譯的時候,是可以打印出相關的信息的。

但是在Jenkins編譯的時候,是不能夠上傳的,如下所示: 


二、解決方法
後來我嘗試找了很多種方法去獲取Git Branch的名字,在Android Studio本地都可以獲取到,如下所示:

參考鏈接:https://stackoverflow.com/questions/6245570/how-to-get-the-current-branch-name-in-git

方法1、git symbolic-ref --short -q HEAD

D:\GitLab Source\XTCLint>git symbolic-ref --short -q HEAD
master

D:\GitLab Source\XTCLint>
1
2
3
4
5


方法2、git rev-parse --abbrev-ref HEAD

D:\GitLab Source\XTCLint>git rev-parse --abbrev-ref HEAD
master
1
2
3


方法3、git branch | grep \* | cut -d ' ' -f2

D:\GitLab Source\XTCLint>git branch | grep \* | cut -d ' ' -f2
master
1
2
3


方法4、git symbolic-ref HEAD | sed -e "s/^refs\/heads\///"

D:\GitLab Source\XTCLint>git symbolic-ref HEAD | sed -e "s/^refs\/heads\///"
master
1
2
3


以上所有的方法,僅僅在Android Studio的終端或者本地gradle代碼中有效,然而在Jenkins服務器編譯的時候都是獲取爲空。

後來我查看了Jenkins的Git插件上的介紹,參考鏈接:https://wiki.jenkins.io/display/JENKINS/Git+Plugin

如上所示,在上面的鏈接中有介紹,有幾個Environment variables環境變量可以使用。

Environment variables

The git plugin sets several environment variables you can use in your scripts:

GIT_COMMIT - SHA of the current
GIT_BRANCH - Name of the remote repository (defaults to origin), followed by name of the branch currently being used, e.g. “origin/master” or “origin/foo”
GIT_LOCAL_BRANCH - Name of the branch on Jenkins. When the “checkout to specific local branch” behavior is configured, the variable is published. If the behavior is configured as null or **, the property will contain the resulting local branch name sans the remote name.
GIT_PREVIOUS_COMMIT - SHA of the previous built commit from the same branch (the current SHA on first build in branch)
GIT_PREVIOUS_SUCCESSFUL_COMMIT - SHA of the previous successfully built commit from the same branch.
GIT_URL - Repository remote URL
GIT_URL_N - Repository remote URLs when there are more than 1 remotes, e.g. GIT_URL_1, GIT_URL_2
GIT_AUTHOR_NAME and GIT_COMMITTER_NAME - The name entered if the “Custom user name/e-mail address” behaviour is enabled; falls back to the value entered in the Jenkins system config under “Global Config user.name Value” (if any)
GIT_AUTHOR_EMAIL and GIT_COMMITTER_EMAIL - The email entered if the “Custom user name/e-mail address” behaviour is enabled; falls back to the value entered in the Jenkins system config under “Global Config user.email Value” (if any)
然後我將這幾個變量,在一個app的Jenkins任務中,編譯完成後的郵件內容中添加了這幾個變量的內容,如下所示:

在構建後的操作中,Editable Email Notification的郵件通知中,將郵件內容改爲如下所示的代碼。

$DEFAULT_CONTENT

<br />
<font color="#0B610B">單元測試</font>
  <li>Launcher單元測試報告&nbsp;:<a href="${BUILD_URL}testReport">點擊查看測試報告</a></li>
  <li>Launcher代碼覆蓋率&nbsp;:<a href="${BUILD_URL}jacoco">點擊查看代碼覆蓋率</a></li>
  <li>Launcher Android Lint&nbsp;:<a href="${BUILD_URL}androidLintResult">點擊查看Android Lint</a></li>


<br />
 <li>GIT_COMMIT&nbsp;:${GIT_COMMIT}</a></li>
 <li>GIT_BRANCH&nbsp;:${GIT_BRANCH}</a></li>
 <li>GIT_LOCAL_BRANCH&nbsp;:${GIT_LOCAL_BRANCH}</a></li>
 <li>GIT_PREVIOUS_COMMIT&nbsp;:${GIT_PREVIOUS_COMMIT}</a></li>
 <li>GIT_PREVIOUS_SUCCESSFUL_COMMIT&nbsp;:${GIT_PREVIOUS_SUCCESSFUL_COMMIT}</a></li>
 <li>GIT_URL&nbsp;:${GIT_URL}</a></li>
 <li>GIT_URL_N&nbsp;:${GIT_URL_N}</a></li>
 <li>GIT_AUTHOR_NAME&nbsp;:${GIT_AUTHOR_NAME}</a></li>
 <li>GIT_COMMITTER_NAME&nbsp;:${GIT_COMMITTER_NAME}</a></li>
 <li>GIT_AUTHOR_EMAIL&nbsp;:${GIT_AUTHOR_EMAIL}</a></li>
 <li> GIT_COMMITTER_EMAIL&nbsp;:${ GIT_COMMITTER_EMAIL}</a></li>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
這樣編譯完後,收到的郵件內容如下: 


如上所示,收到的郵件內容包含了Git的相關信息:

GIT_COMMIT :118fa74e6a09c8c5ae713523692add256bfa6afb
GIT_BRANCH :origin/feature/UseByAnonymousDBMigrateAndApiChange
GIT_LOCAL_BRANCH :${GIT_LOCAL_BRANCH}
GIT_PREVIOUS_COMMIT :118fa74e6a09c8c5ae713523692add256bfa6afb
GIT_PREVIOUS_SUCCESSFUL_COMMIT :118fa74e6a09c8c5ae713523692add256bfa6afb
GIT_URL :[email protected]:Android/WatchApp/Third/NetEaseCloudMusic.git
GIT_URL_N :${GIT_URL_N}
GIT_AUTHOR_NAME :${GIT_AUTHOR_NAME}
GIT_COMMITTER_NAME :${GIT_COMMITTER_NAME}
GIT_AUTHOR_EMAIL :${GIT_AUTHOR_EMAIL}
GIT_COMMITTER_EMAIL :${ GIT_COMMITTER_EMAIL}
1
2
3
4
5
6
7
8
9
10
11
其中,GIT_BRANCH這個環境變量的值爲origin/feature/UseByAnonymousDBMigrateAndApiChange,代表Jenkins上/UseByAnonymousDBMigrateAndApiChange分支遠程Gitlab上該分支映射的遠程分支。因此我們可以對GIT_BRANCH這個環境變量做做文章。

將之前gradle腳本中的getGitBranch方法,做如下修改,區分編譯環境是Jenkins還是本地。環境不同,運行不同的腳本獲取Git Branch的名字。當處於Jenkins環境的時候,先通過GIT_BRANCH這個環境變量獲取到Jenkins拉下來的分支對應的遠程分支,然後通過字符串分離,獲取到分支名。

/**
 * 獲取Git 分支名
 *
 *參考Jenkins git 創建文檔: https://wiki.jenkins.io/display/JENKINS/Git+Plugin
 *   Environment variables

 The git plugin sets several environment variables you can use in your scripts:

 GIT_COMMIT - SHA of the current
 GIT_BRANCH - Name of the remote repository (defaults to origin), followed by name of the branch currently being used, e.g. "origin/master" or "origin/foo"
 GIT_LOCAL_BRANCH - Name of the branch on Jenkins. When the "checkout to specific local branch" behavior is configured, the variable is published.  If the behavior is configured as null or **, the property will contain the resulting local branch name sans the remote name.
 GIT_PREVIOUS_COMMIT - SHA of the previous built commit from the same branch (the current SHA on first build in branch)
 GIT_PREVIOUS_SUCCESSFUL_COMMIT - SHA of the previous successfully built commit from the same branch.
 GIT_URL - Repository remote URL
 GIT_URL_N - Repository remote URLs when there are more than 1 remotes, e.g. GIT_URL_1, GIT_URL_2
 GIT_AUTHOR_NAME and GIT_COMMITTER_NAME - The name entered if the "Custom user name/e-mail address" behaviour is enabled; falls back to the value entered in the Jenkins system config under "Global Config user.name Value" (if any)
 GIT_AUTHOR_EMAIL and GIT_COMMITTER_EMAIL - The email entered if the "Custom user name/e-mail address" behaviour is enabled; falls back to the value entered in the Jenkins system config under "Global Config user.email Value" (if any)
 *
 *
 */
def getGitBranch() {
    //判斷是否處於Jenkins編譯環境
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.gitBranch = env.GIT_BRANCH
        String[] stringArray = ext.gitBranch.split("/")
        if (stringArray.length > 0) {
            return stringArray[stringArray.length - 1]
        } else {
            return "UnKnown Branch"
        }
    } else {
        return 'git symbolic-ref --short -q HEAD'.execute().text.trim()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
完整代碼如下所示:

/**
 * 獲取Git 分支名
 *
 *參考Jenkins git 創建文檔: https://wiki.jenkins.io/display/JENKINS/Git+Plugin
 *   Environment variables

 The git plugin sets several environment variables you can use in your scripts:

 GIT_COMMIT - SHA of the current
 GIT_BRANCH - Name of the remote repository (defaults to origin), followed by name of the branch currently being used, e.g. "origin/master" or "origin/foo"
 GIT_LOCAL_BRANCH - Name of the branch on Jenkins. When the "checkout to specific local branch" behavior is configured, the variable is published.  If the behavior is configured as null or **, the property will contain the resulting local branch name sans the remote name.
 GIT_PREVIOUS_COMMIT - SHA of the previous built commit from the same branch (the current SHA on first build in branch)
 GIT_PREVIOUS_SUCCESSFUL_COMMIT - SHA of the previous successfully built commit from the same branch.
 GIT_URL - Repository remote URL
 GIT_URL_N - Repository remote URLs when there are more than 1 remotes, e.g. GIT_URL_1, GIT_URL_2
 GIT_AUTHOR_NAME and GIT_COMMITTER_NAME - The name entered if the "Custom user name/e-mail address" behaviour is enabled; falls back to the value entered in the Jenkins system config under "Global Config user.name Value" (if any)
 GIT_AUTHOR_EMAIL and GIT_COMMITTER_EMAIL - The email entered if the "Custom user name/e-mail address" behaviour is enabled; falls back to the value entered in the Jenkins system config under "Global Config user.email Value" (if any)
 *
 *
 */
def getGitBranch() {
    //判斷是否處於Jenkins編譯環境
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.gitBranch = env.GIT_BRANCH
        String[] stringArray = ext.gitBranch.split("/")
        if (stringArray.length > 0) {
            return stringArray[stringArray.length - 1]
        } else {
            return "UnKnown Branch"
        }
    } else {
        return 'git symbolic-ref --short -q HEAD'.execute().text.trim()
    }
}


/**
 * 獲取Git 版本號
 */
def getGitSHA() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 獲取Git Tag
 */
def getGitTag() {
    return 'git describe --tags'.execute([], project.rootDir).text.trim()
}

/**
 * 獲取Git 提交次數
 */
def getGitCommitCount() {
    return 100 + Interger.parse('git rev-list --count HEAD'.execute([], project.rootDir).text.trim())
}

/**
 * 判斷是否有jenkins
 */
boolean isInJenkins() {
    Map<String, String> map = System.getenv()
    if (map == null) {
        return false
    }
    String str = map.get("Path")
    if (str != null) {
        //it's windows
        return false
    } else {
        str = ""
        Iterator it = map.iterator()
        while (it.hasNext()) {
            str += it.next()
        }
        return str.contains("jenkins")
    }
}
/**
 * 獲取jenkins任務名
 */
def getJenkinsName() {
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.name = env.JOB_URL
        String[] stringArray = ext.name.split("/")
        if (stringArray.length > 0) {
            return stringArray[stringArray.length - 1]
        } else {
            return "Local"
        }
    } else {
        return "Local"
    }
}

/**
 * 獲取Jenkins Build 號
 * @return
 */
def getJenkinsBuildCode() {
    boolean flag = isInJenkins()
    if (flag) {
        ext.env = System.getenv()
        ext.buildNumber = env.BUILD_NUMBER?.toInteger()
        return "$buildNumber"
    } else {
        return 0
    }
}

/**
 * 定義幾個變量,在build.gradle裏面引用
 */
ext {
    gitTag = getGitTag()
    gitBranch = getGitBranch()
    gitSHA = getGitSHA()
    jenkinsRevision = getJenkinsBuildCode()
    jenkinsName = getJenkinsName()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
現在測試下Jenkins編譯是否正常,可以看到一切都正常了。

參考鏈接
https://wiki.jenkins.io/display/JENKINS/Git+Plugin
https://stackoverflow.com/questions/6245570/how-to-get-the-current-branch-name-in-git


作者:歐陽鵬 歡迎轉載,與人分享是進步的源泉! 
轉載請保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/77802596

如果覺得本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行隨意打賞。您的支持將鼓勵我繼續創作!
--------------------- 
作者:歐陽鵬 
來源:CSDN 
原文:https://blog.csdn.net/ouyang_peng/article/details/77802596 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章