gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/tools/go_branch.sh (about)

     1  #!/bin/bash
     2  
     3  # Copyright 2019 The gVisor Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  set -xeou pipefail
    18  
    19  # Remember our current directory.
    20  declare orig_dir
    21  orig_dir=$(pwd)
    22  readonly orig_dir
    23  
    24  # Record the current working commit.
    25  declare head
    26  head=$(git describe --always)
    27  readonly head
    28  
    29  # Create a temporary working directory, and ensure that this directory and all
    30  # subdirectories are cleaned up upon exit.
    31  declare tmp_dir
    32  tmp_dir=$(mktemp -d)
    33  readonly tmp_dir
    34  finish() {
    35    cd "${orig_dir}"          # Leave tmp_dir.
    36    rm -rf "${tmp_dir}"       # Remove all contents.
    37    git checkout -f "${head}" # Restore commit.
    38  }
    39  trap finish EXIT
    40  
    41  # Discover the package name from the go.mod file.
    42  declare module origpwd othersrc
    43  module=$(cat go.mod | grep -E "^module" | cut -d' ' -f2)
    44  origpwd=$(pwd)
    45  othersrc=("go.mod" "go.sum" "AUTHORS" "LICENSE")
    46  readonly module origpwd othersrc
    47  
    48  # Build a full gopath.
    49  declare -r go_output="${tmp_dir}/output"
    50  make build BAZEL_OPTIONS="" TARGETS="//:gopath"
    51  unzip bazel-bin/gopath.zip -d "${go_output}"
    52  
    53  # We expect to have an existing go branch that we will use as the basis for this
    54  # commit. That branch may be empty, but it must exist. We search for this branch
    55  # using the local branch, the "origin" branch, and other remotes, in order.
    56  git fetch --all
    57  declare go_branch
    58  go_branch=$( \
    59    git show-ref --hash refs/heads/go || \
    60    git show-ref --hash refs/remotes/origin/go || \
    61    git show-ref --hash go | head -n 1 \
    62  )
    63  readonly go_branch
    64  
    65  # Clone the current repository to the temporary directory, and check out the
    66  # current go_branch directory. We move to the new repository for convenience.
    67  declare repo_orig
    68  repo_orig="$(pwd)"
    69  readonly repo_orig
    70  declare -r repo_new="${tmp_dir}/repository"
    71  git clone . "${repo_new}"
    72  cd "${repo_new}"
    73  
    74  # Setup the repository and checkout the branch.
    75  git config user.email "gvisor-bot@google.com"
    76  git config user.name "gVisor bot"
    77  git fetch origin "${go_branch}"
    78  git checkout -b go "${go_branch}"
    79  
    80  # Start working on a merge commit that combines the previous history with the
    81  # current history. Note that we don't actually want any changes yet.
    82  #
    83  # N.B. The git behavior changed at some point and the relevant flag was added
    84  # to allow for override, so try the only behavior first then pass the flag.
    85  git merge --no-commit --strategy ours "${head}" || \
    86    git merge --allow-unrelated-histories --no-commit --strategy ours "${head}"
    87  
    88  # Normalize the permissions on the old branch. Note that they should be
    89  # normalized if constructed by this tool, but we do so before the rsync.
    90  find . -type f -exec chmod 0644 {} \;
    91  find . -type d -exec chmod 0755 {} \;
    92  
    93  # Sync the entire gopath. Note that we exclude auto-generated source files that
    94  # will change here. Otherwise, it adds a tremendous amount of noise to commits.
    95  # If this file disappears in the future, then presumably we will still delete
    96  # the underlying directory.
    97  declare -r gopath="${go_output}/src/${module}"
    98  rsync --recursive --delete \
    99    --exclude .git \
   100    "${gopath}/" .
   101  
   102  # Add additional files.
   103  for file in "${othersrc[@]}"; do
   104    cp "${origpwd}"/"${file}" .
   105  done
   106  
   107  # Construct a new README.md.
   108  cat > README.md <<EOF
   109  # gVisor
   110  
   111  This branch is a synthetic branch, containing only Go sources, that is
   112  compatible with standard Go tools. See the master branch for authoritative
   113  sources and tests.
   114  EOF
   115  
   116  # There are a few solitary files that can get left behind due to the way bazel
   117  # constructs the gopath target. Note that we don't find all Go files here
   118  # because they may correspond to unused templates, etc.
   119  declare -ar binaries=( "runsc" "shim" "webhook" "tools/checklocks/cmd/checklocks" )
   120  for target in "${binaries[@]}"; do
   121    mkdir -p "${target}"
   122    cp "${repo_orig}/${target}"/*.go "${target}/"
   123  done
   124  
   125  # Normalize all permissions. The way bazel constructs the :gopath tree may leave
   126  # some strange permissions on files. We don't have anything in this tree that
   127  # should be execution, only the Go source files, README.md, and ${othersrc}.
   128  find . -type f -exec chmod 0644 {} \;
   129  find . -type d -exec chmod 0755 {} \;
   130  
   131  # Update the current working set and commit.
   132  # If the current working commit has already been committed to the remote go
   133  # branch, then we have nothing to commit here. So allow empty commit. This can
   134  # occur when this script is run parallely (via pull_request and push events)
   135  # and the push workflow finishes before the pull_request workflow can run this.
   136  git add --all && git commit --allow-empty -m "Merge ${head} (automated)"
   137  
   138  # Push the branch back to the original repository.
   139  git remote add orig "${repo_orig}" && git push -f orig go:go