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