]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
script/ceph-backport.sh: infer whether to --prepare
authorNathan Cutler <ncutler@suse.com>
Thu, 5 Sep 2019 08:56:05 +0000 (10:56 +0200)
committerNathan Cutler <ncutler@suse.com>
Fri, 6 Sep 2019 10:47:27 +0000 (12:47 +0200)
If the current branch is wip-$issue_id-$release, then assume
prepare phase has already been completed.

If that branch doesn't exist, do --prepare even if the --prepare
option was not passed explicitly.

Signed-off-by: Nathan Cutler <ncutler@suse.com>
src/script/ceph-backport.sh

index 031d5080f919bca73cf4b8a27a5a779310a41be6..34ec61ae8d8cb6ea589c63dae60991a47a9e6387 100755 (executable)
 # local clone.
 #
 # Third, choose a Backport tracker issue you would like to stage a backport for.
-# Let's assume the Backport tracker issue you chose has the number 31459.
+# Let's assume the Backport tracker issue you chose has the number 31459 and 
+# the backport targets luminous.
 #
 # Then run:
 #
-#     ceph-backport.sh 31459 --prepare
+#     ceph-backport.sh 31459
 #
 # Assuming 31459 is a properly-linked Backport issue and the "Pull request ID"
 # field of the parent issue has been correctly populated, the script will
 # automatically:
 #
-# 1. determine which stable branch the backport is targeting
-# 2. create a local wip branch based on the tip of that stable branch
-# 3. cherry-pick the commits from the master PR
+# 1. determine which stable branch the backport is targeting (luminous)
+# 2. create a local backport branch, wip-31459-luminous, based on the tip of
+#    luminous
+# 3. determine parent issue and master PR and cherry-pick the commits from the
+#    master PR
 #
 # If there were no cherry-pick conflicts, the script will continue (see steps
 # 4-6, below).
 #
 # If any commit fails to cherry-pick cleanly, the script will abort, giving
 # the user an opportunity to resolve the conflicts manually and re-run the
-# script (without --prepare the second time) -- in that case the script will
-# assume the current branch is the backport branch with cherry-picking
-# completed, and start from step 4:
+# script. When the script sees that the local backport branch (wip-31459-luminous)
+# already exists, it assumes that cherry-picking has been completed, and starts
+# from step 4:
 #
 # 4. push the wip branch to the user's fork
 # 5. open the backport PR on GitHub with the correct Milestone setting
 # Happy backporting!
 # Nathan
 #
-source $HOME/bin/backport_common.sh
+
 this_script=$(basename "$0")
 
-remote_api_output=$(mktemp /tmp/${this_script}.remote_api_output.XXXXX)
-function rm_tmp_files {
-    rm -f "$remote_api_output"
+function debug {
+    log debug $@
+}
+
+function error {
+    log error $@
+}
+
+function failed_required_variable_check {
+    local varname="$1"
+    error "$varname not defined. Did you create $HOME/bin/backport_common.sh?"
+    info "(For detailed instructions, see comment block at the beginning of the script)"
+    exit 1
+}
+
+function info {
+    log info $@
+}
+
+function init_mandatory_vars {
+    debug Initializing mandatory variables
+    test "$redmine_key"     || failed_required_variable_check redmine_key
+    test "$redmine_user_id" || failed_required_variable_check redmine_user_id
+    test "$github_token"    || failed_required_variable_check github_token
+    test "$github_user"     || failed_required_variable_check github_user
+    true "${github_repo:=origin}"
+    true "${ceph_repo:=upstream}"
+    true "${redmine_endpoint:="https://tracker.ceph.com"}"
+    true "${github_endpoint:="https://github.com/ceph/ceph"}"
+    debug "Redmine user: ${redmine_user_id}"
+    debug "GitHub user:  ${github_user}"
+    debug "Fork remote:  ${github_repo}"
+    if git remote -v | egrep ^${github_repo}\\s+ ; then
+        true  # remote exists; good
+    else
+        error "github_repo is set to ->$github_repo<- but this remote does not exist"
+        exit 1
+    fi
+    debug "Ceph remote:  ${ceph_repo}"
+    if git remote -v | egrep ^${ceph_repo}\\s+ ; then
+        true  # remote exists; good
+    else
+        error "ceph_repo is set to ->$ceph_repo<- but this remote does not exist"
+        exit 1
+    fi
 }
-trap rm_tmp_files EXIT
 
 function log {
     local level="$1"
@@ -201,43 +245,6 @@ function log {
     fi
 }
 
-function error {
-    log error $@
-}
-
-function warning {
-    log warning $@
-}
-
-function info {
-    log info $@
-}
-
-function debug {
-    log debug $@
-}
-
-function usage {
-    log bare
-    log bare "Usage:"
-    log bare "   ${this_script} BACKPORT_TRACKER_ISSUE_NUMBER [--debug] [--prepare] [--verbose]"
-    log bare
-    log bare "Example:"
-    log bare "   ${this_script} 19206 --prepare"
-    log bare
-    log bare "The script must be run from inside a local git clone."
-    log bare
-    log bare "Documentation can be found in the comment block at the top of the script itself."
-    exit 1
-}
-
-function failed_required_variable_check {
-    local varname="$1"
-    error "$varname not defined. Did you create $HOME/bin/backport_common.sh?"
-    info "(For detailed instructions, see comment block at the beginning of the script)"
-    exit 1
-}
-
 function populate_original_issue {
     if [ -z "$original_issue" ] ; then
         original_issue=$(curl --silent ${redmine_url}.json?include=relations |
@@ -312,9 +319,9 @@ function prepare {
                 for ((j=$i-1; j>=0; j--)) ; do
                     info "-> missing commit: $(git log --oneline --max-count=1 --no-decorate pr-$original_pr~$j)"
                 done
-                info "Finally, re-run the script without --prepare"
+                info "Finally, re-run the script"
             else
-                info "Then re-run the script without --prepare"
+                info "Then re-run the script"
             fi
             exit 1
         fi
@@ -322,19 +329,50 @@ function prepare {
     info "Cherry picking completed without conflicts"
 }
 
+function usage {
+    log bare
+    log bare "Usage:"
+    log bare "   ${this_script} BACKPORT_TRACKER_ISSUE_NUMBER [--debug] [--prepare] [--verbose]"
+    log bare
+    log bare "Example:"
+    log bare "   ${this_script} 19206 --prepare"
+    log bare
+    log bare "The script must be run from inside a local git clone."
+    log bare
+    log bare "Documentation can be found in the comment block at the top of the script itself."
+    exit 1
+}
+
+function warning {
+    log warning $@
+}
+
+
+if git show-ref HEAD >/dev/null 2>&1 ; then
+    debug "In a local git clone. Good."
+else
+    error "This script must be run from inside a local git clone"
+    exit 1
+fi
+
+
+#
+# process command-line arguments
+#
+
 munged_options=$(getopt -o dhpv --long "debug,help,prepare,verbose" -n "$this_script" -- "$@")
 eval set -- "$munged_options"
 
 DEBUG=""
 HELP=""
 ISSUE=""
-PREPARE=""
+EXPLICIT_PREPARE=""
 VERBOSE=""
 while true ; do
     case "$1" in
         --debug|-d) DEBUG="$1" ; shift ;;
         --help|-h) HELP="$1" ; shift ;;
-        --prepare|-p) PREPARE="$1" ; shift ;;
+        --prepare|-p) EXPLICIT_PREPARE="$1" ; shift ;;
         --verbose|-v) VERBOSE="$1" ; shift ;;
         --) shift ; ISSUE="$1" ; break ;;
         *) echo "Internal error" ; false ;;
@@ -361,50 +399,25 @@ if [ "$VERBOSE" ]; then
     VERBOSE="--verbose"
 fi
 
-debug Checking mandatory variables
-test "$redmine_key"     || failed_required_variable_check redmine_key
-test "$redmine_user_id" || failed_required_variable_check redmine_user_id
-test "$github_token"    || failed_required_variable_check github_token
-test "$github_user"     || failed_required_variable_check github_user
-true "${github_repo:=origin}"
-true "${ceph_repo:=upstream}"
-redmine_endpoint="https://tracker.ceph.com"
-github_endpoint="https://github.com/ceph/ceph"
-original_issue=
-original_pr=
-original_pr_url=
 
