groovy 脚本实例 检测git提交信息并推送到企业微信
检测git提交信息并推送到企业微信
package common.ecs
import groovy.json.JsonSlurperClassic
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
node('ecs_wuhan_docker') {
properties([
parameters([
string(name: 'setBeginTime', description: '不指定默认使用上一次执行的结束时间,格式:2022-mm-dd', defaultValue: '2022-mm-dd', trim: true)
]),
disableConcurrentBuilds(),
pipelineTriggers([cron('H 10 * * *')]),
buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '7', numToKeepStr: '30')),
])
/**
* 1. checkout ecs src
* 2. find client api path
* 3. request path commits && modify file
* 4. notice msg
*/
String project = "ecs2(357)"
String branchName = 'dev'
/**
* 开始时间优先使用页面设置的时间,其次获取上一次执行的时间,如果都没有获取当前时间
*/
if (setBeginTime == '2022-mm-dd') {
setBeginTime = sh(returnStdout: true, script: 'date -d -1days "+%Y-%m-%d"').trim()
}
String beginTime = "$setBeginTime" + 'T00:00:00.000Z'
stage('checkout src') {
deleteDir()
cloneProjectBranch(['ecs2'], 'ecs-platform', branchName, 'jenkins')
}
def apiPaths
stage('find client api path') {
dir('ecs2') {
apiPaths = sh(returnStdout: true, script: "find ./ecs -type d -name client|grep api-client").trim()
}
}
String dayStr = sh(returnStdout: true, script: 'date "+%Y-%m-%d"').trim()
def results
def initLength
stage('request commits and file') {
dir('ecs2') {
StringBuffer sb = new StringBuffer("方舟平台client api变化自动检测:\n")
initLength = sb.length()
Map parallelMap = [:]
for (item in apiPaths.split("\\n")) {
def apiPathStr = item
parallelMap.put(apiPathStr.split('/')[2], {
String apiPath = apiPathStr.substring(2)
def commitsObjList = getCommitsByPath(project, beginTime, branchName, apiPath)
for (commitsObj in commitsObjList) {
String commitId = commitsObj.get("commitId")
String fileName = commitsObj.get("fileName")
String authorName = commitsObj.get("authorName")
String taskName = "${fileName}接口变更-" + dayStr
String taskId = createTapdTask(taskName, authorName)
String commitUrl = "https://192.168.48.50/ecs-platform/ecs2/commit/${commitId}"
String desc = "文件变更地址: <a rel=\"noopener\" href=\"${commitUrl}\">${commitUrl}</a>"
//createTaskComments(desc, taskId)
String commitMsg = commitsObj.get("commitMsg")
sb.append(commitMsg + '\n')
}
})
}
parallel(parallelMap)
results = sb.toString()
}
}
stage('notice msg') {
print(results)
if (initLength < results.length()) {
wxNotice(results, ['8577f1c3-e3ee-4930-9572-efcac46151d4'])
}
}
}
// 字段名 必选 类型及范围 说明
// name 是 string 标题
// priority 否 string 优先级
// iteration_id 否 integer 迭代
// owner 否 string 当前处理人
// cc 否 string 抄送人
// creator 是 string 创建人
// begin 否 date 预计开始
// due 否 date 预计结束
// created 否 datetime 创建时间
// modified 否 datetime 最后修改时间
// completed 否 datetime 完成时间
// effort 否 string 预估工时
// effort_completed 否 string 完成工时
// remain 否 float 剩余工时
// exceed 否 float 超出工时
// progress 否 integer 进度
// story_id 否 integer 需求
// description 否 string 详细描述
// workspace_id 是 integer 项目ID
// custom_field_ 否 string或者integer 自定义字段参数,具体字段名通过接口 https://www.tapd.cn/help/view#1120003271001001454 获取
def createTapdTask(String taskName, String owner) {
String creator = '杜永军'
String workspaceId = '61177290'
String story_id = '1185347'
String password = 'fuS4sCW3:1384FFB8-EC11-CB10-3830-FA6C1D58D896'
// curl -u 'api_user:api_password' -d 'workspace_id=20003271&name=task_created_by_api&creator=tapd_api' 'https://api.tapd.cn/tasks'
String url = "curl -u '${password}' 'https://api.tapd.cn/tasks' " +
"--data-urlencode 'name=${taskName}' \\\n" +
"--data-urlencode 'workspace_id=${workspaceId}' \\\n" +
"--data-urlencode 'story_id=${story_id}' \\\n" +
"--data-urlencode 'owner=${owner}' \\\n" +
"--data-urlencode 'creator=${creator}' \\\n"
String taskId
retry(3) {
String createResultJson = sh(returnStdout: true, script: url).trim()
taskId = new JsonSlurperClassic().parseText(createResultJson).get("data").get("Task").get("id")
}
return taskId
}
//description 是 string 内容
//author 是 string 评论人
//entry_type 是 string 评论类型(取值: bug、 bug_remark (流转缺陷时候的评论)、 stories、 tasks、items(工作项评论) 。)
//entry_id 是 integer 评论所依附的业务对象实体id
//workspace_id 是 integer 项目ID
//fields 否 string 设置获取的字段,多个字段间以','逗号隔开
def createTaskComments(String description, String taskId) {
String creator = '杜永军'
String workspaceId = '61177290'
String story_id = '1185347'
String password = 'fuS4sCW3:1384FFB8-EC11-CB10-3830-FA6C1D58D896'
// curl -u 'api_user:api_password' -d 'workspace_id=20355782&entry_type=bug&entry_id=1020355782500647717&description=ccc&author=xuanfang' ''
String url = "curl -u '${password}' 'https://api.tapd.cn/comments' " +
"--data-urlencode 'workspace_id=${workspaceId}' \\\n" +
"--data-urlencode 'author=${creator}' \\\n" +
"--data-urlencode 'entry_type=tasks' \\\n" +
"--data-urlencode 'entry_id=${taskId}' \\\n" +
"--data-urlencode 'description=${description}' \\\n"
retry(3) {
sh(returnStdout: true, script: url).trim()
}
}
def cloneProjectBranch(projectNames, group, branch, userName) {
withCredentials([usernamePassword(credentialsId: 'ecs_git', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
def encodedPass = URLEncoder.encode(PASS, "UTF-8")
try {
sh 'git config --global http.sslVerify false'
} catch (e) {
}
Map parallelMap = [:]
for (item in projectNames) {
def projectName = item
parallelMap.put(projectName, {
sh "git clone --depth=1 https://${USER}:${encodedPass}@192.168.48.50/${group}/${projectName}.git ${projectName}"
dir(projectName) {
sh "git config user.email ${userName}@yuanian.com"
sh "git config user.name ${userName}"
if (isHasFeature(branch)) {
sh "git checkout ${branch}"
}
}
})
}
parallel(parallelMap)
}
}
def isHasFeature(featureName) {
String featureCount = sh(returnStdout: true, script: "git ls-remote|grep .*/${featureName}\$ | wc -l").trim()
return Integer.parseInt(featureCount) > 0
}
/**
* 具体的文件是否有修改
*
* @param projectName 数据安全前端(716)要符合这样的格式
* @param bgTime
* @param branchName
* @param 具体的文件路径
* @return
*/
def getCommitsByPath(String projectName, String bgTime, String branchName, String path) {
String projectId = projectName.split("\\(")[1].replace(")", "")
def json = getJsonMsgByPath(projectId, bgTime, branchName, path)
if (json.size() > 0) {
return parseJson(json, path, projectId)
}
return ''
}
def getJsonMsgByPath(String projectId, String bgTime, String branchName, String path) {
echo "----------------本次查询条件: 项目是:$projectId 开始时间:$bgTime 分支:$branchName 路径:$path -------------"
String beginTime = fixBeginTime(bgTime)
String json
withCredentials([string(credentialsId: 'gitLab_token', variable: 'TOKEN')]) {
String curlStr = "https://192.168.48.50/api/v4/projects/${projectId}/repository/commits?ref_name=${branchName}&since=%27${beginTime}%27"
if (path != null) {
curlStr += "&path=" + path
}
json = sh(returnStdout: true, script: "curl -k '${curlStr}' -H 'PRIVATE-TOKEN:${TOKEN}'").trim()
}
return new JsonSlurperClassic().parseText(json)
}
/**
* json示例
*{* "id": "f3938cacdcfab98c7d40c6d9dcaa77dde5bfdcbe",
* "short_id": "f3938cac",
* "created_at": "2021-08-05T06:45:10.000Z",
* "parent_ids": ["2e0481f627766425a27371eac4322027c8fc47c5"],
* "title": "bug_id=1167320539001168204 修改可视化数据流jobName字段长度",
* "message": "bug_id=1167320539001168204 修改可视化数据流jobName字段长度\n",
* "author_name": "tangshouxi",
* "author_email": "tangshx@yuanian.com",
* "authored_date": "2021-08-05T06:45:10.000Z",
* "committer_name": "tangshouxi",
* "committer_email": "tangshx@yuanian.com",
* "committed_date": "2021-08-05T06:45:10.000Z"
*}* @param projectName
* @param json
* @return
*/
def parseJson(commitsJson, String pathName, projectId) {
Map parallelMap = [:]
def list = []
for (item in commitsJson) {
def commitJson = item
String short_id = commitJson.get("short_id")
parallelMap.put(short_id, {
String message = commitJson.get("message").replaceAll("\n", "")
String author_name = commitJson.get("author_name")
String committed_date = commitJson.get("committed_date")
// gitLab提交记录ID
String commitId = commitJson.get("id")
String commitMsg = "提交人:" + author_name + " 提交时间:" + committed_date.substring(0, committed_date.indexOf("T")) + " 备注:" + message
def diffFileJson = getDiffFileJson(projectId, short_id)
diffFileJson.each { diff ->
String old_path = diff.get("old_path")
if (old_path.contains("api-client/") && old_path.contains("/client/")) {
//获取java包名路径
// 如:com/yuanian/console/client/IConsoleUserClient.java
String modifyPath = old_path.substring(old_path.indexOf('com/'))
//通过路径获取文件名称
//如:IRulemanagementMetadataClient.java
String fileName = old_path.substring(old_path.lastIndexOf('/') + 1)
def commitObj = [:]
commitObj.put("commitId", commitId)
commitObj.put("fileName", fileName)
commitObj.put("commitMsg", commitMsg)
commitObj.put("authorName", author_name)
commitObj.put("modifyPath", modifyPath)
list.add(commitObj)
}
}
})
}
parallel(parallelMap)
return list
// StringBuffer sb = new StringBuffer("pathName:${pathName}\n")
// for (Map.Entry<String, StringBuffer> entry : map.entrySet()) {
// sb.append("\t变更文件路径:" + entry.key + "\n")
// sb.append(entry.getValue())
// }
// return sb.toString()
}
def getDiffFileJson(projectId, short_id) {
String curlStr = "https://192.168.48.50/api/v4/projects/${projectId}/repository/commits/${short_id}/diff"
String json
withCredentials([string(credentialsId: 'gitLab_token', variable: 'TOKEN')]) {
json = sh(returnStdout: true, script: "curl -k '${curlStr}' -H 'PRIVATE-TOKEN:${TOKEN}'").trim()
}
return new JsonSlurperClassic().parseText(json)
}
/**
* 要减8小时,转为UTC时间
*/
def fixBeginTime(String beginTime) {
CharSequence cs = beginTime.replace("Z", "")
def day = LocalDateTime.parse(cs, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
day = day.minusHours(8)
return day.toString()
}
def wxNotice(msg, tokenKeys) {
for (tokenKey in tokenKeys) {
sh """
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${tokenKey}' \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "text",
"text": {
"content": "${msg}",
"mentioned_mobile_list":["@all"]
}
}'
"""
}
}