-
Notifications
You must be signed in to change notification settings - Fork 4k
/
check-api-compatibility.sh
executable file
·114 lines (95 loc) · 3.42 KB
/
check-api-compatibility.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/bin/bash
# Check API compatibility of all packages
set -eu
repo_root="$(cd $(dirname $0)/.. && pwd)"
tmpdir=/tmp/compat-check
package_name() {
node -pe "require('$1/package.json').name"
}
# Determine whether an NPM package exists on NPM
#
# Doesn't use 'npm view' as that is slow. Direct curl'ing npmjs is better
package_exists_on_npm() {
pkg=$1
ver=${2:-} # optional
curl -I 2>/dev/null https://registry.npmjs.org/$pkg/$ver | head -n 1 | grep 200 >/dev/null
}
#----------------------------------------------------------------------
list_jsii_packages() {
echo "Listing jsii packages..." >&2
for dir in $(npx lerna ls -p); do
if [[ -f $dir/.jsii ]]; then
echo "$dir"
fi
done
}
jsii_package_dirs=$(list_jsii_packages)
#----------------------------------------------------------------------
# dirs_for_existing_pkgs DIRECTORY VERSION
#
# Input a directory and a version, output the directory IF it exists on NPM at that version
dirs_for_existing_pkgs() {
local dir="$1"
local ver="$2"
if package_exists_on_npm $(package_name $dir) $ver; then
echo "$dir"
echo -n "." >&2
else
echo -n "x" >&2
fi
}
export -f package_name
export -f package_exists_on_npm
export -f dirs_for_existing_pkgs
if ! ${SKIP_DOWNLOAD:-false}; then
echo "Filtering on existing packages on NPM..." >&2
echo "Determining baseline version... " >&2
build_version=$(node -p 'require("./scripts/resolve-version.js").version')
echo "Build version: ${build_version}." >&2
# Either called as:
# - find-latest-release "<=2.14.0" (PR build); or
# - find-latest-release "<=2.15.0-rc.0" (CI build); or
# - find-latest-release "<=2.15.0" (release build)
# all of which will find 2.14.0 as the version to compare against.
version=$(node ./scripts/find-latest-release.js "<=${build_version}")
echo "Released version: $version." >&2
echo "Using version '$version' as the baseline..." >&2
# Filter packages by existing at the target version
existing_pkg_dirs=$(echo "$jsii_package_dirs" | xargs -n1 -P4 -I {} bash -c 'dirs_for_existing_pkgs "$@" "'$version'"' _ {})
existing_names=$(echo "$existing_pkg_dirs" | xargs -n1 -P4 -I {} bash -c 'package_name "$@"' _ {})
install_versions=$(for name in $existing_names; do echo "${name}@${version}"; done)
echo " Done." >&2
rm -rf $tmpdir
mkdir -p $tmpdir
echo "Installing from NPM..." >&2
# Use npm7 instead of whatever the current NPM version is to make sure we
# automatically install peer dependencies
(cd $tmpdir && npx npm@^7.0.0 install --prefix $tmpdir $install_versions)
fi
#----------------------------------------------------------------------
echo "Checking compatibility..." >&2
success=true
for dir in $jsii_package_dirs; do
name=$(package_name "$dir")
if [[ ! -d $tmpdir/node_modules/$name ]]; then continue; fi
if [[ ! -f $tmpdir/node_modules/$name/.jsii ]]; then continue; fi
echo -n "$name... "
if npx jsii-diff \
--keys \
--ignore-file ${repo_root}/allowed-breaking-changes.txt \
$tmpdir/node_modules/$name \
$dir \
2>$tmpdir/output.txt; then
echo "OK."
else
success=false
echo "CHANGES."
cat $tmpdir/output.txt
fi
done
if $success; then
echo "All OK." >&2
else
echo "Some packages seem to have undergone breaking API changes. Please avoid." >&2
exit 1
fi