Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add script to automate pulling changes from upstream WPT.
- Loading branch information
Showing
2 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}" |