DoneSpeak

通过Git Hook关联Tapd和Commit

字数: 1.3k时长: 6 min
2021/05/24 Share

提示 61
Don’t Use Manual Procedures.
不要使用手工流程

–《程序员修炼之道 - 从小工到专家》

前言

Tapd提供了Gitlab代码关联的功能,我们可以利用这个功能将代码的提交和Tapd中的需求进行关联。

tapd-gitlab

可以通过如下的commit message将commit与tapd的story/bug/task进行关联。

1
2
3
4
5
6
# 关联需求
--story=[story id] --user=[username in tapd]
# 关联任务
--task=[task id] --user=[username in tapd]
# 关联缺陷
--bug=[bug id] --user=[username in tapd]

比如

1
git commit -m "add tapd description to README.md --story=1000011" --user="Donespeak"

要输入的内容非常的多,如果每次输入commit message的时候都需要做这部分工作,那么太浪费时间了。能够自动化的都自动化。

根据分支名/commit信息关联Tapd

commit-msg

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
#!/bin/bash

# 该脚本会根据分支名称,自动添加绑定tapd需求的信息
# 需要提供环境变量 TAPD_USERNAME 以填充user信息

# 分支名 | 绑定TAPD
# --- | ---
# tapd-S1234 | story 1234
# tapd-B1234 | bug 1234
# tapd-T1234 | task 1234

COMMIT_MSG_FILE=$1

BRANCH_PREFIX="tapd-"
BRANCH_REX="$BRANCH_PREFIX[STB]{1}[0-9]+(-.*)?"
TAPD_REFER_REX="--(story|task|bug)=[0-9]+[ ]+--user="
TAPD_REFER_MSG_REX=".*$TAPD_REFER_REX.*"

findTypeIdFromBranch() {
local BRANCH=$(git branch | grep '*' | sed 's/* //')
if [[ ! "$BRANCH" =~ $BRANCH_REX ]]; then
return 1
fi
local TYPE_ID=$($BRANCH#$BRANCH_PREFIX | grep -Eo '^[SBT]{1}[0-9]+')
findTypeId $TYPE_ID
}

findTypeIdFromMsg() {
local MSG=$1
local TYPE_ID=$(echo $MSG | grep -Eo "^#[SBT]{1}[0-9]+" | tr -d '#')
echo $TYPE_ID
if [ -z $TYPE_ID ]; then
return 1
fi

findTypeId $TYPE_ID
}

findTypeId() {
local TYPE_ID=$1
if [ ${#TYPE_ID} -lt 1 ]; then
return 1
fi

TYPE_CHAR=$(echo ${TYPE_ID: 0: 1})
ID=$(echo ${TYPE_ID: 1})

case "$TYPE_CHAR" in
S) TYPE="story"
;;
T) TYPE="task"
;;
B) TYPE="bug"
;;
*)
return 1
;;
esac
}

ORIGIN_COMMIT_MSG=$(cat $COMMIT_MSG_FILE)
COMMIT_MSG=$ORIGIN_COMMIT_MSG

# --- 如果已经添加关联,则不做处理 ---
if [[ $COMMIT_MSG =~ $TAPD_REFER_MSG_REX ]]; then
exit 0
fi

findTypeIdFromMsg $COMMIT_MSG
FAIL=$?

if [ $FAIL -eq 1 ]; then
findTypeIdFromBranch
FAIL=$?
fi

if [ $FAIL -eq 1 ]; then
echo "WARN: The format of branch name and commit message is incorrect."
echo "The format of branch should be ${BRANCH_PREFIX}[STB]<tapdId> (example: ${BRANCH_PREFIX}S12345);"
echo "Or the commit message should start with #[STB]<tapdId> (example: #S12345, message)."
# 格式不符合,中止提交
exit 0
fi

# --- 判断必要环境变量 ---

if [ -z $TAPD_USERNAME ]; then
echo "WARN: environment value TAPD_USERNAME is required."
echo "You can config with the following commands. (Replace [yourname] with your name in Tapd. Using .zshrc instead of .bash_profile if zsh)"
printf "\n\t%s\n\t%s\n\n" "echo -e '\nexport TAPD_USERNAME=\"[yourname]\"' >> ~/.bash_profile" "source ~/.bash_profile"
exit 0
fi

# --- 增加TAPD关联 ---

echo "$COMMIT_MSG" > "$COMMIT_MSG_FILE"
echo -e "\n\n--$TYPE=$ID --user=$TAPD_USERNAME" >> "$COMMIT_MSG_FILE"

环境变量配置

如下命令只要执行一次。

Bash

1
2
3
# 其中的Bees360替换为在Tapd平台的用户名
echo -e '\nexport TAPD_USERNAME="Bees360"' >> ~/.bash_profile
source ~/.bash_profile

Zsh

1
2
3
# 其中的Bees360替换为在Tapd平台的用户名
echo -e '\nexport TAPD_USERNAME="Bees360"' >> ~/.zshrc
source ~/.zshrc

执行样例

branch含有tapd id

1
2
3
git checkout tapd-S1234
# 缺省Tapd Id
git commit -m "add more detail to README.md"

生成如下commit message:

1
2
3
add more detail to README.md

--story=1234 --user=Bees360

message中提供tapd id

1
git commit -m "#S1234, add more detail to README.md"

生成如下commit message:

1
2
3
#S1234, add more detail to README.md

