Skip to content

Commit 4782ef4

Browse files
committed
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: nodejs/security-wg#828
1 parent 7ef5c60 commit 4782ef4

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

.github/workflows/tools.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ jobs:
172172
label: crypto, notable-change
173173
run: |
174174
node ./tools/dep_updaters/update-root-certs.mjs -v -f "$GITHUB_ENV"
175+
- id: googletest
176+
subsystem: deps
177+
label: dependencies, test
178+
run: |
179+
./tools/dep_updaters/update-googletest.sh > temp-output
180+
cat temp-output
181+
tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true
182+
rm temp-output
175183
steps:
176184
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
177185
with:
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/bin/sh
2+
set -e
3+
# Shell script to update GoogleTest in the source tree to the most recent version.
4+
# GoogleTest follows the Abseil Live at Head philosophy and rarely creates tags
5+
# or GitHub releases, so instead, we use the latest commit on the main branch.
6+
7+
BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd)
8+
DEPS_DIR="$BASE_DIR/deps"
9+
10+
[ -z "$NODE" ] && NODE="$BASE_DIR/out/Release/node"
11+
[ -x "$NODE" ] || NODE=$(command -v node)
12+
13+
NEW_UPSTREAM_SHA1=$(git ls-remote "https://github.com/google/googletest.git" HEAD | awk '{print $1}')
14+
NEW_VERSION=$(echo $NEW_UPSTREAM_SHA1 | head -c 7)
15+
16+
echo "Comparing $NEW_VERSION with current revision"
17+
18+
git remote add googletest-upstream https://github.com/google/googletest.git
19+
git fetch googletest-upstream $NEW_UPSTREAM_SHA1
20+
git remote remove googletest-upstream
21+
22+
DIFF_TREE=$(
23+
git diff HEAD:deps/googletest/LICENSE $NEW_UPSTREAM_SHA1:LICENSE
24+
git diff-tree HEAD:deps/googletest/include $NEW_UPSTREAM_SHA1:googletest/include
25+
git diff-tree HEAD:deps/googletest/src $NEW_UPSTREAM_SHA1:googletest/src
26+
)
27+
28+
if [ -z "$DIFF_TREE" ]; then
29+
echo "Skipped because googletest is on the latest version."
30+
exit 0
31+
fi
32+
33+
# This is a rather arbitrary restriction. This script is assumed to run on
34+
# Sunday, shortly after midnight UTC. This check thus prevents pulling in the
35+
# most recent commits if any changes were made on Friday or Saturday (UTC).
36+
# Because of Google's own "Live at Head" philosophy, new bugs that are likely to
37+
# affect Node.js tend to be fixed quickly, so we don't want to pull in a commit
38+
# that was just pushed, and instead rather wait for the next week's update. If
39+
# no commits have been pushed in the last two days, we assume that the most
40+
# recent commit is stable enough to be pulled in.
41+
LAST_CHANGE_DATE=$(git log -1 --format=%ct $NEW_UPSTREAM_SHA1 -- LICENSE googletest/include googletest/src)
42+
if [ "$LAST_CHANGE_DATE" -gt $(date -d 'now - 2 days' '+%s') ]; then
43+
echo "Skipped because the latest version is too recent."
44+
exit 0
45+
fi
46+
47+
echo "Creating temporary work tree"
48+
49+
WORKSPACE=$(mktemp -d 2> /dev/null || mktemp -d -t 'tmp')
50+
WORKTREE="$WORKSPACE/googletest"
51+
52+
cleanup () {
53+
EXIT_CODE=$?
54+
[ -d "$WORKTREE" ] && git worktree remove -f "$WORKTREE"
55+
[ -d "$WORKSPACE" ] && rm -rf "$WORKSPACE"
56+
exit $EXIT_CODE
57+
}
58+
59+
trap cleanup INT TERM EXIT
60+
61+
git worktree add "$WORKTREE" "$NEW_UPSTREAM_SHA1"
62+
63+
echo "Copying LICENSE, include and src to deps/googletest"
64+
for p in LICENSE googletest/include googletest/src ; do
65+
rm -rf "$DEPS_DIR/googletest/$(basename "$p")"
66+
cp -R "$WORKTREE/$p" "$DEPS_DIR/googletest/$(basename "$p")"
67+
done
68+
69+
echo "Updating googletest.gyp"
70+
71+
NEW_GYP=$(
72+
sed "/'googletest_sources': \[/q" "$DEPS_DIR/googletest/googletest.gyp"
73+
for f in $( (cd deps/googletest/ && find include src -type f \( -iname '*.h' -o -iname '*.cc' \) ) | LANG=C LC_ALL=C sort --stable ); do
74+
if [ "$(basename "$f")" != "gtest_main.cc" ] &&
75+
[ "$(basename "$f")" != "gtest-all.cc" ] &&
76+
[ "$(basename "$f")" != "gtest_prod.h" ] ; then
77+
echo " '$f',"
78+
fi
79+
done
80+
sed -ne '/\]/,$ p' "$DEPS_DIR/googletest/googletest.gyp"
81+
)
82+
83+
echo "$NEW_GYP" >"$DEPS_DIR/googletest/googletest.gyp"
84+
85+
echo "All done!"
86+
echo ""
87+
echo "Please git stage googletest, commit the new version:"
88+
echo ""
89+
echo "$ git stage -A deps/googletest"
90+
echo "$ git commit -m \"deps: update googletest to $NEW_VERSION\""
91+
echo ""
92+
93+
# The last line of the script should always print the new version,
94+
# as we need to add it to $GITHUB_ENV variable.
95+
echo "NEW_VERSION=$NEW_VERSION"

0 commit comments

Comments
 (0)