blob: a97af6338cada5e6b8d977a547b5ce1d42c77ae3 [file] [log] [blame]
Arthur Shef974bc12024-02-04 22:28:10 -08001#!/bin/bash
2set -ex
3
4echo "########################################################################"
5echo " Gerrit Environment"
6env |grep '^GERRIT'
7echo "########################################################################"
8SSH_PARAMS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAcceptedKeyTypes=+ssh-rsa -p 29418 -i ${CI_BOT_KEY}"
9GERRIT_URL="review.trustedfirmware.org"
10GERRIT_CHANGE_URL_BASE=${GERRIT_CHANGE_URL%/*}
11GERRIT_QUERY_PARAMS="--dependencies --current-patch-set --format=JSON change:"
12QUERY_DEPENDENCY_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit query ${GERRIT_QUERY_PARAMS}"
13ALLOW_CI_COMMENT="Trigger Allow-CI job by ${BUILD_URL}"
14VOTE_ALLOW_CI_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review --label ${ALLOW_CI_JOB} -m \"${ALLOW_CI_COMMENT}\" ${GERRIT_PATCHSET_REVISION}"
15SUBMIT_COMMENT="Submit patch by ${BUILD_URL}"
16SUBMIT_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review -m \"${SUBMIT_COMMENT}\" --submit"
17err_msg=$(mktemp)
18
19function get_top_patch() {
20 # Get the top of the patch stack
21 # return: change_no,commit_revision
22 local change_no=$1
23
24 patch_info=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null| jq -n 'input')
25 revision=$(echo ${patch_info} | jq -r '.currentPatchSet.revision')
26 ret=${change_no},${revision}
27
28 neededBy=$(echo ${patch_info} | jq -c 'select(.neededBy)')
29 while [ -n "${neededBy}" ];
30 do
31 change_no=$(echo ${neededBy} | jq -r '.neededBy[0].number')
32 revision=$(echo ${neededBy} | jq -r '.neededBy[0].revision')
33 ret=${change_no},${revision}
34 neededBy=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -c 'select(.neededBy)')
35 done
36
37 echo ${ret}
38}
39
40function check_ok_to_submit() {
41 # Check if this patch meets the submit requirement
42 # The submit requirement is
43 # Verified: 1
44 # Code-Owner-Review: 1
45 # Maintainer-Review: 1
46 # return:
47 # "True": if the submit requirement is met
48 # "False: if the submit requirement is not met
49 # "MERGED": if the patch has been merged
50 local change_no=$1
51
52 patch_info=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -n 'input')
53 patch_votes=$(echo ${patch_info} | jq -c 'select(.currentPatchSet.approvals)')
54
55 if [ $(echo ${patch_info} | jq -r '.status') == "MERGED" ]; then
56 echo "MERGED"
57 elif test -n "${patch_votes}" &&
58 jq -e '.currentPatchSet.approvals[] | select(.type == "Code-Owner-Review" and .value == "1")' <<< "${patch_votes}" > /dev/null &&
59 jq -e '.currentPatchSet.approvals[] | select(.type == "Maintainer-Review" and .value == "1")' <<< "${patch_votes}" > /dev/null &&
60 jq -e '.currentPatchSet.approvals[] | select(.type == "Verified" and .value == "1")' <<< "${patch_votes}" > /dev/null; then
61 echo "True"
62 else
63 echo "${GERRIT_CHANGE_URL_BASE}/${change_no} doesn't meet the submit requirement" >> /dev/stderr
64 echo "False"
65 fi
66}
67
68function submit_patch_stack() {
69 # Check the whole patch stack from top to bottom
70 # to see if all patches meet the submit requirements
71 local change_no=$1
72 local can_merge="True"
73
74 top_patch=$(get_top_patch ${change_no})
75 top_patch_no=$(echo ${top_patch} | cut -d ',' -f 1)
76 top_patch_rev=$(echo ${top_patch} | cut -d ',' -f 2)
77
78 patch_to_be_checked=${top_patch_no}
79 while [ -n "${patch_to_be_checked}" ];
80 do
81 set +x # disable debugging log to prevent comtaminate the message we want to keep
82 can_submit=$(check_ok_to_submit ${patch_to_be_checked} 2>> ${err_msg})
83 set -x
84 # The patch that we just checked was merged, exit the loop
85 [ "${can_submit}" == "MERGED" ] && break
86 [ "${can_merge}" == "True" ] && can_merge=${can_submit}
87 patch_to_be_checked=$(ssh ${QUERY_DEPENDENCY_CMD}${patch_to_be_checked} 2>/dev/null | jq 'select(.dependsOn) | .dependsOn[].number' )
88 done
89 if [ "${can_merge}" == "True" ]; then
90 # Check the patch stack agein to ensure it hasn't been merged yet
91 if [ $(ssh ${QUERY_DEPENDENCY_CMD}${top_patch_no} | jq -r 'select(.status)|.status') != "MERGED" ];then
92 echo "The whole patch stack meets the submit requirements, merge it"
93 ssh ${SUBMIT_CMD} ${top_patch_rev} 2> /dev/null
94 else
95 echo "The whole patch stack has been merged!"
96 fi
97 else
98 echo "The patch stack can not be merged!"
99 cat ${err_msg}
100 fi
101}
102
103function trigger_allow_ci_on_top_of_patch_stack() {
104 # This function will set ${ALLOW_CI_JOB} on the
105 # top of the patch stack or a single patch
106 local change_no=$1
107
108 neededBy=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -c 'select(.neededBy)')
109 if [ -z "${neededBy}" ]; then
110 echo -e "Trigger Allow-CI job on ${GERRIT_CHANGE_URL}"
111 ssh ${VOTE_ALLOW_CI_CMD} 2>/dev/null
112 else
113 echo "This patch is not on the top of a patch stack"
114 fi
115}
116
117case ${GERRIT_EVENT_TYPE} in
118 "comment-added")
119 echo "Triggered by comment-added"
120 # Check eack patch. if all patches meet the submit requirements
121 # merge it
122 submit_patch_stack ${GERRIT_CHANGE_NUMBER}
123 ;;
124 "patchset-created")
125 echo "Triggered by patchset-created"
126 # New patch / patch stack is created
127 # Set Allow-CI on the top of it
128 trigger_allow_ci_on_top_of_patch_stack ${GERRIT_CHANGE_NUMBER}
129 ;;
130esac
131rm -f ${err_msg}