mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
merge-into-chromeos: Create chain of merge commits
We can use the gerrit api to detect previous merge commits the bot has made, then use those as the base for the next merge. This will create smaller merges and is easier to manage as we do not have to abandon so many changes. One complication is detecting possible cherry picks the oncall may have added to the previous merge commit. Only open merge commits are taken into account. BUG=b:213932296 TEST=./ci/kokoro/simulate build-merge-into-chromeos.sh Change-Id: I795109be4c45bec49068c3e292a3947505755442 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3381832 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: Dennis Kempin <denniskempin@google.com>
This commit is contained in:
parent
a06f22f2ac
commit
5a250fcb26
1 changed files with 107 additions and 14 deletions
|
@ -5,12 +5,81 @@
|
|||
set -e
|
||||
cd "${KOKORO_ARTIFACTS_DIR}/git/crosvm"
|
||||
|
||||
ORIGIN=https://chromium.googlesource.com/chromiumos/platform/crosvm
|
||||
RETRIES=3
|
||||
readonly GERRIT_URL=https://chromium-review.googlesource.com
|
||||
readonly ORIGIN=${GERRIT_URL}/chromiumos/platform/crosvm
|
||||
readonly RETRIES=3
|
||||
|
||||
gerrit_api() {
|
||||
# Call gerrit API. Strips XSSI protection line from output.
|
||||
# See: https://gerrit-review.googlesource.com/Documentation/dev-rest-api.html
|
||||
local url="${GERRIT_URL}/${1}"
|
||||
curl --silent "$url" | tail -n +2
|
||||
}
|
||||
|
||||
query_change() {
|
||||
# Query gerrit for a specific change.
|
||||
# See: https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-change
|
||||
gerrit_api "changes/$1/?o=CURRENT_REVISION"
|
||||
}
|
||||
|
||||
query_changes() {
|
||||
# Query gerrit for a list of changes.
|
||||
# See: https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
|
||||
local query=$(printf '%s+' "$@")
|
||||
gerrit_api "changes/?q=${query}"
|
||||
}
|
||||
|
||||
query_related_changes() {
|
||||
# Query related changes from gerrit.
|
||||
# See: https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-related-changes
|
||||
gerrit_api "changes/$1/revisions/current/related"
|
||||
}
|
||||
|
||||
get_previous_merge_id() {
|
||||
# Query all open merge commits previously made by crosvm-bot. May be null if
|
||||
# none are open.
|
||||
query=(
|
||||
project:chromiumos/platform/crosvm
|
||||
branch:chromeos
|
||||
status:open
|
||||
owner:crosvm-bot@crosvm-packages.iam.gserviceaccount.com
|
||||
)
|
||||
# Pick the one that was created last.
|
||||
query_changes "${query[@]}" |
|
||||
jq --raw-output 'sort_by(.created)[-1].change_id'
|
||||
}
|
||||
|
||||
get_last_change_in_chain() {
|
||||
# Use the related changes API to find the last change in the chain of
|
||||
# commits.
|
||||
local change_id=$1
|
||||
|
||||
# The list of commits is sorted by the git commit order, with the latest
|
||||
# change first and includes the current change.
|
||||
local last_change
|
||||
last_change=$(query_related_changes "$change_id" | jq --raw-output \
|
||||
"[.changes[] | select(.status == \"NEW\")][0].change_id")
|
||||
|
||||
# If there are no related changes the list will be empty.
|
||||
if [ "$last_change" == "null" ]; then
|
||||
echo "${change_id}"
|
||||
else
|
||||
echo "${last_change}"
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_change() {
|
||||
# Fetch the provided change and print the commit sha.
|
||||
local change_id=$1
|
||||
|
||||
# Find the git ref we need to fetch.
|
||||
local change_ref
|
||||
change_ref=$(query_change "$change_id" |
|
||||
jq --raw-output -e ".revisions[.current_revision].ref")
|
||||
git fetch -q origin "${change_ref}"
|
||||
}
|
||||
|
||||
gerrit_prerequisites() {
|
||||
set -e
|
||||
|
||||
# Authenticate to GoB if we don't already have a cookie.
|
||||
# This should only happen when running in Kokoro, not locally.
|
||||
# See: go/gob-gce
|
||||
|
@ -18,10 +87,11 @@ gerrit_prerequisites() {
|
|||
git clone https://gerrit.googlesource.com/gcompute-tools \
|
||||
"${KOKORO_ARTIFACTS_DIR}/gcompute-tools"
|
||||
"${KOKORO_ARTIFACTS_DIR}/gcompute-tools/git-cookie-authdaemon" --no-fork
|
||||
fi
|
||||
|
||||
git config user.name "Crosvm Bot"
|
||||
git config user.email crosvm-bot@crosvm-packages.iam.gserviceaccount.com
|
||||
# Setup correct user info for the service account.
|
||||
git config user.name "Crosvm Bot"
|
||||
git config user.email crosvm-bot@crosvm-packages.iam.gserviceaccount.com
|
||||
fi
|
||||
|
||||
# We cannot use the original origin that kokoro used, as we no longer have
|
||||
# access the GoB host via rpc://.
|
||||
|
@ -53,7 +123,6 @@ upload_with_retries() {
|
|||
}
|
||||
|
||||
main() {
|
||||
set -e
|
||||
gerrit_prerequisites
|
||||
|
||||
# Make a copy of the merge script, so we are using the HEAD version to
|
||||
|
@ -64,14 +133,38 @@ main() {
|
|||
git clean -f -d -x
|
||||
git checkout -f
|
||||
|
||||
# Remember the HEAD that Kokoro checked out. This is usually origin/main
|
||||
# but can also be manually specified when triggering the job.
|
||||
local target=$(git rev-parse HEAD)
|
||||
# Parent commit to use for this merge.
|
||||
local parent_commit="origin/chromeos"
|
||||
|
||||
# Perform merge on a tracking branch.
|
||||
git checkout -b chromeos origin/chromeos
|
||||
# Query gerrit to find the latest merge commit and fetch it to be used as
|
||||
# a parent.
|
||||
local previous_merge="$(get_previous_merge_id)"
|
||||
if [ "$previous_merge" != "null" ]; then
|
||||
# The oncall may have uploaded a custom merge or cherry-pick on top
|
||||
# of the detected merge. Find the last changed in that chain.
|
||||
local last_change_in_chain=$(get_last_change_in_chain "${previous_merge}")
|
||||
echo "Found previous merge: ${GERRIT_URL}/q/${previous_merge}"
|
||||
echo "Last change in that chain: ${GERRIT_URL}/q/${last_change_in_chain}"
|
||||
fetch_change "${last_change_in_chain}"
|
||||
parent_commit="FETCH_HEAD"
|
||||
fi
|
||||
|
||||
local merge_list=$(git log --oneline --decorate=no --no-color \
|
||||
"${parent_commit}..origin/main")
|
||||
if [ -z "$merge_list" ]; then
|
||||
echo "Already up to date, nothing to merge."
|
||||
return
|
||||
else
|
||||
echo "Merge list:"
|
||||
echo "${merge_list}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Checking out parent: ${parent_commit}"
|
||||
git checkout -b chromeos "${parent_commit}"
|
||||
git branch --set-upstream-to origin/chromeos chromeos
|
||||
"${KOKORO_ARTIFACTS_DIR}/create_merge" "${target}"
|
||||
|
||||
"${KOKORO_ARTIFACTS_DIR}/create_merge" "origin/main"
|
||||
|
||||
upload_with_retries
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue