diff options
Diffstat (limited to '')
-rwxr-xr-x | tools/github-sync/sync-to-github.sh | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tools/github-sync/sync-to-github.sh b/tools/github-sync/sync-to-github.sh new file mode 100755 index 0000000000..d677649748 --- /dev/null +++ b/tools/github-sync/sync-to-github.sh @@ -0,0 +1,159 @@ +#!/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/. */ + +# Do NOT set -x here, since that will expose a secret API token! +set -o errexit +set -o nounset +set -o pipefail + +if [[ "$(uname)" != "Linux" ]]; then + echo "Error: this script must be run on Linux due to readlink semantics" + exit 1 +fi + +# GECKO_PATH should definitely be set +if [[ -z "${GECKO_PATH}" ]]; then + echo "Error: GECKO_PATH must point to a hg clone of mozilla-central" + exit 1 +fi + +# Internal variables, don't fiddle with these +MYSELF=$(readlink -f ${0}) +MYDIR=$(dirname "${MYSELF}") +WORKDIR="${HOME}/.ghsync" +TMPDIR="${WORKDIR}/tmp" + +NAME="$1" +RELATIVE_PATH="$2" +DOWNSTREAM_REPO="$3" +BORS="$4" +BRANCH="github-sync" + +mkdir -p "${TMPDIR}" + +# Bring the project clone to a known good up-to-date state +if [[ ! -d "${WORKDIR}/${NAME}" ]]; then + echo "Setting up ${NAME} repo..." + git clone "https://github.com/${DOWNSTREAM_REPO}" "${WORKDIR}/${NAME}" + pushd "${WORKDIR}/${NAME}" + git remote add moz-gfx https://github.com/moz-gfx/${NAME} + popd +else + echo "Updating ${NAME} repo..." + pushd "${WORKDIR}/${NAME}" + git checkout master + git pull + popd +fi + +if [[ -n "${GITHUB_SECRET:-}" ]]; then + echo "Obtaining github API token..." + # Be careful, GITHUB_TOKEN is secret, so don't log it (or any variables + # built using it). + GITHUB_TOKEN=$( + curl -sSfL "$TASKCLUSTER_PROXY_URL/secrets/v1/secret/${GITHUB_SECRET}" | + ${MYDIR}/read-json.py "secret/token" + ) + AUTH="moz-gfx:${GITHUB_TOKEN}" + CURL_AUTH="Authorization: bearer ${GITHUB_TOKEN}" +fi + +echo "Pushing base ${BRANCH} branch..." +pushd "${WORKDIR}/${NAME}" +git fetch moz-gfx +git checkout -B ${BRANCH} moz-gfx/${BRANCH} || git checkout -B ${BRANCH} master + +if [[ -n "${GITHUB_SECRET:-}" ]]; then + # git may emit error messages that contain the URL, so let's sanitize them + # or we might leak the auth token to the task log. + git push "https://${AUTH}@github.com/moz-gfx/${NAME}" \ + "${BRANCH}:${BRANCH}" 2>&1 | sed -e "s/${AUTH}/_SANITIZED_/g" + # Re-fetch to update the remote moz-gfx/$BRANCH branch in the local repo; + # normally the push does this but we use a fully-qualified URL for + # pushing so it doesn't happen. + git fetch moz-gfx +fi +popd + +# Run the converter +echo "Running converter..." +pushd "${GECKO_PATH}" +"${MYDIR}/converter.py" "${WORKDIR}/${NAME}" "${RELATIVE_PATH}" +popd + +# Check to see if we have changes that need pushing +echo "Checking for new changes..." +pushd "${WORKDIR}/${NAME}" +PATCHCOUNT=$(git log --oneline moz-gfx/${BRANCH}..${BRANCH}| wc -l) +if [[ ${PATCHCOUNT} -eq 0 ]]; then + echo "No new patches found, aborting..." + exit 0 +fi + +# Log the new changes, just for logging purposes +echo "Here are the new changes:" +git log --graph --stat moz-gfx/${BRANCH}..${BRANCH} + +# Collect PR numbers of PRs opened on Github and merged to m-c +set +e +FIXES=$( + git log master..${BRANCH} | + grep "\[import_pr\] From https://github.com/${DOWNSTREAM_REPO}/pull" | + sed -e "s%.*pull/% Fixes #%" | + uniq | + tr '\n' ',' +) +echo "${FIXES}" +set -e + +if [[ -z "${GITHUB_SECRET:-}" ]]; then + echo "Running in try push, exiting now" + exit 0 +fi + +echo "Pushing new changes to moz-gfx..." +# git may emit error messages that contain the URL, so let's sanitize them +# or we might leak the auth token to the task log. +git push "https://${AUTH}@github.com/moz-gfx/${NAME}" +${BRANCH}:${BRANCH} \ + 2>&1 | sed -e "s/${AUTH}/_SANITIZED_/g" + +CURL_HEADER="Accept: application/vnd.github.v3+json" +CURL=(curl -sSfL -H "${CURL_HEADER}" -H "${CURL_AUTH}") +# URL extracted here mostly to make servo-tidy happy with line lengths +API_URL="https://api.github.com/repos/${DOWNSTREAM_REPO}" + +# Check if there's an existing PR open +echo "Listing pre-existing pull requests..." +"${CURL[@]}" "${API_URL}/pulls?head=moz-gfx:${BRANCH}" | + tee "${TMPDIR}/pr.get" +set +e +COMMENT_URL=$(cat "${TMPDIR}/pr.get" | ${MYDIR}/read-json.py "0/comments_url") +HAS_COMMENT_URL="${?}" +set -e + +if [[ ${HAS_COMMENT_URL} -ne 0 ]]; then + echo "Pull request not found, creating..." + # The PR doesn't exist yet, so let's create it + ( echo -n '{ "title": "Sync changes from mozilla-central '"${RELATIVE_PATH}"'"' + echo -n ', "body": "'"${FIXES}"'"' + echo -n ', "head": "moz-gfx:'"${BRANCH}"'"' + echo -n ', "base": "master" }' + ) > "${TMPDIR}/pr.create" + "${CURL[@]}" -d "@${TMPDIR}/pr.create" "${API_URL}/pulls" | + tee "${TMPDIR}/pr.response" + COMMENT_URL=$( + cat "${TMPDIR}/pr.response" | + ${MYDIR}/read-json.py "comments_url" + ) +fi + +# At this point COMMENTS_URL should be set, so leave a comment to tell bors +# to merge the PR. +echo "Posting r+ comment to ${COMMENT_URL}..." +echo '{ "body": "'"$BORS"' r=auto" }' > "${TMPDIR}/bors_rplus" +"${CURL[@]}" -d "@${TMPDIR}/bors_rplus" "${COMMENT_URL}" + +echo "All done!" |