{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/78260064","id":78260064,"diff_hunk":"@@ -1061,537 +1031,8 @@ function kube::release::create_tarball() {\n   \"${TAR}\" czf \"${tarfile}\" -C \"${stagingdir}\" kubernetes --owner=0 --group=0\n }\n \n-# ---------------------------------------------------------------------------\n-# GCS Release\n-\n-function kube::release::gcs::release() {\n-  [[ ${KUBE_GCS_UPLOAD_RELEASE} =~ ^[yY]$ ]] || return 0\n-\n-  kube::release::gcs::verify_prereqs || return 1\n-  kube::release::gcs::ensure_release_bucket || return 1\n-  kube::release::gcs::copy_release_artifacts || return 1\n-}\n-\n-# Verify things are set up for uploading to GCS\n-function kube::release::gcs::verify_prereqs() {\n-  if [[ -z \"$(which gsutil)\" || -z \"$(which gcloud)\" ]]; then\n-    echo \"Releasing Kubernetes requires gsutil and gcloud.  Please download,\"\n-    echo \"install and authorize through the Google Cloud SDK: \"\n-    echo\n-    echo \"  https://developers.google.com/cloud/sdk/\"\n-    return 1\n-  fi\n-\n-  if [[ -z \"${GCLOUD_ACCOUNT-}\" ]]; then\n-    GCLOUD_ACCOUNT=$(gcloud config list --format='value(core.account)' 2>/dev/null)\n-  fi\n-  if [[ -z \"${GCLOUD_ACCOUNT-}\" ]]; then\n-    echo \"No account authorized through gcloud.  Please fix with:\"\n-    echo\n-    echo \"  gcloud auth login\"\n-    return 1\n-  fi\n-\n-  if [[ -z \"${GCLOUD_PROJECT-}\" ]]; then\n-    GCLOUD_PROJECT=$(gcloud config list --format='value(core.project)' 2>/dev/null)\n-  fi\n-  if [[ -z \"${GCLOUD_PROJECT-}\" ]]; then\n-    echo \"No account authorized through gcloud.  Please fix with:\"\n-    echo\n-    echo \"  gcloud config set project <project id>\"\n-    return 1\n-  fi\n-}\n-\n-# Create a unique bucket name for releasing Kube and make sure it exists.\n-function kube::release::gcs::ensure_release_bucket() {\n-  local project_hash\n-  project_hash=$(kube::build::short_hash \"$GCLOUD_PROJECT\")\n-  KUBE_GCS_RELEASE_BUCKET=${KUBE_GCS_RELEASE_BUCKET-kubernetes-releases-${project_hash}}\n-\n-  if ! gsutil ls \"gs://${KUBE_GCS_RELEASE_BUCKET}\" >/dev/null 2>&1 ; then\n-    echo \"Creating Google Cloud Storage bucket: $KUBE_GCS_RELEASE_BUCKET\"\n-    gsutil mb -p \"${GCLOUD_PROJECT}\" \"gs://${KUBE_GCS_RELEASE_BUCKET}\" || return 1\n-  fi\n-}\n-\n-function kube::release::gcs::stage_and_hash() {\n-  kube::build::ensure_tar || return 1\n-\n-  # Split the args into srcs... and dst\n-  local -r args=( \"$@\" )\n-  local -r split=$((${#args[@]}-1)) # Split point for src/dst args\n-  local -r srcs=( \"${args[@]::${split}}\" )\n-  local -r dst=\"${args[${split}]}\"\n-\n-  for src in ${srcs[@]}; do\n-    srcdir=$(dirname ${src})\n-    srcthing=$(basename ${src})\n-    mkdir -p ${GCS_STAGE}/${dst} || return 1\n-    \"${TAR}\" c -C ${srcdir} ${srcthing} | \"${TAR}\" x -C ${GCS_STAGE}/${dst} || return 1\n-  done\n-}\n-\n-function kube::release::gcs::copy_release_artifacts() {\n-  # TODO: This isn't atomic.  There will be points in time where there will be\n-  # no active release.  Also, if something fails, the release could be half-\n-  # copied.  The real way to do this would perhaps to have some sort of release\n-  # version so that we are never overwriting a destination.\n-  local -r gcs_destination=\"gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_RELEASE_PREFIX}\"\n-\n-  kube::log::status \"Staging release artifacts to ${GCS_STAGE}\"\n-\n-  rm -rf ${GCS_STAGE} || return 1\n-  mkdir -p ${GCS_STAGE} || return 1\n-\n-  # Stage everything in release directory\n-  kube::release::gcs::stage_and_hash \"${RELEASE_DIR}\"/* . || return 1\n-\n-  # Having the configure-vm.sh script and GCI code from the GCE cluster\n-  # deploy hosted with the release is useful for GKE.\n-  kube::release::gcs::stage_and_hash \"${RELEASE_STAGE}/full/kubernetes/cluster/gce/configure-vm.sh\" extra/gce || return 1\n-  kube::release::gcs::stage_and_hash \"${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/node.yaml\" extra/gce || return 1\n-  kube::release::gcs::stage_and_hash \"${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/master.yaml\" extra/gce || return 1\n-  kube::release::gcs::stage_and_hash \"${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/configure.sh\" extra/gce || return 1\n-\n-  # Upload the \"naked\" binaries to GCS.  This is useful for install scripts that\n-  # download the binaries directly and don't need tars.\n-  local platform platforms\n-  platforms=($(cd \"${RELEASE_STAGE}/client\" ; echo *))\n-  for platform in \"${platforms[@]}\"; do\n-    local src=\"${RELEASE_STAGE}/client/${platform}/kubernetes/client/bin/*\"\n-    local dst=\"bin/${platform/-//}/\"\n-    # We assume here the \"server package\" is a superset of the \"client package\"\n-    if [[ -d \"${RELEASE_STAGE}/server/${platform}\" ]]; then\n-      src=\"${RELEASE_STAGE}/server/${platform}/kubernetes/server/bin/*\"\n-    fi\n-    kube::release::gcs::stage_and_hash \"$src\" \"$dst\" || return 1\n-  done\n-\n-  kube::log::status \"Hashing files in ${GCS_STAGE}\"\n-  find ${GCS_STAGE} -type f | while read path; do\n-    kube::release::md5 ${path} > \"${path}.md5\" || return 1\n-    kube::release::sha1 ${path} > \"${path}.sha1\" || return 1\n-  done\n-\n-  kube::log::status \"Copying release artifacts to ${gcs_destination}\"\n-\n-  # First delete all objects at the destination\n-  if gsutil ls \"${gcs_destination}\" >/dev/null 2>&1; then\n-    kube::log::error \"${gcs_destination} not empty.\"\n-    [[ ${KUBE_GCS_DELETE_EXISTING} =~ ^[yY]$ ]] || {\n-      read -p \"Delete everything under ${gcs_destination}? [y/n] \" -r || {\n-        kube::log::status \"EOF on prompt.  Skipping upload\"\n-        return\n-      }\n-      [[ $REPLY =~ ^[yY]$ ]] || {\n-        kube::log::status \"Skipping upload\"\n-        return\n-      }\n-    }\n-    kube::log::status \"Deleting everything under ${gcs_destination}\"\n-    gsutil -q -m rm -f -R \"${gcs_destination}\" || return 1\n-  fi\n-\n-  local gcs_options=()\n-  if [[ ${KUBE_GCS_NO_CACHING} =~ ^[yY]$ ]]; then\n-    gcs_options=(\"-h\" \"Cache-Control:private, max-age=0\")\n-  fi\n-\n-  gsutil -q -m \"${gcs_options[@]+${gcs_options[@]}}\" cp -r \"${GCS_STAGE}\"/* ${gcs_destination} || return 1\n-\n-  # TODO(jbeda): Generate an HTML page with links for this release so it is easy\n-  # to see it.  For extra credit, generate a dynamic page that builds up the\n-  # release list using the GCS JSON API.  Use Angular and Bootstrap for extra\n-  # extra credit.\n-\n-  if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then\n-    kube::log::status \"Marking all uploaded objects public\"\n-    gsutil -q -m acl ch -R -g all:R \"${gcs_destination}\" >/dev/null 2>&1 || return 1\n-  fi\n-\n-  gsutil ls -lhr \"${gcs_destination}\" || return 1\n-\n-  if [[ -n \"${KUBE_GCS_RELEASE_BUCKET_MIRROR:-}\" ]] &&\n-     [[ \"${KUBE_GCS_RELEASE_BUCKET_MIRROR}\" != \"${KUBE_GCS_RELEASE_BUCKET}\" ]]; then\n-    local -r gcs_mirror=\"gs://${KUBE_GCS_RELEASE_BUCKET_MIRROR}/${KUBE_GCS_RELEASE_PREFIX}\"\n-    kube::log::status \"Mirroring build to ${gcs_mirror}\"\n-    gsutil -q -m \"${gcs_options[@]+${gcs_options[@]}}\" rsync -d -r \"${gcs_destination}\" \"${gcs_mirror}\" || return 1\n-    if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then\n-      kube::log::status \"Marking all uploaded mirror objects public\"\n-      gsutil -q -m acl ch -R -g all:R \"${gcs_mirror}\" >/dev/null 2>&1 || return 1\n-    fi\n-  fi\n-}\n-\n-# Publish a new ci version, (latest,) but only if the release files actually\n-# exist on GCS.\n-#\n-# Globals:\n-#   See callees\n-# Arguments:\n-#   None\n-# Returns:\n-#   Success\n-function kube::release::gcs::publish_ci() {\n-  kube::release::gcs::verify_release_files || return 1\n-\n-  kube::release::parse_and_validate_ci_version \"${KUBE_GCS_PUBLISH_VERSION}\" || return 1\n-  local -r version_major=\"${VERSION_MAJOR}\"\n-  local -r version_minor=\"${VERSION_MINOR}\"\n-\n-  local -r publish_files=(ci/latest.txt ci/latest-${version_major}.txt ci/latest-${version_major}.${version_minor}.txt)\n-\n-  for publish_file in ${publish_files[*]}; do\n-    # If there's a version that's above the one we're trying to release, don't\n-    # do anything, and just try the next one.\n-    kube::release::gcs::verify_ci_ge \"${publish_file}\" || continue\n-    kube::release::gcs::publish \"${publish_file}\" || return 1\n-  done\n-}\n-\n-# Publish a new official version, (latest or stable,) but only if the release\n-# files actually exist on GCS and the release we're dealing with is newer than\n-# the contents in GCS.\n-#\n-# Globals:\n-#   KUBE_GCS_PUBLISH_VERSION\n-#   See callees\n-# Arguments:\n-#   release_kind: either 'latest' or 'stable'\n-# Returns:\n-#   Success\n-function kube::release::gcs::publish_official() {\n-  local -r release_kind=\"${1-}\"\n-\n-  kube::release::gcs::verify_release_files || return 1\n-\n-  kube::release::parse_and_validate_release_version \"${KUBE_GCS_PUBLISH_VERSION}\" || return 1\n-  local -r version_major=\"${VERSION_MAJOR}\"\n-  local -r version_minor=\"${VERSION_MINOR}\"\n-\n-  local publish_files\n-  if [[ \"${release_kind}\" == 'latest' ]]; then\n-    publish_files=(release/latest.txt release/latest-${version_major}.txt release/latest-${version_major}.${version_minor}.txt)\n-  elif [[ \"${release_kind}\" == 'stable' ]]; then\n-    publish_files=(release/stable.txt release/stable-${version_major}.txt release/stable-${version_major}.${version_minor}.txt)\n-  else\n-    kube::log::error \"Wrong release_kind: must be 'latest' or 'stable'.\"\n-    return 1\n-  fi\n-\n-  for publish_file in ${publish_files[*]}; do\n-    # If there's a version that's above the one we're trying to release, don't\n-    # do anything, and just try the next one.\n-    kube::release::gcs::verify_release_gt \"${publish_file}\" || continue\n-    kube::release::gcs::publish \"${publish_file}\" || return 1\n-  done\n-}\n-\n-# Verify that the release files we expect actually exist.\n-#\n-# Globals:\n-#   KUBE_GCS_RELEASE_BUCKET\n-#   KUBE_GCS_RELEASE_PREFIX\n-# Arguments:\n-#   None\n-# Returns:\n-#   If release files exist\n-function kube::release::gcs::verify_release_files() {\n-  local -r release_dir=\"gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_RELEASE_PREFIX}\"\n-  if ! gsutil ls \"${release_dir}\" >/dev/null 2>&1 ; then\n-    kube::log::error \"Release files don't exist at '${release_dir}'\"\n-    return 1\n-  fi\n-}\n-\n-# Check if the new version is greater than the version currently published on\n-# GCS.\n-#\n-# Globals:\n-#   KUBE_GCS_PUBLISH_VERSION\n-#   KUBE_GCS_RELEASE_BUCKET\n-# Arguments:\n-#   publish_file: the GCS location to look in\n-# Returns:\n-#   If new version is greater than the GCS version\n-#\n-# TODO(16529): This should all be outside of build an in release, and should be\n-# refactored to reduce code duplication.  Also consider using strictly nested\n-# if and explicit handling of equals case.\n-function kube::release::gcs::verify_release_gt() {\n-  local -r publish_file=\"${1-}\"\n-  local -r new_version=${KUBE_GCS_PUBLISH_VERSION}\n-  local -r publish_file_dst=\"gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}\"\n-\n-  kube::release::parse_and_validate_release_version \"${new_version}\" || return 1\n-\n-  local -r version_major=\"${VERSION_MAJOR}\"\n-  local -r version_minor=\"${VERSION_MINOR}\"\n-  local -r version_patch=\"${VERSION_PATCH}\"\n-  local -r version_prerelease=\"${VERSION_PRERELEASE}\"\n-  local -r version_prerelease_rev=\"${VERSION_PRERELEASE_REV}\"\n-\n-  local gcs_version\n-  if gcs_version=\"$(gsutil cat \"${publish_file_dst}\")\"; then\n-    kube::release::parse_and_validate_release_version \"${gcs_version}\" || {\n-      kube::log::error \"${publish_file_dst} contains invalid release version, can't compare: '${gcs_version}'\"\n-      return 1\n-    }\n-\n-    local -r gcs_version_major=\"${VERSION_MAJOR}\"\n-    local -r gcs_version_minor=\"${VERSION_MINOR}\"\n-    local -r gcs_version_patch=\"${VERSION_PATCH}\"\n-    local -r gcs_version_prerelease=\"${VERSION_PRERELEASE}\"\n-    local -r gcs_version_prerelease_rev=\"${VERSION_PRERELEASE_REV}\"\n-\n-    local greater=true\n-    if [[ \"${version_major}\" -lt \"${gcs_version_major}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_major}\" -gt \"${gcs_version_major}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_minor}\" -lt \"${gcs_version_minor}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_minor}\" -gt \"${gcs_version_minor}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_patch}\" -lt \"${gcs_version_patch}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_patch}\" -gt \"${gcs_version_patch}\" ]]; then\n-      : # fall out\n-    # Use lexicographic (instead of integer) comparison because\n-    # version_prerelease is a string, (\"alpha\" or \"beta\",) but first check if\n-    # either is an official release (i.e. empty prerelease string).\n-    #\n-    # We have to do this because lexicographically \"beta\" > \"alpha\" > \"\", but\n-    # we want official > beta > alpha.\n-    elif [[ -n \"${version_prerelease}\" && -z \"${gcs_version_prerelease}\" ]]; then\n-      greater=false\n-    elif [[ -z \"${version_prerelease}\" && -n \"${gcs_version_prerelease}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_prerelease}\" < \"${gcs_version_prerelease}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_prerelease}\" > \"${gcs_version_prerelease}\" ]]; then\n-      : # fall out\n-    # Finally resort to -le here, since we want strictly-greater-than.\n-    elif [[ \"${version_prerelease_rev}\" -le \"${gcs_version_prerelease_rev}\" ]]; then\n-      greater=false\n-    fi\n-\n-    if [[ \"${greater}\" != \"true\" ]]; then\n-      kube::log::status \"${new_version} (just uploaded) <= ${gcs_version} (latest on GCS), not updating ${publish_file_dst}\"\n-      return 1\n-    else\n-      kube::log::status \"${new_version} (just uploaded) > ${gcs_version} (latest on GCS), updating ${publish_file_dst}\"\n-    fi\n-  else  # gsutil cat failed; file does not exist\n-    kube::log::error \"Release file '${publish_file_dst}' does not exist.  Continuing.\"\n-    return 0\n-  fi\n-}\n-\n-# Check if the new version is greater than or equal to the version currently\n-# published on GCS.  (Ignore the build; if it's different, overwrite anyway.)\n-#\n-# Globals:\n-#   KUBE_GCS_PUBLISH_VERSION\n-#   KUBE_GCS_RELEASE_BUCKET\n-# Arguments:\n-#   publish_file: the GCS location to look in\n-# Returns:\n-#   If new version is greater than the GCS version\n-#\n-# TODO(16529): This should all be outside of build an in release, and should be\n-# refactored to reduce code duplication.  Also consider using strictly nested\n-# if and explicit handling of equals case.\n-function kube::release::gcs::verify_ci_ge() {\n-  local -r publish_file=\"${1-}\"\n-  local -r new_version=${KUBE_GCS_PUBLISH_VERSION}\n-  local -r publish_file_dst=\"gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}\"\n-\n-  kube::release::parse_and_validate_ci_version \"${new_version}\" || return 1\n-\n-  local -r version_major=\"${VERSION_MAJOR}\"\n-  local -r version_minor=\"${VERSION_MINOR}\"\n-  local -r version_patch=\"${VERSION_PATCH}\"\n-  local -r version_prerelease=\"${VERSION_PRERELEASE}\"\n-  local -r version_prerelease_rev=\"${VERSION_PRERELEASE_REV}\"\n-  local -r version_commits=\"${VERSION_COMMITS}\"\n-\n-  local gcs_version\n-  if gcs_version=\"$(gsutil cat \"${publish_file_dst}\")\"; then\n-    kube::release::parse_and_validate_ci_version \"${gcs_version}\" || {\n-      kube::log::error \"${publish_file_dst} contains invalid ci version, can't compare: '${gcs_version}'\"\n-      return 1\n-    }\n-\n-    local -r gcs_version_major=\"${VERSION_MAJOR}\"\n-    local -r gcs_version_minor=\"${VERSION_MINOR}\"\n-    local -r gcs_version_patch=\"${VERSION_PATCH}\"\n-    local -r gcs_version_prerelease=\"${VERSION_PRERELEASE}\"\n-    local -r gcs_version_prerelease_rev=\"${VERSION_PRERELEASE_REV}\"\n-    local -r gcs_version_commits=\"${VERSION_COMMITS}\"\n-\n-    local greater=true\n-    if [[ \"${version_major}\" -lt \"${gcs_version_major}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_major}\" -gt \"${gcs_version_major}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_minor}\" -lt \"${gcs_version_minor}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_minor}\" -gt \"${gcs_version_minor}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_patch}\" -lt \"${gcs_version_patch}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_patch}\" -gt \"${gcs_version_patch}\" ]]; then\n-      : # fall out\n-    # Use lexicographic (instead of integer) comparison because\n-    # version_prerelease is a string, (\"alpha\" or \"beta\")\n-    elif [[ \"${version_prerelease}\" < \"${gcs_version_prerelease}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_prerelease}\" > \"${gcs_version_prerelease}\" ]]; then\n-      : # fall out\n-    elif [[ \"${version_prerelease_rev}\" -lt \"${gcs_version_prerelease_rev}\" ]]; then\n-      greater=false\n-    elif [[ \"${version_prerelease_rev}\" -gt \"${gcs_version_prerelease_rev}\" ]]; then\n-      : # fall out\n-    # If either version_commits is empty, it will be considered less-than, as\n-    # expected, (e.g. 1.2.3-beta < 1.2.3-beta.1).\n-    elif [[ \"${version_commits}\" -lt \"${gcs_version_commits}\" ]]; then\n-      greater=false\n-    fi\n-\n-    if [[ \"${greater}\" != \"true\" ]]; then\n-      kube::log::status \"${new_version} (just uploaded) < ${gcs_version} (latest on GCS), not updating ${publish_file_dst}\"\n-      return 1\n-    else\n-      kube::log::status \"${new_version} (just uploaded) >= ${gcs_version} (latest on GCS), updating ${publish_file_dst}\"\n-    fi\n-  else  # gsutil cat failed; file does not exist\n-    kube::log::error \"File '${publish_file_dst}' does not exist.  Continuing.\"\n-    return 0\n-  fi\n-}\n-\n-# Publish a release to GCS: upload a version file, if KUBE_GCS_MAKE_PUBLIC,\n-# make it public, and verify the result.\n-#\n-# Globals:\n-#   KUBE_GCS_RELEASE_BUCKET\n-#   RELEASE_STAGE\n-#   KUBE_GCS_PUBLISH_VERSION\n-#   KUBE_GCS_MAKE_PUBLIC\n-# Arguments:\n-#   publish_file: the GCS location to look in\n-# Returns:\n-#   If new version is greater than the GCS version\n-function kube::release::gcs::publish() {\n-  local -r publish_file=\"${1-}\"\n-\n-  kube::release::gcs::publish_to_bucket \"${KUBE_GCS_RELEASE_BUCKET}\" \"${publish_file}\" || return 1\n-\n-  if [[ -n \"${KUBE_GCS_RELEASE_BUCKET_MIRROR:-}\" ]] &&\n-     [[ \"${KUBE_GCS_RELEASE_BUCKET_MIRROR}\" != \"${KUBE_GCS_RELEASE_BUCKET}\" ]]; then\n-    kube::release::gcs::publish_to_bucket \"${KUBE_GCS_RELEASE_BUCKET_MIRROR}\" \"${publish_file}\" || return 1\n-  fi\n-}\n-\n-\n-function kube::release::gcs::publish_to_bucket() {\n-  local -r publish_bucket=\"${1}\"\n-  local -r publish_file=\"${2}\"\n-  local -r publish_file_dst=\"gs://${publish_bucket}/${publish_file}\"\n-\n-  mkdir -p \"${RELEASE_STAGE}/upload\" || return 1\n-  echo \"${KUBE_GCS_PUBLISH_VERSION}\" > \"${RELEASE_STAGE}/upload/latest\" || return 1\n-\n-  gsutil -m cp \"${RELEASE_STAGE}/upload/latest\" \"${publish_file_dst}\" || return 1\n-\n-  local contents\n-  if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then\n-    kube::log::status \"Making uploaded version file public and non-cacheable.\"\n-    gsutil acl ch -R -g all:R \"${publish_file_dst}\" >/dev/null 2>&1 || return 1\n-    gsutil setmeta -h \"Cache-Control:private, max-age=0\" \"${publish_file_dst}\" >/dev/null 2>&1 || return 1\n-    # If public, validate public link\n-    local -r public_link=\"https://storage.googleapis.com/${publish_bucket}/${publish_file}\"\n-    kube::log::status \"Validating uploaded version file at ${public_link}\"\n-    contents=\"$(curl -s \"${public_link}\")\"\n-  else\n-    # If not public, validate using gsutil\n-    kube::log::status \"Validating uploaded version file at ${publish_file_dst}\"\n-    contents=\"$(gsutil cat \"${publish_file_dst}\")\"\n-  fi\n-  if [[ \"${contents}\" == \"${KUBE_GCS_PUBLISH_VERSION}\" ]]; then\n-    kube::log::status \"Contents as expected: ${contents}\"\n-  else\n-    kube::log::error \"Expected contents of file to be ${KUBE_GCS_PUBLISH_VERSION}, but got ${contents}\"\n-    return 1\n-  fi\n-}\n-\n-# ---------------------------------------------------------------------------\n-# Docker Release\n-\n-# Releases all docker images to a docker registry specified by KUBE_DOCKER_REGISTRY\n-# using tag KUBE_DOCKER_IMAGE_TAG.\n-#\n-# Globals:\n-#   KUBE_DOCKER_REGISTRY\n-#   KUBE_DOCKER_IMAGE_TAG\n-#   KUBE_SERVER_PLATFORMS\n-# Returns:\n-#   If new pushing docker images was successful.\n-function kube::release::docker::release() {\n-  local binaries=(\n-    \"kube-apiserver\"\n-    \"kube-controller-manager\"\n-    \"kube-scheduler\"\n-    \"kube-proxy\"\n-    \"hyperkube\"\n-  )\n-\n-  local docker_push_cmd=(\"${DOCKER[@]}\")\n-  if [[ \"${KUBE_DOCKER_REGISTRY}\" == \"gcr.io/\"* ]]; then\n-    docker_push_cmd=(\"gcloud\" \"docker\")\n-  fi\n-\n-  if [[ \"${KUBE_DOCKER_REGISTRY}\" == \"gcr.io/google_containers\" ]]; then\n-    # Activate credentials for the k8s.production.user@gmail.com\n-    gcloud config set account k8s.production.user@gmail.com\n-  fi\n-\n-  for arch in \"${KUBE_SERVER_PLATFORMS[@]##*/}\"; do\n-    for binary in \"${binaries[@]}\"; do\n-\n-      # TODO(IBM): Enable hyperkube builds for ppc64le again\n-      if [[ ${binary} != \"hyperkube\" || ${arch} != \"ppc64le\" ]]; then\n-\n-        local docker_target=\"${KUBE_DOCKER_REGISTRY}/${binary}-${arch}:${KUBE_DOCKER_IMAGE_TAG}\"\n-        kube::log::status \"Pushing ${binary} to ${docker_target}\"\n-        \"${docker_push_cmd[@]}\" push \"${docker_target}\"\n-\n-        # If we have a amd64 docker image. Tag it without -amd64 also and push it for compatibility with earlier versions\n-        if [[ ${arch} == \"amd64\" ]]; then\n-          local legacy_docker_target=\"${KUBE_DOCKER_REGISTRY}/${binary}:${KUBE_DOCKER_IMAGE_TAG}\"\n-\n-          \"${DOCKER[@]}\" tag -f \"${docker_target}\" \"${legacy_docker_target}\" 2>/dev/null\n-\n-          kube::log::status \"Pushing ${binary} to ${legacy_docker_target}\"\n-          \"${docker_push_cmd[@]}\" push \"${legacy_docker_target}\"\n-        fi\n-      fi\n-    done\n-  done\n-  if [[ \"${KUBE_DOCKER_REGISTRY}\" == \"gcr.io/google_containers\" ]]; then\n-    # Activate default account\n-    gcloud config set account ${USER}@google.com\n-  fi\n-}\n-\n-function kube::release::gcloud_account_is_active() {\n-  local -r account=\"${1-}\"\n-  if [[ \"$(gcloud config list --format='value(core.account)')\" == \"${account}\" ]]; then\n-    return 0\n-  else\n-    return 1\n-  fi\n-}\n+###############################################################################\n+# The ::release:: namespace functions have been moved to","path":"build/common.sh","position":576,"original_position":576,"commit_id":"0cfb2548cbfdedf50eab002d461ceb3df8c4c9b2","original_commit_id":"0cfb2548cbfdedf50eab002d461ceb3df8c4c9b2","user":{"login":"ixdy","id":8061296,"avatar_url":"https://avatars.githubusercontent.com/u/8061296?v=3","gravatar_id":"","url":"https://api.github.com/users/ixdy","html_url":"https://github.com/ixdy","followers_url":"https://api.github.com/users/ixdy/followers","following_url":"https://api.github.com/users/ixdy/following{/other_user}","gists_url":"https://api.github.com/users/ixdy/gists{/gist_id}","starred_url":"https://api.github.com/users/ixdy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ixdy/subscriptions","organizations_url":"https://api.github.com/users/ixdy/orgs","repos_url":"https://api.github.com/users/ixdy/repos","events_url":"https://api.github.com/users/ixdy/events{/privacy}","received_events_url":"https://api.github.com/users/ixdy/received_events","type":"User","site_admin":false},"body":"they didn't all move (hence my comment) - maybe update this comment to note that the actual release functions have moved, but the packaging ones (related to build) remain.","created_at":"2016-09-09T22:46:30Z","updated_at":"2016-09-09T22:46:30Z","html_url":"https://github.com/kubernetes/kubernetes/pull/24629#discussion_r78260064","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/78260064"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/24629#discussion_r78260064"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629","id":67430319,"html_url":"https://github.com/kubernetes/kubernetes/pull/24629","diff_url":"https://github.com/kubernetes/kubernetes/pull/24629.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/24629.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/24629","number":24629,"state":"open","locked":false,"title":"Deprecate release infrastructure and doc - moved to kubernetes/release","user":{"login":"david-mcmahon","id":15622407,"avatar_url":"https://avatars.githubusercontent.com/u/15622407?v=3","gravatar_id":"","url":"https://api.github.com/users/david-mcmahon","html_url":"https://github.com/david-mcmahon","followers_url":"https://api.github.com/users/david-mcmahon/followers","following_url":"https://api.github.com/users/david-mcmahon/following{/other_user}","gists_url":"https://api.github.com/users/david-mcmahon/gists{/gist_id}","starred_url":"https://api.github.com/users/david-mcmahon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-mcmahon/subscriptions","organizations_url":"https://api.github.com/users/david-mcmahon/orgs","repos_url":"https://api.github.com/users/david-mcmahon/repos","events_url":"https://api.github.com/users/david-mcmahon/events{/privacy}","received_events_url":"https://api.github.com/users/david-mcmahon/received_events","type":"User","site_admin":false},"body":"Part 2 of https://github.com/kubernetes/release/pull/1\r\nThis PR finalizes the split between the main kubernetes repo and the release tooling now under kubernetes/release.\r\n\r\nref #16529\n\n<!-- Reviewable:start -->\n---\nThis change is [<img src=\"https://reviewable.kubernetes.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.kubernetes.io/reviews/kubernetes/kubernetes/24629)\n<!-- Reviewable:end -->\n","created_at":"2016-04-21T22:07:42Z","updated_at":"2016-09-09T22:46:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6000ff7c71553b5eeac79356869a83ff97d06b76","assignee":{"login":"spxtr","id":7368979,"avatar_url":"https://avatars.githubusercontent.com/u/7368979?v=3","gravatar_id":"","url":"https://api.github.com/users/spxtr","html_url":"https://github.com/spxtr","followers_url":"https://api.github.com/users/spxtr/followers","following_url":"https://api.github.com/users/spxtr/following{/other_user}","gists_url":"https://api.github.com/users/spxtr/gists{/gist_id}","starred_url":"https://api.github.com/users/spxtr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spxtr/subscriptions","organizations_url":"https://api.github.com/users/spxtr/orgs","repos_url":"https://api.github.com/users/spxtr/repos","events_url":"https://api.github.com/users/spxtr/events{/privacy}","received_events_url":"https://api.github.com/users/spxtr/received_events","type":"User","site_admin":false},"assignees":[{"login":"spxtr","id":7368979,"avatar_url":"https://avatars.githubusercontent.com/u/7368979?v=3","gravatar_id":"","url":"https://api.github.com/users/spxtr","html_url":"https://github.com/spxtr","followers_url":"https://api.github.com/users/spxtr/followers","following_url":"https://api.github.com/users/spxtr/following{/other_user}","gists_url":"https://api.github.com/users/spxtr/gists{/gist_id}","starred_url":"https://api.github.com/users/spxtr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spxtr/subscriptions","organizations_url":"https://api.github.com/users/spxtr/orgs","repos_url":"https://api.github.com/users/spxtr/repos","events_url":"https://api.github.com/users/spxtr/events{/privacy}","received_events_url":"https://api.github.com/users/spxtr/received_events","type":"User","site_admin":false},{"login":"ixdy","id":8061296,"avatar_url":"https://avatars.githubusercontent.com/u/8061296?v=3","gravatar_id":"","url":"https://api.github.com/users/ixdy","html_url":"https://github.com/ixdy","followers_url":"https://api.github.com/users/ixdy/followers","following_url":"https://api.github.com/users/ixdy/following{/other_user}","gists_url":"https://api.github.com/users/ixdy/gists{/gist_id}","starred_url":"https://api.github.com/users/ixdy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ixdy/subscriptions","organizations_url":"https://api.github.com/users/ixdy/orgs","repos_url":"https://api.github.com/users/ixdy/repos","events_url":"https://api.github.com/users/ixdy/events{/privacy}","received_events_url":"https://api.github.com/users/ixdy/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/24629/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/0cfb2548cbfdedf50eab002d461ceb3df8c4c9b2","head":{"label":"david-mcmahon:release-deprecation","ref":"release-deprecation","sha":"0cfb2548cbfdedf50eab002d461ceb3df8c4c9b2","user":{"login":"david-mcmahon","id":15622407,"avatar_url":"https://avatars.githubusercontent.com/u/15622407?v=3","gravatar_id":"","url":"https://api.github.com/users/david-mcmahon","html_url":"https://github.com/david-mcmahon","followers_url":"https://api.github.com/users/david-mcmahon/followers","following_url":"https://api.github.com/users/david-mcmahon/following{/other_user}","gists_url":"https://api.github.com/users/david-mcmahon/gists{/gist_id}","starred_url":"https://api.github.com/users/david-mcmahon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-mcmahon/subscriptions","organizations_url":"https://api.github.com/users/david-mcmahon/orgs","repos_url":"https://api.github.com/users/david-mcmahon/repos","events_url":"https://api.github.com/users/david-mcmahon/events{/privacy}","received_events_url":"https://api.github.com/users/david-mcmahon/received_events","type":"User","site_admin":false},"repo":{"id":49242094,"name":"kubernetes","full_name":"david-mcmahon/kubernetes","owner":{"login":"david-mcmahon","id":15622407,"avatar_url":"https://avatars.githubusercontent.com/u/15622407?v=3","gravatar_id":"","url":"https://api.github.com/users/david-mcmahon","html_url":"https://github.com/david-mcmahon","followers_url":"https://api.github.com/users/david-mcmahon/followers","following_url":"https://api.github.com/users/david-mcmahon/following{/other_user}","gists_url":"https://api.github.com/users/david-mcmahon/gists{/gist_id}","starred_url":"https://api.github.com/users/david-mcmahon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-mcmahon/subscriptions","organizations_url":"https://api.github.com/users/david-mcmahon/orgs","repos_url":"https://api.github.com/users/david-mcmahon/repos","events_url":"https://api.github.com/users/david-mcmahon/events{/privacy}","received_events_url":"https://api.github.com/users/david-mcmahon/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/david-mcmahon/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/david-mcmahon/kubernetes","forks_url":"https://api.github.com/repos/david-mcmahon/kubernetes/forks","keys_url":"https://api.github.com/repos/david-mcmahon/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/david-mcmahon/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/david-mcmahon/kubernetes/teams","hooks_url":"https://api.github.com/repos/david-mcmahon/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/david-mcmahon/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/david-mcmahon/kubernetes/events","assignees_url":"https://api.github.com/repos/david-mcmahon/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/david-mcmahon/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/david-mcmahon/kubernetes/tags","blobs_url":"https://api.github.com/repos/david-mcmahon/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/david-mcmahon/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/david-mcmahon/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/david-mcmahon/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/david-mcmahon/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/david-mcmahon/kubernetes/languages","stargazers_url":"https://api.github.com/repos/david-mcmahon/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/david-mcmahon/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/david-mcmahon/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/david-mcmahon/kubernetes/subscription","commits_url":"https://api.github.com/repos/david-mcmahon/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/david-mcmahon/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/david-mcmahon/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/david-mcmahon/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/david-mcmahon/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/david-mcmahon/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/david-mcmahon/kubernetes/merges","archive_url":"https://api.github.com/repos/david-mcmahon/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/david-mcmahon/kubernetes/downloads","issues_url":"https://api.github.com/repos/david-mcmahon/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/david-mcmahon/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/david-mcmahon/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/david-mcmahon/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/david-mcmahon/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/david-mcmahon/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/david-mcmahon/kubernetes/deployments","created_at":"2016-01-08T01:45:12Z","updated_at":"2016-07-21T21:10:08Z","pushed_at":"2016-09-08T22:27:18Z","git_url":"git://github.com/david-mcmahon/kubernetes.git","ssh_url":"git@github.com:david-mcmahon/kubernetes.git","clone_url":"https://github.com/david-mcmahon/kubernetes.git","svn_url":"https://github.com/david-mcmahon/kubernetes","homepage":"http://kubernetes.io","size":320149,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"0037b67cdf824bf928f7f40342d542941df5776f","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Production-Grade Container Scheduling and Management","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-09-09T22:34:52Z","pushed_at":"2016-09-09T22:36:39Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":560478,"stargazers_count":16669,"watchers_count":16669,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":5374,"mirror_url":null,"open_issues_count":4456,"forks":5374,"open_issues":4456,"watchers":16669,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/24629"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/24629"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/24629/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/24629/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/0cfb2548cbfdedf50eab002d461ceb3df8c4c9b2"}}}}
{"actor":{"display_login":"ixdy"}}