github.com/cornelk/go-cloud@v0.17.1/internal/testing/check_api_change.sh (about) 1 #!/usr/bin/env bash 2 # Copyright 2019 The Go Cloud Development Kit Authors 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # https://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 # This script checks to see if there are any incompatible API changes on the 17 # current branch relative to the upstream branch. 18 # It fails if it finds any, unless there is a commit with BREAKING_CHANGE_OK 19 # in the first line of the commit message. 20 # 21 # It checks all modules listed in allmodules, and skips packages with 22 # "internal" or "test" in their name. 23 # 24 # It expects to be run at the root of the repository, and that HEAD is pointing 25 # to a commit that merges between the pull request and the upstream branch 26 # (TRAVIS_BRANCH). This is what Travis does (see 27 # https://docs.travis-ci.com/user/pull-requests/ for details), but if you 28 # are testing this script manually, you may need to manually create a merge 29 # commit. 30 31 set -euo pipefail 32 33 UPSTREAM_BRANCH="${TRAVIS_BRANCH:-master}" 34 echo "Checking for incompatible API changes relative to ${UPSTREAM_BRANCH}..." 35 36 INSTALL_DIR="$(mktemp -d)" 37 MASTER_CLONE_DIR="$(mktemp -d)" 38 PKGINFO_BRANCH=$(mktemp) 39 PKGINFO_MASTER=$(mktemp) 40 41 function cleanup() { 42 rm -rf "$INSTALL_DIR" "$MASTER_CLONE_DIR" 43 rm -f "$PKGINFO_BRANCH" "$PKGINFO_MASTER" 44 } 45 trap cleanup EXIT 46 47 # Move to a temporary directory while installing apidiff to avoid changing 48 # the local .mod file. 49 ( cd "$INSTALL_DIR" && exec go mod init unused ) 50 ( cd "$INSTALL_DIR" && exec go install golang.org/x/exp/cmd/apidiff ) 51 52 git clone -b "$UPSTREAM_BRANCH" . "$MASTER_CLONE_DIR" &> /dev/null 53 54 # Run the following checks in the master directory 55 ORIG_DIR="$(pwd)" 56 cd "$MASTER_CLONE_DIR" 57 58 incompatible_change_pkgs=() 59 while read -r path || [[ -n "$path" ]]; do 60 echo " checking packages in module $path" 61 pushd "$path" &> /dev/null 62 63 PKGS=$(go list ./...) 64 for pkg in $PKGS; do 65 if [[ "$pkg" =~ "test" ]] || [[ "$pkg" =~ "internal" ]] || [[ "$pkg" =~ "samples" ]]; then 66 continue 67 fi 68 echo " checking ${pkg}..." 69 70 # Compute export data for the current branch. 71 package_deleted=0 72 (cd "$ORIG_DIR/$path" && apidiff -w "$PKGINFO_BRANCH" "$pkg") || package_deleted=1 73 if [[ $package_deleted -eq 1 ]]; then 74 echo " package ${pkg} was deleted! Recording as an incompatible change."; 75 incompatible_change_pkgs+=("${pkg}"); 76 continue; 77 fi 78 79 # Compute export data for master@HEAD. 80 apidiff -w "$PKGINFO_MASTER" "$pkg" 81 82 # Print all changes for posterity. 83 apidiff "$PKGINFO_MASTER" "$PKGINFO_BRANCH" 84 85 # Note if there's an incompatible change. 86 ic=$(apidiff -incompatible "$PKGINFO_MASTER" "$PKGINFO_BRANCH") 87 if [ -n "$ic" ]; then 88 incompatible_change_pkgs+=("$pkg"); 89 fi 90 done 91 popd &> /dev/null 92 done < <( sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' ) 93 94 if [ ${#incompatible_change_pkgs[@]} -eq 0 ]; then 95 # No incompatible changes, we are good. 96 echo "OK: No incompatible changes found." 97 exit 0; 98 fi 99 echo "Found breaking API change(s) in: ${incompatible_change_pkgs[*]}." 100 101 # Found incompatible changes; see if they were declared as OK via a commit. 102 cd "$ORIG_DIR" 103 if git cherry -v master | grep -q "BREAKING_CHANGE_OK"; then 104 echo "Allowing them due to a commit message with BREAKING_CHANGE_OK."; 105 exit 0; 106 fi 107 108 echo "FAIL. If this is expected and OK, you can pass this check by adding a commit with BREAKING_CHANGE_OK in the first line of the message." 109 exit 1