github.com/imran-kn/cilium-fork@v1.6.9/contrib/release/lib/gitlib.sh (about) 1 #!/bin/bash 2 # 3 # Copyright 2016 The Kubernetes Authors All rights reserved. 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 ############################################################################### 18 # GIT-related constants and functions 19 20 ############################################################################### 21 # CONSTANTS 22 ############################################################################### 23 GHCURL="curl -s --fail --retry 10 -u ${GITHUB_TOKEN:-$FLAGS_github_token}:x-oauth-basic" 24 JCURL="curl -g -s --fail --retry 10" 25 CILIUM_GITHUB_API='https://api.github.com/repos/cilium/cilium' 26 CILIUM_GITHUB_RAW_ORG='https://raw.githubusercontent.com/cilium' 27 28 CILIUM_GITHUB_SEARCHAPI='https://api.github.com/search/issues?per_page=100&q=is:pr%20is:merged%20repo:cilium/cilium%20' 29 CILIUM_GITHUB_URL='https://github.com/cilium/cilium' 30 CILIUM_GITHUB_SSH='git@github.com:cilium/cilium.git' 31 32 # Regular expressions for bash regex matching 33 # 0=entire branch name 34 # 1=Major 35 # 2=Minor 36 # 3=.Patch 37 # 4=Patch 38 BRANCH_REGEX="master|release-([0-9]{1,})\.([0-9]{1,})(\.([0-9]{1,}))*$" 39 # release - 1=Major, 2=Minor, 3=Patch, 4=-(alpha|beta|rc), 5=rev 40 # dotzero - 1=Major, 2=Minor 41 # build - 1=build number, 2=sha1 42 declare -A VER_REGEX=([release]="v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[a-zA-Z0-9]+)*\.*(0|[1-9][0-9]*)?" 43 [dotzero]="v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.0$" 44 [build]="([0-9]{1,})\+([0-9a-f]{5,40})" 45 ) 46 47 ############################################################################### 48 # FUNCTIONS 49 ############################################################################### 50 51 ############################################################################### 52 # Attempt to authenticate to github using ssh and if unsuccessful provide 53 # guidance for setup 54 # 55 gitlib::ssh_auth () { 56 57 logecho -n "Checking ssh auth to github.com: " 58 if ssh -T ${CILIUM_GITHUB_SSH%%:*} 2>&1 |fgrep -wq denied; then 59 logecho $FAILED 60 logecho 61 logecho "See https://help.github.com/categories/ssh" 62 return 1 63 fi 64 65 logecho $OK 66 } 67 68 69 ############################################################################### 70 # Check if authenticated (GITHUB_TOKEN) user is a repo admin. 71 # Repo admins always have access to push to any restricted branch. 72 # See: https://github.com/cilium/cilium/settings/branches 73 # 74 # returns 1 if authenticated user is NOT a repo admin 75 gitlib::is_repo_admin () { 76 local result 77 78 logecho -n "Checking repo admin state: " 79 result=$($GHCURL $CILIUM_GITHUB_API | jq -r '.permissions.admin') 80 81 if [[ $result == "true" ]]; then 82 logecho $OK 83 return 0 84 else 85 logecho $FAILED 86 logecho 87 logecho "You must be a repo admin to continue." 88 logecho "1. Ensure you are a member" 89 logecho "2. Use the 'Request to Join'" 90 return 1 91 fi 92 } 93 94 ############################################################################### 95 # Looks up the list of releases on github and puts the last release per branch 96 # into a global branch-indexed dictionary LAST_RELEASE[$branch] 97 # 98 # USEFUL: LAST_TAG=$(git describe --abbrev=0 --tags) 99 gitlib::last_releases () { 100 local release 101 local branch_name 102 local latest_branch 103 declare -Ag LAST_RELEASE 104 105 logecho -n "Setting last releases by branch: " 106 for release in $($GHCURL $CILIUM_GITHUB_API/releases|\ 107 jq -r '.[] | select(.draft==false) | .tag_name'); do 108 # Alpha releases only on master branch 109 if [[ $release =~ -alpha ]]; then 110 LAST_RELEASE[master]=${LAST_RELEASE[master]:-$release} 111 elif [[ $release =~ v([0-9]+\.[0-9]+)\.([0-9]+(-.+)?) ]]; then 112 # Latest vx.x.0 release goes on both master and release branch. 113 if [[ ${BASH_REMATCH[2]} == "0" ]]; then 114 LAST_RELEASE[master]=${LAST_RELEASE[master]:-$release} 115 fi 116 branch_name=release-${BASH_REMATCH[1]} 117 LAST_RELEASE[$branch_name]=${LAST_RELEASE[$branch_name]:-$release} 118 fi 119 done 120 121 logecho -r "$OK" 122 } 123 124 ############################################################################### 125 # What branch am I on? 126 # @optparam repo_dir - An alternative (to current working dir) git repo 127 # prints current branch name 128 # returns 1 if current working directory is not git repository 129 gitlib::current_branch () { 130 local repo_dir=$1 131 local -a git_args 132 133 [[ -n "$repo_dir" ]] && git_args=("-C" "$repo_dir") 134 135 if ! git ${git_args[*]} rev-parse --abbrev-ref HEAD 2>/dev/null; then 136 ( 137 logecho 138 logecho "Not a git repository!" 139 logecho 140 ) >&2 141 return 1 142 fi 143 } 144 145 ############################################################################### 146 # Show the pending/open PRs on a branch 147 # @param branch 148 # returns 1 if current working directory is not git repository 149 gitlib::pending_prs () { 150 local branch=$1 151 local pr 152 local login 153 local date 154 local msg 155 local sep 156 157 if ((FLAGS_htmlize_md)); then 158 echo "PR | Milestone | User | Date | Commit Message" 159 echo "-- | --------- | ---- | ---- | --------------" 160 sep="|" 161 fi 162 163 while read pr milestone login date msg; do 164 # "escape" '*' in commit messages so they don't mess up formatting. 165 msg=$(echo $msg |sed 's, *\* *, * ,g') 166 printf "%-8s $sep %-4s $sep %-10s $sep %-18s $sep %s\n" \ 167 "#$pr" "$milestone" "@$login" "$(date +"%F %R" -d "$date")" "$msg" 168 done < <($GHCURL $CILIUM_GITHUB_API/pulls\?state\=open\&base\=$branch |\ 169 jq -r \ 170 '.[] | "\(.number)\t\(.milestone.title)\t\(.user.login)\t\(.updated_at)\t\(.title)"') 171 } 172 173 ############################################################################### 174 # Validates github token using the standard $GITHUB_TOKEN in your env 175 # returns 0 if token is valid 176 # returns 1 if token is invalid 177 gitlib::github_api_token () { 178 logecho -n "Checking for a valid github API token: " 179 if ! $GHCURL $CILIUM_GITHUB_API >/dev/null 2>&1; then 180 logecho -r "$FAILED" 181 logecho 182 logecho "No valid github token found in environment or command-line!" 183 logecho 184 logecho "If you don't have a token yet, go get one at" \ 185 "https://github.com/settings/tokens/new" 186 logecho "1. Fill in 'Token description': $PROG-token" 187 logecho "2. Check the []repo box" 188 logecho "3. Click the 'Generate token' button at the bottom of the page" 189 logecho "4. Use your new token in one of two ways:" 190 logecho " * Set GITHUB_TOKEN in your environment" 191 logecho " * Specify your --github-token=<token> on the command line" 192 common::exit 1 193 fi 194 logecho -r "$OK" 195 } 196 197 ############################################################################## 198 # Git repo sync 199 # @param repo - full git url 200 # @param dest - destination directory 201 gitlib::sync_repo () { 202 local repo=$1 203 local dest=$2 204 205 logecho -n "Syncing ${repo##*/} to $dest: " 206 if [[ -d $dest ]]; then 207 ( 208 cd $dest 209 logrun git checkout master 210 logrun -s git pull 211 ) || return 1 212 else 213 logrun -s git clone $repo $dest || return 1 214 fi 215 } 216 217 ############################################################################## 218 # Does git branch exist? 219 # @param branch - branch 220 gitlib::branch_exists () { 221 local branch=$1 222 223 git ls-remote --exit-code $CILIUM_GITHUB_URL \ 224 refs/heads/$branch &>/dev/null 225 } 226 227 ############################################################################## 228 # Fetch, rebase and push master. 229 gitlib::push_master () { 230 local dryrun_flag=" --dry-run" 231 ((FLAGS_nomock)) && dryrun_flag="" 232 233 logecho -n "Checkout master branch to push objects: " 234 logrun -s git checkout master || return 1 235 236 logecho -n "Rebase master branch: " 237 logrun git fetch origin || return 1 238 logrun -s git rebase origin/master || return 1 239 logecho -n "Pushing$dryrun_flag master branch: " 240 logrun -s git push$dryrun_flag origin master || return 1 241 } 242 243 ############################################################################## 244 # Ensure TOOL_ROOT running with a synced repo. 245 # 246 gitlib::repo_state () { 247 local branch=$(gitlib::current_branch $TOOL_ROOT) || return 1 248 local remote=$(git -C $TOOL_ROOT remote -v |\ 249 awk '/kubernetes\/release(.git)* \(fetch\)/ {print $1}') 250 local commit=$(git -C $TOOL_ROOT \ 251 ls-remote --heads $remote refs/heads/master | cut -f1) 252 local output=$(git -C $TOOL_ROOT branch --contains $commit $branch 2>&-) 253 254 logecho -n "Checking $TOOL_ROOT state: " 255 if [[ -n "$output" ]]; then 256 logecho $OK 257 else 258 logecho "$FAILED" 259 logecho 260 logecho "$TOOL_ROOT is not up to date." 261 logecho "$ git pull # to try again" 262 return 1 263 fi 264 }