diff --git a/.circleci/scripts/cherry-picker.sh b/.circleci/scripts/cherry-picker.sh index 4be9e4982..af765f243 100755 --- a/.circleci/scripts/cherry-picker.sh +++ b/.circleci/scripts/cherry-picker.sh @@ -6,50 +6,106 @@ # Requires $CIRCLE_PROJECT_USERNAME, $CIRCLE_PROJECT_REPONAME, and $CIRCLE_SHA1 from CircleCI #!/bin/bash +# colorized status prompt +function status { + tput setaf 4 + echo "$@" + tput sgr0 +} + +# This function will do the cherry-picking of a commit on a branch +# Exit 1 if cherry-picking fails +function cherry_pick_with_slack_notification { + # Arguments: + # $1 - branch to cherry-pick to + # $2 - commit to cherry-pick + # $3 - url to PR of commit + + local branch=$1 + local commit=$2 + local pr_url=$3 + + git checkout $branch || exit 1 + # If git cherry-pick fails, we send a failure notification + if ! git cherry-pick $commit; then + status "🍒❌ Cherry pick of commit ${commit:0:7} from $pr_url onto $branch failed!" + curl -X POST -H 'Content-type: application/json' \ + --data \ + "{ \ + \"attachments\": [ \ + { \ + \"fallback\": \"Cherry pick failed!\", \ + \"text\": \"🍒❌ Cherry picking of <$pr_url|${commit:0:7}> to \`$branch\` failed!\n\nBuild Log: ${CIRCLE_BUILD_URL}\", \ + \"footer\": \"${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}\", \ + \"ts\": \"$(date +%s)\", \ + \"color\": \"danger\" \ + } \ + ] \ + }" ${CONSUL_SLACK_WEBHOOK_URL} + git status + exit 1 + # Else we send a success notification + else + status "🍒✅ Cherry picking of PR commit ${commit:0:7} from $pr_url succeeded!" + curl -X POST -H 'Content-type: application/json' \ + --data \ + "{ \ + \"attachments\": [ \ + { \ + \"fallback\": \"Cherry pick succeeded!\", \ + \"text\": \"🍒✅ Cherry picking of <$pr_url|${commit:0:7}> to \`$branch\` succeeded!\n\nBuild Log: ${CIRCLE_BUILD_URL}\", \ + \"footer\": \"${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}\", \ + \"ts\": \"$(date +%s)\", \ + \"color\": \"good\" \ + } \ + ] \ + }" ${CONSUL_SLACK_WEBHOOK_URL} + fi +} + # search for the PR labels applicable to the specified commit resp=$(curl -f -s "https://api.github.com/search/issues?q=repo:$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME+sha:$CIRCLE_SHA1") -status="$?" -if [[ "$status" -ne 0 ]]; then - echo "The GitHub API returned $status which means it was probably rate limited." - exit $status +ret="$?" +if [[ "$ret" -ne 0 ]]; then + status "The GitHub API returned $ret which means it was probably rate limited." + exit $ret fi # get the count from the GitHub API to check if the commit matched a PR count=$(echo "$resp" | jq '.total_count') if [[ "$count" -eq 0 ]]; then - echo "This commit was not associated with a PR" - exit 0 + status "This commit was not associated with a PR" + exit 0 fi # If the API returned a non-zero count, we have found a PR with that commit so we find # the labels from the PR labels=$(echo "$resp" | jq --raw-output '.items[].labels[] | .name') -status="$?" -if [[ "$status" -ne 0 ]]; then - pr_url=$(echo "$resp" | jq --raw-output '.items[].pull_request.url') - echo "jq exited with $status when trying to find label names. Are there labels applied to the PR ($pr_url)?" - # This can be a valid error but usually this means we do not have any labels so it doesn't signal - # cherry-picking is possible. Exit 0 for now unless we run into cases where these failures are important. - exit 0 +ret="$?" +if [[ "$ret" -ne 0 ]]; then + pr_url=$(echo "$resp" | jq --raw-output '.items[].pull_request.html_url') + status "jq exited with $ret when trying to find label names. Are there labels applied to the PR ($pr_url)?" + # This can be a valid error but usually this means we do not have any labels so it doesn't signal + # cherry-picking is possible. Exit 0 for now unless we run into cases where these failures are important. + exit 0 fi # loop through all labels on the PR for label in $labels; do git config --local user.email "hashicorp-ci@users.noreply.github.com" git config --local user.name "hashicorp-ci" - echo "checking label: $label" + status "checking label: $label" # if the label matches docs*, it will attempt to cherry-pick to stable-website if [[ $label =~ docs* ]]; then - echo "docs" - git checkout stable-website || exit 1 - git cherry-pick $CIRCLE_SHA1 || exit 1 + status "backporting to stable-website" + branch="stable-website" + cherry_pick_with_slack_notification $branch $CIRCLE_SHA1 $pr_url git push origin stable-website # else if the label matches backport/*, it will attempt to cherry-pick to the release branch elif [[ $label =~ backport/* ]]; then - echo "backporting to $label" + status "backporting to $label" branch="${label/backport/release}.x" - git checkout $branch || exit 1 - git cherry-pick $CIRCLE_SHA1 || exit 1 + cherry_pick_with_slack_notification $branch $CIRCLE_SHA1 $pr_url git push origin $branch fi -done +done \ No newline at end of file