github.com/containers/podman/v4@v4.9.4/hack/make-and-check-size (about)

     1  #!/bin/bash
     2  #
     3  # make-and-check-size - wrapper around 'make' that also checks binary growth
     4  #
     5  # This script is intended to be run via 'git rebase -x', in a form such as:
     6  #
     7  #     context_dir=$(mktemp -d --tmpdir make-size-check.XXXXXXX)
     8  #     git rebase ${GIT_BASE_BRANCH}^ -x "hack/make-and-check-size $context_dir"
     9  #     rm -rf $context_dir
    10  #
    11  # (Carefully note the '^' next to GIT_BASE_BRANCH!)
    12  #
    13  # A 'git rebase -x' has long been a part of our usual CI; it guarantees
    14  # that each commit (whether in a single- or multi-commit PR) can be
    15  # compiled individually.
    16  #
    17  # By adding the '^' to GIT_BASE_BRANCH we establish a baseline and store
    18  # the binary sizes of each file (podman, podman-remote) prior to our PR.
    19  #
    20  # context_dir is a temporary directory used to store the original sizes
    21  # of each binary file under bin/
    22  #
    23  # *IMPORTANT NOTE*: this script will leave the git checkout in a funky state!
    24  # (because we rebase onto a nonterminal commit). I believe this is OK, since
    25  # this script is only invoked in CI from runner.sh and only in a scratch VM.
    26  # Running this in a development environment would yield unpredictable results
    27  # anyway, by rebasing onto origin/main by default and by leaving an aborted
    28  # rebase on failure.
    29  #
    30  ME=$(basename $0)
    31  
    32  ###############################################################################
    33  # BEGIN end-user-customizable settings
    34  
    35  # Maximum allowable size, in bytes
    36  MAX_BIN_GROWTH=$((50 * 1024))
    37  
    38  # Github label which allows overriding this check
    39  OVERRIDE_LABEL=bloat_approved
    40  
    41  # END   end-user-customizable settings
    42  ###############################################################################
    43  
    44  #
    45  # Helper function: queries github for labels on this PR
    46  #
    47  function bloat_approved() {
    48      # Argument is the actual size increase in this build.
    49      # FIXME: 2022-03-21: this is not actually used atm, but Ed hopes some day
    50      #        to implement a more robust size-override mechanism, such as by
    51      #        requiring a MAX_BIN_GROWTH=nnn statement in github comments.
    52      local actual_growth="$1"
    53  
    54      if [[ -z "$CIRRUS_PR" ]]; then
    55          echo "$ME: cannot query github: \$CIRRUS_PR is undefined" >&2
    56          return 1
    57      fi
    58      if [[ -z "$CIRRUS_REPO_CLONE_TOKEN" ]]; then
    59          echo "$ME: cannot query github: \$CIRRUS_REPO_CLONE_TOKEN is undefined" >&2
    60          return 1
    61      fi
    62  
    63      query="{
    64    \"query\": \"query {
    65    repository(owner: \\\"containers\\\", name: \\\"podman\\\") {
    66      pullRequest(number: $CIRRUS_PR) {
    67        labels(first: 100) {
    68          nodes {
    69            name
    70          }
    71        }
    72      }
    73    }
    74  }\"
    75  }"
    76  
    77      result=$(curl -s -H "Authorization: bearer $CIRRUS_REPO_CLONE_TOKEN" -H "Accept: application/vnd.github.antiope-preview+json" -H "Content-Type: application/json" -X POST --data @- https://api.github.com/graphql <<<"$query")
    78  
    79      labels=$(jq -r '.data.repository.pullRequest.labels.nodes[].name' <<<"$result")
    80  
    81      grep -q -w "$OVERRIDE_LABEL" <<<"$labels"
    82  }
    83  
    84  # ACTUAL CODE BEGINS HERE
    85  set -e
    86  
    87  # Must be invoked with one argument, an existing context directory
    88  context_dir=${1?Missing CONTEXT-DIR argument}
    89  if [[ ! -d $context_dir ]]; then
    90      echo "$ME: directory '$context_dir' does not exist"
    91      exit 1
    92  fi
    93  
    94  # This is the original (and primary) purpose of this check: if 'make' fails,
    95  # there is no point in continuing.  Show at least the commit title since
    96  # the ID may not match anything human recognisable.
    97  echo
    98  echo "Building: $(git log -n 1 --no-show-signature --oneline)"
    99  make
   100  
   101  # Determine size of each built file.
   102  # - If this is our first time through, preserve that size in a tmpfile
   103  # - On all subsequent runs, compare built size to initial size
   104  for bin in bin/*;do
   105      size=$(stat -c %s $bin)
   106  
   107      saved_size_file=$context_dir/$(basename $bin)
   108      if [[ -e $saved_size_file ]]; then
   109          # Not the first time through: compare to original size
   110          size_orig=$(< $saved_size_file)
   111          delta_size=$(( size - size_orig ))
   112  
   113          printf "%-20s size=%9d  delta=%6d\n" $bin $size $delta_size
   114          if [[ $delta_size -gt $MAX_BIN_GROWTH ]]; then
   115              separator=$(printf "%.0s*" {1..75})   # row of stars, for highlight
   116              echo "$separator"
   117              echo "* $bin grew by $delta_size bytes; max allowed is $MAX_BIN_GROWTH."
   118              echo "*"
   119              if bloat_approved $delta_size; then
   120                  echo "* Continuing due to '$OVERRIDE_LABEL' label"
   121                  echo "*"
   122                  echo "$separator"
   123              else
   124                  echo "* Please investigate, and fix if possible."
   125                  echo "*"
   126                  echo "* A repo admin can override by setting the $OVERRIDE_LABEL label"
   127                  echo "$separator"
   128                  exit 1
   129              fi
   130          fi
   131      else
   132          # First time through: preserve original file size
   133          echo $size >$saved_size_file
   134          printf "%-20s size=%9d\n" $bin $size
   135      fi
   136  done