-if git show-ref HEAD >/dev/null 2>&1 ; then
-    debug "In a local git clone. Good."
-else
-    error "This script must be run from inside a local git clone"
-    exit 1
-fi
+#
+# initialize mandatory variables and check values for sanity
+#
 
-if [ $VERBOSE ] ; then
-    debug "Redmine user: ${redmine_user_id}"
-    debug "GitHub user:  ${github_user}"
-    debug "Fork remote:  ${github_repo}"
-    if git remote -v | egrep ^${github_repo}\\s+ ; then
-        true  # remote exists; good
-    else
-        error "github_repo is set to ->$github_repo<- but this remote does not exist"
-        exit 1
-    fi
-    debug "Ceph remote:  ${ceph_repo}"
-    if git remote -v | egrep ^${ceph_repo}\\s+ ; then
-        true  # remote exists; good
-    else
-        error "ceph_repo is set to ->$ceph_repo<- but this remote does not exist"
-        exit 1
-    fi
-fi
+BACKPORT_COMMON=$HOME/bin/backport_common.sh
+[ -f "$BACKPORT_COMMON" ] && source $HOME/bin/backport_common.sh
+init_mandatory_vars
+
+
+#
+# query remote Redmine API for information about the Backport tracker issue
+#
 
 redmine_url="${redmine_endpoint}/issues/${issue}"
 debug "Considering Redmine issue: $redmine_url - is it in the Backport tracker?"
 
-curl --silent "${redmine_url}.json" > $remote_api_output
-tracker=$(cat $remote_api_output | jq -r '.issue.tracker.name')
+remote_api_output=$(curl --silent "${redmine_url}.json")
+tracker=$(echo $remote_api_output | jq -r '.issue.tracker.name')
 if [ "$tracker" = "Backport" ]; then
     debug "Yes, $redmine_url is a Backport issue"
 else
@@ -414,7 +427,7 @@ else
 fi
 
 debug "Looking up release/milestone of $redmine_url"
-milestone=$(cat $remote_api_output | jq -r '.issue.custom_fields[0].value')
+milestone=$(echo $remote_api_output | jq -r '.issue.custom_fields[0].value')
 if [ "$milestone" ] ; then
     debug "Release/milestone: $milestone"
 else
@@ -422,7 +435,7 @@ else
     exit 1
 fi
 
-tracker_title=$(cat $remote_api_output | jq -r '.issue.subject')
+tracker_title=$(echo $remote_api_output | jq -r '.issue.subject')
 debug "Title of $redmine_url is ->$tracker_title<-"
 
 # milestone numbers can be obtained manually with:
@@ -440,24 +453,37 @@ fi
 info "Milestone/release is $milestone"
 debug "Milestone number is $milestone_number"
 
-local_branch=wip-${issue}-${target_branch}
 
-if [ "$PREPARE" ]; then
-    debug "'--prepare' found, will only prepare the backport"
-    prepare
-fi
+#
+# --prepare phase
+#
 
-current_branch=$(git rev-parse --abbrev-ref HEAD)
-if [ "$current_branch" = "$local_branch" ] ; then
-    true  # all is well
+local_branch=wip-${issue}-${target_branch}
+if git show-ref --verify --quiet refs/heads/$local_branch ; then
+    if [ "$EXPLICIT_PREPARE" ] ; then
+        error "local branch $local_branch already exists -- cannot --prepare"
+        exit 1
+    fi
+    warning "local branch $local_branch already exists: skipping cherry-pick phase!"
+    PREPARE=""
 else
-    error "local branch is $current_branch, but I needed $local_branch"
-    exit 1
+    info "$local_branch does not exist: will create it and attempt automated cherry-pick"
+    PREPARE="--prepare"
 fi
+[ "$PREPARE" ] && prepare
+
+
+#
+# at this point, local branch exists and is assumed to contain cherry-pick(s)
+#
 
 debug "Pushing local branch $local_branch to remote $github_repo"
 git push -u $github_repo $local_branch
 
+original_issue=""
+original_pr=""
+original_pr_url=""
+
 debug "Generating backport PR description"
 populate_original_issue
 populate_original_pr