git 服务器端钩子
我在服务器上运行一个Python脚本时遇到了问题,这个脚本是用来查找提交信息的,确保它遵循特定的格式。不过因为我无法让用户输入,所以用户名和密码是写死在代码里的。现在我也无法获取到在这次推送之前的提交信息列表。
#!/usr/bin/python
import SOAPpy
import getpass
import datetime
import sys
import re
import logging
import os
def login(x,y):
try:
auth = soap.login(x, y)
return auth
except:
sys.exit( "Invalid username or password")
def getIssue(auth,issue):
try:
issue = soap.getIssue(auth, issue)
except:
sys.exit("No issue of that type found : Make sure all PRs are vaild jira PRs")
def git_get_commit_msg(commit_id):
return get_shell_cmd_output("git rev-list --pretty --max-count=1 " + commit_id)
def git_get_last_commit_id():
return get_shell_cmd_output("git log --pretty=format:%H -1")
def getCommitText():
commit_msg_filename = sys.argv[1]
try:
commit_msg_text = open(commit_msg_filename).read()
return commit_msg_text
except:
sys.exit("Could not read commit message")
def git_get_array_of_commit_ids(start_id, end_id):
output = get_shell_cmd_output("git rev-list " + start_id + ".." + end_id)
if output == "":
return None
commit_id_array = string.split(output, '\n')
return commit_id_array
def get_shell_cmd_output(cmd):
try:
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
return proc.stdout.read().rstrip('\n')
except KeyboardInterrupt:
logging.info("... interrupted")
except Exception, e:
logging.error("Failed trying to execute '%s'", cmd)
def findpattern(commit_msg):
pattern = re.compile("\w\w*-\d\d*")
group = pattern.findall(commit_msg)
print group
found = len(group)
found =0
issues = 0
for match in group:
auth = soap.login(jirauser,passwd)
getIssue(auth,match)
issues = issues + 1
found+=1
if found ==0:
sys.exit("No issue patterns found.")
print "Retrieved issues: " + str(issues)
def update():
print sys.argv[2]
print sys.argv[3]
old_commit_id = sys.argv[2]
new_commit_id = sys.argv[3]
commit_id_array = git_get_array_of_commit_ids(old_commit_id, new_commit_id)
for commit_id in commit_id_array:
commit_text = git_get_commit_msg(commit_id)
findpattern(commit_text)
soap = SOAPpy.WSDL.Proxy('some url')
# this line if for repointing the input from dev/null
#sys.stdin = open('/dev/tty', 'r') # this fails horribly.
#ask user for input
#jirauser = raw_inp
#("Username for jira: ")
jirauser = "username"
passwd = "987654321"
#passwd = getpass.getpass("Password for %s: " % jirauser)
login(jirauser,passwd)
#commit_msg = getCommitText()
#findpattern(commit_msg)
update()
这段代码的主要目的是检查本地的提交记录,并从中找出符合特定模式的内容,同时还要在JIRA系统中检查这个拉取请求(PR)是否存在。这个代码是在推送到代码库时自动触发的服务器端钩子。
如果有人能给我一些关于编写Python钩子的建议,我会非常感激。谢谢!
2 个回答
当你的更新钩子触发时,服务器已经有了新的提交。问题是你的钩子是否允许相关的引用(ref)进行更改。你希望从本地(发送)仓库获取哪些信息呢?
关于凭证的问题,可以让所有人通过一个统一的用户来处理。例如,GitHub就是用的git用户,所以他们的SSH地址都是以git@github.com:...
开头的。然后在~git/.ssh/authorized_keys
文件中,把每个密钥和一个用户名关联起来。请注意,下面的内容应该在同一行,但为了展示方便而换行了。
no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding, command="env myuser=gbgcoll /usr/bin/git-shell -c \"${SSH_ORIGINAL_COMMAND:-}\"" ssh-rsa AAAAB...
现在,为了查看谁在尝试进行更新,你的钩子会检查$myuser
这个环境变量。
不过,这样并不能给你每个用户的Jira凭证。为了解决这个问题,可以创建一个虚拟的Jira账户,给它所有内容的只读权限,然后把这个Jira账户的凭证硬编码到你的钩子里。这样就可以验证某个PR是否存在了。
我建议你去看看 gitorious(http://gitorious.org/gitorious)。他们使用 SSH 来处理身份验证和权限管理,也就是说,通过 SSH 可以获取用户名。他们的 git 仓库上还有一些钩子(hooks)。我觉得你可以看看他们是怎么用 Ruby 处理 git 钩子的,这可能会对你有帮助。