[PATCHv2] pre-push hook checking bugzilla IDs on rhelX branches (fixed version)
Vratislav Podzimek
vpodzime at redhat.com
Wed Jan 29 08:50:35 UTC 2014
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
docs/commit-log.txt | 5 +++
scripts/githooks/check_commit_msg.sh | 72 ++++++++++++++++++++++++++++++++
scripts/githooks/pre-push | 80 ++++++++++++++++++++++++++++++++++++
3 files changed, 157 insertions(+)
create mode 100755 scripts/githooks/check_commit_msg.sh
create mode 100755 scripts/githooks/pre-push
diff --git a/docs/commit-log.txt b/docs/commit-log.txt
index 7671f71..2e3f227 100644
--- a/docs/commit-log.txt
+++ b/docs/commit-log.txt
@@ -56,3 +56,8 @@ following are rules to follow when committing a change to the git repo:
First, it verifies that the bug referenced is a RHEL bug and in correct
states. Second, it adds the appropriate Resolves/Related/Conflicts line
to the RPM spec file changelog.
+
+It is recommended to use the pre-push hook checking commit messages for RHEL bug
+numbers and checking the referenced bugs for all the necessary acks. To make it
+work, just copy the scripts/githooks/pre-push and
+scripts/githooks/check_commit_msg.sh scripts to the .git/hooks/ directory.
diff --git a/scripts/githooks/check_commit_msg.sh b/scripts/githooks/check_commit_msg.sh
new file mode 100755
index 0000000..8022f22
--- /dev/null
+++ b/scripts/githooks/check_commit_msg.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+# Check whether the given commit has a valid BZ ID reference for the given
+# release.
+#
+# $1 -- release number
+# $2 -- commit hash
+#
+
+exec 1>&2
+
+bzcmd="bugzilla"
+release=${1}
+commit=${2}
+msg="$(git show -s --pretty='%s%n%b' ${commit})"
+summary="$(git show -s --pretty='%s%n%b' ${commit}|head -n 1)"
+
+## helper functions ##
+# Check the bz to see if it has an ack for this release. If the branch is
+# a local branch, just warn. If it is the primary branch, block the commit.
+bz_has_ack() {
+ bug=$1
+ flags=$(${bzcmd} query --bug_id=${bug} --outputformat="%{flags}")
+
+ ack_pattern="rhel-${release}\.[[:digit:]]+\.[[:digit:]]+\+"
+ if [[ ! "$flags" =~ $ack_pattern ]]; then
+ echo "*** BZ ${bug} is missing acks: ${flags}"
+
+ return 1
+ fi
+ return 0
+}
+
+echo "${summary}" | grep -i '^new version' > /dev/null
+if [ $? -eq 0 ]; then
+ # "New version" commit doesn't need a BZ ID
+ exit 0
+fi
+
+for word in ${summary} ; do
+ echo "${word}" | grep -q -E "^.*(#[0-9]+).*"
+ if [ $? -eq 0 ]; then
+ bug="$(echo "${word}" | sed -e 's/^(#//g' -e 's/).*$//g')"
+ ${bzcmd} query --bug_id=${bug} --outputformat="%{product}" | grep -q "^Red Hat Enterprise Linux.*"
+ if [ $? -ne 0 ]; then
+ echo "*** BZ ${bug} is not a RHEL bug."
+ exit 1
+ fi
+ bz_has_ack ${bug}
+ exit $?
+ fi
+done
+
+last=$(($(echo ${msg} |wc -l) - 2))
+if [ ${last} -gt 0 ]; then
+ tail -n ${last} ${msg} | grep -v "^#" |
+ grep -E "^(Resolves|Related|Conflicts): rhbz#[0-9]+$" |
+ while read line ; do
+ bug="$(echo ${line} | cut -d '#' -f 2)"
+ ${bzcmd} query --bug_id=${bug} --outputformat="%{product}" | grep -q "^Red Hat Enterprise Linux.*"
+ if [ $? -ne 0 ]; then
+ echo "*** BZ ${bug} is not a RHEL bug."
+ exit 1
+ fi
+ bz_has_ack ${bug}
+ exit $?
+ done
+fi
+
+# nothing found
+echo "*** Commit ${commit} doesn't have bugzilla ID specified ***"
+exit 1
diff --git a/scripts/githooks/pre-push b/scripts/githooks/pre-push
new file mode 100755
index 0000000..316048e
--- /dev/null
+++ b/scripts/githooks/pre-push
@@ -0,0 +1,80 @@
+#!/bin/bash
+#
+# pre-push hook that checks that all commits that are about to be pushed have
+# the bugzilla ID specified and the bug reports have all the necessary acks.
+#
+
+exec 1>&2
+
+echo "*** Checking commits that are about to be pushed" >&2
+
+## initialization ##
+remote="${1}"
+branch="${2}"
+ACK_FATAL=0
+branch_name=$(git branch | grep ^* | cut -c3-)
+branch_pattern="^rhel([[:digit:]])-(.*)"
+if [[ ! "$branch_name" =~ $branch_pattern ]]; then
+ exit 0
+fi
+release=${BASH_REMATCH[1]}
+
+# Is this a local branch, or the primary branch?
+if [ "${BASH_REMATCH[2]}" == "branch" ]; then
+ # Make a missing ack block the commit
+ ACK_FATAL=0
+else
+ # Missing acks are just warnings
+ ACK_FATAL=1
+fi
+
+if [ -f "${HOME}/.rhbzauth" ]; then
+ . "${HOME}/.rhbzauth"
+fi
+
+bzcmd="bugzilla"
+if [ ! -z "${RHBZ_USER}" ]; then
+ if [ ! -z "${RHBZ_PASSWORD}" ]; then
+ bzcmd_login="${bzcmd} --user=${RHBZ_USER} --password=${RHBZ_PASSWORD} login"
+ else
+ bzcmd_login="${bzcmd} --user=${RHBZ_USER} login"
+ fi
+else
+ bzcmd_login="bugzilla"
+fi
+
+commits=$(git log --pretty='%H' ${remote}/${branch_name}..${branch_name})
+if [ $? != 0 ]; then
+ if [ -n ${NEW_BRANCH} ]; then
+ exit 0
+ else
+ echo "*** Cannot find the remote branch ***"
+ echo 'Set the $NEW_BRANCH variable to an nonempty string to allow this push'
+ exit 1
+ fi
+fi
+
+${bzcmd} >/dev/null 2>&1
+if [ $? -eq 127 ]; then
+ echo "*** 'yum install python-bugzilla' to validate bug references."
+
+ msg="$(mktemp $(pwd)/commit.msg.XXXXXXXXXX)"
+ cp "${1}" "${msg}"
+ echo
+ echo "Aborted commit message written to: $(basename ${msg})"
+ exit 1
+else
+ ${bzcmd_login} >/dev/null
+fi
+
+## main ##
+# fork separate process for every commit, querying bugzilla takes time
+num_commits=$(echo ${commits}|wc -w)
+echo ${commits}|xargs -n1 --max-procs=${num_commits} .git/hooks/check_commit_msg.sh ${release}
+xargs_ret=$?
+if [ ${ACK_FATAL} == "0" ]; then
+ test ${xargs_ret} -eq 0
+ exit $?
+else
+ exit 0
+fi
--
1.8.5.3
More information about the anaconda-patches
mailing list