Skip to content

Commit d1eb30f

Browse files
committedMay 18, 2020
Add apidiff script to check go signature changes
Signed-off-by: Davanum Srinivas <davanum@gmail.com>
1 parent 30445f8 commit d1eb30f

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
 

‎.github/workflows/test.yml

+24
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,27 @@ jobs:
3030
docker run --rm -v `pwd`:/go/src/k8s.io/klog -w /go/src/k8s.io/klog \
3131
golangci/golangci-lint:v1.23.8 golangci-lint run --disable-all -v \
3232
-E govet -E misspell -E gofmt -E ineffassign -E golint
33+
apidiff:
34+
runs-on: ubuntu-latest
35+
if: github.base_ref
36+
steps:
37+
- name: Install Go
38+
uses: actions/setup-go@v1
39+
with:
40+
go-version: 1.13.x
41+
- name: Add GOBIN to PATH
42+
run: echo "::add-path::$(go env GOPATH)/bin"
43+
- name: Install dependencies
44+
run: go get golang.org/x/exp/cmd/apidiff
45+
- name: Checkout old code
46+
uses: actions/checkout@v2
47+
with:
48+
ref: ${{ github.base_ref }}
49+
path: "old"
50+
- name: Checkout new code
51+
uses: actions/checkout@v2
52+
with:
53+
path: "new"
54+
- name: APIDiff
55+
run: ./hack/verify-apidiff.sh -d ../old
56+
working-directory: "new"

‎hack/verify-apidiff.sh

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2020 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -o errexit
18+
set -o nounset
19+
set -o pipefail
20+
21+
function usage {
22+
local script="$(basename $0)"
23+
24+
echo >&2 "Usage: ${script} [-r <branch|tag> | -d <dir>]
25+
26+
This script should be run at the root of a module.
27+
28+
-r <branch|tag>
29+
Compare the exported API of the local working copy with the
30+
exported API of the local repo at the specified branch or tag.
31+
32+
-d <dir>
33+
Compare the exported API of the local working copy with the
34+
exported API of the specified directory, which should point
35+
to the root of a different version of the same module.
36+
37+
Examples:
38+
${script} -r master
39+
${script} -r v1.10.0
40+
${script} -r release-1.10
41+
${script} -d /path/to/historical/version
42+
"
43+
exit 1
44+
}
45+
46+
ref=""
47+
dir=""
48+
while getopts r:d: o
49+
do case "$o" in
50+
r) ref="$OPTARG";;
51+
d) dir="$OPTARG";;
52+
[?]) usage;;
53+
esac
54+
done
55+
56+
# If REF and DIR are empty, print usage and error
57+
if [[ -z "${ref}" && -z "${dir}" ]]; then
58+
usage;
59+
fi
60+
# If REF and DIR are both set, print usage and error
61+
if [[ -n "${ref}" && -n "${dir}" ]]; then
62+
usage;
63+
fi
64+
65+
if ! which apidiff > /dev/null; then
66+
echo "Installing golang.org/x/exp/cmd/apidiff..."
67+
pushd "${TMPDIR:-/tmp}" > /dev/null
68+
go get golang.org/x/exp/cmd/apidiff
69+
popd > /dev/null
70+
fi
71+
72+
output=$(mktemp -d -t "apidiff.output.XXXX")
73+
cleanup_output () { rm -fr "${output}"; }
74+
trap cleanup_output EXIT
75+
76+
# If ref is set, clone . to temp dir at $ref, and set $dir to the temp dir
77+
clone=""
78+
base="${dir}"
79+
if [[ -n "${ref}" ]]; then
80+
base="${ref}"
81+
clone=$(mktemp -d -t "apidiff.clone.XXXX")
82+
cleanup_clone_and_output () { rm -fr "${clone}"; cleanup_output; }
83+
trap cleanup_clone_and_output EXIT
84+
git clone . -q --no-tags -b "${ref}" "${clone}"
85+
dir="${clone}"
86+
fi
87+
88+
pushd "${dir}" >/dev/null
89+
echo "Inspecting API of ${base}..."
90+
go list ./... > packages.txt
91+
for pkg in $(cat packages.txt); do
92+
mkdir -p "${output}/${pkg}"
93+
apidiff -w "${output}/${pkg}/apidiff.output" "${pkg}"
94+
done
95+
popd >/dev/null
96+
97+
retval=0
98+
99+
echo "Comparing with ${base}..."
100+
for pkg in $(go list ./...); do
101+
# New packages are ok
102+
if [ ! -f "${output}/${pkg}/apidiff.output" ]; then
103+
continue
104+
fi
105+
106+
# Check for incompatible changes to previous packages
107+
incompatible=$(apidiff -incompatible "${output}/${pkg}/apidiff.output" "${pkg}")
108+
if [[ -n "${incompatible}" ]]; then
109+
echo >&2 "FAIL: ${pkg} contains incompatible changes:
110+
${incompatible}
111+
"
112+
retval=1
113+
fi
114+
done
115+
116+
# Check for removed packages
117+
removed=$(comm -23 "${dir}/packages.txt" <(go list ./...))
118+
if [[ -n "${removed}" ]]; then
119+
echo >&2 "FAIL: removed packages:
120+
${removed}
121+
"
122+
retval=1
123+
fi
124+
125+
exit $retval

0 commit comments

Comments
 (0)
Please sign in to comment.