servo/etc/ci/update-wpt-checkout
2018-11-19 14:46:43 +01:00

188 lines
5.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
set -o errexit
set -o nounset
set -o pipefail
REMOTE_NAME=sync-fork
LOG_FILE=test-wpt.log
CURRENT_DATE=$(date +"%d-%m-%Y")
BRANCH_NAME="wpt_update_${CURRENT_DATE}"
export GIT_AUTHOR_NAME="WPT Sync Bot"
export GIT_AUTHOR_EMAIL="josh+wptsync@joshmatthews.net"
export GIT_COMMITTER_NAME="${GIT_AUTHOR_NAME}"
export GIT_COMMITTER_EMAIL="${GIT_AUTHOR_EMAIL}"
# Retrieve the HEAD commit and extract its hash
function latest_git_commit() {
git log -1 --oneline | cut -f 1 -d ' '
}
# Create a new branch for this sync, pull down all changes from the upstream
# web-platform-tests repository, and commit the changes.
function unsafe_pull_from_upstream() {
git checkout -b "${1}" || return 1
OLD_COMMIT=$(latest_git_commit)
# Fetch all changes from upstream WPT and automatically transpose them
# into a single servo commit.
./mach update-wpt --sync --no-upstream --patch || return 2
# If there was no new commit created, there are no changes that need syncing.
# Skip the remaining steps.
if [[ "$(latest_git_commit)" == "${OLD_COMMIT}" ]]; then
return 255
fi
# Update the manifest to include the new changes.
./mach update-manifest || return 3
# Amend the existing commit with the new changes from updating the manifest.
git commit -a --amend --no-edit || return 4
}
# Remove all local traces of this sync operation.
function cleanup() {
git remote rm "${REMOTE_NAME}" || true
git reset --hard || true
git checkout master || true
git branch -D "${BRANCH_NAME}" || true
./mach update-wpt --abort || true
}
# Build Servo and run the full WPT testsuite, saving the results to a log file.
function unsafe_run_tests() {
# Run the full testsuite and record the new test results.
./mach test-wpt --release --processes 6 --log-raw "${1}" \
--always-succeed || return 1
}
# Using an existing log file, update the expected test results and amend the
# last commit with the new results.
function unsafe_update_metadata() {
./mach update-wpt "${1}" || return 1
# Ensure any new directories or ini files are included in these changes.
git add tests/wpt/metadata tests/wpt/mozilla/meta || return 2
# Merge all changes with the existing commit.
git commit -a --amend --no-edit || return 3
}
# Push the branch to a remote branch, then open a PR for the branch
# against servo/servo.
function unsafe_open_pull_request() {
WPT_SYNC_USER=servo-wpt-sync
# If the branch doesn't exist, we'll silently exit. This deals with the
# case where an earlier step either failed or discovered that syncing
# is unnecessary.
git checkout "${BRANCH_NAME}" || return 0
if [[ -z "${WPT_SYNC_TOKEN+set}" ]]; then
echo "Github auth token missing from WPT_SYNC_TOKEN."
return 1
fi
# Push the changes to a remote branch owned by the bot.
AUTH="${WPT_SYNC_USER}:${WPT_SYNC_TOKEN}"
UPSTREAM="https://${AUTH}@github.com/${WPT_SYNC_USER}/servo.git"
git remote add "${REMOTE_NAME}" "${UPSTREAM}" || return 2
git push -f "${REMOTE_NAME}" "${BRANCH_NAME}" &>/dev/null || return 3
# Prepare the pull request metadata.
BODY="Automated downstream sync of changes from upstream as of "
BODY+="${CURRENT_DATE}.\n"
BODY+="[no-wpt-sync]"
cat <<EOF >prdata.json || return 4
{
"title": "Sync WPT with upstream (${CURRENT_DATE})",
"head": "${WPT_SYNC_USER}:${BRANCH_NAME}",
"base": "master",
"body": "${BODY}",
"maintainer_can_modify": true
}
EOF
# Open a pull request using the new branch.
curl -H "Authorization: token ${WPT_SYNC_TOKEN}" \
-H "Content-Type: application/json" \
--data @prdata.json \
https://api.github.com/repos/servo/servo/pulls || return 5
}
function pull_from_upstream() {
unsafe_pull_from_upstream "${1}" || { code="${?}"; cleanup; return "${code}"; }
}
function run_tests() {
unsafe_run_tests "${1}" || { code="${?}"; cleanup; return "${code}"; }
}
function update_metadata() {
unsafe_update_metadata "${1}" || { code="${?}"; cleanup; return "${code}"; }
}
function open_pull_request() {
unsafe_open_pull_request || { code="${?}"; cleanup; return "${code}"; }
}
SCRIPT_NAME="${0}"
function update_test_results() {
run_tests "${LOG_FILE}"
update_metadata "${LOG_FILE}"
}
function fetch_upstream_changes() {
pull_from_upstream "${BRANCH_NAME}"
}
function usage() {
echo "usage: ${SCRIPT_NAME} [cmd]"
echo " commands:"
echo " - fetch-upstream-changes: create a branch with the latest changes from upstream"
echo " - update-test-results: run the tests, update the expected test results, and commit the changes"
echo " - fetch-and-update-expectations: combines fetch-upstream-changes and update-test-results"
echo " - open-pr: open a pull request with the latest changes"
echo " - cleanup: cleanup all traces of an in-progress sync and checkout the master branch"
exit 1
}
function main() {
if [[ "${1}" == "fetch-upstream-changes" ]] || [[ "${1}" == "fetch-and-update-expectations" ]]; then
code=""
fetch_upstream_changes || code="${?}"
if [[ "${code}" == "255" ]]; then
echo "No changes to sync."
return 0
elif [[ "${code}" != "" ]]; then
return "${code}"
fi
fi
if [[ "${1}" == "update-test-results" ]] || [[ "${1}" == "fetch-and-update-expectations" ]]; then
update_test_results
elif [[ "${1}" == "open-pr" ]]; then
open_pull_request
elif [[ "${1}" == "cleanup" ]]; then
cleanup
else
usage
fi
}
if [[ "$#" != 1 ]]; then
usage
fi
# Ensure we clean up after ourselves if this script is interrupted.
trap 'cleanup' SIGINT SIGTERM
main "${1}"