Skip to content

Commit

Permalink
Add script to automate pulling changes from upstream WPT.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdm committed Jan 26, 2018
1 parent 6b2e528 commit 0c95c69
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
3 changes: 3 additions & 0 deletions etc/ci/buildbot_steps.yml
Expand Up @@ -73,6 +73,9 @@ mac-nightly:
- env PKG_CONFIG_PATH=/usr/local/opt/zlib/lib/pkgconfig ./mach build --release
- ./mach package --release
- ./mach upload-nightly mac
- ./etc/ci/update-wpt-checkout fetch-and-update-expectations
- ./etc/ci/update-wpt-checkout open-pr
- ./etc/ci/update-wpt-checkout cleanup

linux-rel-intermittent:
- ./mach clean-nightlies --keep 3 --force
Expand Down
186 changes: 186 additions & 0 deletions etc/ci/update-wpt-checkout
@@ -0,0 +1,186 @@
#!/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 http://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"

# 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 24 --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
# Ignore any metadata changes to files that weren't modified by this sync.
git checkout -- tests/wpt/mozilla/meta || return 2
# Ensure any new directories or ini files are included in these changes.
git add tests/wpt/metadata || return 3
# Merge all changes with the existing commit.
git commit -a --amend --no-edit || return 4
}

# 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}" || 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 4
}

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
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}"

0 comments on commit 0c95c69

Please sign in to comment.