go.uber.org/yarpc@v1.72.1/etc/bin/update-deps.sh (about)

     1  #!/usr/bin/env bash
     2  set -euo pipefail
     3  IFS=$'\n\t'
     4  
     5  # This script will update the dependencies for the branch that it was executed
     6  # with. If the update didn't cause any generated code to change and the tests
     7  # continue to pass, the change will be pushed directly to the branch. If the
     8  # generated code changed or the tests failed, the change will be pushed to a
     9  # new branch and a pull request will be created.
    10  #
    11  # Variables to control the behavior of this script:
    12  #
    13  # GITHUB_USER (required)
    14  #   GitHub username used to authenticate requests.
    15  # GITHUB_TOKEN (required)
    16  #   GitHub token to authenticate $GITHUB_USER.
    17  # GITHUB_EMAIL (optional)
    18  #   Email address of the GitHub user.
    19  # GITHUB_REPO (optional)
    20  #   GitHub repository in the form $user/$repo. This will usually be inferred
    21  #   automatically from BUILDKITE_REPO.
    22  # GIT_REMOTE (optional)
    23  #   Name of the git remote to which changes will be pushed. Defaults to
    24  #   "origin".
    25  #
    26  # The following variables set by BuildKite are also accepted.
    27  #
    28  #   BUILDKITE_BRANCH
    29  #   BUILDKITE_BUILD_CREATOR (optional)
    30  #   BUILDKITE_BUILD_CREATOR_EMAIL (optional)
    31  #   BUILDKITE_BUILD_NUMBER (optional)
    32  #   BUILDKITE_REPO (optional)
    33  #
    34  # See https://buildkite.com/docs/builds/environment-variables for what they mean.
    35  #
    36  # Either BUILDKITE_BUILD_CREATOR_EMAIL or GITHUB_EMAIL must be present. If
    37  # BUILDKITE_BUILD_CREATOR_EMAIL was specified, BUILDKITE_BUILD_CREATOR must
    38  # also be present.
    39  
    40  if [ -z "${GITHUB_USER:-}" ] || [ -z "${GITHUB_TOKEN:-}" ]; then
    41    echo "GITHUB_USER or GITHUB_TOKEN is unset."
    42    echo "Please set these variables."
    43    exit 1
    44  fi
    45  
    46  if [ -z "${BUILDKITE_BRANCH:-}" ]; then
    47    echo "BUILDKITE_BRANCH is unset. Is this running on BuildKite?"
    48    exit 1
    49  fi
    50  
    51  AUTHOR="$GITHUB_USER"
    52  EMAIL=""
    53  if [ -z "${GITHUB_EMAIL:-}" ]; then
    54    if [ -z "${BUILDKITE_BUILD_CREATOR_EMAIL:-}" ]; then
    55      echo "Either GITHUB_EMAIL or BUILDKITE_BUILD_CREATOR_EMAIL is required."
    56      exit 1
    57    elif [ -z "${BUILDKITE_BUILD_CREATOR:-}" ]; then
    58      echo "BUILDKITE_BUILD_CREATOR is required if BUILDKITE_BUILD_CREATOR_EMAIL was provided."
    59      exit 1
    60    else
    61      # If we're using the build creator's email address, we should use their name
    62      # too.
    63      AUTHOR="$BUILDKITE_BUILD_CREATOR"
    64      EMAIL="$BUILDKITE_BUILD_CREATOR_EMAIL"
    65    fi
    66  else
    67    EMAIL="$GITHUB_EMAIL"
    68  fi
    69  
    70  
    71  export GIT_AUTHOR_NAME="$AUTHOR"
    72  export GIT_COMMITTER_NAME="$AUTHOR"
    73  export GIT_AUTHOR_EMAIL="$EMAIL"
    74  export GIT_COMMITTER_EMAIL="$EMAIL"
    75  
    76  REMOTE="${GIT_REMOTE:-origin}"
    77  BRANCH="$BUILDKITE_BRANCH"
    78  
    79  GITHUB_REPO=${GITHUB_REPO:-}
    80  if [ -z "$GITHUB_REPO" ]; then
    81    case "${BUILDKITE_REPO:-}" in
    82      "git@github.com:"*)
    83        GITHUB_REPO="${BUILDKITE_REPO#git@github.com:}"
    84        GITHUB_REPO="${GITHUB_REPO%.git}"
    85        ;;
    86      "https://github.com/"*)
    87        GITHUB_REPO="${BUILDKITE_REPO#https://github.com/}"
    88        GITHUB_REPO="${GITHUB_REPO%.git}"
    89        ;;
    90      *)
    91        echo "Could not determine GITHUB_REPO from BUILDKITE_REPO."
    92        echo "You can set it explicitly if you're not running this from CI."
    93        exit 1
    94    esac
    95  fi
    96  
    97  # When pushing over ssh, automatically add the host to known_hosts instead of
    98  # prompting with,
    99  #
   100  #   The authenticity of host '...' can't be established.
   101  #   RSA key fingerprint is ...
   102  #   Are you sure you want to continue connecting (yes/no)?
   103  export GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no"
   104  
   105  # Returns the current date in ISO8601 format.
   106  now() {
   107    date +%Y-%m-%dT%H:%M:%S
   108  }
   109  
   110  changed_files()
   111  {
   112    # BuildKite's docker-compose plugin generates a fake docker-compose so we
   113    # need to ignore it anytime we do git status.
   114    git --no-pager diff --name-only "$@" | grep -v '^docker-compose.buildkite'
   115  }
   116  
   117  # update_module $DIR updates the Go module in $DIR.
   118  update_module()
   119  {
   120    echo "--- Updating module $1"
   121    (cd "$1" && go get -u all && go mod tidy)
   122    if [ -n "$(changed_files)" ]; then
   123      git add --verbose "$1/go.mod" "$1/go.sum"
   124    fi
   125  }
   126  
   127  if [ -n "$(changed_files)" ]; then
   128    echo "Working tree is dirty."
   129    echo "Please verify that you don't have any uncommitted changes."
   130    git status
   131    exit 1
   132  fi
   133  
   134  echo "--- Updating dependencies"
   135  update_module "."
   136  update_module "internal/examples"
   137  update_module "internal/crossdock"
   138  
   139  if [ -z "$(changed_files --staged)" ]; then
   140    echo "Nothing changed. Exiting."
   141    exit 0
   142  fi
   143  
   144  echo "--- Committing update"
   145  git commit -m "Update dependencies at $(now)"
   146  
   147  echo "--- Updating generated code"
   148  make generate
   149  
   150  # Generated code might affect dependencies.
   151  go mod tidy
   152  (cd internal/examples && go mod tidy)
   153  (cd internal/crossdock && go mod tidy)
   154  
   155  # We want to push directly to the remote only if the generated code did not
   156  # change and all tests pass.
   157  if [ -z "$(changed_files)" ]; then
   158    if make lint test examples; then
   159      echo "--- Generated code did not change and the tests passed."
   160      echo "--- Pushing changes and exiting."
   161      git push "$REMOTE" HEAD:"$BRANCH"
   162      exit 0
   163    fi
   164  else
   165    # Check in the generated code ignoring the BuildKite docker-compose.
   166    changed_files | xargs git add --verbose
   167    git commit -m "Update generated code at $(now)"
   168  fi
   169  
   170  PR_BRANCH=""
   171  if [ -z "${BUILDKITE_BUILD_NUMBER:-}" ]; then
   172    # Use a different branch namespace if we're not running in BuildKite.
   173    PR_BRANCH="update-deps/$(now)"
   174  else
   175    PR_BRANCH="update-deps/buildkite/$BUILDKITE_BUILD_NUMBER"
   176  fi
   177  
   178  echo "--- Creating a pull request using branch $PR_BRANCH"
   179  git push "$REMOTE" HEAD:"refs/heads/$PR_BRANCH"
   180  
   181  # This needs to be a function so that we can pipe into it from the python
   182  # command with the heredoc without making an overly long line. That is, we
   183  # want to avoid,
   184  #
   185  #   python - foo bar <<EOF | curl --user ... -X POST [very long line]
   186  create_pull_request()
   187  {
   188    curl --user "$GITHUB_USER:$GITHUB_TOKEN" -X POST \
   189      --data @- "https://api.github.com/repos/$GITHUB_REPO/pulls"
   190  }
   191  
   192  python - "$PR_BRANCH" "$BRANCH" <<EOF | create_pull_request
   193  import sys, json
   194  
   195  print(json.dumps({
   196    "title": "Update dependencies on $(now)",
   197    "head": sys.argv[1],
   198    "base": sys.argv[2],
   199    "maintainer_can_modify": True,
   200    "body": """I tried to update the dependencies but either the generated
   201  code changed or some tests failed, so I need someone to validate or fix this
   202  change.
   203  
   204  Thanks!""",
   205  }))
   206  EOF
   207  
   208  # vim:ts=2 sw=2 et: