Initial commit
Some checks failed
Continuous Integration - Pull Request / code-tests (pull_request) Has been cancelled
Continuous Integration - Pull Request / deployment-tests (local-code) (pull_request) Has been cancelled
helm-chart-ci / helm-chart-ci (pull_request) Has been cancelled
kubevious-manifests-ci / kubevious-manifests-ci (pull_request) Has been cancelled
kustomize-build-ci / kustomize-build-ci (pull_request) Has been cancelled
terraform-validate-ci / terraform-validate-ci (pull_request) Has been cancelled
Clean up deployment / cleanup-namespace (pull_request) Has been cancelled
Continuous Integration - Main/Release / code-tests (push) Has been cancelled
Continuous Integration - Main/Release / deployment-tests (local-code) (push) Has been cancelled
helm-chart-ci / helm-chart-ci (push) Has been cancelled
kubevious-manifests-ci / kubevious-manifests-ci (push) Has been cancelled
kustomize-build-ci / kustomize-build-ci (push) Has been cancelled
terraform-validate-ci / terraform-validate-ci (push) Has been cancelled
Some checks failed
Continuous Integration - Pull Request / code-tests (pull_request) Has been cancelled
Continuous Integration - Pull Request / deployment-tests (local-code) (pull_request) Has been cancelled
helm-chart-ci / helm-chart-ci (pull_request) Has been cancelled
kubevious-manifests-ci / kubevious-manifests-ci (pull_request) Has been cancelled
kustomize-build-ci / kustomize-build-ci (pull_request) Has been cancelled
terraform-validate-ci / terraform-validate-ci (pull_request) Has been cancelled
Clean up deployment / cleanup-namespace (pull_request) Has been cancelled
Continuous Integration - Main/Release / code-tests (push) Has been cancelled
Continuous Integration - Main/Release / deployment-tests (local-code) (push) Has been cancelled
helm-chart-ci / helm-chart-ci (push) Has been cancelled
kubevious-manifests-ci / kubevious-manifests-ci (push) Has been cancelled
kustomize-build-ci / kustomize-build-ci (push) Has been cancelled
terraform-validate-ci / terraform-validate-ci (push) Has been cancelled
This commit is contained in:
102
docs/releasing/README.md
Normal file
102
docs/releasing/README.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Releasing Online Boutique
|
||||
|
||||
This document walks through the process of creating a new release of Online Boutique.
|
||||
|
||||
## Prerequisites for tagging a release
|
||||
|
||||
1. Choose the logical [next release tag](https://github.com/GoogleCloudPlatform/bank-of-anthos/releases), using [semantic versioning](https://semver.org/): `vX.Y.Z`.
|
||||
|
||||
If this release includes significant feature changes, update the minor version (`Y`). Otherwise, for bug-fix releases or standard quarterly release, update the patch version `Z`).
|
||||
|
||||
2. Ensure that the following commands are in your `PATH`:
|
||||
- `gsed` (found in the `gnu-sed` Brew package for macOS, or by symlinking `sed` for Linux)
|
||||
- `gcloud`
|
||||
- `helm`
|
||||
|
||||
3. Make sure that your `gcloud` is authenticated:
|
||||
|
||||
```sh
|
||||
gcloud auth login
|
||||
gcloud auth configure-docker us-central1-docker.pkg.dev
|
||||
```
|
||||
|
||||
## Create and tag the new release
|
||||
|
||||
Run the `make-release.sh` script found inside the `docs/releasing/` directory:
|
||||
|
||||
```sh
|
||||
# assuming you are inside the root path of the bank-of-anthos repository
|
||||
export TAG=vX.Y.Z # This is the new version (e.g. `v0.3.5`)
|
||||
export REPO_PREFIX=us-central1-docker.pkg.dev/google-samples/microservices-demo # This is the Docker repository for tagged images
|
||||
export PROJECT_ID=google-samples # This is the Google Cloud project for the release CI
|
||||
./docs/releasing/make-release.sh
|
||||
```
|
||||
|
||||
This script does the following:
|
||||
1. Uses `make-docker-images.sh` to build and push a Docker image for each microservice to the previously specified repository.
|
||||
2. Uses `make-release-artifacts.sh` to regenerates (and update the image $TAGS) YAML file at `./release/kubernetes-manifests.yaml` and `./kustomize/base/`.
|
||||
3. Runs `git tag` and pushes a new branch (e.g., `release/v0.3.5`) with the changes to `./release/kubernetes-manifests.yaml`.
|
||||
|
||||
You can then browse the [Container Registry repository](https://pantheon.corp.google.com/gcr/images/google-samples/global/microservices-demo?project=google-samples) to make sure a Docker image was created for each microservice (with the new version tag).
|
||||
|
||||
## Create the PR
|
||||
|
||||
Now that the release branch has been created, you can find it in the [list of branches](https://github.com/GoogleCloudPlatform/microservices-demo/branches) and create a pull request targeting `main` (the default branch).
|
||||
|
||||
This process is going to trigger multiple CI checks as well as stage the release onto a temporary cluster. Once the PR has been approved and all checks are successfully passing, you can then merge the branch. Make sure to include the release draft (see next section) in the pull-request description for reviewers to see.
|
||||
|
||||
Once reviewed and you're ready to merge, make sure to not delete the release branch or the tags during that process.
|
||||
|
||||
## Add notes to the release
|
||||
|
||||
Once the PR has been fully merged, you are ready to create a new release for the newly created [tag](https://github.com/GoogleCloudPlatform/microservices-demo/tags).
|
||||
- Click the breadcrumbs on the row of the latest tag that was created in the [tags](https://github.com/GoogleCloudPlatform/microservices-demo/tags) page
|
||||
- Select the `Create release` option
|
||||
|
||||
The release notes should contain a brief description of the changes since the previous release (like bug fixed and new features). For inspiration, you can look at the list of [releases](https://github.com/GoogleCloudPlatform/microservices-demo/releases).
|
||||
|
||||
> ***Note:*** No assets need to be uploaded. They are picked up automatically from the tagged revision
|
||||
|
||||
## Deploy on the production environment
|
||||
|
||||
Once the release notes are published, you should then replace the version of the production environment to the newly published version.
|
||||
|
||||
1. Connect to the [online-boutique-release GKE cluster](https://pantheon.corp.google.com/kubernetes/clusters/details/us-central1-c/online-boutique-release/details?project=online-boutique-ci):
|
||||
|
||||
```sh
|
||||
gcloud container clusters get-credentials online-boutique-release \
|
||||
--zone us-central1-c --project online-boutique-ci
|
||||
```
|
||||
|
||||
2. Deploy `release/kubernetes-manifests.yaml` to it:
|
||||
|
||||
```sh
|
||||
kubectl apply -f ./release/kubernetes-manifests.yaml
|
||||
```
|
||||
|
||||
3. Remove unnecessary objects:
|
||||
|
||||
```sh
|
||||
kubectl delete service frontend-external
|
||||
kubectl delete deployment loadgenerator
|
||||
```
|
||||
|
||||
3. Make sure [cymbal-shops.retail.cymbal.dev](https://cymbal-shops.retail.cymbal.dev) works.
|
||||
|
||||
## Update major tags
|
||||
|
||||
1. Update the relevant major tag (for example, `v1`):
|
||||
|
||||
```sh
|
||||
export MAJOR_TAG=v0 # Edit this as needed (to v1/v2/v3/etc)
|
||||
git checkout release/${TAG}
|
||||
git pull
|
||||
git push --delete origin ${MAJOR_TAG} # Delete the remote tag (if it exists)
|
||||
git tag --delete ${MAJOR_TAG} # Delete the local tag (if it exists)
|
||||
git tag -a ${MAJOR_TAG} -m "Updating ${MAJOR_TAG} to its most recent release: ${TAG}"
|
||||
git push origin ${MAJOR_TAG} # Push the new tag to origin
|
||||
```
|
||||
|
||||
## Announce the new release internally
|
||||
|
||||
Once the new release is out, you can now announce it via [g/online-boutique-announce](https://groups.google.com/a/google.com/g/online-boutique-announce).
|
||||
13
docs/releasing/license_header.txt
Normal file
13
docs/releasing/license_header.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
48
docs/releasing/make-docker-images.sh
Executable file
48
docs/releasing/make-docker-images.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019 Google LLC
|
||||
#
|
||||
# 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 and pushes docker image for each demo microservice.
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
REPO_ROOT=$SCRIPT_DIR/../..
|
||||
|
||||
log() { echo "$1" >&2; }
|
||||
|
||||
TAG="${TAG:?TAG env variable must be specified}"
|
||||
REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified}"
|
||||
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified e.g. google-samples}"
|
||||
|
||||
while IFS= read -d $'\0' -r dir; do
|
||||
# build image
|
||||
svcname="$(basename "${dir}")"
|
||||
builddir="${dir}"
|
||||
#PR 516 moved cartservice build artifacts one level down to src
|
||||
if [ $svcname == "cartservice" ]
|
||||
then
|
||||
builddir="${dir}/src"
|
||||
fi
|
||||
image="${REPO_PREFIX}/$svcname:$TAG"
|
||||
image_with_sample_public_image_tag="${REPO_PREFIX}/$svcname:sample-public-image-$TAG"
|
||||
(
|
||||
cd "${builddir}"
|
||||
log "Building (and pushing) image on Google Cloud Build: ${image}"
|
||||
gcloud builds submit --project=${PROJECT_ID} --tag=${image}
|
||||
gcloud artifacts docker tags add ${image} ${image_with_sample_public_image_tag}
|
||||
)
|
||||
done < <(find "${REPO_ROOT}/src" -mindepth 1 -maxdepth 1 -type d -print0)
|
||||
|
||||
log "Successfully built and pushed all images."
|
||||
36
docs/releasing/make-helm-chart.sh
Executable file
36
docs/releasing/make-helm-chart.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Packages and pushes Online Boutique's Helm chart in public Artifact Registry.
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
REPO_ROOT=$SCRIPT_DIR/../..
|
||||
|
||||
log() { echo "$1" >&2; }
|
||||
|
||||
TAG="${TAG:?TAG env variable must be specified}"
|
||||
HELM_CHART_REPO="us-docker.pkg.dev/online-boutique-ci/charts"
|
||||
|
||||
cd ${REPO_ROOT}/helm-chart
|
||||
gsed -i "s/^appVersion:.*/appVersion: \"${TAG}\"/" Chart.yaml
|
||||
gsed -i "s/^version:.*/version: ${TAG:1}/" Chart.yaml
|
||||
helm package .
|
||||
helm push onlineboutique-${TAG:1}.tgz oci://$HELM_CHART_REPO
|
||||
|
||||
rm ./onlineboutique-${TAG:1}.tgz
|
||||
|
||||
log "Successfully built and pushed the Helm chart."
|
||||
137
docs/releasing/make-release-artifacts.sh
Executable file
137
docs/releasing/make-release-artifacts.sh
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019 Google LLC
|
||||
#
|
||||
# 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 compiles manifest files with the image tags and places them in
|
||||
# /release/...
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
REPO_ROOT=$SCRIPT_DIR/../..
|
||||
[[ -n "${DEBUG:-}" ]] && set -x
|
||||
|
||||
log() { echo "$1" >&2; }
|
||||
|
||||
TAG="${TAG:?TAG env variable must be specified}"
|
||||
REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified}"
|
||||
OUT_DIR="${OUT_DIR:-${REPO_ROOT}/release}"
|
||||
|
||||
print_license_header() {
|
||||
cat "${SCRIPT_DIR}/license_header.txt"
|
||||
echo
|
||||
}
|
||||
|
||||
print_autogenerated_warning() {
|
||||
cat<<EOF
|
||||
# ----------------------------------------------------------
|
||||
# WARNING: This file is autogenerated. Do not manually edit.
|
||||
# ----------------------------------------------------------
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# define gsed as a function on Linux for compatibility
|
||||
[ "$(uname -s)" == "Linux" ] && gsed() {
|
||||
sed "$@"
|
||||
}
|
||||
|
||||
read_manifests_except_kustomization() {
|
||||
local dir
|
||||
dir="$1"
|
||||
|
||||
while IFS= read -d $'\0' -r file; do
|
||||
echo "---"
|
||||
|
||||
# strip license headers (pattern "^# ")
|
||||
awk '
|
||||
/^[^# ]/ { found = 1 }
|
||||
found { print }' "${file}"
|
||||
done < <(find "${dir}" -name '*.yaml' ! -name 'kustomization.yaml' -type f -print0)
|
||||
}
|
||||
|
||||
mk_kubernetes_manifests() {
|
||||
out_manifest="$(read_manifests_except_kustomization "${REPO_ROOT}/kubernetes-manifests")"
|
||||
|
||||
# replace "image" repo, tag for each service
|
||||
for dir in ./src/*/
|
||||
do
|
||||
svcname="$(basename "${dir}")"
|
||||
image="$REPO_PREFIX/$svcname:$TAG"
|
||||
|
||||
pattern="^(\s*)image:\s.*$svcname(.*)(\s*)"
|
||||
replace="\1image: $image\3"
|
||||
out_manifest="$(gsed -r "s|$pattern|$replace|g" <(echo "${out_manifest}") )"
|
||||
done
|
||||
|
||||
print_license_header
|
||||
print_autogenerated_warning
|
||||
echo '# [START gke_release_kubernetes_manifests_microservices_demo]'
|
||||
echo "${out_manifest}"
|
||||
echo "# [END gke_release_kubernetes_manifests_microservices_demo]"
|
||||
}
|
||||
|
||||
mk_istio_manifests() {
|
||||
print_license_header
|
||||
print_autogenerated_warning
|
||||
echo '# [START servicemesh_release_istio_manifests_microservices_demo]'
|
||||
|
||||
# This just copies the yaml from the component (excluding kustomization.yaml)
|
||||
# since there is no easy way to render individual kustomize component resources
|
||||
read_manifests_except_kustomization "${REPO_ROOT}/kustomize/components/service-mesh-istio/"
|
||||
echo '# [END servicemesh_release_istio_manifests_microservices_demo]'
|
||||
}
|
||||
|
||||
mk_kustomize_base() {
|
||||
for file_to_copy in ./kubernetes-manifests/*.yaml
|
||||
do
|
||||
# Don't copy kustomization.yaml.
|
||||
if [[ $file_to_copy == "./kubernetes-manifests/kustomization.yaml" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
cp ${file_to_copy} ./kustomize/base/
|
||||
|
||||
service_name="$(basename "${file_to_copy}" .yaml)"
|
||||
image="$REPO_PREFIX/$service_name:$TAG"
|
||||
|
||||
# Inside redis.yaml, we use the official `redis:alpine` Docker image.
|
||||
# We don't use an image from `us-central1-docker.pkg.dev/google-samples/microservices-demo`.
|
||||
if [[ $service_name == "redis" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
pattern="^(\s*)image:\s.*${service_name}(.*)(\s*)"
|
||||
replace="\1image: ${image}\3"
|
||||
gsed --in-place --regexp-extended "s|${pattern}|${replace}|g" ./kustomize/base/${service_name}.yaml
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
mkdir -p "${OUT_DIR}"
|
||||
local k8s_manifests_file istio_manifests_file
|
||||
|
||||
k8s_manifests_file="${OUT_DIR}/kubernetes-manifests.yaml"
|
||||
mk_kubernetes_manifests > "${k8s_manifests_file}"
|
||||
log "Written ${k8s_manifests_file}"
|
||||
|
||||
istio_manifests_file="${OUT_DIR}/istio-manifests.yaml"
|
||||
mk_istio_manifests > "${istio_manifests_file}"
|
||||
log "Written ${istio_manifests_file}"
|
||||
|
||||
mk_kustomize_base
|
||||
log "Written Kustomize base"
|
||||
}
|
||||
|
||||
main
|
||||
69
docs/releasing/make-release.sh
Executable file
69
docs/releasing/make-release.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2019 Google LLC
|
||||
#
|
||||
# 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 creates a new release by:
|
||||
# - 1. building/pushing images
|
||||
# - 2. injecting tags into YAML manifests
|
||||
# - 3. creating a new git tag
|
||||
# - 4. pushing the tag/commit to main.
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
REPO_ROOT=$SCRIPT_DIR/../..
|
||||
[[ -n "${DEBUG:-}" ]] && set -x
|
||||
|
||||
log() { echo "$1" >&2; }
|
||||
fail() { log "$1"; exit 1; }
|
||||
|
||||
TAG="${TAG:?TAG env variable must be specified}"
|
||||
REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified e.g. us-central1-docker.pkg.dev\/google-samples\/microservices-demo}"
|
||||
PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified e.g. google-samples}"
|
||||
|
||||
if [[ "$TAG" != v* ]]; then
|
||||
fail "\$TAG must start with 'v', e.g. v0.1.0 (got: $TAG)"
|
||||
fi
|
||||
|
||||
# ensure there are no uncommitted changes
|
||||
if [[ $(git status -s | wc -l) -gt 0 ]]; then
|
||||
echo "error: can't have uncommitted changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# make sure local source is up to date
|
||||
git checkout main
|
||||
git pull
|
||||
|
||||
# build and push images
|
||||
"${SCRIPT_DIR}"/make-docker-images.sh
|
||||
|
||||
# update yaml
|
||||
"${SCRIPT_DIR}"/make-release-artifacts.sh
|
||||
|
||||
# build and push images
|
||||
"${SCRIPT_DIR}"/make-helm-chart.sh
|
||||
|
||||
# create git release / push to new branch
|
||||
git checkout -b "release/${TAG}"
|
||||
git add "${REPO_ROOT}/release/"
|
||||
git add "${REPO_ROOT}/kustomize/base/"
|
||||
git add "${REPO_ROOT}/helm-chart/"
|
||||
git commit --allow-empty -m "Release $TAG"
|
||||
log "Pushing k8s manifests to release/${TAG}..."
|
||||
git tag "$TAG"
|
||||
git push --set-upstream origin "release/${TAG}"
|
||||
git push --tags
|
||||
|
||||
log "Successfully tagged release $TAG."
|
||||
Reference in New Issue
Block a user