From 4e07b43d702784c73c3232a6c3ab0490c215af7e Mon Sep 17 00:00:00 2001 From: David McMahon Date: Thu, 14 Apr 2016 18:30:16 -0700 Subject: [PATCH] Deprecate kubernetes/kubenetes release infrastructure and doc. --- build/common.sh | 569 +---------------------------- build/make-release-notes.sh | 43 --- build/push-devel-build.sh | 34 -- build/push-official-release.sh | 59 --- docs/devel/README.md | 6 +- docs/devel/making-release-notes.md | 86 ----- docs/devel/releasing.md | 309 ---------------- release/OWNERS | 2 - release/build-official-release.sh | 143 -------- release/cut-official-release.sh | 335 ----------------- 10 files changed, 6 insertions(+), 1580 deletions(-) delete mode 100755 build/make-release-notes.sh delete mode 100755 build/push-devel-build.sh delete mode 100755 build/push-official-release.sh delete mode 100644 docs/devel/making-release-notes.md delete mode 100644 docs/devel/releasing.md delete mode 100644 release/OWNERS delete mode 100755 release/build-official-release.sh delete mode 100755 release/cut-official-release.sh diff --git a/build/common.sh b/build/common.sh index 51bc823c2f3..6929a38349e 100755 --- a/build/common.sh +++ b/build/common.sh @@ -409,36 +409,6 @@ function kube::build::destroy_container() { "${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true } -# Validate a release version -# -# Globals: -# None -# Arguments: -# version -# Returns: -# If version is a valid release version -# Sets: (e.g. for '1.2.3-alpha.4') -# VERSION_MAJOR (e.g. '1') -# VERSION_MINOR (e.g. '2') -# VERSION_PATCH (e.g. '3') -# VERSION_EXTRA (e.g. '-alpha.4') -# VERSION_PRERELEASE (e.g. 'alpha') -# VERSION_PRERELEASE_REV (e.g. '4') -function kube::release::parse_and_validate_release_version() { - local -r version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-(beta|alpha)\\.(0|[1-9][0-9]*))?$" - local -r version="${1-}" - [[ "${version}" =~ ${version_regex} ]] || { - kube::log::error "Invalid release version: '${version}', must match regex ${version_regex}" - return 1 - } - VERSION_MAJOR="${BASH_REMATCH[1]}" - VERSION_MINOR="${BASH_REMATCH[2]}" - VERSION_PATCH="${BASH_REMATCH[3]}" - VERSION_EXTRA="${BASH_REMATCH[4]}" - VERSION_PRERELEASE="${BASH_REMATCH[5]}" - VERSION_PRERELEASE_REV="${BASH_REMATCH[6]}" -} - # Validate a ci version # # Globals: @@ -1061,537 +1031,8 @@ function kube::release::create_tarball() { "${TAR}" czf "${tarfile}" -C "${stagingdir}" kubernetes --owner=0 --group=0 } -# --------------------------------------------------------------------------- -# GCS Release - -function kube::release::gcs::release() { - [[ ${KUBE_GCS_UPLOAD_RELEASE} =~ ^[yY]$ ]] || return 0 - - kube::release::gcs::verify_prereqs || return 1 - kube::release::gcs::ensure_release_bucket || return 1 - kube::release::gcs::copy_release_artifacts || return 1 -} - -# Verify things are set up for uploading to GCS -function kube::release::gcs::verify_prereqs() { - if [[ -z "$(which gsutil)" || -z "$(which gcloud)" ]]; then - echo "Releasing Kubernetes requires gsutil and gcloud. Please download," - echo "install and authorize through the Google Cloud SDK: " - echo - echo " https://developers.google.com/cloud/sdk/" - return 1 - fi - - if [[ -z "${GCLOUD_ACCOUNT-}" ]]; then - GCLOUD_ACCOUNT=$(gcloud config list --format='value(core.account)' 2>/dev/null) - fi - if [[ -z "${GCLOUD_ACCOUNT-}" ]]; then - echo "No account authorized through gcloud. Please fix with:" - echo - echo " gcloud auth login" - return 1 - fi - - if [[ -z "${GCLOUD_PROJECT-}" ]]; then - GCLOUD_PROJECT=$(gcloud config list --format='value(core.project)' 2>/dev/null) - fi - if [[ -z "${GCLOUD_PROJECT-}" ]]; then - echo "No account authorized through gcloud. Please fix with:" - echo - echo " gcloud config set project " - return 1 - fi -} - -# Create a unique bucket name for releasing Kube and make sure it exists. -function kube::release::gcs::ensure_release_bucket() { - local project_hash - project_hash=$(kube::build::short_hash "$GCLOUD_PROJECT") - KUBE_GCS_RELEASE_BUCKET=${KUBE_GCS_RELEASE_BUCKET-kubernetes-releases-${project_hash}} - - if ! gsutil ls "gs://${KUBE_GCS_RELEASE_BUCKET}" >/dev/null 2>&1 ; then - echo "Creating Google Cloud Storage bucket: $KUBE_GCS_RELEASE_BUCKET" - gsutil mb -p "${GCLOUD_PROJECT}" "gs://${KUBE_GCS_RELEASE_BUCKET}" || return 1 - fi -} - -function kube::release::gcs::stage_and_hash() { - kube::build::ensure_tar || return 1 - - # Split the args into srcs... and dst - local -r args=( "$@" ) - local -r split=$((${#args[@]}-1)) # Split point for src/dst args - local -r srcs=( "${args[@]::${split}}" ) - local -r dst="${args[${split}]}" - - for src in ${srcs[@]}; do - srcdir=$(dirname ${src}) - srcthing=$(basename ${src}) - mkdir -p ${GCS_STAGE}/${dst} || return 1 - "${TAR}" c -C ${srcdir} ${srcthing} | "${TAR}" x -C ${GCS_STAGE}/${dst} || return 1 - done -} - -function kube::release::gcs::copy_release_artifacts() { - # TODO: This isn't atomic. There will be points in time where there will be - # no active release. Also, if something fails, the release could be half- - # copied. The real way to do this would perhaps to have some sort of release - # version so that we are never overwriting a destination. - local -r gcs_destination="gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_RELEASE_PREFIX}" - - kube::log::status "Staging release artifacts to ${GCS_STAGE}" - - rm -rf ${GCS_STAGE} || return 1 - mkdir -p ${GCS_STAGE} || return 1 - - # Stage everything in release directory - kube::release::gcs::stage_and_hash "${RELEASE_DIR}"/* . || return 1 - - # Having the configure-vm.sh script and GCI code from the GCE cluster - # deploy hosted with the release is useful for GKE. - kube::release::gcs::stage_and_hash "${RELEASE_STAGE}/full/kubernetes/cluster/gce/configure-vm.sh" extra/gce || return 1 - kube::release::gcs::stage_and_hash "${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/node.yaml" extra/gce || return 1 - kube::release::gcs::stage_and_hash "${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/master.yaml" extra/gce || return 1 - kube::release::gcs::stage_and_hash "${RELEASE_STAGE}/full/kubernetes/cluster/gce/gci/configure.sh" extra/gce || return 1 - - # Upload the "naked" binaries to GCS. This is useful for install scripts that - # download the binaries directly and don't need tars. - local platform platforms - platforms=($(cd "${RELEASE_STAGE}/client" ; echo *)) - for platform in "${platforms[@]}"; do - local src="${RELEASE_STAGE}/client/${platform}/kubernetes/client/bin/*" - local dst="bin/${platform/-//}/" - # We assume here the "server package" is a superset of the "client package" - if [[ -d "${RELEASE_STAGE}/server/${platform}" ]]; then - src="${RELEASE_STAGE}/server/${platform}/kubernetes/server/bin/*" - fi - kube::release::gcs::stage_and_hash "$src" "$dst" || return 1 - done - - kube::log::status "Hashing files in ${GCS_STAGE}" - find ${GCS_STAGE} -type f | while read path; do - kube::release::md5 ${path} > "${path}.md5" || return 1 - kube::release::sha1 ${path} > "${path}.sha1" || return 1 - done - - kube::log::status "Copying release artifacts to ${gcs_destination}" - - # First delete all objects at the destination - if gsutil ls "${gcs_destination}" >/dev/null 2>&1; then - kube::log::error "${gcs_destination} not empty." - [[ ${KUBE_GCS_DELETE_EXISTING} =~ ^[yY]$ ]] || { - read -p "Delete everything under ${gcs_destination}? [y/n] " -r || { - kube::log::status "EOF on prompt. Skipping upload" - return - } - [[ $REPLY =~ ^[yY]$ ]] || { - kube::log::status "Skipping upload" - return - } - } - kube::log::status "Deleting everything under ${gcs_destination}" - gsutil -q -m rm -f -R "${gcs_destination}" || return 1 - fi - - local gcs_options=() - if [[ ${KUBE_GCS_NO_CACHING} =~ ^[yY]$ ]]; then - gcs_options=("-h" "Cache-Control:private, max-age=0") - fi - - gsutil -q -m "${gcs_options[@]+${gcs_options[@]}}" cp -r "${GCS_STAGE}"/* ${gcs_destination} || return 1 - - # TODO(jbeda): Generate an HTML page with links for this release so it is easy - # to see it. For extra credit, generate a dynamic page that builds up the - # release list using the GCS JSON API. Use Angular and Bootstrap for extra - # extra credit. - - if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then - kube::log::status "Marking all uploaded objects public" - gsutil -q -m acl ch -R -g all:R "${gcs_destination}" >/dev/null 2>&1 || return 1 - fi - - gsutil ls -lhr "${gcs_destination}" || return 1 - - if [[ -n "${KUBE_GCS_RELEASE_BUCKET_MIRROR:-}" ]] && - [[ "${KUBE_GCS_RELEASE_BUCKET_MIRROR}" != "${KUBE_GCS_RELEASE_BUCKET}" ]]; then - local -r gcs_mirror="gs://${KUBE_GCS_RELEASE_BUCKET_MIRROR}/${KUBE_GCS_RELEASE_PREFIX}" - kube::log::status "Mirroring build to ${gcs_mirror}" - gsutil -q -m "${gcs_options[@]+${gcs_options[@]}}" rsync -d -r "${gcs_destination}" "${gcs_mirror}" || return 1 - if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then - kube::log::status "Marking all uploaded mirror objects public" - gsutil -q -m acl ch -R -g all:R "${gcs_mirror}" >/dev/null 2>&1 || return 1 - fi - fi -} - -# Publish a new ci version, (latest,) but only if the release files actually -# exist on GCS. -# -# Globals: -# See callees -# Arguments: -# None -# Returns: -# Success -function kube::release::gcs::publish_ci() { - kube::release::gcs::verify_release_files || return 1 - - kube::release::parse_and_validate_ci_version "${KUBE_GCS_PUBLISH_VERSION}" || return 1 - local -r version_major="${VERSION_MAJOR}" - local -r version_minor="${VERSION_MINOR}" - - local -r publish_files=(ci/latest.txt ci/latest-${version_major}.txt ci/latest-${version_major}.${version_minor}.txt) - - for publish_file in ${publish_files[*]}; do - # If there's a version that's above the one we're trying to release, don't - # do anything, and just try the next one. - kube::release::gcs::verify_ci_ge "${publish_file}" || continue - kube::release::gcs::publish "${publish_file}" || return 1 - done -} - -# Publish a new official version, (latest or stable,) but only if the release -# files actually exist on GCS and the release we're dealing with is newer than -# the contents in GCS. -# -# Globals: -# KUBE_GCS_PUBLISH_VERSION -# See callees -# Arguments: -# release_kind: either 'latest' or 'stable' -# Returns: -# Success -function kube::release::gcs::publish_official() { - local -r release_kind="${1-}" - - kube::release::gcs::verify_release_files || return 1 - - kube::release::parse_and_validate_release_version "${KUBE_GCS_PUBLISH_VERSION}" || return 1 - local -r version_major="${VERSION_MAJOR}" - local -r version_minor="${VERSION_MINOR}" - - local publish_files - if [[ "${release_kind}" == 'latest' ]]; then - publish_files=(release/latest.txt release/latest-${version_major}.txt release/latest-${version_major}.${version_minor}.txt) - elif [[ "${release_kind}" == 'stable' ]]; then - publish_files=(release/stable.txt release/stable-${version_major}.txt release/stable-${version_major}.${version_minor}.txt) - else - kube::log::error "Wrong release_kind: must be 'latest' or 'stable'." - return 1 - fi - - for publish_file in ${publish_files[*]}; do - # If there's a version that's above the one we're trying to release, don't - # do anything, and just try the next one. - kube::release::gcs::verify_release_gt "${publish_file}" || continue - kube::release::gcs::publish "${publish_file}" || return 1 - done -} - -# Verify that the release files we expect actually exist. -# -# Globals: -# KUBE_GCS_RELEASE_BUCKET -# KUBE_GCS_RELEASE_PREFIX -# Arguments: -# None -# Returns: -# If release files exist -function kube::release::gcs::verify_release_files() { - local -r release_dir="gs://${KUBE_GCS_RELEASE_BUCKET}/${KUBE_GCS_RELEASE_PREFIX}" - if ! gsutil ls "${release_dir}" >/dev/null 2>&1 ; then - kube::log::error "Release files don't exist at '${release_dir}'" - return 1 - fi -} - -# Check if the new version is greater than the version currently published on -# GCS. -# -# Globals: -# KUBE_GCS_PUBLISH_VERSION -# KUBE_GCS_RELEASE_BUCKET -# Arguments: -# publish_file: the GCS location to look in -# Returns: -# If new version is greater than the GCS version -# -# TODO(16529): This should all be outside of build an in release, and should be -# refactored to reduce code duplication. Also consider using strictly nested -# if and explicit handling of equals case. -function kube::release::gcs::verify_release_gt() { - local -r publish_file="${1-}" - local -r new_version=${KUBE_GCS_PUBLISH_VERSION} - local -r publish_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}" - - kube::release::parse_and_validate_release_version "${new_version}" || return 1 - - local -r version_major="${VERSION_MAJOR}" - local -r version_minor="${VERSION_MINOR}" - local -r version_patch="${VERSION_PATCH}" - local -r version_prerelease="${VERSION_PRERELEASE}" - local -r version_prerelease_rev="${VERSION_PRERELEASE_REV}" - - local gcs_version - if gcs_version="$(gsutil cat "${publish_file_dst}")"; then - kube::release::parse_and_validate_release_version "${gcs_version}" || { - kube::log::error "${publish_file_dst} contains invalid release version, can't compare: '${gcs_version}'" - return 1 - } - - local -r gcs_version_major="${VERSION_MAJOR}" - local -r gcs_version_minor="${VERSION_MINOR}" - local -r gcs_version_patch="${VERSION_PATCH}" - local -r gcs_version_prerelease="${VERSION_PRERELEASE}" - local -r gcs_version_prerelease_rev="${VERSION_PRERELEASE_REV}" - - local greater=true - if [[ "${version_major}" -lt "${gcs_version_major}" ]]; then - greater=false - elif [[ "${version_major}" -gt "${gcs_version_major}" ]]; then - : # fall out - elif [[ "${version_minor}" -lt "${gcs_version_minor}" ]]; then - greater=false - elif [[ "${version_minor}" -gt "${gcs_version_minor}" ]]; then - : # fall out - elif [[ "${version_patch}" -lt "${gcs_version_patch}" ]]; then - greater=false - elif [[ "${version_patch}" -gt "${gcs_version_patch}" ]]; then - : # fall out - # Use lexicographic (instead of integer) comparison because - # version_prerelease is a string, ("alpha" or "beta",) but first check if - # either is an official release (i.e. empty prerelease string). - # - # We have to do this because lexicographically "beta" > "alpha" > "", but - # we want official > beta > alpha. - elif [[ -n "${version_prerelease}" && -z "${gcs_version_prerelease}" ]]; then - greater=false - elif [[ -z "${version_prerelease}" && -n "${gcs_version_prerelease}" ]]; then - : # fall out - elif [[ "${version_prerelease}" < "${gcs_version_prerelease}" ]]; then - greater=false - elif [[ "${version_prerelease}" > "${gcs_version_prerelease}" ]]; then - : # fall out - # Finally resort to -le here, since we want strictly-greater-than. - elif [[ "${version_prerelease_rev}" -le "${gcs_version_prerelease_rev}" ]]; then - greater=false - fi - - if [[ "${greater}" != "true" ]]; then - kube::log::status "${new_version} (just uploaded) <= ${gcs_version} (latest on GCS), not updating ${publish_file_dst}" - return 1 - else - kube::log::status "${new_version} (just uploaded) > ${gcs_version} (latest on GCS), updating ${publish_file_dst}" - fi - else # gsutil cat failed; file does not exist - kube::log::error "Release file '${publish_file_dst}' does not exist. Continuing." - return 0 - fi -} - -# Check if the new version is greater than or equal to the version currently -# published on GCS. (Ignore the build; if it's different, overwrite anyway.) -# -# Globals: -# KUBE_GCS_PUBLISH_VERSION -# KUBE_GCS_RELEASE_BUCKET -# Arguments: -# publish_file: the GCS location to look in -# Returns: -# If new version is greater than the GCS version -# -# TODO(16529): This should all be outside of build an in release, and should be -# refactored to reduce code duplication. Also consider using strictly nested -# if and explicit handling of equals case. -function kube::release::gcs::verify_ci_ge() { - local -r publish_file="${1-}" - local -r new_version=${KUBE_GCS_PUBLISH_VERSION} - local -r publish_file_dst="gs://${KUBE_GCS_RELEASE_BUCKET}/${publish_file}" - - kube::release::parse_and_validate_ci_version "${new_version}" || return 1 - - local -r version_major="${VERSION_MAJOR}" - local -r version_minor="${VERSION_MINOR}" - local -r version_patch="${VERSION_PATCH}" - local -r version_prerelease="${VERSION_PRERELEASE}" - local -r version_prerelease_rev="${VERSION_PRERELEASE_REV}" - local -r version_commits="${VERSION_COMMITS}" - - local gcs_version - if gcs_version="$(gsutil cat "${publish_file_dst}")"; then - kube::release::parse_and_validate_ci_version "${gcs_version}" || { - kube::log::error "${publish_file_dst} contains invalid ci version, can't compare: '${gcs_version}'" - return 1 - } - - local -r gcs_version_major="${VERSION_MAJOR}" - local -r gcs_version_minor="${VERSION_MINOR}" - local -r gcs_version_patch="${VERSION_PATCH}" - local -r gcs_version_prerelease="${VERSION_PRERELEASE}" - local -r gcs_version_prerelease_rev="${VERSION_PRERELEASE_REV}" - local -r gcs_version_commits="${VERSION_COMMITS}" - - local greater=true - if [[ "${version_major}" -lt "${gcs_version_major}" ]]; then - greater=false - elif [[ "${version_major}" -gt "${gcs_version_major}" ]]; then - : # fall out - elif [[ "${version_minor}" -lt "${gcs_version_minor}" ]]; then - greater=false - elif [[ "${version_minor}" -gt "${gcs_version_minor}" ]]; then - : # fall out - elif [[ "${version_patch}" -lt "${gcs_version_patch}" ]]; then - greater=false - elif [[ "${version_patch}" -gt "${gcs_version_patch}" ]]; then - : # fall out - # Use lexicographic (instead of integer) comparison because - # version_prerelease is a string, ("alpha" or "beta") - elif [[ "${version_prerelease}" < "${gcs_version_prerelease}" ]]; then - greater=false - elif [[ "${version_prerelease}" > "${gcs_version_prerelease}" ]]; then - : # fall out - elif [[ "${version_prerelease_rev}" -lt "${gcs_version_prerelease_rev}" ]]; then - greater=false - elif [[ "${version_prerelease_rev}" -gt "${gcs_version_prerelease_rev}" ]]; then - : # fall out - # If either version_commits is empty, it will be considered less-than, as - # expected, (e.g. 1.2.3-beta < 1.2.3-beta.1). - elif [[ "${version_commits}" -lt "${gcs_version_commits}" ]]; then - greater=false - fi - - if [[ "${greater}" != "true" ]]; then - kube::log::status "${new_version} (just uploaded) < ${gcs_version} (latest on GCS), not updating ${publish_file_dst}" - return 1 - else - kube::log::status "${new_version} (just uploaded) >= ${gcs_version} (latest on GCS), updating ${publish_file_dst}" - fi - else # gsutil cat failed; file does not exist - kube::log::error "File '${publish_file_dst}' does not exist. Continuing." - return 0 - fi -} - -# Publish a release to GCS: upload a version file, if KUBE_GCS_MAKE_PUBLIC, -# make it public, and verify the result. -# -# Globals: -# KUBE_GCS_RELEASE_BUCKET -# RELEASE_STAGE -# KUBE_GCS_PUBLISH_VERSION -# KUBE_GCS_MAKE_PUBLIC -# Arguments: -# publish_file: the GCS location to look in -# Returns: -# If new version is greater than the GCS version -function kube::release::gcs::publish() { - local -r publish_file="${1-}" - - kube::release::gcs::publish_to_bucket "${KUBE_GCS_RELEASE_BUCKET}" "${publish_file}" || return 1 - - if [[ -n "${KUBE_GCS_RELEASE_BUCKET_MIRROR:-}" ]] && - [[ "${KUBE_GCS_RELEASE_BUCKET_MIRROR}" != "${KUBE_GCS_RELEASE_BUCKET}" ]]; then - kube::release::gcs::publish_to_bucket "${KUBE_GCS_RELEASE_BUCKET_MIRROR}" "${publish_file}" || return 1 - fi -} - - -function kube::release::gcs::publish_to_bucket() { - local -r publish_bucket="${1}" - local -r publish_file="${2}" - local -r publish_file_dst="gs://${publish_bucket}/${publish_file}" - - mkdir -p "${RELEASE_STAGE}/upload" || return 1 - echo "${KUBE_GCS_PUBLISH_VERSION}" > "${RELEASE_STAGE}/upload/latest" || return 1 - - gsutil -m cp "${RELEASE_STAGE}/upload/latest" "${publish_file_dst}" || return 1 - - local contents - if [[ ${KUBE_GCS_MAKE_PUBLIC} =~ ^[yY]$ ]]; then - kube::log::status "Making uploaded version file public and non-cacheable." - gsutil acl ch -R -g all:R "${publish_file_dst}" >/dev/null 2>&1 || return 1 - gsutil setmeta -h "Cache-Control:private, max-age=0" "${publish_file_dst}" >/dev/null 2>&1 || return 1 - # If public, validate public link - local -r public_link="https://storage.googleapis.com/${publish_bucket}/${publish_file}" - kube::log::status "Validating uploaded version file at ${public_link}" - contents="$(curl -s "${public_link}")" - else - # If not public, validate using gsutil - kube::log::status "Validating uploaded version file at ${publish_file_dst}" - contents="$(gsutil cat "${publish_file_dst}")" - fi - if [[ "${contents}" == "${KUBE_GCS_PUBLISH_VERSION}" ]]; then - kube::log::status "Contents as expected: ${contents}" - else - kube::log::error "Expected contents of file to be ${KUBE_GCS_PUBLISH_VERSION}, but got ${contents}" - return 1 - fi -} - -# --------------------------------------------------------------------------- -# Docker Release - -# Releases all docker images to a docker registry specified by KUBE_DOCKER_REGISTRY -# using tag KUBE_DOCKER_IMAGE_TAG. -# -# Globals: -# KUBE_DOCKER_REGISTRY -# KUBE_DOCKER_IMAGE_TAG -# KUBE_SERVER_PLATFORMS -# Returns: -# If new pushing docker images was successful. -function kube::release::docker::release() { - local binaries=( - "kube-apiserver" - "kube-controller-manager" - "kube-scheduler" - "kube-proxy" - "hyperkube" - ) - - local docker_push_cmd=("${DOCKER[@]}") - if [[ "${KUBE_DOCKER_REGISTRY}" == "gcr.io/"* ]]; then - docker_push_cmd=("gcloud" "docker") - fi - - if [[ "${KUBE_DOCKER_REGISTRY}" == "gcr.io/google_containers" ]]; then - # Activate credentials for the k8s.production.user@gmail.com - gcloud config set account k8s.production.user@gmail.com - fi - - for arch in "${KUBE_SERVER_PLATFORMS[@]##*/}"; do - for binary in "${binaries[@]}"; do - - # TODO(IBM): Enable hyperkube builds for ppc64le again - if [[ ${binary} != "hyperkube" || ${arch} != "ppc64le" ]]; then - - local docker_target="${KUBE_DOCKER_REGISTRY}/${binary}-${arch}:${KUBE_DOCKER_IMAGE_TAG}" - kube::log::status "Pushing ${binary} to ${docker_target}" - "${docker_push_cmd[@]}" push "${docker_target}" - - # If we have a amd64 docker image. Tag it without -amd64 also and push it for compatibility with earlier versions - if [[ ${arch} == "amd64" ]]; then - local legacy_docker_target="${KUBE_DOCKER_REGISTRY}/${binary}:${KUBE_DOCKER_IMAGE_TAG}" - - "${DOCKER[@]}" tag -f "${docker_target}" "${legacy_docker_target}" 2>/dev/null - - kube::log::status "Pushing ${binary} to ${legacy_docker_target}" - "${docker_push_cmd[@]}" push "${legacy_docker_target}" - fi - fi - done - done - if [[ "${KUBE_DOCKER_REGISTRY}" == "gcr.io/google_containers" ]]; then - # Activate default account - gcloud config set account ${USER}@google.com - fi -} - -function kube::release::gcloud_account_is_active() { - local -r account="${1-}" - if [[ "$(gcloud config list --format='value(core.account)')" == "${account}" ]]; then - return 0 - else - return 1 - fi -} +############################################################################### +# Most of the ::release:: namespace functions have been moved to +# github.com/kubernetes/release. Have a look in that repo and specifically in +# lib/releaselib.sh for ::release::-related functionality. +############################################################################### diff --git a/build/make-release-notes.sh b/build/make-release-notes.sh deleted file mode 100755 index 23355579d06..00000000000 --- a/build/make-release-notes.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Clean out the output directory on the docker host. -set -o errexit -set -o nounset -set -o pipefail - -function pop_dir { - popd > /dev/null -} - -KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. -source "${KUBE_ROOT}/hack/lib/init.sh" - -if [[ -z "${1:-}" ]]; then - echo "Usage: ${0} --api-token=$TOKEN [opts]" - echo "To create a GitHub API token, see https://github.com/settings/tokens" - exit 1 -fi - -pushd . > /dev/null -trap 'pop_dir' INT TERM EXIT - -kube::golang::build_binaries contrib/release-notes -kube::golang::place_bins -echo "Fetching release notes" -releasenotes=$(kube::util::find-binary "release-notes") -"${releasenotes}" --last-release-pr=${1} --current-release-pr=${2} ${@} - diff --git a/build/push-devel-build.sh b/build/push-devel-build.sh deleted file mode 100755 index 244f0071a81..00000000000 --- a/build/push-devel-build.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Pushes a development build to a directory in your current project, -# pushing to something like: -# gs://kubernetes-releases-3fda2/devel/v0.8.0-437-g7f147ed/ - -set -o errexit -set -o nounset -set -o pipefail - -LATEST=$(git describe) -KUBE_GCS_NO_CACHING=n -KUBE_GCS_MAKE_PUBLIC=y -KUBE_GCS_UPLOAD_RELEASE=y -KUBE_GCS_RELEASE_PREFIX="devel/${LATEST}" - -KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. -source "${KUBE_ROOT}/build/common.sh" - -kube::release::gcs::release diff --git a/build/push-official-release.sh b/build/push-official-release.sh deleted file mode 100755 index f3b91993735..00000000000 --- a/build/push-official-release.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# Copyright 2014 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Pushes an official release to our official release location - -set -o errexit -set -o nounset -set -o pipefail - -if [[ "$#" -lt 1 ]]; then - echo "Usage: ${0} []" - echo "( defaults to 'latest')" - exit 1 -fi - -KUBE_RELEASE_VERSION="${1-}" -KUBE_RELEASE_TYPE="${2:-"latest"}" - -KUBE_GCS_NO_CACHING='n' -KUBE_GCS_MAKE_PUBLIC='y' -KUBE_GCS_UPLOAD_RELEASE='y' -KUBE_GCS_RELEASE_BUCKET='kubernetes-release' -KUBE_GCS_RELEASE_PREFIX="release/${KUBE_RELEASE_VERSION}" -KUBE_GCS_PUBLISH_VERSION="${KUBE_RELEASE_VERSION}" - -KUBE_DOCKER_REGISTRY="gcr.io/google_containers" -KUBE_DOCKER_IMAGE_TAG="${KUBE_RELEASE_VERSION}" -KUBE_GCLOUD_PRODUCTION_ACCOUNT="k8s.production.user@gmail.com" - -KUBE_ROOT="$(dirname "${BASH_SOURCE}")/.." -source "${KUBE_ROOT}/build/common.sh" - -if "${KUBE_ROOT}/cluster/kubectl.sh" 'version' | grep 'Client' | grep 'dirty'; then - echo "!!! Tag at invalid point, or something else is bad. Build is dirty. Don't push this build." >&2 - exit 1 -fi - -if ! kube::release::gcloud_account_is_active "${KUBE_GCLOUD_PRODUCTION_ACCOUNT}"; then - kube::log::error "Pushing images to gcr.io/google_containers requires being logged in as ${KUBE_GCLOUD_PRODUCTION_ACCOUNT}" - return 1 -fi - -kube::release::parse_and_validate_release_version "${KUBE_RELEASE_VERSION}" -kube::release::gcs::release -kube::release::docker::release -kube::release::gcs::publish_official $KUBE_RELEASE_TYPE diff --git a/docs/devel/README.md b/docs/devel/README.md index bf28c603594..c77aa2db85f 100644 --- a/docs/devel/README.md +++ b/docs/devel/README.md @@ -110,11 +110,7 @@ Guide](../admin/README.md). ## Building releases -* **Making release notes** ([making-release-notes.md](making-release-notes.md)): Generating release notes for a new release. - -* **Releasing Kubernetes** ([releasing.md](releasing.md)): How to create a Kubernetes release (as in version) - and how the version information gets embedded into the built binaries. - +See the [kubernetes/release](https://github.com/kubernetes/release) repository for details on creating releases and related tools and helper scripts. [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/README.md?pixel)]() diff --git a/docs/devel/making-release-notes.md b/docs/devel/making-release-notes.md deleted file mode 100644 index bc51f22cd22..00000000000 --- a/docs/devel/making-release-notes.md +++ /dev/null @@ -1,86 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

