blob: 3e8f6350c11c8bd6f53a293ec911de8ee81d65f6 [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}"
Arthur Shef974bc12024-02-04 22:28:10 -080016err_msg=$(mktemp)
17
18function get_top_patch() {
19 # Get the top of the patch stack
20 # return: change_no,commit_revision
21 local change_no=$1
22
23 patch_info=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null| jq -n 'input')
24 revision=$(echo ${patch_info} | jq -r '.currentPatchSet.revision')
25 ret=${change_no},${revision}
26
27 neededBy=$(echo ${patch_info} | jq -c 'select(.neededBy)')
28 while [ -n "${neededBy}" ];
29 do
30 change_no=$(echo ${neededBy} | jq -r '.neededBy[0].number')
31 revision=$(echo ${neededBy} | jq -r '.neededBy[0].revision')
32 ret=${change_no},${revision}
33 neededBy=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -c 'select(.neededBy)')
34 done
35
36 echo ${ret}
37}
38
39function check_ok_to_submit() {
40 # Check if this patch meets the submit requirement
41 # The submit requirement is
42 # Verified: 1
43 # Code-Owner-Review: 1
44 # Maintainer-Review: 1
45 # return:
46 # "True": if the submit requirement is met
47 # "False: if the submit requirement is not met
48 # "MERGED": if the patch has been merged
49 local change_no=$1
50
51 patch_info=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -n 'input')
52 patch_votes=$(echo ${patch_info} | jq -c 'select(.currentPatchSet.approvals)')
53
54 if [ $(echo ${patch_info} | jq -r '.status') == "MERGED" ]; then
55 echo "MERGED"
56 elif test -n "${patch_votes}" &&
57 jq -e '.currentPatchSet.approvals[] | select(.type == "Code-Owner-Review" and .value == "1")' <<< "${patch_votes}" > /dev/null &&
58 jq -e '.currentPatchSet.approvals[] | select(.type == "Maintainer-Review" and .value == "1")' <<< "${patch_votes}" > /dev/null &&
59 jq -e '.currentPatchSet.approvals[] | select(.type == "Verified" and .value == "1")' <<< "${patch_votes}" > /dev/null; then
60 echo "True"
61 else
62 echo "${GERRIT_CHANGE_URL_BASE}/${change_no} doesn't meet the submit requirement" >> /dev/stderr
63 echo "False"
64 fi
65}
66
67function submit_patch_stack() {
68 # Check the whole patch stack from top to bottom
69 # to see if all patches meet the submit requirements
70 local change_no=$1
71 local can_merge="True"
72
73 top_patch=$(get_top_patch ${change_no})
74 top_patch_no=$(echo ${top_patch} | cut -d ',' -f 1)
75 top_patch_rev=$(echo ${top_patch} | cut -d ',' -f 2)
76
77 patch_to_be_checked=${top_patch_no}
78 while [ -n "${patch_to_be_checked}" ];
79 do
80 set +x # disable debugging log to prevent comtaminate the message we want to keep
81 can_submit=$(check_ok_to_submit ${patch_to_be_checked} 2>> ${err_msg})
82 set -x
83 # The patch that we just checked was merged, exit the loop
84 [ "${can_submit}" == "MERGED" ] && break
85 [ "${can_merge}" == "True" ] && can_merge=${can_submit}
86 patch_to_be_checked=$(ssh ${QUERY_DEPENDENCY_CMD}${patch_to_be_checked} 2>/dev/null | jq 'select(.dependsOn) | .dependsOn[].number' )
87 done
88 if [ "${can_merge}" == "True" ]; then
89 # Check the patch stack agein to ensure it hasn't been merged yet
90 if [ $(ssh ${QUERY_DEPENDENCY_CMD}${top_patch_no} | jq -r 'select(.status)|.status') != "MERGED" ];then
91 echo "The whole patch stack meets the submit requirements, merge it"
Arthur She8e2202e2024-04-20 22:41:39 -070092 ssh ${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review ${top_patch_rev} --message "\"${SUBMIT_COMMENT}\"" --submit
Arthur Shef974bc12024-02-04 22:28:10 -080093 else
94 echo "The whole patch stack has been merged!"
95 fi
96 else
97 echo "The patch stack can not be merged!"
98 cat ${err_msg}
99 fi
100}
101
102function trigger_allow_ci_on_top_of_patch_stack() {
103 # This function will set ${ALLOW_CI_JOB} on the
104 # top of the patch stack or a single patch
105 local change_no=$1
106
107 neededBy=$(ssh ${QUERY_DEPENDENCY_CMD}${change_no} 2>/dev/null | jq -c 'select(.neededBy)')
108 if [ -z "${neededBy}" ]; then
109 echo -e "Trigger Allow-CI job on ${GERRIT_CHANGE_URL}"
110 ssh ${VOTE_ALLOW_CI_CMD} 2>/dev/null
111 else
112 echo "This patch is not on the top of a patch stack"
113 fi
114}
115
116case ${GERRIT_EVENT_TYPE} in
117 "comment-added")
118 echo "Triggered by comment-added"
119 # Check eack patch. if all patches meet the submit requirements
120 # merge it
Arthur She6162aa42024-03-13 10:11:22 -0700121 if [ "${ENABLE_PATCH_AUTO_SUBMISSION}" == "true" ]; then
122 submit_patch_stack ${GERRIT_CHANGE_NUMBER}
123 else
124 echo "Patch auto submission function is disabled"
125 fi
Arthur Shef974bc12024-02-04 22:28:10 -0800126 ;;
127 "patchset-created")
128 echo "Triggered by patchset-created"
129 # New patch / patch stack is created
130 # Set Allow-CI on the top of it
Arthur She6162aa42024-03-13 10:11:22 -0700131 if [ "${ENABLE_AUTO_ALLOW_CI_JOB}" == "true" ]; then
132 trigger_allow_ci_on_top_of_patch_stack ${GERRIT_CHANGE_NUMBER}
133 else
134 echo "Allow-CI job auto submission function is disabled"
135 fi
Arthur Shef974bc12024-02-04 22:28:10 -0800136 ;;
137esac
138rm -f ${err_msg}