--story=1234 --user=Bees360

自动添加commit统一前缀

在提交的message中,我比较喜欢在message的开头增加关联的需求编号,这样在查看commit的时候可以一目了然看到commit属于哪个需求的。

prepare-commit-msg

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
#!/bin/bash

# 该脚本会根据分支名称,自动添加绑定tapd需求id前缀

# 分支名 | commit 格式
# --- | ---
# tapd-S1234 | #S1234, message
# tapd-B1234 | #B1234, message
# tapd-T1234 | #T1234, message

COMMIT_MSG_FILE=$1

BRANCH_PREFIX="tapd-"
BRANCH_REX="$BRANCH_PREFIX[STB]{1}[0-9]+(-.*)?"
TAPD_MSG_PREFIX_REX="#[STB]{1}[0-9]+(-.*)?"

findTypeIdFromBranch() {
local BRANCH=$(git branch | grep '*' | sed 's/* //')
if [[ ! "$BRANCH" =~ $BRANCH_REX ]]; then
return 1
fi
local TYPE_ID=$(echo $BRANCH | tr -d $BRANCH_PREFIX | grep -Eo '^[SBT]{1}[0-9]+')
findTypeId $TYPE_ID
}

findTypeId() {
local TYPE_ID=$1
if [ ${#TYPE_ID} -lt 1 ]; then
return 1
fi

TYPE_CHAR=$(echo ${TYPE_ID: 0: 1})
ID=$(echo ${TYPE_ID: 1})

case "$TYPE_CHAR" in
S) TYPE="story"
;;
T) TYPE="task"
;;
B) TYPE="bug"
;;
*)
return 1
;;
esac
}

ORIGIN_COMMIT_MSG=$(cat $COMMIT_MSG_FILE)
COMMIT_MSG=$ORIGIN_COMMIT_MSG

# --- 如果已经添加前缀,则不做处理 ---
if [[ $COMMIT_MSG =~ $TAPD_MSG_PREFIX_REX.* ]]; then
exit 0
fi

findTypeIdFromBranch
FAIL=$?

if [ $FAIL -eq 1 ]; then
exit 0
fi

# --- 增加前缀 ----

COMMIT_MSG="#$TYPE_CHAR$ID, $COMMIT_MSG"

echo "$COMMIT_MSG" > "$COMMIT_MSG_FILE"

执行样例

branch含有tapd id

1
2
3
git checkout tapd-S1234
# 缺省Tapd Id
git commit -m "add more detail to README.md"

生成如下commit message:

1
#1234, add more detail to README.md

message中提供tapd id

1
2
git checkout tapd-S1234
git commit -m "#S100012, add more detail to README.md"

生成如下commit message:

1
#S100012, add more detail to README.md

自动添加commit统一前缀 - 关联Gitlab Issue

和上面的代码差不多,只是做了一点点修改。

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
#!/bin/bash

# 分支名 | commit 格式
# --- | ---
# issue-1234 | #1234, message

COMMIT_MSG_FILE=$1

BRANCH_PREFIX="issue-"
BRANCH_REX="$BRANCH_PREFIX{1}[0-9]+(-.*)?"
TAPD_MSG_PREFIX_REX="#{1}[0-9]+(-.*)?"

findIssueIdFromBranch() {
local BRANCH=$(git branch | grep '*' | sed 's/* //')
if [[ ! "$BRANCH" =~ $BRANCH_REX ]]; then
return 1
fi
ISSUE_ID=$(ech $BRANCH | tr -d $BRANCH_PREFIX | grep -Eo '^[0-9]+')
}

ORIGIN_COMMIT_MSG=$(cat $COMMIT_MSG_FILE)
COMMIT_MSG=$ORIGIN_COMMIT_MSG

# --- 如果已经添加前缀,则不做处理 ---
if [[ $COMMIT_MSG =~ $TAPD_MSG_PREFIX_REX.* ]]; then
exit 0
fi

findIssueIdFromBranch
FAIL=$?

if [ $FAIL -eq 1 ]; then
echo "WARN: The branch name format shoud be ${BRANCH_PREFIX}<issue number>, example ${BRANCH_PREFIX}100011"
# 强制格式,则可以`exit 1`以执行失败
exit 0
fi

# --- 增加前缀 ----

COMMIT_MSG="#$ISSUE_ID, $COMMIT_MSG"

echo "$COMMIT_MSG" > "$COMMIT_MSG_FILE"

Makefile 实现make指令安装

将以上的文件添加到git项目根目录的git-hooks目录下,并添加如下Makefile文件。

Makefile

1
2
3
4
install-git-hooks: .git/hooks/prepare-commit-msg  .git/hooks/commit-msg  .git/hooks/pre-push

.git/hooks/%: git-hooks/%
ln -s $(PWD)/$< $(PWD)/$@

通过如下指令可以完成githook的自动关联。

1
make install-git-hooks

参考

CATALOG
  1. 1. 前言
  2. 2. 根据分支名/commit信息关联Tapd
    1. 2.1. commit-msg
    2. 2.2. 环境变量配置
    3. 2.3. 执行样例
  3. 3. 自动添加commit统一前缀
    1. 3.1. prepare-commit-msg
    2. 3.2. 执行样例
  4. 4. 自动添加commit统一前缀 - 关联Gitlab Issue
  5. 5. Makefile 实现make指令安装
  6. 6. 参考