PLEASE NOTE: This document applies to the HEAD of the source tree

- -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - - -The latest release of this document can be found -[here](http://releases.k8s.io/release-1.4/docs/devel/making-release-notes.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -## Making release notes - -This documents the process for making release notes for a release. - -### 1) Note the PR number of the previous release - -Find the most-recent PR that was merged with the previous .0 release. Remember -this as $LASTPR. - -- _TODO_: Figure out a way to record this somewhere to save the next -release engineer time. - -Find the most-recent PR that was merged with the current .0 release. Remember -this as $CURRENTPR. - -### 2) Run the release-notes tool - -```bash -${KUBERNETES_ROOT}/build/make-release-notes.sh $LASTPR $CURRENTPR -``` - -### 3) Trim the release notes - -This generates a list of the entire set of PRs merged since the last minor -release. It is likely long and many PRs aren't worth mentioning. If any of the -PRs were cherrypicked into patches on the last minor release, you should exclude -them from the current release's notes. - -Open up `candidate-notes.md` in your favorite editor. - -Remove, regroup, organize to your hearts content. - - -### 4) Update CHANGELOG.md - -With the final markdown all set, cut and paste it to the top of `CHANGELOG.md` - -### 5) Update the Release page - - * Switch to the [releases](https://github.com/kubernetes/kubernetes/releases) -page. - - * Open up the release you are working on. - - * Cut and paste the final markdown from above into the release notes - - * Press Save. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/making-release-notes.md?pixel)]() - diff --git a/docs/devel/releasing.md b/docs/devel/releasing.md deleted file mode 100644 index 72dad8b517f..00000000000 --- a/docs/devel/releasing.md +++ /dev/null @@ -1,309 +0,0 @@ - - - - -WARNING -WARNING -WARNING -WARNING -WARNING - -

PLEASE NOTE: This document applies to the HEAD of the source tree

- -If you are using a released version of Kubernetes, you should -refer to the docs that go with that version. - - - -The latest release of this document can be found -[here](http://releases.k8s.io/release-1.4/docs/devel/releasing.md). - -Documentation for other releases can be found at -[releases.k8s.io](http://releases.k8s.io). - --- - - - - - -# Releasing Kubernetes - -This document explains how to cut a release, and the theory behind it. If you -just want to cut a release and move on with your life, you can stop reading -after the first section. - -## How to cut a Kubernetes release - -Regardless of whether you are cutting a major or minor version, cutting a -release breaks down into four pieces: - -1. selecting release components; -1. cutting/branching the release; -1. building and pushing the binaries; and -1. publishing binaries and release notes. -1. updating the master branch. - -You should progress in this strict order. - -### Selecting release components - -First, figure out what kind of release you're doing, what branch you're cutting -from, and other prerequisites. - -* Alpha releases (`vX.Y.0-alpha.W`) are cut directly from `master`. - * Alpha releases don't require anything besides green tests, (see below). -* Beta releases (`vX.Y.Z-beta.W`) are cut from their respective release branch, - `release-X.Y`. - * Make sure all necessary cherry picks have been resolved. You should ensure - that all outstanding cherry picks have been reviewed and merged and the - branch validated on Jenkins. See [Cherry Picks](cherry-picks.md) for more - information on how to manage cherry picks prior to cutting the release. - * Beta releases also require green tests, (see below). -* Official releases (`vX.Y.Z`) are cut from their respective release branch, - `release-X.Y`. - * Official releases should be similar or identical to their respective beta - releases, so have a look at the cherry picks that have been merged since - the beta release and question everything you find. - * Official releases also require green tests, (see below). -* New release series are also cut directly from `master`. - * **This is a big deal!** If you're reading this doc for the first time, you - probably shouldn't be doing this release, and should talk to someone on the - release team. - * New release series cut a new release branch, `release-X.Y`, off of - `master`, and also release the first beta in the series, `vX.Y.0-beta.0`. - * Every change in the `vX.Y` series from this point on will have to be - cherry picked, so be sure you want to do this before proceeding. - * You should still look for green tests, (see below). - -No matter what you're cutting, you're going to want to look at -[Jenkins](http://kubekins.dls.corp.google.com/) (Google internal only). Figure -out what branch you're cutting from, (see above,) and look at the critical jobs -building from that branch. First glance through builds and look for nice solid -rows of green builds, and then check temporally with the other critical builds -to make sure they're solid around then as well. - -If you're doing an alpha release or cutting a new release series, you can -choose an arbitrary build. If you are doing an official release, you have to -release from HEAD of the branch, (because you have to do some version-rev -commits,) so choose the latest build on the release branch. (Remember, that -branch should be frozen.) - -Once you find some greens, you can find the build hash for a build by looking at -the Full Console Output and searching for `build_version=`. You should see a line: - -```console -build_version=v1.2.0-alpha.2.164+b44c7d79d6c9bb -``` - -Or, if you're cutting from a release branch (i.e. doing an official release), - -```console -build_version=v1.1.0-beta.567+d79d6c9bbb44c7 -``` - -Please note that `build_version` was called `githash` versions prior to v1.2. - -Because Jenkins builds frequently, if you're looking between jobs -(e.g. `kubernetes-e2e-gke-ci` and `kubernetes-e2e-gce`), there may be no single -`build_version` that's been run on both jobs. In that case, take the a green -`kubernetes-e2e-gce` build (but please check that it corresponds to a temporally -similar build that's green on `kubernetes-e2e-gke-ci`). Lastly, if you're having -trouble understanding why the GKE continuous integration clusters are failing -and you're trying to cut a release, don't hesitate to contact the GKE -oncall. - -Before proceeding to the next step: - -```sh -export BUILD_VERSION=v1.2.0-alpha.2.164+b44c7d79d6c9bb -``` - -Where `v1.2.0-alpha.2.164+b44c7d79d6c9bb` is the build hash you decided on. This -will become your release point. - -### Cutting/branching the release - -You'll need the latest version of the releasing tools: - -```console -git clone git@github.com:kubernetes/kubernetes.git -cd kubernetes -``` - -or `git fetch upstream && git checkout upstream/master` from an existing repo. - -Decide what version you're cutting and export it: - -- alpha release: `export RELEASE_VERSION="vX.Y.0-alpha.W"`; -- beta release: `export RELEASE_VERSION="vX.Y.Z-beta.W"`; -- official release: `export RELEASE_VERSION="vX.Y.Z"`; -- new release series: `export RELEASE_VERSION="vX.Y"`. - -Then, run - -```console -./release/cut-official-release.sh "${RELEASE_VERSION}" "${BUILD_VERSION}" -``` - -This will do a dry run of the release. It will give you instructions at the -end for `pushd`ing into the dry-run directory and having a look around. -`pushd` into the directory and make sure everything looks as you expect: - -```console -git log "${RELEASE_VERSION}" # do you see the commit you expect? -make release -./cluster/kubectl.sh version -c -``` - -If you're satisfied with the result of the script, go back to `upstream/master` -run - -```console -./release/cut-official-release.sh "${RELEASE_VERSION}" "${BUILD_VERSION}" --no-dry-run -``` - -and follow the instructions. - -### Publishing binaries and release notes - -Only publish a beta release if it's a standalone pre-release (*not* -vX.Y.Z-beta.0). We create beta tags after we do official releases to -maintain proper semantic versioning, but we don't publish these beta releases. - -The script you ran above will prompt you to take any remaining steps to push -tars, and will also give you a template for the release notes. Compose an -email to the team with the template. Figure out what the PR numbers for this -release and last release are, and get an api-token from GitHub -(https://github.com/settings/tokens). From a clone of -[kubernetes/contrib](https://github.com/kubernetes/contrib), - -``` -go run release-notes/release-notes.go --last-release-pr= --current-release-pr= --api-token= --base= -``` - -where `` is `master` for alpha releases and `release-X.Y` for beta and official releases. - -**If this is a first official release (vX.Y.0)**, look through the release -notes for all of the alpha releases since the last cycle, and include anything -important in release notes. - -Feel free to edit the notes, (e.g. cherry picks should generally just have the -same title as the original PR). - -Send the email out, letting people know these are the draft release notes. If -they want to change anything, they should update the appropriate PRs with the -`release-note` label. - -When you're ready to announce the release, [create a GitHub -release](https://github.com/kubernetes/kubernetes/releases/new): - -1. pick the appropriate tag; -1. check "This is a pre-release" if it's an alpha or beta release; -1. fill in the release title from the draft; -1. re-run the appropriate release notes tool(s) to pick up any changes people - have made; -1. find the appropriate `kubernetes.tar.gz` in [GCS bucket](https://console.developers.google.com/storage/browser/kubernetes-release/release/), - download it, double check the hash (compare to what you had in the release - notes draft), and attach it to the release; and -1. publish! - -### Manual tasks for new release series - -*TODO(#20946) Burn this list down.* - -If you are cutting a new release series, there are a few tasks that haven't yet -been automated that need to happen after the branch has been cut: - -1. Update the master branch constant for doc generation: change the - `latestReleaseBranch` in `cmd/mungedocs/mungedocs.go` to the new release - branch (`release-X.Y`), run `hack/update-generated-docs.sh`. This will let - the unversioned warning in docs point to the latest release series. Please - send the changes as a PR titled "Update the latestReleaseBranch to - release-X.Y in the munger". -1. Send a note to the test team (@kubernetes/goog-testing) that a new branch - has been created. - 1. There is currently much work being done on our Jenkins infrastructure - and configs. Eventually we could have a relatively simple interface - to make this change or a way to automatically use the new branch. - See [recent Issue #22672](https://github.com/kubernetes/kubernetes/issues/22672). - 1. You can provide this guidance in the email to aid in the setup: - 1. See [End-2-End Testing in Kubernetes](e2e-tests.md) for the test jobs - that should be running in CI, which are under version control in - `hack/jenkins/e2e.sh` (on the release branch) and - `hack/jenkins/job-configs/kubernetes-jenkins/kubernetes-e2e.yaml` - (in `master`). You'll want to munge these for the release - branch so that, as we cherry-pick fixes onto the branch, we know that - it builds, etc. (Talk with @ihmccreery for more details.) - 1. Make sure all features that are supposed to be GA are covered by tests, - but remove feature tests on the release branch for features that aren't - GA. You can use `hack/list-feature-tests.sh` to see a list of tests - labeled as `[Feature:.+]`; make sure that these are all either - covered in CI jobs on the release branch or are experimental - features. (The answer should already be 'yes', but this is a - good time to reconcile.) - 1. Make a dashboard in Jenkins that contains all of the jobs for this - release cycle, and also add them to Critical Builds. (Don't add - them to the merge-bot blockers; see kubernetes/contrib#156.) - - -## Injecting Version into Binaries - -*Please note that this information may be out of date. The scripts are the -authoritative source on how version injection works.* - -Kubernetes may be built from either a git tree or from a tarball. We use -`make` to encapsulate a number of build steps into a single command. This -includes generating code, which means that tools like `go build` might work -(once files are generated) but might be using stale generated code. `make` is -the supported way to build. - -When building from git, we want to be able to insert specific information about -the build tree at build time. In particular, we want to use the output of `git -describe` to generate the version of Kubernetes and the status of the build -tree (add a `-dirty` prefix if the tree was modified.) - -When building from a tarball or using the Go build system, we will not have -access to the information about the git tree, but we still want to be able to -tell whether this build corresponds to an exact release (e.g. v0.3) or is -between releases (e.g. at some point in development between v0.3 and v0.4). - -In order to cover the different build cases, we start by providing information -that can be used when using only Go build tools or when we do not have the git -version information available. - -To be able to provide a meaningful version in those cases, we set the contents -of variables in a Go source file that will be used when no overrides are -present. - -We are using `pkg/version/base.go` as the source of versioning in absence of -information from git. Here is a sample of that file's contents: - -```go -var ( - gitVersion string = "v0.4-dev" // version from git, output of $(git describe) - gitCommit string = "" // sha1 from git, output of $(git rev-parse HEAD) -) -``` - -This means a build with `go install` or `go get` or a build from a tarball will -yield binaries that will identify themselves as `v0.4-dev` and will not be able -to provide you with a SHA1. - -To add the extra versioning information when building from git, the -`make` build will gather that information (using `git describe` and -`git rev-parse`) and then create a `-ldflags` string to pass to `go install` and -tell the Go linker to override the contents of those variables at build time. It -can, for instance, tell it to override `gitVersion` and set it to -`v0.4-13-g4567bcdef6789-dirty` and set `gitCommit` to `4567bcdef6789...` which -is the complete SHA1 of the (dirty) tree used at build time. - - - -[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/releasing.md?pixel)]() - diff --git a/release/OWNERS b/release/OWNERS deleted file mode 100644 index beec2797361..00000000000 --- a/release/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -assignees: - - ihmccreery diff --git a/release/build-official-release.sh b/release/build-official-release.sh deleted file mode 100755 index 8577352e80f..00000000000 --- a/release/build-official-release.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Builds an official release based on a git tag, with instructions for -# how to proceed after the bits are built. - -set -o errexit -set -o nounset -set -o pipefail - -# Get the md5 (duplicated from common.sh, but don't want to pull in -# all of common.sh here) -function md5() { - if which md5 >/dev/null 2>&1; then - md5 -q "$1" - else - md5sum "$1" | awk '{ print $1 }' - fi -} - -# Get the sha1 (duplicated from common.sh, but don't want to pull in -# all of common.sh here) -function sha1() { - if which shasum >/dev/null 2>&1; then - shasum -a1 "$1" | awk '{ print $1 }' - else - sha1sum "$1" | awk '{ print $1 }' - fi -} - -declare -r KUBE_GITHUB="https://github.com/kubernetes/kubernetes.git" -declare -r KUBE_RELEASE_VERSION=${1-} -declare -r TMPDIR=${TMPDIR:-"/tmp"} -declare -r KUBE_RELEASE_UMASK=${KUBE_RELEASE_UMASK:-022} - -VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-(beta|alpha)\\.(0|[1-9][0-9]*))?$" -[[ ${KUBE_RELEASE_VERSION} =~ ${VERSION_REGEX} ]] || { - echo "!!! You must specify the version you are releasing in the form of '${VERSION_REGEX}'" >&2 - exit 1 -} -VERSION_MAJOR="${BASH_REMATCH[1]}" -VERSION_MINOR="${BASH_REMATCH[2]}" -if [[ "$KUBE_RELEASE_VERSION" =~ "alpha" ]]; then - # We don't want to version docs for alpha releases, so we are just pointing to head. - RELEASE_BRANCH="master" -else - RELEASE_BRANCH="release-${VERSION_MAJOR}.${VERSION_MINOR}" -fi - -if [[ "$KUBE_RELEASE_VERSION" =~ alpha|beta ]]; then - KUBE_RELEASE_TYPE="latest" -else - KUBE_RELEASE_TYPE="stable" -fi - -declare -r KUBE_BUILD_DIR=$(mktemp -d "${TMPDIR}/kubernetes-build-release-${KUBE_RELEASE_VERSION}-XXXXXXX") - -# Set the default umask for the release. This ensures consistency -# across our release builds. -umask "${KUBE_RELEASE_UMASK}" - -echo "Cloning ${KUBE_GITHUB} at ${KUBE_RELEASE_VERSION}." -echo -echo "NOTE: Ignore the deatched HEAD warning you're about to get. We want that." -echo -git clone ${KUBE_GITHUB} -b "${KUBE_RELEASE_VERSION}" "${KUBE_BUILD_DIR}" - -# !!! REMINDER !!! -# -# Past this point, you are dealing with a different release. Don't -# assume you're executing code from the same repo as this script is -# running in. This needs to be a version agnostic build. - -echo -echo "Cloned, building release." -echo - -cd "${KUBE_BUILD_DIR}" - -export KUBE_RELEASE_RUN_TESTS=n -export KUBE_SKIP_CONFIRMATIONS=y -# In order to build docker images for a release and tag them appropriately we need -# to set these two variables. -export KUBE_DOCKER_REGISTRY="gcr.io/google_containers" -export KUBE_DOCKER_IMAGE_TAG="${KUBE_RELEASE_VERSION}" - -make release - -if ${KUBE_BUILD_DIR}/cluster/kubectl.sh version | grep Client | grep dirty; then - echo "!!! Tag at invalid point, or something else is bad. Build is dirty. Don't push this build." >&2 - exit 1 -fi - -ln -s ${KUBE_BUILD_DIR}/_output/release-tars/kubernetes.tar.gz ${KUBE_BUILD_DIR} - -MD5=$(md5 "${KUBE_BUILD_DIR}/kubernetes.tar.gz") -SHA1=$(sha1 "${KUBE_BUILD_DIR}/kubernetes.tar.gz") - -cat <<- EOM - -Success! You must now do the following (you may want to cut and paste these -instructions elsewhere): - - 1) pushd ${KUBE_BUILD_DIR}; build/push-official-release.sh ${KUBE_RELEASE_VERSION} ${KUBE_RELEASE_TYPE} - - 2) Release notes draft, to be published when the release is announced: - - a) Title: - - Release ${KUBE_RELEASE_VERSION} - - b) Template for the description: - -## [Documentation](http://releases.k8s.io/${RELEASE_BRANCH}/docs/README.md) -## [Examples](http://releases.k8s.io/${RELEASE_BRANCH}/examples) -## Changes since (last PR ) - - - -binary | hash alg | hash ------- | -------- | ---- -\`kubernetes.tar.gz\` | md5 | \`${MD5}\` -\`kubernetes.tar.gz\` | sha1 | \`${SHA1}\` - - 3) Ensure all the binaries are in place on GCS before cleaning, (you might - want to wait until the release is announced and published on GitHub, too). - - 4) make clean; popd; rm -rf ${KUBE_BUILD_DIR} - -EOM diff --git a/release/cut-official-release.sh b/release/cut-official-release.sh deleted file mode 100755 index f1225606542..00000000000 --- a/release/cut-official-release.sh +++ /dev/null @@ -1,335 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script automates the release processes for all pre-releases and official -# releases for Kubernetes. See docs/devel/releasing.md for more info. - -set -o errexit -set -o nounset -set -o pipefail - -# Sets DIR, INSTRUCTIONS -function main() { - # Parse arguments - if [[ "$#" -ne 2 && "$#" -ne 3 ]]; then - usage - exit 1 - fi - local -r new_version=${1-} - local -r build_version=${2-} - DRY_RUN=true - if [[ "${3-}" == "--no-dry-run" ]]; then - echo "!!! This NOT is a dry run." - DRY_RUN=false - else - echo "This is a dry run." - fi - - check-prereqs - - # Get and verify version info - local -r alpha_version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.0-alpha\\.([1-9][0-9]*)$" - local -r beta_version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-beta\\.([1-9][0-9]*)$" - local -r official_version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" - local -r series_version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" - if [[ "${new_version}" =~ $alpha_version_regex ]]; then - local -r release_type='alpha' - local -r version_major="${BASH_REMATCH[1]}" - local -r version_minor="${BASH_REMATCH[2]}" - local -r version_alpha_rev="${BASH_REMATCH[3]}" - elif [[ "${new_version}" =~ $beta_version_regex ]]; then - local -r release_type='beta' - local -r version_major="${BASH_REMATCH[1]}" - local -r version_minor="${BASH_REMATCH[2]}" - local -r version_patch="${BASH_REMATCH[3]}" - local -r version_beta_rev="${BASH_REMATCH[4]}" - elif [[ "${new_version}" =~ $official_version_regex ]]; then - local -r release_type='official' - local -r version_major="${BASH_REMATCH[1]}" - local -r version_minor="${BASH_REMATCH[2]}" - local -r version_patch="${BASH_REMATCH[3]}" - elif [[ "${new_version}" =~ $series_version_regex ]]; then - local -r release_type='series' - local -r version_major="${BASH_REMATCH[1]}" - local -r version_minor="${BASH_REMATCH[2]}" - else - usage - echo - echo "!!! You specified an invalid version '${new_version}'." - exit 1 - fi - - # Get the git commit from the build_version and verify it - local -r git_commit_regex="^[0-9a-f]{7}$" - local -r git_commit=$(echo "${build_version}" | awk -F'+' '{print $2}' | head -c7) - if ! [[ "${git_commit}" =~ $git_commit_regex ]]; then - usage - echo - echo "!!! You specified an invalid build_version '${build_version}'." - echo "!!! Tried to extract commit, got ${git_commit}." - exit 1 - fi - echo "Doing ${release_type} release '${new_version}'." - - # Set the default umask for the release. This ensures consistency - # across our release builds. - # - # TODO(ihmccreery): This should be in our build process, not our release - # process. - local -r release_umask=${release_umask:-022} - umask "${release_umask}" - - declare -r TMPDIR=${TMPDIR:-"/tmp"} - local -r github="https://github.com/kubernetes/kubernetes.git" - declare -r DIR=$(mktemp -d "${TMPDIR}/kubernetes-${release_type}-release-${new_version}-XXXXXXX") - - # Start a tmp file that will hold instructions for the user. - declare -r INSTRUCTIONS=$(mktemp "${TMPDIR}/kubernetes-${release_type}-release-${new_version}-instructions-XXXXXXX") - if $DRY_RUN; then - cat > "${INSTRUCTIONS}" <<- EOM -Success on dry run! Do - - pushd ${DIR} - -to see what happened. - -You would now do the following, if not a dry run: - -EOM - else - cat > "${INSTRUCTIONS}" <<- EOM -Success! You must now do the following (you may want to cut and paste these -instructions elsewhere): - -EOM - fi - - echo "Cloning from '${github}'..." - git clone "${github}" "${DIR}" - - # !!! REMINDER !!! - # - # Past this point, you are dealing with a different clone of the repo at some - # version. Don't assume you're executing code from the same repo as this script - # is running in. This is a version agnostic process. - pushd "${DIR}" - - if [[ "${release_type}" == 'alpha' ]]; then - local -r ancestor="v${version_major}.${version_minor}.0-alpha.$((${version_alpha_rev}-1))" - - git checkout "${git_commit}" - verify-at-git-commit "${git_commit}" - verify-ancestor "${ancestor}" - - alpha-release "${new_version}" - elif [[ "${release_type}" == 'beta' ]]; then - local -r release_branch="release-${version_major}.${version_minor}" - local -r ancestor="v${version_major}.${version_minor}.${version_patch}-beta.$((${version_beta_rev}-1))" - - git checkout "${release_branch}" - verify-at-git-commit "${git_commit}" - verify-ancestor "${ancestor}" - - beta-release "${new_version}" - - git-push ${release_branch} - elif [[ "${release_type}" == 'official' ]]; then - local -r release_branch="release-${version_major}.${version_minor}" - local -r beta_version="v${version_major}.${version_minor}.$((${version_patch}+1))-beta.0" - local -r ancestor="${new_version}-beta.0" - - git checkout "${release_branch}" - verify-at-git-commit "${git_commit}" - verify-ancestor "${ancestor}" - - official-release "${new_version}" - beta-release "${beta_version}" - - git-push ${release_branch} - else # [[ "${release_type}" == 'series' ]] - local -r release_branch="release-${version_major}.${version_minor}" - local -r alpha_version="v${version_major}.$((${version_minor}+1)).0-alpha.0" - local -r beta_version="v${version_major}.${version_minor}.0-beta.0" - # NOTE: We check the second alpha version, ...-alpha.1, because ...-alpha.0 - # is the branch point for the previous release cycle, so could provide a - # false positive if we accidentally try to release off of the old release - # branch. - local -r ancestor="v${version_major}.${version_minor}.0-alpha.1" - - git checkout "${git_commit}" - verify-at-git-commit "${git_commit}" - verify-ancestor "${ancestor}" - - alpha-release "${alpha_version}" - - echo "Branching ${release_branch}." - git checkout -b "${release_branch}" - versionize-docs-and-commit "${release_branch}" - - beta-release "${beta_version}" - - git-push ${release_branch} - fi - - echo - cat "${INSTRUCTIONS}" -} - -function usage() { - echo "Usage: ${0} [--no-dry-run]" - echo - echo " is the version you want to release," - echo " is the version of the build you want to mark as ." - echo "Please see docs/devel/releasing.md for more info." -} - -function check-prereqs() { - SED=sed - if which gsed &>/dev/null; then - SED=gsed - fi - if ! ($SED --version 2>&1 | grep -q GNU); then - echo "!!! GNU sed is required. If on OS X, use 'brew install gnu-sed'." - exit 1 - fi -} - -function alpha-release() { - local -r alpha_version="${1}" - - echo "Doing an alpha release of ${alpha_version}." - - echo "Tagging ${alpha_version} at $(current-git-commit)." - git tag -a -m "Kubernetes pre-release ${alpha_version}" "${alpha_version}" - git-push "${alpha_version}" - - cat >> "${INSTRUCTIONS}" <<- EOM -- Finish the ${alpha_version} release build: from this directory (clone of - upstream/master), - ./release/build-official-release.sh ${alpha_version} -EOM -} - -function beta-release() { - local -r beta_version="${1}" - - echo "Doing a beta release of ${beta_version}." - - rev-version-and-commit "${beta_version}" - - echo "Tagging ${beta_version} at $(current-git-commit)." - git tag -a -m "Kubernetes pre-release ${beta_version}" "${beta_version}" - git-push "${beta_version}" - - cat >> "${INSTRUCTIONS}" <<- EOM -- Finish the ${beta_version} release build: from this directory (clone of - upstream/master), - ./release/build-official-release.sh ${beta_version} -EOM -} - -function official-release() { - local -r official_version="${1}" - - echo "Doing an official release of ${official_version}." - - rev-version-and-commit "${official_version}" - - echo "Tagging ${official_version} at $(current-git-commit)." - git tag -a -m "Kubernetes release ${official_version}" "${official_version}" - git-push "${official_version}" - - cat >> "${INSTRUCTIONS}" <<- EOM -- Finish the ${official_version} release build: from this directory (clone of - upstream/master), - ./release/build-official-release.sh ${official_version} -EOM -} - -function verify-at-git-commit() { - local -r git_commit="${1}" - echo "Verifying we are at ${git_commit}." - if [[ $(current-git-commit) != ${git_commit} ]]; then - cat <<- EOM -!!! We are not at commit ${git_commit}! (If you're cutting a beta or official -release, that probably means your release branch isn't frozen, so the commit -you want to release isn't at HEAD of the release branch.)" -EOM - exit 1 - fi -} - -function current-git-commit() { - git rev-parse --short HEAD -} - -function verify-ancestor() { - local -r ancestor="${1}" - # Check to make sure the previous version is an ancestor. - echo "Checking that previous version '${ancestor}' is an ancestor." - if ! git merge-base --is-ancestor "${ancestor}" HEAD; then - echo "!!! Previous version '${ancestor}' is not an ancestor!" - exit 1 - fi -} - -function versionize-docs-and-commit() { - local -r release_branch="${1}" - echo "Versionizing docs for ${release_branch} and committing." - # NOTE: This is using versionize-docs.sh at the release point. - ./build/versionize-docs.sh ${release_branch} - git commit -am "Versioning docs and examples for ${release_branch}." -} - -function rev-version-and-commit() { - local -r version="${1}" - local -r version_file="pkg/version/base.go" - - local -r version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-beta\\.(0|[1-9][0-9]*))?$" - if [[ "${version}" =~ $version_regex ]]; then - local -r version_major="${BASH_REMATCH[1]}" - # We append a '+' to the minor version on a beta build per hack/lib/version.sh's logic. - if [[ -z "${BASH_REMATCH[4]}" ]]; then - local -r version_minor="${BASH_REMATCH[2]}" - else - local -r version_minor="${BASH_REMATCH[2]}+" - fi - else - echo "!!! Something went wrong. Tried to rev version to invalid version; should not have gotten to this point." - exit 1 - fi - - echo "Updating ${version_file} to ${version}" - $SED -ri -e "s/gitMajor\s+string = \"[^\"]*\"/gitMajor string = \"${version_major}\"/" "${version_file}" - $SED -ri -e "s/gitMinor\s+string = \"[^\"]*\"/gitMinor string = \"${version_minor}\"/" "${version_file}" - $SED -ri -e "s/gitVersion\s+string = \"[^\"]*\"/gitVersion string = \"${version}+\$Format:%h\$\"/" "${version_file}" - gofmt -s -w "${version_file}" - - echo "Committing version change ${version}" - git add "${version_file}" - git commit -m "Kubernetes version ${version}" -} - -function git-push() { - local -r object="${1}" - if $DRY_RUN; then - echo "Dry run: would have done git push origin ${object}" - else - git push origin "${object}" - fi -} - -main "$@"