Arthur She | f974bc1 | 2024-02-04 22:28:10 -0800 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | set -ex |
| 3 | |
| 4 | echo "########################################################################" |
| 5 | echo " Gerrit Environment" |
| 6 | env |grep '^GERRIT' |
| 7 | echo "########################################################################" |
| 8 | SSH_PARAMS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PubkeyAcceptedKeyTypes=+ssh-rsa -p 29418 -i ${CI_BOT_KEY}" |
| 9 | GERRIT_URL="review.trustedfirmware.org" |
| 10 | GERRIT_CHANGE_URL_BASE=${GERRIT_CHANGE_URL%/*} |
| 11 | GERRIT_QUERY_PARAMS="--dependencies --current-patch-set --format=JSON change:" |
| 12 | QUERY_DEPENDENCY_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit query ${GERRIT_QUERY_PARAMS}" |
| 13 | ALLOW_CI_COMMENT="Trigger Allow-CI job by ${BUILD_URL}" |
| 14 | VOTE_ALLOW_CI_CMD="${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review --label ${ALLOW_CI_JOB} -m \"${ALLOW_CI_COMMENT}\" ${GERRIT_PATCHSET_REVISION}" |
| 15 | SUBMIT_COMMENT="Submit patch by ${BUILD_URL}" |
Arthur She | f974bc1 | 2024-02-04 22:28:10 -0800 | [diff] [blame] | 16 | err_msg=$(mktemp) |
| 17 | |
| 18 | function 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 | |
| 39 | function 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 | |
| 67 | function 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 She | 8e2202e | 2024-04-20 22:41:39 -0700 | [diff] [blame] | 92 | ssh ${SSH_PARAMS} ${CI_BOT_USERNAME}@${GERRIT_URL} gerrit review ${top_patch_rev} --message "\"${SUBMIT_COMMENT}\"" --submit |
Arthur She | f974bc1 | 2024-02-04 22:28:10 -0800 | [diff] [blame] | 93 | 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 | |
| 102 | function 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 | |
| 116 | case ${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 She | 6162aa4 | 2024-03-13 10:11:22 -0700 | [diff] [blame] | 121 | 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 She | f974bc1 | 2024-02-04 22:28:10 -0800 | [diff] [blame] | 126 | ;; |
| 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 She | 6162aa4 | 2024-03-13 10:11:22 -0700 | [diff] [blame] | 131 | 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 She | f974bc1 | 2024-02-04 22:28:10 -0800 | [diff] [blame] | 136 | ;; |
| 137 | esac |
| 138 | rm -f ${err_msg} |