From 54b4fc2e95b16e06abffffa06d18ed75310134a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 19 Apr 2023 17:07:01 +0200 Subject: [PATCH] tools: add update script for googletest GoogleTest follows the Abseil Live at Head philosophy, and rarely creates tags or GitHub releases, so instead, follow Google's recommendation and update to the upstream HEAD every once in a while. The tricky bit is properly updating googletest.gyp, and this script might fail doing so in the future. Refs: https://github.com/nodejs/security-wg/issues/828 PR-URL: https://github.com/nodejs/node/pull/47482 Reviewed-By: Yagiz Nizipli Reviewed-By: Marco Ippolito Reviewed-By: Rafael Gonzaga --- .github/workflows/tools.yml | 9 +++ tools/dep_updaters/update-googletest.sh | 93 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100755 tools/dep_updaters/update-googletest.sh diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 8a8d103c66ddba..c6a5fee477b003 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -23,6 +23,7 @@ on: - corepack - doc - eslint + - googletest - libuv - lint-md-dependencies - llhttp @@ -237,6 +238,14 @@ jobs: cat temp-output tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output + - id: googletest + subsystem: deps + label: dependencies, test + run: | + ./tools/dep_updaters/update-googletest.sh > temp-output + cat temp-output + tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true + rm temp-output steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 if: github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id diff --git a/tools/dep_updaters/update-googletest.sh b/tools/dep_updaters/update-googletest.sh new file mode 100755 index 00000000000000..ba2cdd1be86ad1 --- /dev/null +++ b/tools/dep_updaters/update-googletest.sh @@ -0,0 +1,93 @@ +#!/bin/sh +set -e +# Shell script to update GoogleTest in the source tree to the most recent version. +# GoogleTest follows the Abseil Live at Head philosophy and rarely creates tags +# or GitHub releases, so instead, we use the latest commit on the main branch. + +BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd) +DEPS_DIR="$BASE_DIR/deps" + +NEW_UPSTREAM_SHA1=$(git ls-remote "https://github.com/google/googletest.git" HEAD | awk '{print $1}') +NEW_VERSION=$(echo "$NEW_UPSTREAM_SHA1" | head -c 7) + +echo "Comparing $NEW_VERSION with current revision" + +git remote add googletest-upstream https://github.com/google/googletest.git +git fetch googletest-upstream "$NEW_UPSTREAM_SHA1" +git remote remove googletest-upstream + +DIFF_TREE=$( + git diff HEAD:deps/googletest/LICENSE "$NEW_UPSTREAM_SHA1:LICENSE" + git diff-tree HEAD:deps/googletest/include "$NEW_UPSTREAM_SHA1:googletest/include" + git diff-tree HEAD:deps/googletest/src "$NEW_UPSTREAM_SHA1:googletest/src" +) + +if [ -z "$DIFF_TREE" ]; then + echo "Skipped because googletest is on the latest version." + exit 0 +fi + +# This is a rather arbitrary restriction. This script is assumed to run on +# Sunday, shortly after midnight UTC. This check thus prevents pulling in the +# most recent commits if any changes were made on Friday or Saturday (UTC). +# Because of Google's own "Live at Head" philosophy, new bugs that are likely to +# affect Node.js tend to be fixed quickly, so we don't want to pull in a commit +# that was just pushed, and instead rather wait for the next week's update. If +# no commits have been pushed in the last two days, we assume that the most +# recent commit is stable enough to be pulled in. +LAST_CHANGE_DATE=$(git log -1 --format=%ct "$NEW_UPSTREAM_SHA1" -- LICENSE googletest/include googletest/src) +TWO_DAYS_AGO=$(date -d 'now - 2 days' '+%s') +if [ "$LAST_CHANGE_DATE" -gt "$TWO_DAYS_AGO" ]; then + echo "Skipped because the latest version is too recent." + exit 0 +fi + +echo "Creating temporary work tree" + +WORKSPACE=$(mktemp -d 2> /dev/null || mktemp -d -t 'tmp') +WORKTREE="$WORKSPACE/googletest" + +cleanup () { + EXIT_CODE=$? + [ -d "$WORKTREE" ] && git worktree remove -f "$WORKTREE" + [ -d "$WORKSPACE" ] && rm -rf "$WORKSPACE" + exit $EXIT_CODE +} + +trap cleanup INT TERM EXIT + +git worktree add "$WORKTREE" "$NEW_UPSTREAM_SHA1" + +echo "Copying LICENSE, include and src to deps/googletest" +for p in LICENSE googletest/include googletest/src ; do + rm -rf "$DEPS_DIR/googletest/$(basename "$p")" + cp -R "$WORKTREE/$p" "$DEPS_DIR/googletest/$(basename "$p")" +done + +echo "Updating googletest.gyp" + +NEW_GYP=$( + sed "/'googletest_sources': \[/q" "$DEPS_DIR/googletest/googletest.gyp" + for f in $( (cd deps/googletest/ && find include src -type f \( -iname '*.h' -o -iname '*.cc' \) ) | LANG=C LC_ALL=C sort --stable ); do + if [ "$(basename "$f")" != "gtest_main.cc" ] && + [ "$(basename "$f")" != "gtest-all.cc" ] && + [ "$(basename "$f")" != "gtest_prod.h" ] ; then + echo " '$f'," + fi + done + sed -ne '/\]/,$ p' "$DEPS_DIR/googletest/googletest.gyp" +) + +echo "$NEW_GYP" >"$DEPS_DIR/googletest/googletest.gyp" + +echo "All done!" +echo "" +echo "Please git stage googletest, commit the new version:" +echo "" +echo "$ git stage -A deps/googletest" +echo "$ git commit -m \"deps: update googletest to $NEW_VERSION\"" +echo "" + +# The last line of the script should always print the new version, +# as we need to add it to $GITHUB_ENV variable. +echo "NEW_VERSION=$NEW_VERSION"