chore(ci): deprecate cherry-pick script and enable backport merge

This commit is contained in:
DanStough 2022-05-06 15:38:02 -04:00 committed by Dan Stough
parent e874b860c0
commit 96225aa2e4
6 changed files with 42 additions and 224 deletions

View File

@ -927,19 +927,6 @@ jobs:
path: *TEST_RESULTS_DIR
- run: *notify-slack-failure
# only runs on main: checks latest commit to see if the PR associated has a backport/* or docs* label to cherry-pick
cherry-picker:
docker:
- image: docker.mirror.hashicorp.services/alpine:3.12
steps:
- run: apk add --no-cache --no-progress git bash curl ncurses jq openssh-client
- checkout
- add_ssh_keys: # needs a key to push cherry-picked commits back to github
fingerprints:
- "fc:55:84:15:0a:1d:c8:e9:06:d0:e8:9c:7b:a9:b7:31"
- run: .circleci/scripts/cherry-picker.sh
- run: *notify-slack-failure
trigger-oss-merge:
docker:
- image: docker.mirror.hashicorp.services/alpine:3.12
@ -1202,13 +1189,7 @@ workflows:
only:
- main
- /release\/\d+\.\d+\.x$/
- cherry-picker:
context: team-consul
filters:
branches:
only:
- main
- /release\/\d+\.\d+\.x$/
load-test:
when: << pipeline.parameters.trigger-load-test >>
jobs:

View File

