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  }