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