@ -1,195 +0,0 @@
#!/usr/bin/env bash
#
# This script is meant to run on every new commit to main in CircleCI. If the commit comes from a PR, it will
# check the PR associated with the commit for labels. If the label matches `docs*` it will be cherry-picked
# to stable-website. If the label matches `backport/*`, it will be cherry-picked to the appropriate `release/*`
# branch.
# Requires $CIRCLE_PROJECT_USERNAME, $CIRCLE_PROJECT_REPONAME, and $CIRCLE_SHA1 from CircleCI
set -o pipefail
# colorized status prompt
function status {
tput setaf 4
echo "$@"
tput sgr0
}
# Returns the latest GitHub "backport/*" label
function get_latest_backport_label {
local resp
local ret
local latest_backport_label
resp=$(curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/labels?per_page=100")
ret="$?"
if [[ "$ret" -ne 0 ]]; then
status "The GitHub API returned $ret which means it was probably rate limited."
exit $ret
fi
latest_backport_label=$(echo "$resp" | jq -r '.[] | select(.name | startswith("backport/")) | .name' | sort -rV | head -n1)
echo "$latest_backport_label"
return 0
}
# 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
#
# Return:
# 0 for success
# 1 for error
local branch="$1"
local commit="$2"
local pr_url="$3"
git checkout "$branch" || exit 1
# If git cherry-pick fails or it fails to push, we send a failure notification
if ! (git cherry-pick --mainline 1 "$commit" && git push origin "$branch"); then
status "🍒❌ Cherry pick of commit ${commit:0:7} from $pr_url onto $branch failed!"
# send slack notification
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}"
# post PR comment to GitHub
github_message=":cherries::x: Cherry pick of commit ${commit} onto \`$branch\` failed! [Build Log]($CIRCLE_BUILD_URL)"
pr_id=$(basename ${pr_url})
curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" \
-X POST \
-d "{ \"body\": \"${github_message}\"}" \
"https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${pr_id}/comments"
# run git status to leave error in CircleCI log
git status
return 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!\", \
\"footer\": \"${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}\", \
\"ts\": \"$(date +%s)\", \
\"color\": \"good\" \
} \
] \
}" "${CONSUL_SLACK_WEBHOOK_URL}"
# post PR comment to GitHub
github_message=":cherries::white_check_mark: Cherry pick of commit ${commit} onto \`$branch\` succeeded!"
pr_id=$(basename ${pr_url})
curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" \
-X POST \
-d "{ \"body\": \"${github_message}\"}" \
"https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${pr_id}/comments"
fi
return 0
}
# search for the PR labels applicable to the specified commit
resp=$(curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/search/issues?q=repo:${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}+sha:${CIRCLE_SHA1}")
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
status "This commit was not associated with a PR"
exit 0
fi
# save PR number
pr_number=$(echo "$resp" | jq '.items[].number')
# comment on the PR with the build number to make it easy to re-run the job when
# cherry-pick labels are added in the future
github_message=":cherries: If backport labels were added before merging, cherry-picking will start automatically.\n\nTo retroactively trigger a backport after merging, add backport labels and re-run ${CIRCLE_BUILD_URL}."
curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" \
-X POST \
-d "{ \"body\": \"${github_message}\"}" \
"https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${pr_number}/comments"
# If the API returned a non-zero count, we have found a PR with that commit so we find
# the labels from the PR
# Sorts the labels from a PR via version sort
labels=$(echo "$resp" | jq --raw-output '.items[].labels[] | .name' | sort -rV)
ret="$?"
pr_url=$(echo "$resp" | jq --raw-output '.items[].pull_request.html_url')
if [[ "$ret" -ne 0 ]]; then
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
# Attach label for latest release branch if 'docs-cherrypick' is present. Will noop if already applied.
latest_backport_label=$(get_latest_backport_label)
status "latest backport label is $latest_backport_label"
if echo "$resp" | jq -e '.items[].labels[] | select(.name | contains("docs-cherrypick"))'; then
labels=$(curl -f -s -H "Authorization: token ${GITHUB_TOKEN}" -X POST -d "{\"labels\":[\"$latest_backport_label\"]}" "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${pr_number}/labels" | jq --raw-output '.[].name' | sort -rV)
ret="$?"
if [[ "$ret" -ne 0 ]]; then
status "Error applying $latest_backport_label to $pr_url"
exit $ret
fi
fi
git config --local user.email "github-team-consul-core@hashicorp.com"
git config --local user.name "hc-github-team-consul-core"
backport_failures=0
# loop through all labels on the PR
for label in $labels; do
status "checking label: $label"
# if the label matches docs-cherrypick, it will attempt to cherry-pick to stable-website
if [[ $label =~ docs-cherrypick ]]; then
status "backporting to stable-website"
branch="stable-website"
cherry_pick_with_slack_notification "$branch" "$CIRCLE_SHA1" "$pr_url"
backport_failures=$((backport_failures + "$?"))
# else if the label matches backport/*, it will attempt to cherry-pick to the release branch
elif [[ $label =~ backport/* ]]; then
status "backporting to $label"
branch="${label/backport/release}.x"
cherry_pick_with_slack_notification "$branch" "$CIRCLE_SHA1" "$pr_url"
backport_failures=$((backport_failures + "$?"))
fi
# reset the working directory for the next label
git reset --hard
done
if [ "$backport_failures" -ne 0 ]; then
echo "$backport_failures backports failed"
exit 1
fi

View File

@ -156,12 +156,25 @@ When you're ready to submit a pull request:
if your changes aren't finalized but would benefit from in-process feedback.
5. If there's any reason Consul users might need to know about this change,
[add a changelog entry](../docs/contributing/add-a-changelog-entry.md).
6. After you submit, the Consul maintainers team needs time to carefully review your
6. Add labels to your pull request. A table of commonly use labels is below.
If you have any questions about which to apply, feel free to call it out in the PR or comments.
| Label | When to Use |
| --- | --- |
| `pr/no-changelog` | This PR does not have an intended changelog entry |
| `pr/no-metrics-test` | This PR does not require any testing for metrics |
| `backport/stable-website` | This PR contains documentation changes that are ready to be deployed immediately. Changes will also automatically get backported to the latest release branch |
| `backport/1.12.x` | Backport the changes in this PR to the targeted release branch. Consult the [Consul Release Notes](https://www.consul.io/docs/release-notes) page to view active releases. |
Other labels may automatically be added by the Github Action CI.
7. After you submit, the Consul maintainers team needs time to carefully review your
contribution and ensure it is production-ready, considering factors such as: security,
backwards-compatibility, potential regressions, etc.
7. After you address Consul maintainer feedback and the PR is approved, a Consul maintainer
8. After you address Consul maintainer feedback and the PR is approved, a Consul maintainer
will merge it. Your contribution will be available from the next major release (e.g., 1.x)
unless explicitly backported to an existing or previous major release by the maintainer.
9. Any backport labels will generate an additional PR to the targeted release branch.
These will be linked in the original PR.
Assuming the tests pass, the PR will be merged automatically.
If the tests fail, it is you responsibility to resolve the issues with backports and request another reviewer.
#### Checklists

View File

@ -8,6 +8,9 @@ on:
types:
- closed
- labeled
branches:
- main
- 'releases/*.*.x'
jobs:
backport:
@ -16,17 +19,33 @@ jobs:
container: hashicorpdev/backport-assistant:0.2.3
steps:
- name: Run Backport Assistant for stable-website
# Update this to auto-merge when we have confidence in the process working and kill Circle
run: |
backport-assistant backport -merge-method=rebase
backport-assistant backport -merge-method=rebase -auto-merge
env:
BACKPORT_LABEL_REGEXP: "type/docs-(?P<target>cherrypick)"
BACKPORT_TARGET_TEMPLATE: "stable-website"
GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Run Backport Assistant for release branches
# Update this to auto-merge when we have confidence in the process working and kill Circle
- name: Backport changes to latest release branch
run: |
backport-assistant backport -merge-method=rebase
resp=$(curl -f -s "https://api.github.com/repos/$GITHUB_REPOSITORY/labels?per_page=100")
ret="$?"
if [[ "$ret" -ne 0 ]]; then
echo "The GitHub API returned $ret"
exit $ret
fi
# get the latest backport label excluding any website labels, ex: `backport/0.3.x` and not `backport/website`
latest_backport_label=$(echo "$resp" | jq -r '.[] | select(.name | (startswith("backport/") and (contains("website") | not))) | .name' | sort -rV | head -n1)
echo "Latest backport label: $latest_backport_label"
# set BACKPORT_TARGET_TEMPLATE for backport-assistant
# trims backport/ from the beginning with parameter substitution
export BACKPORT_TARGET_TEMPLATE="release/${latest_backport_label#backport/}.x"
backport-assistant backport -merge-method=rebase -automerge
env:
BACKPORT_LABEL_REGEXP: "type/docs-(?P<target>cherrypick)"
GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Run Backport Assistant for release branches
run: |
backport-assistant backport -merge-method=rebase -auto-merge
env:
BACKPORT_LABEL_REGEXP: "backport/(?P<target>\\d+\\.\\d+)"
BACKPORT_TARGET_TEMPLATE: "release/{{.target}}.x"

View File

@ -17,7 +17,7 @@ jobs:
steps:
- name: Comment on PR
run: |
github_message="After merging, confirm that you see messages like: 🍒✅ Cherry pick of commit ... onto ... succeeded!"
github_message="After merging, confirm that you see linked PRs AND check that them for CI errors."
curl -s -H "Authorization: token ${{ secrets.PR_COMMENT_TOKEN }}" \
-X POST \
-d "{ \"body\": \"${github_message}\"}" \

View File

@ -8,7 +8,7 @@ on:
jobs:
metrics_test_check:
if: "!contains(github.event.pull_request.labels.*.name, 'pr/no-metrics-test')"
if: "! ( contains(github.event.pull_request.labels.*.name, 'pr/no-metrics-test') || github.event.pull_request.user.login == 'hc-github-team-consul-core' )"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2