mirror of https://github.com/k3s-io/k3s
commit
1407fd2071
|
@ -1,153 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Bumps the version number by creating a couple of commits.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: ${0} <version>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||
|
||||
NEW_VERSION=${1-}
|
||||
|
||||
fetch_url=$(git remote -v | grep kubernetes/kubernetes.git | grep fetch | awk '{ print $2 }')
|
||||
if ! push_url=$(git remote -v | grep kubernetes/kubernetes.git | grep push | awk '{ print $2 }'); then
|
||||
push_url="https://github.com/kubernetes/kubernetes.git"
|
||||
fi
|
||||
fetch_remote=$(git remote -v | grep kubernetes/kubernetes.git | grep fetch | awk '{ print $1 }')
|
||||
|
||||
VERSION_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
|
||||
[[ ${NEW_VERSION} =~ $VERSION_REGEX ]] || {
|
||||
echo "!!! You must specify the version in the form of '$VERSION_REGEX'" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
VERSION_MAJOR="${BASH_REMATCH[1]}"
|
||||
VERSION_MINOR="${BASH_REMATCH[2]}"
|
||||
VERSION_PATCH="${BASH_REMATCH[3]}"
|
||||
|
||||
if ! git diff HEAD --quiet; then
|
||||
echo "!!! You must not have any uncommitted changes when running this command"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git diff-files --quiet pkg/version/base.go; then
|
||||
echo "!!! You have changes in 'pkg/version/base.go' already."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release_branch="release-${VERSION_MAJOR}.${VERSION_MINOR}"
|
||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
head_commit=$(git rev-parse --short HEAD)
|
||||
|
||||
if [[ "${VERSION_PATCH}" != "0" ]]; then
|
||||
# sorry, no going back in time, pull latest from upstream
|
||||
git remote update > /dev/null 2>&1
|
||||
|
||||
if git ls-remote --tags --exit-code ${fetch_url} refs/tags/${NEW_VERSION} > /dev/null; then
|
||||
echo "!!! You are trying to tag ${NEW_VERSION} but it already exists. Stop it!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
last_version="v${VERSION_MAJOR}.${VERSION_MINOR}.$((VERSION_PATCH-1))"
|
||||
if ! git ls-remote --tags --exit-code ${fetch_url} refs/tags/${last_version} > /dev/null; then
|
||||
echo "!!! You are trying to tag ${NEW_VERSION} but ${last_version} doesn't even exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# this is rather magic. This checks that HEAD is a descendant of the github branch release-x.y
|
||||
branches=$(git branch --contains $(git ls-remote --heads ${fetch_url} refs/heads/${release_branch} | cut -f1) ${current_branch})
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "!!! git failed, I dunno...."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${branches} != "* ${current_branch}" ]]; then
|
||||
echo "!!! You are trying to tag to an existing minor release but branch: ${release_branch} is not an ancestor of ${current_branch}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
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'."
|
||||
fi
|
||||
|
||||
echo "+++ Running ./versionize-docs"
|
||||
# Links in docs should always point to the release branch.
|
||||
${KUBE_ROOT}/build/versionize-docs.sh ${release_branch}
|
||||
git commit -am "Versioning docs and examples to ${release_branch}"
|
||||
|
||||
VERSION_FILE="${KUBE_ROOT}/pkg/version/base.go"
|
||||
|
||||
GIT_MINOR="${VERSION_MINOR}.${VERSION_PATCH}"
|
||||
echo "+++ Updating to ${NEW_VERSION}"
|
||||
$SED -ri -e "s/gitMajor\s+string = \"[^\"]*\"/gitMajor string = \"${VERSION_MAJOR}\"/" "${VERSION_FILE}"
|
||||
$SED -ri -e "s/gitMinor\s+string = \"[^\"]*\"/gitMinor string = \"${GIT_MINOR}\"/" "${VERSION_FILE}"
|
||||
$SED -ri -e "s/gitVersion\s+string = \"[^\"]*\"/gitVersion string = \"$NEW_VERSION-${release_branch}+\$Format:%h\$\"/" "${VERSION_FILE}"
|
||||
gofmt -s -w "${VERSION_FILE}"
|
||||
|
||||
echo "+++ Committing version change"
|
||||
git add "${VERSION_FILE}"
|
||||
git commit -m "Kubernetes version ${NEW_VERSION}"
|
||||
|
||||
echo "+++ Tagging version"
|
||||
git tag -a -m "Kubernetes version ${NEW_VERSION}" "${NEW_VERSION}"
|
||||
# We have to sleep for a bit so that the timestamp of the beta tag is after the
|
||||
# timestamp of the release version, so that future commits are described as
|
||||
# beta, and not release versions.
|
||||
echo "+++ Waiting for 5 seconds to ensure timestamps are different before continuing"
|
||||
sleep 5
|
||||
echo "+++ Tagging beta tag"
|
||||
declare -r beta_ver="v${VERSION_MAJOR}.${VERSION_MINOR}.$((${VERSION_PATCH}+1))-beta"
|
||||
git tag -a -m "Kubernetes version ${beta_ver}" "${beta_ver}"
|
||||
newtag=$(git rev-parse --short HEAD)
|
||||
|
||||
if [[ "${VERSION_PATCH}" == "0" ]]; then
|
||||
declare -r alpha_ver="v${VERSION_MAJOR}.$((${VERSION_MINOR}+1)).0-alpha.0"
|
||||
git tag -a -m "Kubernetes pre-release branch ${alpha_ver}" "${alpha_ver}" "${head_commit}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Success you must now:"
|
||||
echo ""
|
||||
echo "- Push the tags:"
|
||||
echo " git push ${push_url} ${NEW_VERSION}"
|
||||
echo " git push ${push_url} ${beta_ver}"
|
||||
|
||||
if [[ "${VERSION_PATCH}" == "0" ]]; then
|
||||
echo "- Push the alpha tag:"
|
||||
echo " git push ${push_url} ${alpha_ver}"
|
||||
echo "- Push the new release branch:"
|
||||
echo " git push ${push_url} ${current_branch}:${release_branch}"
|
||||
echo "- DO NOTHING TO MASTER. You were done with master when you pushed the alpha tag."
|
||||
else
|
||||
echo "- Send branch: ${current_branch} as a PR to ${release_branch} <-- NOTE THIS"
|
||||
echo "- In the contents of the PR, include the PRs in the release:"
|
||||
echo " hack/cherry_pick_list.sh ${current_branch}^1"
|
||||
echo " This helps cross-link PRs to patch releases they're part of in GitHub."
|
||||
echo "- Have someone review the PR. This is a mechanical review to ensure it contains"
|
||||
echo " the ${NEW_VERSION} commit, which was tagged at ${newtag}."
|
||||
fi
|
|
@ -35,23 +35,26 @@ Documentation for other releases can be found at
|
|||
|
||||
Legend:
|
||||
|
||||
* **Kube <major>.<minor>.<patch>** refers to the version of Kubernetes that is released. This versions all components: apiserver, kubelet, kubectl, etc.
|
||||
* **Kube X.Y.Z** refers to the version of Kubernetes that is released. This versions all components: apiserver, kubelet, kubectl, etc. (**X** is the major version, **Y** is the minor version, and **Z** is the patch version.)
|
||||
* **API vX[betaY]** refers to the version of the HTTP API.
|
||||
|
||||
## Release Timeline
|
||||
## Release versioning
|
||||
|
||||
### Minor version scheme and timeline
|
||||
|
||||
* Kube 1.0.0, 1.0.1 -- DONE!
|
||||
* Kube 1.0.X (X>1): Standard operating procedure. We patch the release-1.0 branch as needed and increment the patch number.
|
||||
* Kube 1.1.0-alpha.X: Released roughly every two weeks by cutting from HEAD. No cherrypick releases. If there is a critical bugfix, a new release from HEAD can be created ahead of schedule.
|
||||
* Kube 1.1.0-beta: When HEAD is feature-complete, we will cut the release-1.1.0 branch 2 weeks prior to the desired 1.1.0 date and only merge PRs essential to 1.1. This cut will be marked as 1.1.0-beta, and HEAD will be revved to 1.2.0-alpha.0.
|
||||
* Kube 1.1.0: Final release, cut from the release-1.1.0 branch cut two weeks prior. Should occur between 3 and 4 months after 1.0. 1.1.1-beta will be tagged at the same time on the same branch.
|
||||
* Kube X.Y.0-alpha.W, W > 0: Alpha releases are released roughly every two weeks directly from the master branch. No cherrypick releases. If there is a critical bugfix, a new release from master can be created ahead of schedule.
|
||||
* Kube X.Y.Z-beta.W: When master is feature-complete for Kube X.Y, we will cut the release-X.Y branch 2 weeks prior to the desired X.Y.0 date and cherrypick only PRs essential to X.Y. This cut will be marked as X.Y.0-beta.0, and master will be revved to X.Y+1.0-alpha.0. If we're not satisfied with X.Y.0-beta.0, we'll release other beta releases, (X.Y.0-beta.W | W > 0) as necessary.
|
||||
* Kube X.Y.0: Final release, cut from the release-X.Y branch cut two weeks prior. X.Y.1-beta.0 will be tagged at the same commit on the same branch. X.Y.0 occur 3 to 4 months after X.Y-1.0.
|
||||
* Kube X.Y.Z, Z > 0: [Patch releases](#patches) are released as we cherrypick commits into the release-X.Y branch, (which is at X.Y.Z-beta.W,) as needed. X.Y.Z is cut straight from the release-X.Y branch, and X.Y.Z+1-beta.0 is tagged on the same commit.
|
||||
|
||||
### Major version timeline
|
||||
|
||||
There is no mandated timeline for major versions. They only occur when we need to start the clock on deprecating features. A given major version should be the latest major version for at least one year from its original release date.
|
||||
|
||||
### CI and dev version scheme
|
||||
|
||||
* Continuous integration versions also exist, and are versioned off of alpha and beta releases. X.Y.Z-alpha.W.C+aaaa is C commits after X.Y.Z-alpha.W, with an additional +aaaa build suffix added; X.Y.Z-beta.W.C+bbbb is C commits after X.Y.Z-beta.W, with an additional +bbbb build suffix added. Furthermore, builds that are built off of a dirty build tree, (during development, with things in the tree that are not checked it,) it will be appended with -dirty.
|
||||
|
||||
## Release versions as related to API versions
|
||||
|
||||
Here is an example major release cycle:
|
||||
|
@ -64,11 +67,11 @@ Here is an example major release cycle:
|
|||
* Before Kube 2.0 is cut, API v2 must be released in 1.x. This enables two things: (1) users can upgrade to API v2 when running Kube 1.x and then switch over to Kube 2.x transparently, and (2) in the Kube 2.0 release itself we can cleanup and remove all API v2beta\* versions because no one should have v2beta\* objects left in their database. As mentioned above, tooling will exist to make sure there are no calls or references to a given API version anywhere inside someone's kube installation before someone upgrades.
|
||||
* Kube 2.0 must include the v1 API, but Kube 3.0 must include the v2 API only. It *may* include the v1 API as well if the burden is not high - this will be determined on a per-major-version basis.
|
||||
|
||||
## Rationale for API v2 being complete before v2.0's release
|
||||
### Rationale for API v2 being complete before v2.0's release
|
||||
|
||||
It may seem a bit strange to complete the v2 API before v2.0 is released, but *adding* a v2 API is not a breaking change. *Removing* the v2beta\* APIs *is* a breaking change, which is what necessitates the major version bump. There are other ways to do this, but having the major release be the fresh start of that release's API without the baggage of its beta versions seems most intuitive out of the available options.
|
||||
|
||||
# Patches
|
||||
## Patches
|
||||
|
||||
Patch releases are intended for critical bug fixes to the latest minor version, such as addressing security vulnerabilities, fixes to problems affecting a large number of users, severe problems with no workaround, and blockers for products based on Kubernetes.
|
||||
|
||||
|
@ -76,7 +79,7 @@ They should not contain miscellaneous feature additions or improvements, and esp
|
|||
|
||||
Dependencies, such as Docker or Etcd, should also not be changed unless absolutely necessary, and also just to fix critical bugs (so, at most patch version changes, not new major nor minor versions).
|
||||
|
||||
# Upgrades
|
||||
## Upgrades
|
||||
|
||||
* Users can upgrade from any Kube 1.x release to any other Kube 1.x release as a rolling upgrade across their cluster. (Rolling upgrade means being able to upgrade the master first, then one node at a time. See #4855 for details.)
|
||||
* No hard breaking changes over version boundaries.
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
// Build it with:
|
||||
// $ dot -Tsvg releasing.dot >releasing.svg
|
||||
|
||||
digraph tagged_release {
|
||||
size = "5,5"
|
||||
// Arrows go up.
|
||||
rankdir = BT
|
||||
subgraph left {
|
||||
// Group the left nodes together.
|
||||
ci012abc -> pr101 -> ci345cde -> pr102
|
||||
style = invis
|
||||
}
|
||||
subgraph right {
|
||||
// Group the right nodes together.
|
||||
version_commit -> dev_commit
|
||||
style = invis
|
||||
}
|
||||
{ // Align the version commit and the info about it.
|
||||
rank = same
|
||||
// Align them with pr101
|
||||
pr101
|
||||
version_commit
|
||||
// release_info shows the change in the commit.
|
||||
release_info
|
||||
}
|
||||
{ // Align the dev commit and the info about it.
|
||||
rank = same
|
||||
// Align them with 345cde
|
||||
ci345cde
|
||||
dev_commit
|
||||
dev_info
|
||||
}
|
||||
// Join the nodes from subgraph left.
|
||||
pr99 -> ci012abc
|
||||
pr102 -> pr100
|
||||
// Do the version node.
|
||||
pr99 -> version_commit
|
||||
dev_commit -> pr100
|
||||
tag -> version_commit
|
||||
pr99 [
|
||||
label = "Merge PR #99"
|
||||
shape = box
|
||||
fillcolor = "#ccccff"
|
||||
style = "filled"
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
ci012abc [
|
||||
label = "012abc"
|
||||
shape = circle
|
||||
fillcolor = "#ffffcc"
|
||||
style = "filled"
|
||||
fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace"
|
||||
];
|
||||
pr101 [
|
||||
label = "Merge PR #101"
|
||||
shape = box
|
||||
fillcolor = "#ccccff"
|
||||
style = "filled"
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
ci345cde [
|
||||
label = "345cde"
|
||||
shape = circle
|
||||
fillcolor = "#ffffcc"
|
||||
style = "filled"
|
||||
fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace"
|
||||
];
|
||||
pr102 [
|
||||
label = "Merge PR #102"
|
||||
shape = box
|
||||
fillcolor = "#ccccff"
|
||||
style = "filled"
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
version_commit [
|
||||
label = "678fed"
|
||||
shape = circle
|
||||
fillcolor = "#ccffcc"
|
||||
style = "filled"
|
||||
fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace"
|
||||
];
|
||||
dev_commit [
|
||||
label = "456dcb"
|
||||
shape = circle
|
||||
fillcolor = "#ffffcc"
|
||||
style = "filled"
|
||||
fontname = "Consolas, Liberation Mono, Menlo, Courier, monospace"
|
||||
];
|
||||
pr100 [
|
||||
label = "Merge PR #100"
|
||||
shape = box
|
||||
fillcolor = "#ccccff"
|
||||
style = "filled"
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
release_info [
|
||||
label = "pkg/version/base.go:\ngitVersion = \"v0.5\";"
|
||||
shape = none
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
dev_info [
|
||||
label = "pkg/version/base.go:\ngitVersion = \"v0.5-dev\";"
|
||||
shape = none
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
tag [
|
||||
label = "$ git tag -a v0.5"
|
||||
fillcolor = "#ffcccc"
|
||||
style = "filled"
|
||||
fontname = "Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif"
|
||||
];
|
||||
}
|
||||
|
|
@ -42,31 +42,67 @@ after the first section.
|
|||
Regardless of whether you are cutting a major or minor version, cutting a
|
||||
release breaks down into four pieces:
|
||||
|
||||
1. Selecting release components.
|
||||
1. Tagging and merging the release in Git.
|
||||
1. Building and pushing the binaries.
|
||||
1. Writing release notes.
|
||||
1. selecting release components;
|
||||
1. cutting/branching the release;
|
||||
1. building and pushing the binaries; and
|
||||
1. publishing binaries and release notes.
|
||||
|
||||
You should progress in this strict order.
|
||||
|
||||
### Building a New Major/Minor Version (`vX.Y.0`)
|
||||
### Selecting release components
|
||||
|
||||
#### Selecting Release Components
|
||||
First, figure out what kind of release you're doing, what branch you're cutting
|
||||
from, and other prerequisites.
|
||||
|
||||
When cutting a major/minor release, your first job is to find the branch
|
||||
point. We cut `vX.Y.0` releases directly from `master`, which is also the
|
||||
branch that we have most continuous validation on. Go first to [the main GCE
|
||||
Jenkins end-to-end job](http://go/k8s-test/job/kubernetes-e2e-gce) and next to [the
|
||||
Critical Builds page](http://go/k8s-test/view/Critical%20Builds) and hopefully find a
|
||||
recent Git hash that looks stable across at least `kubernetes-e2e-gce` and
|
||||
`kubernetes-e2e-gke-ci`. 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. Once you find some greens, you
|
||||
can find the Git hash for a build by looking at the "Console Log", then look for
|
||||
`githash=`. You should see a line line:
|
||||
* 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://go/k8s-test/). 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 git hash for a build by looking at
|
||||
the Full Console Output and searching for `githash=`. You should see a line:
|
||||
|
||||
```console
|
||||
+ githash=v0.20.2-322-g974377b
|
||||
githash=v1.2.0-alpha.2.164+b44c7d79d6c9bb
|
||||
```
|
||||
|
||||
Or, if you're cutting from a release branch (i.e. doing an official release),
|
||||
|
||||
```console
|
||||
githash=v1.1.0-beta.567+d79d6c9bbb44c7
|
||||
```
|
||||
|
||||
Because Jenkins builds frequently, if you're looking between jobs
|
||||
|
@ -81,101 +117,156 @@ oncall.
|
|||
Before proceeding to the next step:
|
||||
|
||||
```sh
|
||||
export BRANCHPOINT=v0.20.2-322-g974377b
|
||||
export GITHASH=v1.2.0-alpha.2.164+b44c7d79d6c9bb
|
||||
```
|
||||
|
||||
Where `v0.20.2-322-g974377b` is the git hash you decided on. This will become
|
||||
our (retroactive) branch point.
|
||||
Where `v1.2.0-alpha.2.164+b44c7d79d6c9bb` is the git hash you decided on. This
|
||||
will become your release point.
|
||||
|
||||
#### Branching, Tagging and Merging
|
||||
### Cutting/branching the release
|
||||
|
||||
Do the following:
|
||||
You'll need the latest version of the releasing tools:
|
||||
|
||||
1. `export VER=x.y` (e.g. `0.20` for v0.20)
|
||||
1. cd to the base of the repo
|
||||
1. `git fetch upstream && git checkout -b release-${VER} ${BRANCHPOINT}` (you did set `${BRANCHPOINT}`, right?)
|
||||
1. Make sure you don't have any files you care about littering your repo (they
|
||||
better be checked in or outside the repo, or the next step will delete them).
|
||||
1. `make clean && git reset --hard HEAD && git clean -xdf`
|
||||
1. `make` (TBD: you really shouldn't have to do this, but the swagger output step requires it right now)
|
||||
1. `./build/mark-new-version.sh v${VER}.0` to mark the new release and get further
|
||||
instructions. This creates a series of commits on the branch you're working
|
||||
on (`release-${VER}`), including forking our documentation for the release,
|
||||
the release version commit (which is then tagged), and the post-release
|
||||
version commit.
|
||||
1. Follow the instructions given to you by that script. They are canon for the
|
||||
remainder of the Git process. If you don't understand something in that
|
||||
process, please ask!
|
||||
```console
|
||||
git clone git@github.com:kubernetes/kubernetes.git
|
||||
cd kubernetes
|
||||
```
|
||||
|
||||
**TODO**: how to fix tags, etc., if you have to shift the release branchpoint.
|
||||
or `git checkout upstream/master` from an existing repo.
|
||||
|
||||
#### Building and Pushing Binaries
|
||||
#### Cutting an alpha release (`vX.Y.0-alpha.W`)
|
||||
|
||||
In your git repo (you still have `${VER}` set from above right?):
|
||||
Figure out what version you're cutting, and
|
||||
|
||||
1. `git checkout upstream/master && build/build-official-release.sh v${VER}.0` (the `build-official-release.sh` script is version agnostic, so it's best to run it off `master` directly).
|
||||
1. Follow the instructions given to you by that script.
|
||||
1. At this point, you've done all the Git bits, you've got all the binary bits pushed, and you've got the template for the release started on GitHub.
|
||||
```console
|
||||
export VER="vX.Y.0-alpha.W"
|
||||
```
|
||||
|
||||
#### Writing Release Notes
|
||||
then, run
|
||||
|
||||
[This helpful guide](making-release-notes.md) describes how to write release
|
||||
notes for a major/minor release. In the release template on GitHub, leave the
|
||||
last PR number that the tool finds for the `.0` release, so the next releaser
|
||||
doesn't have to hunt.
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}"
|
||||
```
|
||||
|
||||
### Building a New Patch Release (`vX.Y.Z` for `Z > 0`)
|
||||
This will do a dry run of:
|
||||
|
||||
#### Selecting Release Components
|
||||
1. mark the `vX.Y.0-alpha.W` tag at the given git hash;
|
||||
1. prompt you to do the remainder of the work, including building the
|
||||
appropriate binaries and pushing them to the appropriate places.
|
||||
|
||||
We cut `vX.Y.Z` releases from the `release-vX.Y` branch after all cherry picks
|
||||
to the branch have been resolved. You should ensure all outstanding cherry picks
|
||||
have been reviewed and merged and the branch validated on Jenkins (validation
|
||||
TBD). See the [Cherry Picks](cherry-picks.md) for more information on how to
|
||||
manage cherry picks prior to cutting the release.
|
||||
If you're satisfied with the result, run
|
||||
|
||||
#### Tagging and Merging
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}" --no-dry-run
|
||||
```
|
||||
|
||||
1. `export VER=x.y` (e.g. `0.20` for v0.20)
|
||||
1. `export PATCH=Z` where `Z` is the patch level of `vX.Y.Z`
|
||||
1. cd to the base of the repo
|
||||
1. `git fetch upstream && git checkout -b upstream/release-${VER} release-${VER}`
|
||||
1. Make sure you don't have any files you care about littering your repo (they
|
||||
better be checked in or outside the repo, or the next step will delete them).
|
||||
1. `make clean && git reset --hard HEAD && git clean -xdf`
|
||||
1. `make` (TBD: you really shouldn't have to do this, but the swagger output step requires it right now)
|
||||
1. `./build/mark-new-version.sh v${VER}.${PATCH}` to mark the new release and get further
|
||||
instructions. This creates a series of commits on the branch you're working
|
||||
on (`release-${VER}`), including forking our documentation for the release,
|
||||
the release version commit (which is then tagged), and the post-release
|
||||
version commit.
|
||||
1. Follow the instructions given to you by that script. They are canon for the
|
||||
remainder of the Git process. If you don't understand something in that
|
||||
process, please ask! When proposing PRs, you can pre-fill the body with
|
||||
`hack/cherry_pick_list.sh upstream/release-${VER}` to inform people of what
|
||||
is already on the branch.
|
||||
and follow the instructions.
|
||||
|
||||
**TODO**: how to fix tags, etc., if the release is changed.
|
||||
#### Cutting an beta release (`vX.Y.Z-beta.W`)
|
||||
|
||||
#### Building and Pushing Binaries
|
||||
Figure out what version you're cutting, and
|
||||
|
||||
In your git repo (you still have `${VER}` and `${PATCH}` set from above right?):
|
||||
```console
|
||||
export VER="vX.Y.Z-beta.W"
|
||||
```
|
||||
|
||||
1. `git checkout upstream/master && build/build-official-release.sh
|
||||
v${VER}.${PATCH}` (the `build-official-release.sh` script is version
|
||||
agnostic, so it's best to run it off `master` directly).
|
||||
1. Follow the instructions given to you by that script. At this point, you've
|
||||
done all the Git bits, you've got all the binary bits pushed, and you've got
|
||||
the template for the release started on GitHub.
|
||||
then, run
|
||||
|
||||
#### Writing Release Notes
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}"
|
||||
```
|
||||
|
||||
Run `hack/cherry_pick_list.sh ${VER}.${PATCH}~1` to get the release notes for
|
||||
the patch release you just created. Feel free to prune anything internal, like
|
||||
you would for a major release, but typically for patch releases we tend to
|
||||
include everything in the release notes.
|
||||
This will do a dry run of:
|
||||
|
||||
## Origin of the Sources
|
||||
1. do a series of commits on the release branch for `vX.Y.Z-beta`;
|
||||
1. mark the `vX.Y.Z-beta` tag at the beta version commit;
|
||||
1. prompt you to do the remainder of the work, including building the
|
||||
appropriate binaries and pushing them to the appropriate places.
|
||||
|
||||
If you're satisfied with the result, run
|
||||
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}" --no-dry-run
|
||||
```
|
||||
|
||||
and follow the instructions.
|
||||
|
||||
#### Cutting an official release (`vX.Y.Z`)
|
||||
|
||||
Figure out what version you're cutting, and
|
||||
|
||||
```console
|
||||
export VER="vX.Y.Z"
|
||||
```
|
||||
|
||||
then, run
|
||||
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}"
|
||||
```
|
||||
|
||||
This will do a dry run of:
|
||||
|
||||
1. do a series of commits on the branch for `vX.Y.Z`;
|
||||
1. mark the `vX.Y.Z` tag at the release version commit;
|
||||
1. do a series of commits on the branch for `vX.Y.(Z+1)-beta` on top of the
|
||||
previous commits;
|
||||
1. mark the `vX.Y.(Z+1)-beta` tag at the beta version commit;
|
||||
1. prompt you to do the remainder of the work, including building the
|
||||
appropriate binaries and pushing them to the appropriate places.
|
||||
|
||||
If you're satisfied with the result, run
|
||||
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}" --no-dry-run
|
||||
```
|
||||
|
||||
and follow the instructions.
|
||||
|
||||
#### Branching a new release series (`vX.Y`)
|
||||
|
||||
Once again, **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.
|
||||
|
||||
Figure out what series you're cutting, and
|
||||
|
||||
```console
|
||||
export VER="vX.Y"
|
||||
```
|
||||
|
||||
then, run
|
||||
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}"
|
||||
```
|
||||
|
||||
This will do a dry run of:
|
||||
|
||||
1. mark the `vX.(Y+1).0-alpha.0` tag at the given git hash on `master`;
|
||||
1. fork a new branch `release-X.Y` off of `master` at the given git hash;
|
||||
1. do a series of commits on the branch for `vX.Y.0-beta`;
|
||||
1. mark the `vX.Y.0-beta` tag at the beta version commit;
|
||||
1. prompt you to do the remainder of the work, including building the
|
||||
appropriate binaries and pushing them to the appropriate places.
|
||||
|
||||
If you're satisfied with the result, run
|
||||
|
||||
```console
|
||||
release/cut-official-release.sh "${VER}" "${GITHASH}" --no-dry-run
|
||||
```
|
||||
|
||||
and follow the instructions.
|
||||
|
||||
### Publishing binaries and release notes
|
||||
|
||||
The script you ran above will prompt you to take any remaining steps, including
|
||||
publishing binaries and release notes.
|
||||
|
||||
## 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 (using `hack/build-go.sh`) or
|
||||
from a tarball (using either `hack/build-go.sh` or `go install`) or directly by
|
||||
|
@ -191,34 +282,6 @@ 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).
|
||||
|
||||
## Version Number Format
|
||||
|
||||
In order to account for these use cases, there are some specific formats that
|
||||
may end up representing the Kubernetes version. Here are a few examples:
|
||||
|
||||
- **v0.5**: This is official version 0.5 and this version will only be used
|
||||
when building from a clean git tree at the v0.5 git tag, or from a tree
|
||||
extracted from the tarball corresponding to that specific release.
|
||||
- **v0.5-15-g0123abcd4567**: This is the `git describe` output and it indicates
|
||||
that we are 15 commits past the v0.5 release and that the SHA1 of the commit
|
||||
where the binaries were built was `0123abcd4567`. It is only possible to have
|
||||
this level of detail in the version information when building from git, not
|
||||
when building from a tarball.
|
||||
- **v0.5-15-g0123abcd4567-dirty** or **v0.5-dirty**: The extra `-dirty` prefix
|
||||
means that the tree had local modifications or untracked files at the time of
|
||||
the build, so there's no guarantee that the source code matches exactly the
|
||||
state of the tree at the `0123abcd4567` commit or at the `v0.5` git tag
|
||||
(resp.)
|
||||
- **v0.5-dev**: This means we are building from a tarball or using `go get` or,
|
||||
if we have a git tree, we are using `go install` directly, so it is not
|
||||
possible to inject the git version into the build information. Additionally,
|
||||
this is not an official release, so the `-dev` prefix indicates that the
|
||||
version we are building is after `v0.5` but before `v0.6`. (There is actually
|
||||
an exception where a commit with `v0.5-dev` is not present on `v0.6`, see
|
||||
later for details.)
|
||||
|
||||
## Injecting Version into Binaries
|
||||
|
||||
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.
|
||||
|
@ -249,94 +312,6 @@ 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.
|
||||
|
||||
## Handling Official Versions
|
||||
|
||||
Handling official versions from git is easy, as long as there is an annotated
|
||||
git tag pointing to a specific version then `git describe` will return that tag
|
||||
exactly which will match the idea of an official version (e.g. `v0.5`).
|
||||
|
||||
Handling it on tarballs is a bit harder since the exact version string must be
|
||||
present in `pkg/version/base.go` for it to get embedded into the binaries. But
|
||||
simply creating a commit with `v0.5` on its own would mean that the commits
|
||||
coming after it would also get the `v0.5` version when built from tarball or `go
|
||||
get` while in fact they do not match `v0.5` (the one that was tagged) exactly.
|
||||
|
||||
To handle that case, creating a new release should involve creating two adjacent
|
||||
commits where the first of them will set the version to `v0.5` and the second
|
||||
will set it to `v0.5-dev`. In that case, even in the presence of merges, there
|
||||
will be a single commit where the exact `v0.5` version will be used and all
|
||||
others around it will either have `v0.4-dev` or `v0.5-dev`.
|
||||
|
||||
The diagram below illustrates it.
|
||||
|
||||
![Diagram of git commits involved in the release](releasing.png)
|
||||
|
||||
After working on `v0.4-dev` and merging PR 99 we decide it is time to release
|
||||
`v0.5`. So we start a new branch, create one commit to update
|
||||
`pkg/version/base.go` to include `gitVersion = "v0.5"` and `git commit` it.
|
||||
|
||||
We test it and make sure everything is working as expected.
|
||||
|
||||
Before sending a PR for it, we create a second commit on that same branch,
|
||||
updating `pkg/version/base.go` to include `gitVersion = "v0.5-dev"`. That will
|
||||
ensure that further builds (from tarball or `go install`) on that tree will
|
||||
always include the `-dev` prefix and will not have a `v0.5` version (since they
|
||||
do not match the official `v0.5` exactly.)
|
||||
|
||||
We then send PR 100 with both commits in it.
|
||||
|
||||
Once the PR is accepted, we can use `git tag -a` to create an annotated tag
|
||||
*pointing to the one commit* that has `v0.5` in `pkg/version/base.go` and push
|
||||
it to GitHub. (Unfortunately GitHub tags/releases are not annotated tags, so
|
||||
this needs to be done from a git client and pushed to GitHub using SSH or
|
||||
HTTPS.)
|
||||
|
||||
## Parallel Commits
|
||||
|
||||
While we are working on releasing `v0.5`, other development takes place and
|
||||
other PRs get merged. For instance, in the example above, PRs 101 and 102 get
|
||||
merged to the master branch before the versioning PR gets merged.
|
||||
|
||||
This is not a problem, it is only slightly inaccurate that checking out the tree
|
||||
at commit `012abc` or commit `345cde` or at the commit of the merges of PR 101
|
||||
or 102 will yield a version of `v0.4-dev` *but* those commits are not present in
|
||||
`v0.5`.
|
||||
|
||||
In that sense, there is a small window in which commits will get a
|
||||
`v0.4-dev` or `v0.4-N-gXXX` label and while they're indeed later than `v0.4`
|
||||
but they are not really before `v0.5` in that `v0.5` does not contain those
|
||||
commits.
|
||||
|
||||
Unfortunately, there is not much we can do about it. On the other hand, other
|
||||
projects seem to live with that and it does not really become a large problem.
|
||||
|
||||
As an example, Docker commit a327d9b91edf has a `v1.1.1-N-gXXX` label but it is
|
||||
not present in Docker `v1.2.0`:
|
||||
|
||||
```console
|
||||
$ git describe a327d9b91edf
|
||||
v1.1.1-822-ga327d9b91edf
|
||||
|
||||
$ git log --oneline v1.2.0..a327d9b91edf
|
||||
a327d9b91edf Fix data space reporting from Kb/Mb to KB/MB
|
||||
|
||||
(Non-empty output here means the commit is not present on v1.2.0.)
|
||||
```
|
||||
|
||||
## Release Notes
|
||||
|
||||
No official release should be made final without properly matching release notes.
|
||||
|
||||
There should be made available, per release, a small summary, preamble, of the
|
||||
major changes, both in terms of feature improvements/bug fixes and notes about
|
||||
functional feature changes (if any) regarding the previous released version so
|
||||
that the BOM regarding updating to it gets as obvious and trouble free as possible.
|
||||
|
||||
After this summary, preamble, all the relevant PRs/issues that got in that
|
||||
version should be listed and linked together with a small summary understandable
|
||||
by plain mortals (in a perfect world PR/issue's title would be enough but often
|
||||
it is just too cryptic/geeky/domain-specific that it isn't).
|
||||
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/devel/releasing.md?pixel)]()
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
|
@ -1,113 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: tagged_release Pages: 1 -->
|
||||
<svg width="257pt" height="360pt"
|
||||
viewBox="0.00 0.00 257.33 360.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(0.649819 0.649819) rotate(0) translate(4 550)">
|
||||
<title>tagged_release</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-550 392,-550 392,4 -4,4"/>
|
||||
<!-- ci012abc -->
|
||||
<g id="node1" class="node"><title>ci012abc</title>
|
||||
<ellipse fill="#ffffcc" stroke="black" cx="56" cy="-115" rx="42.7926" ry="42.7926"/>
|
||||
<text text-anchor="middle" x="56" y="-111.3" font-family="Consolas, Liberation Mono, Menlo, Courier, monospace" font-size="14.00">012abc</text>
|
||||
</g>
|
||||
<!-- pr101 -->
|
||||
<g id="node2" class="node"><title>pr101</title>
|
||||
<polygon fill="#ccccff" stroke="black" points="112,-255 0,-255 0,-219 112,-219 112,-255"/>
|
||||
<text text-anchor="middle" x="56" y="-233.3" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">Merge PR #101</text>
|
||||
</g>
|
||||
<!-- ci012abc->pr101 -->
|
||||
<g id="edge1" class="edge"><title>ci012abc->pr101</title>
|
||||
<path fill="none" stroke="black" d="M56,-157.97C56,-174.83 56,-193.784 56,-208.789"/>
|
||||
<polygon fill="black" stroke="black" points="52.5001,-208.93 56,-218.93 59.5001,-208.93 52.5001,-208.93"/>
|
||||
</g>
|
||||
<!-- ci345cde -->
|
||||
<g id="node3" class="node"><title>ci345cde</title>
|
||||
<ellipse fill="#ffffcc" stroke="black" cx="62" cy="-359" rx="42.7926" ry="42.7926"/>
|
||||
<text text-anchor="middle" x="62" y="-355.3" font-family="Consolas, Liberation Mono, Menlo, Courier, monospace" font-size="14.00">345cde</text>
|
||||
</g>
|
||||
<!-- pr101->ci345cde -->
|
||||
<g id="edge2" class="edge"><title>pr101->ci345cde</title>
|
||||
<path fill="none" stroke="black" d="M56.8597,-255.193C57.5237,-268.473 58.4796,-287.592 59.3874,-305.748"/>
|
||||
<polygon fill="black" stroke="black" points="55.904,-306.17 59.8991,-315.982 62.8953,-305.82 55.904,-306.17"/>
|
||||
</g>
|
||||
<!-- pr102 -->
|
||||
<g id="node4" class="node"><title>pr102</title>
|
||||
<polygon fill="#ccccff" stroke="black" points="129,-474 17,-474 17,-438 129,-438 129,-474"/>
|
||||
<text text-anchor="middle" x="73" y="-452.3" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">Merge PR #102</text>
|
||||
</g>
|
||||
<!-- ci345cde->pr102 -->
|
||||
<g id="edge3" class="edge"><title>ci345cde->pr102</title>
|
||||
<path fill="none" stroke="black" d="M66.8248,-401.668C67.8523,-410.542 68.9117,-419.692 69.8567,-427.853"/>
|
||||
<polygon fill="black" stroke="black" points="66.3936,-428.375 71.0207,-437.906 73.3472,-427.57 66.3936,-428.375"/>
|
||||
</g>
|
||||
<!-- pr100 -->
|
||||
<g id="node10" class="node"><title>pr100</title>
|
||||
<polygon fill="#ccccff" stroke="black" points="174,-546 62,-546 62,-510 174,-510 174,-546"/>
|
||||
<text text-anchor="middle" x="118" y="-524.3" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">Merge PR #100</text>
|
||||
</g>
|
||||
<!-- pr102->pr100 -->
|
||||
<g id="edge6" class="edge"><title>pr102->pr100</title>
|
||||
<path fill="none" stroke="black" d="M84.1236,-474.303C89.355,-482.441 95.6999,-492.311 101.478,-501.299"/>
|
||||
<polygon fill="black" stroke="black" points="98.6526,-503.377 107.004,-509.896 104.541,-499.591 98.6526,-503.377"/>
|
||||
</g>
|
||||
<!-- version_commit -->
|
||||
<g id="node5" class="node"><title>version_commit</title>
|
||||
<ellipse fill="#ccffcc" stroke="black" cx="173" cy="-237" rx="42.7926" ry="42.7926"/>
|
||||
<text text-anchor="middle" x="173" y="-233.3" font-family="Consolas, Liberation Mono, Menlo, Courier, monospace" font-size="14.00">678fed</text>
|
||||
</g>
|
||||
<!-- dev_commit -->
|
||||
<g id="node6" class="node"><title>dev_commit</title>
|
||||
<ellipse fill="#ffffcc" stroke="black" cx="169" cy="-359" rx="42.7926" ry="42.7926"/>
|
||||
<text text-anchor="middle" x="169" y="-355.3" font-family="Consolas, Liberation Mono, Menlo, Courier, monospace" font-size="14.00">456dcb</text>
|
||||
</g>
|
||||
<!-- version_commit->dev_commit -->
|
||||
<g id="edge4" class="edge"><title>version_commit->dev_commit</title>
|
||||
<path fill="none" stroke="black" d="M171.601,-279.97C171.322,-288.326 171.027,-297.195 170.739,-305.844"/>
|
||||
<polygon fill="black" stroke="black" points="167.24,-305.74 170.405,-315.851 174.236,-305.973 167.24,-305.74"/>
|
||||
</g>
|
||||
<!-- dev_commit->pr100 -->
|
||||
<g id="edge8" class="edge"><title>dev_commit->pr100</title>
|
||||
<path fill="none" stroke="black" d="M158.36,-400.568C152.438,-422.433 144.719,-449.815 137,-474 134.253,-482.606 131.013,-491.906 127.994,-500.278"/>
|
||||
<polygon fill="black" stroke="black" points="124.616,-499.325 124.47,-509.919 131.191,-501.729 124.616,-499.325"/>
|
||||
</g>
|
||||
<!-- release_info -->
|
||||
<g id="node7" class="node"><title>release_info</title>
|
||||
<text text-anchor="middle" x="304" y="-240.8" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">pkg/version/base.go:</text>
|
||||
<text text-anchor="middle" x="304" y="-225.8" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">gitVersion = "v0.5";</text>
|
||||
</g>
|
||||
<!-- dev_info -->
|
||||
<g id="node8" class="node"><title>dev_info</title>
|
||||
<text text-anchor="middle" x="309" y="-362.8" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">pkg/version/base.go:</text>
|
||||
<text text-anchor="middle" x="309" y="-347.8" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">gitVersion = "v0.5-dev";</text>
|
||||
</g>
|
||||
<!-- pr99 -->
|
||||
<g id="node9" class="node"><title>pr99</title>
|
||||
<polygon fill="#ccccff" stroke="black" points="143,-36 39,-36 39,-0 143,-0 143,-36"/>
|
||||
<text text-anchor="middle" x="91" y="-14.3" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">Merge PR #99</text>
|
||||
</g>
|
||||
<!-- pr99->ci012abc -->
|
||||
<g id="edge5" class="edge"><title>pr99->ci012abc</title>
|
||||
<path fill="none" stroke="black" d="M84.5805,-36.4245C81.5586,-44.6267 77.7879,-54.8615 73.9865,-65.1795"/>
|
||||
<polygon fill="black" stroke="black" points="70.6804,-64.0292 70.5075,-74.6226 77.2488,-66.4492 70.6804,-64.0292"/>
|
||||
</g>
|
||||
<!-- pr99->version_commit -->
|
||||
<g id="edge7" class="edge"><title>pr99->version_commit</title>
|
||||
<path fill="none" stroke="black" d="M97.4344,-36.0276C109.585,-68.1826 136.317,-138.924 154.498,-187.038"/>
|
||||
<polygon fill="black" stroke="black" points="151.318,-188.523 158.127,-196.64 157.866,-186.048 151.318,-188.523"/>
|
||||
</g>
|
||||
<!-- tag -->
|
||||
<g id="node11" class="node"><title>tag</title>
|
||||
<ellipse fill="#ffcccc" stroke="black" cx="226" cy="-115" rx="71.4873" ry="18"/>
|
||||
<text text-anchor="middle" x="226" y="-111.3" font-family="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif" font-size="14.00">$ git tag -a v0.5</text>
|
||||
</g>
|
||||
<!-- tag->version_commit -->
|
||||
<g id="edge9" class="edge"><title>tag->version_commit</title>
|
||||
<path fill="none" stroke="black" d="M218.519,-132.939C212.168,-147.318 202.736,-168.673 194.103,-188.22"/>
|
||||
<polygon fill="black" stroke="black" points="190.784,-187.071 189.946,-197.632 197.188,-189.899 190.784,-187.071"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 7.1 KiB |
|
@ -45,7 +45,7 @@ declare -r KUBE_GITHUB="https://github.com/kubernetes/kubernetes.git"
|
|||
declare -r KUBE_RELEASE_VERSION=${1-}
|
||||
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]*)$"
|
||||
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
|
||||
|
@ -88,29 +88,31 @@ 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")
|
||||
|
||||
echo ""
|
||||
echo "Success! You must now do the following: (you may want to cut"
|
||||
echo " and paste these instructions elsewhere, step 1 can be spammy)"
|
||||
echo ""
|
||||
echo " 1) (cd ${KUBE_BUILD_DIR}; build/push-official-release.sh ${KUBE_RELEASE_VERSION})"
|
||||
echo " 2) Go to https://github.com/GoogleCloudPlatform/kubernetes/releases"
|
||||
echo " and create a new 'Release ${KUBE_RELEASE_VERSION} Candidate' release"
|
||||
echo " with the ${KUBE_RELEASE_VERSION} tag. Mark it as a pre-release."
|
||||
echo " 3) Upload the ${KUBE_BUILD_DIR}/kubernetes.tar.gz to GitHub"
|
||||
echo " 4) Use this template for the release:"
|
||||
echo ""
|
||||
echo "## [Documentation](http://releases.k8s.io/${KUBE_RELEASE_VERSION}/docs/README.md)"
|
||||
echo "## [Examples](http://releases.k8s.io/${KUBE_RELEASE_VERSION}/examples)"
|
||||
echo "## Changes since <last release> (last PR <last PR>)"
|
||||
echo ""
|
||||
echo "<release notes>"
|
||||
echo ""
|
||||
echo "binary | hash alg | hash"
|
||||
echo "------ | -------- | ----"
|
||||
echo "\`kubernetes.tar.gz\` | md5 | \`${MD5}\`"
|
||||
echo "\`kubernetes.tar.gz\` | sha1 | \`${SHA1}\`"
|
||||
echo ""
|
||||
echo " We'll fill in the release notes in the next stage."
|
||||
echo " 5) Ensure all the binaries are in place on GitHub and GCS before cleaning."
|
||||
echo " 6) (cd ${KUBE_BUILD_DIR}; make clean; cd -; rm -rf ${KUBE_BUILD_DIR})"
|
||||
echo ""
|
||||
cat <<- EOM
|
||||
|
||||
Success! You must now do the following: (you may want to cut
|
||||
and paste these instructions elsewhere, step 1 can be spammy)
|
||||
|
||||
1) (cd ${KUBE_BUILD_DIR}; build/push-official-release.sh ${KUBE_RELEASE_VERSION})
|
||||
2) Go to https://github.com/GoogleCloudPlatform/kubernetes/releases
|
||||
and create a new 'Release ${KUBE_RELEASE_VERSION} Candidate' release
|
||||
with the ${KUBE_RELEASE_VERSION} tag. Mark it as a pre-release.
|
||||
3) Upload the ${KUBE_BUILD_DIR}/kubernetes.tar.gz to GitHub
|
||||
4) Use this template for the release:
|
||||
|
||||
## [Documentation](http://releases.k8s.io/${KUBE_RELEASE_VERSION}/docs/README.md)
|
||||
## [Examples](http://releases.k8s.io/${KUBE_RELEASE_VERSION}/examples)
|
||||
## Changes since <last release> (last PR <last PR>)
|
||||
|
||||
<release notes>
|
||||
|
||||
binary | hash alg | hash
|
||||
------ | -------- | ----
|
||||
\`kubernetes.tar.gz\` | md5 | \`${MD5}\`
|
||||
\`kubernetes.tar.gz\` | sha1 | \`${SHA1}\`
|
||||
|
||||
We'll fill in the release notes in the next stage.
|
||||
5) Ensure all the binaries are in place on GitHub and GCS before cleaning.
|
||||
6) (cd ${KUBE_BUILD_DIR}; make clean; cd -; rm -rf ${KUBE_BUILD_DIR})
|
||||
|
||||
EOM
|
|
@ -0,0 +1,350 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
#
|
||||
# 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 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
local -r new_version=${1-}
|
||||
# TODO(ihmccreery) Stop calling it githash; it's not a githash.
|
||||
local -r githash=${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 githash and verify it
|
||||
local -r git_commit_regex="^[0-9a-f]{7}$"
|
||||
local -r git_commit=$(echo "${githash}" | awk -F'+' '{print $2}' | head -c7)
|
||||
if ! [[ "${git_commit}" =~ $git_commit_regex ]]; then
|
||||
usage
|
||||
echo
|
||||
echo "!!! You specified an invalid githash '${githash}'."
|
||||
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}"
|
||||
|
||||
local -r github="https://github.com/kubernetes/kubernetes.git"
|
||||
declare -r DIR="/tmp/kubernetes-${release_type}-release-${new_version}-$(date +%s)"
|
||||
|
||||
# Start a tmp file that will hold instructions for the user.
|
||||
declare -r INSTRUCTIONS="/tmp/kubernetes-${release_type}-release-${new_version}-$(date +%s)-instructions"
|
||||
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:
|
||||
|
||||
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"
|
||||
local -r ancestor="${new_version}-beta"
|
||||
|
||||
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"
|
||||
# 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} <version> <githash> [--no-dry-run]"
|
||||
echo
|
||||
echo "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}
|
||||
- Prep release notes:
|
||||
- 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 at upstream/master,
|
||||
go run release-notes/release-notes.go --last-release-pr=<number> --current-release-pr=<number> --api-token=<token>
|
||||
Feel free to prune.
|
||||
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}"
|
||||
|
||||
# NOTE: We currently don't publish beta release notes, since they'll go out
|
||||
# with the official release, so we don't prompt for compiling them here.
|
||||
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}
|
||||
- Prep release notes:
|
||||
- From this directory (clone of upstream/master), run
|
||||
./hack/cherry_pick_list.sh ${official_version}
|
||||
to get the release notes for the patch release you just created. Feel
|
||||
free to prune anything internal, but typically for patch releases we tend
|
||||
to include everything in the release notes.
|
||||
- If this is a first official release (vX.Y.0), scan through the release
|
||||
notes for all of the alpha releases since the last cycle, and include
|
||||
anything important in release notes.
|
||||
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 ${object}"
|
||||
else
|
||||
echo "NOT A DRY RUN: you don't really want to git push ${object}, do you?"
|
||||
# git push "${object}"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue