2009-10-01 25 views
14

有沒有人有一個git的承諾掛鉤,我可以使用,這將確保一個JIRA問題編號出現在簽入的消息?我沒有經驗,從一個混帳駕駛JIRA提交鉤子所以任何幫助,將不勝感激 - 工作源更是如此!JIRA代碼驗證犯了「混帳」鉤

回答

16

首先,鉤可執行文件:

chmod a+x .git/hooks/commit-msg 

追加以下幾行,用在項目的代碼項目。

test "" != "$(grep 'PROJECT-' "$1")" || { 
     echo >&2 "ERROR: Commit message is missing Jira issue number." 
     exit 1 
} 
+5

要檢查多個項目,並確保有問題的ID,使用:grep的-E '(PRJA | PRJB) - [[:數字:]] +' – Martin 2013-02-21 09:33:05

+0

是否有可能在Atlassian方面進行驗證?爲了避免不得不告訴對方球隊中的非技術性的傢伙如何做到這一點的。 – 2015-11-30 14:24:18

-1

我會寫一個提交鉤子,確保看起來像JIRA問題編號出現在提交消息的某處。要做到這一點,一個簡單的正則表達式匹配會做到這一點:

/[A-Z0-9]+-\d+/ 

如果你想,額外的錯字保護可以保證第一部分與您在JIRA設置一些項目標識符匹配:

/(ABC|XYZ|PONIES)-\d+/ 

我發現有在試圖確保的是,一部分指的是有效的問題數量幾乎沒有價值。是不是真的有什麼辦法來確定用戶是否已經輸入了正確的問題數(即使你設法限制它打開的問題,用戶仍然可以輸入一個不相關的懸而未決的問題數)。用戶在提交代碼時應該小心謹慎。

0
#!/usr/bin/env ruby 
# 
# Update JIRA with git commit messages 
# 
# == Usage == 
# 
# To update a JIRA issue, prepend the first line of your git commit 
# message with the issue key and a colon: 
# 
#  $ git commit -m "GIT-1: Updates something" 
# 
# A comment will be added to the GIT-1 issue that looks something 
# like: 
# 
#  Commit: <Hash> 
#  Author: Bob Example <[email protected]> 
#  Date: Mon Jul 14 14:00:00 -0400 2008 
# 
#  GIT-1: Updates something 
# 
# To change an issue's status, append an action string: 
# 
#  GIT-1 resolved: Updates something 
#  GIT-1 closed: Finishes this 
#  GIT-1 reopen: Starting work on this 
# 
# To update multiple issues, separate them with a comma: 
# 
#  GIT-1, GIT-2: Adds comments to GIT-1 and GIT-2 
#  GIT-1, GIT-2 resolved: Updates GIT-1 and resolves GIT-2 
# 
# == Installation == 
# 
# To get this working, first install a few gems: 
# 
#  $ gem install soap4r 
# 
# Now, jira4r, which has to be pulled down from subversion: 
# 
#  $ svn co http://svn.rubyhaus.org/jira4r/trunk jira4r 
#  $ cd jira4r 
#  $ gem build jira4r.gemspec 
#  $ gem install jira4r-*.gem 
# 
# And finally, grit, a Ruby git library. As of today (July 14, 2008), 
# the most updated fork is being maintained by Scott Chacon on github. 
# For whatever reason, my attempt to install the gem directly wasn't 
# working (doesn't appear to be exposed?), so I cloned and installed 
# directly: 
# 
#  $ git clone git://github.com/schacon/grit.git 
#  $ cd grit 
#  $ gem build grit.gemspec 
#  $ gem install grit-*.gem 
# 
# When the gem gets fixed, it should be a simple: 
# 
#  $ gem sources --add http://gems.github.com 
#  $ gem install schacon-grit 
# 
# Now just copy/symlink/move an executable copy of this file into your 
# .git/hooks directory (be sure not to overwrite an existing hook): 
# 
#  $ cp jira-post-receive /path/to/repo/.git/hooks/post-receive 
# 
# And don't forget to update some globals below. Voila. You should 
# be in business. 
# 
# == TODO == 
# 
# * Get status changes with comments working. 
# 

require "rubygems" 
require "jira4r/jira_tool" 
require "grit" 

