github.com/yorinasub17/go-cloud@v0.27.40/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  # GITHUB_BASE_REF).
    27  
    28  set -euo pipefail
    29  
    30  UPSTREAM_BRANCH="${GITHUB_BASE_REF:-master}"
    31  echo "Checking for incompatible API changes relative to ${UPSTREAM_BRANCH}..."
    32  
    33  MASTER_CLONE_DIR="$(mktemp -d)"
    34  PKGINFO_BRANCH=$(mktemp)
    35  PKGINFO_MASTER=$(mktemp)
    36  
    37  function cleanup() {
    38    rm -f "$PKGINFO_BRANCH" "$PKGINFO_MASTER"
    39  }
    40  trap cleanup EXIT
    41  
    42  # Install apidiff.
    43  go install golang.org/x/exp/cmd/apidiff@latest
    44  
    45  git clone -b "$UPSTREAM_BRANCH" . "$MASTER_CLONE_DIR" &> /dev/null
    46  
    47  # Run the following checks in the master directory
    48  ORIG_DIR="$(pwd)"
    49  cd "$MASTER_CLONE_DIR"
    50  
    51  incompatible_change_pkgs=()
    52  while read -r path || [[ -n "$path" ]]; do
    53    echo "  checking packages in module $path"
    54    pushd "$path" &> /dev/null
    55  
    56    PKGS=$(go list ./...)
    57    for pkg in $PKGS; do
    58      if [[ "$pkg" =~ "test" ]] || [[ "$pkg" =~ "internal" ]] || [[ "$pkg" =~ "samples" ]]; then
    59        continue
    60      fi
    61      echo "    checking ${pkg}..."
    62  
    63      # Compute export data for the current branch.
    64      package_deleted=0
    65      (cd "$ORIG_DIR/$path" && apidiff -w "$PKGINFO_BRANCH" "$pkg") || package_deleted=1
    66      if [[ $package_deleted -eq 1 ]]; then
    67        echo "    package ${pkg} was deleted! Recording as an incompatible change.";
    68        incompatible_change_pkgs+=("${pkg}");
    69        continue;
    70      fi
    71  
    72      # Compute export data for master@HEAD.
    73      apidiff -w "$PKGINFO_MASTER" "$pkg"
    74  
    75      # Print all changes for posterity.
    76      apidiff "$PKGINFO_MASTER" "$PKGINFO_BRANCH"
    77  
    78      # Note if there's an incompatible change.
    79      ic=$(apidiff -incompatible "$PKGINFO_MASTER" "$PKGINFO_BRANCH")
    80      if [ -n "$ic" ]; then
    81        incompatible_change_pkgs+=("$pkg");
    82      fi
    83    done
    84    popd &> /dev/null
    85  done < <( sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' )
    86  
    87  if [ ${#incompatible_change_pkgs[@]} -eq 0 ]; then
    88    # No incompatible changes, we are good.
    89    echo "OK: No incompatible changes found."
    90    exit 0;
    91  fi
    92  echo "Found breaking API change(s) in: ${incompatible_change_pkgs[*]}."
    93  
    94  # Found incompatible changes; see if they were declared as OK via a commit.
    95  cd "$ORIG_DIR"
    96  if git cherry -v master | grep -q "BREAKING_CHANGE_OK"; then
    97    echo "Allowing them due to a commit message with BREAKING_CHANGE_OK.";
    98    exit 0;
    99  fi
   100  
   101  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."
   102  exit 1