github.com/datadog/cilium@v1.6.12/contrib/backporting/check-stable (about)

     1  #!/bin/bash
     2  #
     3  # Copyright 2016 The Kubernetes Authors All rights reserved.
     4  # Copyright 2019 Authors of Cilium
     5  #
     6  # Licensed under the Apache License, Version 2.0 (the "License");
     7  # you may not use this file except in compliance with the License.
     8  # You may obtain a copy of the License at
     9  #
    10  #     http://www.apache.org/licenses/LICENSE-2.0
    11  #
    12  # Unless required by applicable law or agreed to in writing, software
    13  # distributed under the License is distributed on an "AS IS" BASIS,
    14  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  # See the License for the specific language governing permissions and
    16  # limitations under the License.
    17  #
    18  # Set PROGram name
    19  PROG=${0##*/}
    20  STABLE_BRANCH=${1:-}
    21  SUMMARY_LOG=${2:-}
    22  
    23  source $(dirname $(readlink -ne $BASH_SOURCE))/../release/lib/common.sh
    24  source $TOOL_LIB_PATH/gitlib.sh
    25  source $(dirname $(readlink -ne $BASH_SOURCE))/common.sh
    26  
    27  # Validate command-line
    28  common::argc_validate 2
    29  
    30  if [[ -z $STABLE_BRANCH ]]; then
    31    logecho "usage: $0 <branch> [summary-file]" >&2
    32    common::exit 1
    33  fi
    34  
    35  ###############################################################################
    36  # FUNCTIONS
    37  ###############################################################################
    38  ###############################################################################
    39  # Get titles from a list of PRs
    40  # @param prs - A space separated list of PRs to extract
    41  #
    42  extract_pr_title () {
    43    local prs="$*"
    44    local pr
    45    local content
    46    local body
    47    local author
    48    local pull_json
    49  
    50    for pr in $prs; do
    51      pull_json="$($GHCURL $CILIUM_GITHUB_API/pulls/$pr)"
    52      [[ -z "$pull_json" ]] && return 1
    53      body="$(echo "$pull_json" |jq -r '.body' |tr -d '\r')"
    54  
    55      content=$(echo "$pull_json" | jq -r '.title')
    56      author=$(echo "$pull_json" | jq -r '.user.login')
    57      content=$(echo "$content" |sed -e '1s/^ *\** *//g' \
    58                                     -e "1s/$/ (@$author)/g")
    59  
    60      logecho -r "$content"
    61    done
    62  }
    63  
    64  ###############################################################################
    65  # Get merged PRs that match a specified label and exclude a specified label
    66  #
    67  # Each returned array entry is in the form "$merged_at#$prnumber"
    68  get_prs () {
    69    local label=$1
    70    local label_exclude=$2
    71    local -a prs
    72    local total
    73    local current_page
    74    local num_pages
    75    local prs_per_page
    76    local url
    77  
    78    prs_per_page=100
    79  
    80    label_opt="%20label:$label"
    81    label_exclude_opt="%20-label:$label_exclude"
    82    url="${CILIUM_GITHUB_SEARCHAPI}$label_opt$label_exclude_opt"
    83    total="$($GHCURL $url | jq -r '.total_count')"
    84  
    85    # Calculate number of pages, rounding up
    86    num_pages=$(((total + prs_per_page - 1) / prs_per_page ))
    87  
    88    for current_page in `seq 1 $num_pages`; do
    89      local page_json
    90      local merged_at
    91      local pr_url
    92      local pr_list
    93  
    94      page_json=$($GHCURL "$url&page=$current_page")
    95      pr_list=$(echo -n $page_json | jq -r '.items[] | (.number | tostring)')
    96      for pr in $pr_list; do
    97        pr_url="https://api.github.com/repos/cilium/cilium/pulls/$pr"
    98        merged_at=$($GHCURL "$pr_url" | jq -r '.merged_at')
    99  
   100        # Never merged ...
   101        if [[ "$merged_at" = "null" ]]; then
   102          continue
   103        fi
   104        prs+=("$merged_at#$pr ")
   105      done
   106    done
   107  
   108    echo "${prs[@]}"
   109  }
   110  
   111  ###############################################################################
   112  # Generates the release notes for one particular PR
   113  generate_commit_list_for_pr () {
   114    local pr=$1
   115    local merged_at=$2
   116    local url
   117    local pr_json
   118    local merge_sha
   119    local commits
   120    local branch
   121    local tmp_file
   122    local patchid
   123    local subject
   124    local tmp_file
   125    local entry_array
   126    local entry_id
   127    local entry_sha
   128    local entry_sub
   129    local upstream
   130  
   131    url="https://api.github.com/repos/cilium/cilium/pulls/$pr/commits"
   132    pr_json="$($GHCURL $url)"
   133    n_commits="$(echo -n $pr_json | jq -r '. | length')"
   134  
   135    tmp_file=`mktemp pr-correlation.XXXXXX`
   136    branch="check-for-stable-$pr"
   137    git fetch -q $REMOTE pull/$pr/head:$branch
   138    # Use GitHub to determine the number of commits to list, but then query
   139    # the branch directly to determine the canonical order of the commits.
   140    for commit in $(git rev-list --reverse -$n_commits $branch); do
   141      patchid="$(git show $commit | git patch-id)"
   142      subject="$(git show -s --pretty="%s" $commit)"
   143      echo "$patchid $subject" >> $tmp_file
   144    done
   145    git branch -q -D $branch
   146    echo "   Merge with $n_commits commit(s) merged at: `date -R -d "$(echo $merged_at | sed 's/T/ /')"`!"
   147    echo "     Branch:     master (!)                          refs/pull/$pr/head"
   148    echo "                 ----------                          -------------------"
   149    echo "     v (start)"
   150    while read entry; do
   151      entry_array=($entry)
   152      entry_id=${entry_array[0]}
   153      entry_sha=${entry_array[1]}
   154      entry_sub=${entry_array[@]:2}
   155      upstream="$(git log -F --since="1year" --pretty="%H" --no-merges --grep "$entry_sub" $REMOTE/master)"
   156      upstream="$(git show $upstream | git patch-id)"
   157      upstream=($upstream)
   158      if [ "$entry_id" == "${upstream[0]}" ]; then
   159        echo -e "     |  ${upstream[1]} via $entry_sha (\"$entry_sub\")"
   160      else
   161        echo -e "     |  Warning: No commit correlation found!    via $entry_sha (\"$entry_sub\")"
   162      fi
   163    done < $tmp_file
   164    echo "     v (end)"
   165    rm -f $tmp_file
   166  }
   167  
   168  ###############################################################################
   169  # MAIN
   170  ###############################################################################
   171  # Initialize and save up to 10 (rotated logs)
   172  MYLOG=/tmp/$PROG.log
   173  REMOTE="$(get_remote)"
   174  # Check token
   175  gitlib::github_api_token
   176  
   177  echo "Checking for backports on branch '${STABLE_BRANCH}'"
   178  
   179  stable_prs=($(get_prs "needs-backport/${STABLE_BRANCH}" "backport-done/${STABLE_BRANCH}"))
   180  echo -e "v$STABLE_BRANCH backports $(date +%Y-%m-%d)\n" | tee $SUMMARY_LOG
   181  echo -e "PRs for stable backporting: ${#stable_prs[@]}\n"
   182  
   183  if [[ ${#stable_prs[@]} > 0 ]]; then
   184    SAVEIFS=$IFS
   185    IFS=$'\n' sorted_prs=($(sort <<<"${stable_prs[*]}"))
   186    IFS=$'\n' stable_prs=($(cut -d'#' -f 2 <<<"${sorted_prs[*]}"))
   187    IFS=$SAVEIFS
   188  
   189    for dated_pr in "${sorted_prs[@]}"; do
   190      merged_at=$(echo "$dated_pr" | cut -d'#' -f 1)
   191      pr=$(echo "$dated_pr" | cut -d'#' -f 2)
   192      title=$(extract_pr_title "$pr")
   193      echo " * PR: $pr -- $title -- https://github.com/cilium/cilium/pull/$pr"
   194      if [[ ! -z $SUMMARY_LOG ]]; then
   195        echo " * #$pr -- $title" >> $SUMMARY_LOG
   196      fi
   197      generate_commit_list_for_pr $pr $merged_at
   198      echo ""
   199    done
   200    echo "When you have backported the above commits, you can update the PR labels via this command:"
   201    echo "$ for pr in ${stable_prs[@]}; do contrib/backporting/set-labels.py \$pr pending ${STABLE_BRANCH}; done"
   202    if [[ ! -z $SUMMARY_LOG ]]; then
   203      echo -e "\nOnce this PR is merged, you can update the PR labels via:" >> $SUMMARY_LOG
   204      echo "\`\`\`upstream-prs" >> $SUMMARY_LOG
   205      echo "$ for pr in ${stable_prs[@]}; do contrib/backporting/set-labels.py \$pr done ${STABLE_BRANCH}; done" >> $SUMMARY_LOG
   206      echo "\`\`\`" >> $SUMMARY_LOG
   207    fi
   208  fi