# Don't forget to set these. 
# 
# I'd recommend creating a dedicated user in JIRA to execute these 
# updates. That user will need permissions to: 
# 
# * Browse Projects 
# * Resolve Issues 
# * Close Issues 
# * Add Comments 
# 
# (I think that's comprehensive.) 
JIRA_ADDRESS = "http://yourserver.com/jira" 
JIRA_PROJECT = "DEMO" 
JIRA_USERNAME = "user" 
JIRA_PASSWORD = "password" 

class JiraPostReceive 
    def initialize(old_commit, new_commit, ref) 
    @old_commit = old_commit 
    @new_commit = new_commit 
    @ref = ref 

    @repo = Grit::Repo.new(".") 
    end 

    def jira 
    unless @jira 
     @jira = Jira4R::JiraTool.new(2, JIRA_ADDRESS) 
     @jira.logger = Logger.new("/dev/null") 
     @jira.login(JIRA_USERNAME, JIRA_PASSWORD) 
    end 
    @jira 
    end 

    def run 
    unless issues.empty? 
     jira # Sets up access to Jira4R::V2 constants 

     issues.each do |issue| 
     begin 
      send_comment(issue) 
      send_new_status(issue) if issue[:new_status] 
     rescue 
      next 
     end 
     end 
    end 
    end 

    # Adds a comment to the JIRA issue 
    # 
    # Unfortunately, all comments originate from the dedicated JIRA 
    # user that's used to post the comment. It's possible to set a 
    # different author for the comment, but looking one up via email 
    # in JIRA doesn't seem possible without giving the user 
    # administrative rights. 
    def send_comment(issue) 
    comment = Jira4R::V2::RemoteComment.new 
    comment.author = JIRA_USERNAME 
    comment.body = generate_comment(issue[:commit]) 

    jira.addComment(issue[:key], comment) 
    end 

    def send_new_status(issue) 
    status_string = case issue[:new_status] 
        when "resolved" then "Resolve Issue" 
        when "closed" then "Close Issue" 
        when "reopen" then "Reopen Issue" 
        end 

    if status = jira.getAvailableActions(issue[:key]). 
     find { |a| a.name == status_string } 
     jira.progressWorkflowAction(issue[:key], status.id.to_s, []) 
    end 
    end 

    def issues 
    issues = [] 
    issued_commits.each do |commit| 
     issue_string = commit.short_message.match(/(.*?):/)[1] 
     issue_string.split(",").each do |snippet| 
     snippet.strip! 
     snippet =~ /(#{JIRA_PROJECT}-\d+)\s?(resolved|closed|reopen)?/i 
     issues << { :key => $1, :new_status => $2, :commit => commit } 
     end 
    end 
    issues 
    end 

    def issued_commits 
    new_commits.select do |commit| 
     commit.short_message =~ /(#{JIRA_PROJECT}-\d+)(.*):/ 
    end 
    end 

    # Fetch commits that are new to the repository 
    # 
    # That super-piped git command makes sure that we only update JIRA 
    # with commits that are new, and haven't been seen in any other 
    # branches. It's lifted verbatim from the post-receive-email hook 
    # that's shipped in the git repository -- 
    # contrib/hooks/post-receive-email. 
    def new_commits 
    common_cmd = "git rev-parse --not --branches | " + 
       "grep -v $(git rev-parse #{@ref}) | " + 
     "git rev-list --stdin " 

    commit_ids = if branch_created? 
        `#{common_cmd} #{@new_commit}`.split 
       elsif branch_updated? 
        `#{common_cmd} #{@old_commit}..#{@new_commit}`.split 
       else 
        [] 
       end 

    commit_ids.map { |id| @repo.commit(id) }.reverse 
    end 

    def generate_comment(commit) 
    <<-EOS 
Commit: #{commit.id} 
Author: #{commit.author.name} <#{commit.author.email}> 
Date: #{commit.authored_date} 

#{commit.message} 
    EOS 
    end 

    def branch_created? 
    @ref =~ /refs\/heads/ && @old_commit =~ /^0+$/ 
    end 

    def branch_updated? 
    @ref =~ /refs\/heads/ && @old_commit !~ /^0+$/ && 
       @new_commit !~ /^0+$/ 
    end 
end 

old_commit, new_commit, ref = STDIN.gets.split 
JiraPostReceive.new(old_commit, new_commit, ref).run 

exit 0 
+2

看起來這是從http://foodforsamurai.com/post/483440483/git-to-jira – dave1010 2011-03-21 16:18:21