Gitlab перехватывает, чтобы заставить разработчика использовать проблему JIRA в их сообщении фиксации - PullRequest
0 голосов
/ 25 ноября 2018

Я хочу реализовать пользовательские перехватчики Gitlab только для одного репозитория с использованием сценариев Linux Bash для следующего:

  1. Я хочу заставить разработчиков указывать номер проблемы JIRA с таким статусом проблемы (например:исправлено, в процессе) в их сообщении о фиксации, если сообщение о фиксации не имеет номера проблемы, push-сообщение должно быть автоматически отклонено.
  2. Если сообщение о фиксации имеет идентификатор проблемы JIRA со статусом, разработчикидолжно быть разрешено выдвигать изменения.

Я запутался между тем, какой лучший хук Gitlab я должен выбрать, и как мне использовать проблему JIRA в сообщении коммита.

1 Ответ

0 голосов
/ 25 ноября 2018

Как оказалось, у меня есть скрипт, который делает именно это.Мой также проверяет соответствие другим проблемам стиля фиксации, но вы можете настроить его под свои требования.

#!/bin/bash
#
# pre-receive hook for Commit Check
#
# Adapted from
#  http://blog.hgomez.net/2015/03/02/Gitlab-custom-hooks-Bash-Way.html

REGEX='^(\(([A-Z]+-[0-9]+|maint|docs)\) [A-Z]|Version [0-9]+).*[^\.]$'

check_single_commit()
{
  FIRST_LINE=$(echo "$COMMIT_MESSAGE" | sed -n 1p)
  SECOND_LINE=$(echo "$COMMIT_MESSAGE" | sed -n 2p)

  # Warn if line 1 > 50 chars
  WIDTH=$(echo $FIRST_LINE | wc -c)
  [ $WIDTH -gt 50 ] && [ $WIDTH -le 70 ] && printf "Warning: first line of commit exceeds 50 characters\n\n"

  # Fail if there is no Jira, docs or maint ref.
  echo $FIRST_LINE | egrep -q "$REGEX"
  COMMIT_CHECK_STATUS=$?
  if [ $COMMIT_CHECK_STATUS -gt 0 ]; then
    echo "Fail: No Jira ref found in commit message"
    echo "Expected: $REGEX"
    echo "Actual:"
    echo "$COMMIT_MESSAGE" |sed -e 's/^/  /'
    echo ""
  fi

  # Fail if second line is not blank.
  if [ ! -z "$SECOND_LINE" ] && [ $COMMIT_CHECK_STATUS -eq 0 ]; then
    [ -z "$SECOND_LINE" ] ; COMMIT_CHECK_STATUS=$?
    echo "Second line of commit is not blank, but is '$SECOND_LINE'"
    echo ""
  fi

  # Fail if line 1 > 70 chars
  if [ $WIDTH -gt 70 ] && [ $COMMIT_CHECK_STATUS -eq 0 ]; then
    [ $WIDTH -le 70 ] ; COMMIT_CHECK_STATUS=$?
    echo "Fail: first line of commit exceeds 70 characters, please use the commit body"
    echo ""
  fi
}

check_all_commits()
{
  REVISIONS=$(git rev-list master..$NEW_VALUE)
  IFS='\n' read -ra LIST_OF_REVISIONS <<< "$REVISIONS"

  for rid in "${!LIST_OF_REVISIONS[@]}"; do
    REVISION=${LIST_OF_REVISIONS[rid]}
    COMMIT_MESSAGE=$(git cat-file commit $REVISION | sed '1,/^$/d')
    check_single_commit

    if [ $COMMIT_CHECK_STATUS -ne 0 ]; then
      echo "Commit validation failed for commit $REVISION" >&2
      echo ""
      echo "Please read: https://chris.beams.io/posts/git-commit/"
      echo ""
      exit 1
    fi
  done
}

# Get custom commit message format

# After a push occurs and before any refs are updated on the remote repository,
# the git-receive-pack process invokes the pre-receive hook script with the
# standard input of one line per ref to be updated:
#
# <old-value> SP <new-value> SP <ref-name> LF
#
# This string represents these arguments:
#
# <old-value> Old object name stored in the ref. When you create a new ref,
# this equals 40 zeroes.
# <new-value> New object name to be stored in the ref. When you delete a ref,
# this equals 40 zeroes.
# <ref-name>  The full name of the ref.

while read OLD_VALUE NEW_VALUE REFNAME ; do
  [ $NEW_VALUE == 0000000000000000000000000000000000000000 ] && exit 0
  check_all_commits
done

exit 0

# vim:set ft=sh
...