2009-10-01 10 views
14

Quelqu'un a-t-il un hook de commit git que je peux utiliser pour m'assurer qu'un numéro de problème JIRA apparaitra dans le message checkin? Je n'ai aucune expérience de conduite JIRA à partir d'un crochet de commit git donc toute aide serait appréciée - source de travail encore plus!Crochet de validation de code JIRA pour 'git'

Répondre

16

Tout d'abord, faire l'exécutable crochet:

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

Ajoutez les lignes suivantes, en remplaçant PROJET avec le code de votre projet.

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

Pour vérifier plusieurs projets et d'assurer qu'il existe un identifiant du problème, utilisez: grep -E '(PRJA | PRJB) - [[: digit:]] +' – Martin

+0

Est-il possible de faire cette validation du côté d'Atlassian? Pour éviter d'avoir à dire à chacun des gars non-techniques de l'équipe comment faire cela. –

-1

Je voudrais écrire un crochet de validation qui garantit que quelque chose que ressemble comme un numéro de problème JIRA apparaît quelque part dans le message de validation. Pour ce faire, un match simple expression régulière ferait:

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

Si vous voulez, pour faute de frappe de protection supplémentaire, vous pouvez faire en sorte que la première partie correspond à un certain identificateur de projet que vous avez mis en place dans JIRA:

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

Je trouve qu'il ya peu de valeur en essayant de faire en sorte que le nombre partie de qui fait référence à un numéro d'émission valide. Il n'y a pas vraiment moyen de déterminer si l'utilisateur a saisi le bon numéro de problème (même si vous parvenez à le limiter aux problèmes ouverts, l'utilisateur peut toujours entrer un numéro de problème ouvert non lié). Les utilisateurs doivent être attentifs lors de la validation du code.

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

On dirait que ça vient de http://foodforsamurai.com/post/483440483/git-to-jira – dave1010

Questions connexes