Проверка фиксации кода JIRA для 'git'

У кого-нибудь есть крюк фиксации git, который я могу использовать, чтобы обеспечить, чтобы номер проблемы JIRA отображался в сообщении проверки? У меня нет опыта вождения JIRA из привязки git, поэтому любая помощь будет оценена по достоинству - рабочий источник еще больше!

Ответы

Ответ 1

Сначала сделайте исполняемый файл hook:

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

Добавьте следующие строки, заменив PROJECT кодом проекта.

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

Ответ 2

Ops, я никогда не использовал git, но друг сделал SVN-Hooks, основу для создания крючков Subversion. Он был закодирован в perl. Может быть, эта помощь в любом случае. Посмотрите на нее там:

http://code.google.com/p/svn-hooks/source/browse/trunk/t/02-jiraacceptance.t

И если вам нужно позвонить нам, КАК МОЖНО СКОРЕЕ, мы будем рады помочь.

Ответ 3

#!/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 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 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 used to post the comment.  It 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 lifted verbatim from the post-receive-email hook
  # that 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

Ответ 4

Я бы написал фиксатор фиксации, который гарантирует, что что-то, что похоже на номер проблемы JIRA, появляется где-то в сообщении фиксации. Для этого простое совпадение с обычным выражением сделало бы это:

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

Если вы хотите, для дополнительной защиты отпечатков вы можете убедиться, что первая часть соответствует определенному идентификатору проекта, который вы установили в JIRA:

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

Я считаю, что мало смысла пытаться удостовериться, что часть номера относится к действительному номеру проблемы. На самом деле не существует способа определить, введен ли пользователь правильный номер проблемы (даже если вам удастся ограничить его открытием проблем, пользователь все равно может ввести несвязанный номер открытой проблемы). От пользователей следует ожидать должной осторожности при совершении кода.