diff --git a/Gopkg.lock b/Gopkg.lock index 96d72fd016a0..9e70d89d36d5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -445,7 +445,7 @@ [[projects]] branch = "master" - digest = "1:d4ad38df40cd7dff18defa1ece52d05973651ccbabfae125f2be2422c5ffd845" + digest = "1:74f4c447fcb425021ba92c5a4ac9aabcd96d99623e2ef5d70d1c5ac455fd389e" name = "github.com/knative/test-infra" packages = [ "scripts", @@ -454,7 +454,7 @@ "tools/dep-collector", ] pruneopts = "UT" - revision = "222c833f8b4a6146b6712cc2e184b48bfee7f3c2" + revision = "5ff6fb1eed88eb395e66a5a6ddafbffde8779648" [[projects]] digest = "1:56dbf15e091bf7926cb33a57cb6bdfc658fc6d3498d2f76f10a97ce7856f1fde" diff --git a/hack/release.md b/hack/release.md index 969bb4344e6f..771c1d34a461 100644 --- a/hack/release.md +++ b/hack/release.md @@ -48,8 +48,6 @@ Examples: ## Creating versioned releases -_Note: only Knative admins can create versioned releases._ - To specify a versioned release to be cut, you must use the `--version` flag. Versioned releases are usually built against a branch in the Knative Serving repository, specified by the `--branch` flag. @@ -65,12 +63,72 @@ repository, specified by the `--branch` flag. - `--release-notes` Points to a markdown file containing a description of the release. This is optional but highly recommended. It has no effect unless `--version` is also passed. - -If this is the first time you're cutting a versioned release, you'll be prompted -for your GitHub username, password, and possibly 2-factor authentication -challenge before the release is published. +- `--github-token` Points to a text file containing the GitHub token to be used + for authentication when publishing the release to GitHub. If this flag is not + used and this is the first time you're publishing a versioned release, you'll + be prompted for your GitHub username, password, and possibly 2-factor + authentication challenge (you must be a Knative admin to have the + required publishing permissions). The release will be published in the _Releases_ page of the Knative Serving repository, with the title _Knative Serving release vX.Y.Z_ and the given release notes. It will also be tagged _vX.Y.Z_ (both on GitHub and as a git annotated tag). + +Example: + +```bash +# Create and publish a versioned release. +./hack/release.sh --publish --tag-release \ + --release-gcr gcr.io/knative-releases \ + --release-gcs knative-releases/serving \ + --version 0.3.0 \ + --branch release-0.3 \ + --release-notes $HOME/docs/release-notes-0.3.md +``` + +## Creating incremental build releases ("dot releases") + +An incremental build release (aka "dot release") is a versioned release built +automatically based on changes in the latest release branch, with the build +number increased. + +For example, if the latest release on release branch `release-0.2` is `v0.2.1`, +creating an incremental build release will result in `v0.2.2`. + +To specify an incremental build release to be cut, you must use the +`--dot-release` flag. The latest branch and release version will be +automatically detected and used. + +_Note 1: when using the `--dot-release` flag, the flags `--nopublish` and +`--notag-release` have no effect. The release is always tagged and published._ + +_Note 2: if the release branch has no new commits since its last release was +cut, the script successfully exits with a warning, and no release will be +created._ + +The following flags are useful when creating incremental build releases: + +- `--branch` Restricts the incremental build release to the given branch. If not + passed, the latest branch will be automatically detected and used. +- `--release-notes` Points to a markdown file containing a description of the + release. If not passed, the notes will be copied from the previous release. +- `--github-token` Points to a text file containing the GitHub token to be used + for authentication when publishing the release to GitHub. If this flag is not + used and this is the first time you're publishing a versioned release, you'll + be prompted for your GitHub username, password, and possibly 2-factor + authentication challenge (you must be a Knative admin to have the + required publishing permissions). + +Like any regular versioned release, an incremental build release is published in +the _Releases_ page of the Knative Serving repository. + +Example: + +```bash +# Create and publish a new dot release. +./hack/release.sh \ + --dot-release \ + --release-gcr gcr.io/knative-releases \ + --release-gcs knative-releases/serving +``` diff --git a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh index c345cfade096..ee891a275913 100755 --- a/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/e2e-tests.sh @@ -292,11 +292,6 @@ GCP_PROJECT="" E2E_SCRIPT="" E2E_CLUSTER_VERSION="" -function abort() { - echo "error: $@" - exit 1 -} - # Parse flags and initialize the test cluster. function initialize() { # Normalize calling script path; we can't use readlink because it's not available everywhere @@ -355,11 +350,9 @@ function initialize() { (( IS_PROW )) && [[ -z "${GCP_PROJECT}" ]] && IS_BOSKOS=1 # Safety checks - - if [[ "${DOCKER_REPO_OVERRIDE}" =~ ^gcr.io/knative-(releases|nightly)/?$ ]]; then - abort "\$DOCKER_REPO_OVERRIDE is set to ${DOCKER_REPO_OVERRIDE}, which is forbidden" - fi - + is_protected_gcr ${DOCKER_REPO_OVERRIDE} && \ + abort "\$DOCKER_REPO_OVERRIDE set to ${DOCKER_REPO_OVERRIDE}, which is forbidden" + readonly RUN_TESTS readonly EMIT_METRICS readonly E2E_CLUSTER_VERSION diff --git a/vendor/github.com/knative/test-infra/scripts/library.sh b/vendor/github.com/knative/test-infra/scripts/library.sh index 53a76af458f0..8a2d1c536c6b 100755 --- a/vendor/github.com/knative/test-infra/scripts/library.sh +++ b/vendor/github.com/knative/test-infra/scripts/library.sh @@ -42,6 +42,13 @@ fi readonly IS_PROW readonly REPO_ROOT_DIR="$(git rev-parse --show-toplevel)" +# Print error message and exit 1 +# Parameters: $1..$n - error message to be displayed +function abort() { + echo "error: $@" + exit 1 +} + # Display a box banner. # Parameters: $1 - character to use for the box. # $2 - banner message. @@ -72,20 +79,6 @@ function function_exists() { [[ "$(type -t $1)" == "function" ]] } -# Remove ALL images in the given GCR repository. -# Parameters: $1 - GCR repository. -function delete_gcr_images() { - for image in $(gcloud --format='value(name)' container images list --repository=$1); do - echo "Checking ${image} for removal" - delete_gcr_images ${image} - for digest in $(gcloud --format='get(digest)' container images list-tags ${image} --limit=99999); do - local full_image="${image}@${digest}" - echo "Removing ${full_image}" - gcloud container images delete -q --force-delete-tags ${full_image} - done - done -} - # Waits until the given object doesn't exist. # Parameters: $1 - the kind of the object. # $2 - object's name. @@ -440,8 +433,22 @@ function check_links_in_markdown() { } # Check format of the given markdown files. -# Parameters: $1...$n - files to inspect +# Parameters: $1..$n - files to inspect function lint_markdown() { # https://github.com/markdownlint/markdownlint run_lint_tool mdl "linting markdown files" "-r ~MD013" $@ } + +# Return 0 if the given parameter is an integer, otherwise 1 +# Parameters: $1 - an integer +function is_int() { + [[ -n $1 && $1 =~ ^[0-9]+$ ]] +} + +# Return 0 if the given parameter is the knative release/nightly gcr, 1 +# otherwise +# Parameters: $1 - gcr name, e.g. gcr.io/knative-nightly +function is_protected_gcr() { + [[ -n $1 && "$1" =~ "^gcr.io/knative-(releases|nightly)/?$" ]] +} + diff --git a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh index 5818fab98f9d..bb8033f5e4f4 100755 --- a/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh +++ b/vendor/github.com/knative/test-infra/scripts/presubmit-tests.sh @@ -48,11 +48,6 @@ function exit_if_presubmit_not_required() { fi } -function abort() { - echo "error: $@" - exit 1 -} - # Process flags and run tests accordingly. function main() { exit_if_presubmit_not_required diff --git a/vendor/github.com/knative/test-infra/scripts/release.sh b/vendor/github.com/knative/test-infra/scripts/release.sh index 71551d11365c..e2e876b3612c 100755 --- a/vendor/github.com/knative/test-infra/scripts/release.sh +++ b/vendor/github.com/knative/test-infra/scripts/release.sh @@ -43,7 +43,7 @@ function tag_images_in_yaml() { # Parameters: $1 - yaml file to copy. function publish_yaml() { function verbose_gsutil_cp { - local DEST=gs://${RELEASE_GCS_BUCKET}/$2/ + local DEST="gs://${RELEASE_GCS_BUCKET}/$2/" echo "Publishing $1 to ${DEST}" gsutil cp $1 ${DEST} } @@ -66,9 +66,27 @@ RELEASE_GCS_BUCKET="" KO_FLAGS="" export KO_DOCKER_REPO="" -function abort() { - echo "error: $@" - exit 1 +# Convenience function to run the hub tool. +# Parameters: $1..$n - arguments to hub. +function hub_tool() { + run_go_tool github.com/github/hub hub $@ +} + +# Return the master version of a release. +# For example, "v0.2.1" returns "0.2" +# Parameters: $1 - release version label. +function master_version() { + local release="${1//v/}" + local tokens=(${release//\./ }) + echo "${tokens[0]}.${tokens[1]}" +} + +# Return the release build number of a release. +# For example, "v0.2.1" returns "1". +# Parameters: $1 - release version label. +function release_build_number() { + local tokens=(${1//\./ }) + echo "${tokens[2]}" } # Parses flags and sets environment variables accordingly. @@ -82,16 +100,25 @@ function parse_flags() { RELEASE_GCS_BUCKET="knative-nightly/$(basename ${REPO_ROOT_DIR})" local has_gcr_flag=0 local has_gcs_flag=0 + local is_dot_release=0 cd ${REPO_ROOT_DIR} while [[ $# -ne 0 ]]; do local parameter=$1 - case $parameter in + case ${parameter} in --skip-tests) SKIP_TESTS=1 ;; --tag-release) TAG_RELEASE=1 ;; --notag-release) TAG_RELEASE=0 ;; --publish) PUBLISH_RELEASE=1 ;; --nopublish) PUBLISH_RELEASE=0 ;; + --dot-release) is_dot_release=1 ;; + --github-token) + shift + [[ $# -ge 1 ]] || abort "missing token file after --github-token" + [[ ! -f "$1" ]] && abort "file $1 doesn't exist" + export GITHUB_TOKEN="$(cat $1)" + [[ -n "${GITHUB_TOKEN}" ]] || abort "file $1 is empty" + ;; --release-gcr) shift [[ $# -ge 1 ]] || abort "missing GCR after --release-gcr" @@ -127,6 +154,51 @@ function parse_flags() { shift done + # Setup dot releases + if (( is_dot_release )); then + echo "Dot release requested" + TAG_RELEASE=1 + PUBLISH_RELEASE=1 + # List latest release + local releases # don't combine with the line below, or $? will be 0 + releases="$(hub_tool release)" + [[ $? -eq 0 ]] || abort "cannot list releases" + # If --release-branch passed, restrict to that release + if [[ -n "${RELEASE_BRANCH}" ]]; then + local version_filter="v${RELEASE_BRANCH##release-}" + echo "Dot release will be generated for ${version_filter}" + releases="$(echo "${releases}" | grep ^${version_filter})" + fi + local last_version="$(echo "${releases}" | grep '^v[0-9]\+\.[0-9]\+\.[0-9]\+$' | sort -r | head -1)" + [[ -n "${last_version}" ]] || abort "no previous release exist" + if [[ -z "${RELEASE_BRANCH}" ]]; then + echo "Last release is ${last_version}" + # Determine branch + local major_minor_version="$(master_version ${last_version})" + RELEASE_BRANCH="release-${major_minor_version}" + echo "Last release branch is ${RELEASE_BRANCH}" + fi + # Ensure there are new commits in the branch, otherwise we don't create a new release + local last_release_commit="$(git rev-list -n 1 ${last_version})" + local release_branch_commit="$(git rev-list -n 1 ${RELEASE_BRANCH})" + if [[ "${last_release_commit}" == "${release_branch_commit}" ]]; then + echo "*** Branch ${RELEASE_BRANCH} is at commit ${release_branch_commit}" + echo "*** Branch ${RELEASE_BRANCH} has no new cherry-picks since release ${last_version}" + echo "*** No dot release will be generated, as no changes exist" + exit 0 + fi + # Create new release version number + local last_build="$(release_build_number ${last_version})" + RELEASE_VERSION="${major_minor_version}.$(( last_build + 1 ))" + echo "Will create release ${RELEASE_VERSION} at commit ${release_branch_commit}" + # If --release-notes not used, copy from the latest release + if [[ -z "${RELEASE_NOTES}" ]]; then + RELEASE_NOTES="$(mktemp)" + hub_tool release show -f "%b" ${last_version} > ${RELEASE_NOTES} + echo "Release notes from ${last_version} copied to ${RELEASE_NOTES}" + fi + fi + # Update KO_DOCKER_REPO and KO_FLAGS if we're not publishing. if (( ! PUBLISH_RELEASE )); then (( has_gcr_flag )) && echo "Not publishing the release, GCR flag is ignored" @@ -178,7 +250,6 @@ function run_validation_tests() { # Initialize everything (flags, workspace, etc) for a release. function initialize() { parse_flags $@ - # Log what will be done and where. banner "Release configuration" echo "- Destination GCR: ${KO_DOCKER_REPO}" @@ -224,7 +295,7 @@ function branch_release() { fi git tag -a ${TAG} -m "${title}" git push $(git remote get-url upstream) tag ${TAG} - run_go_tool github.com/github/hub hub release create \ + hub_tool release create \ --prerelease \ ${attachments[@]} \ --file=${description} \