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:
61
docs/adding-new-microservice.md
Normal file
61
docs/adding-new-microservice.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Adding a new microservice
|
||||
|
||||
This document outlines the steps required to add a new microservice to the Online Boutique application.
|
||||
|
||||
## 1. Create a new directory
|
||||
|
||||
Create a new directory for your microservice within the `src/` directory. The directory name should be the name of your microservice.
|
||||
|
||||
## 2. Add source code
|
||||
|
||||
Place your microservice's source code inside the newly created directory. The structure of this directory should follow the conventions of the existing microservices. For example, a Python-based service would include at minimum the following files:
|
||||
|
||||
- `README.md`: The service's description and documentation.
|
||||
- `main.py`: The application's entry point.
|
||||
- `requirements.in`: A list of Python dependencies.
|
||||
- `Dockerfile`: To containerize the application.
|
||||
|
||||
Take a look at existing microservices for inspiration.
|
||||
|
||||
## 3. Create a Dockerfile
|
||||
|
||||
Create a `Dockerfile` in your microservice's directory. This file will define the steps to build a container image for your service.
|
||||
|
||||
Refer to this example and tweak based on your new service's needs: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/src/frontend/Dockerfile
|
||||
|
||||
## 4. Create Kubernetes manifests
|
||||
|
||||
Create a new directory under `kustomize/components/` in the root of the repository for your microservice. Inside this directory, add the necessary Kubernetes YAML files for your new microservice. This typically includes:
|
||||
|
||||
- A **Deployment** to manage your service's pods.
|
||||
- A **Service** to expose your microservice to other services within the cluster.
|
||||
|
||||
Ensure you follow the existing naming conventions and that the container image specified in the Deployment matches the one built by your `cloudbuild.yaml` and `skaffold.yaml` files.
|
||||
|
||||
Refer to this example and tweak based on your new service's needs: https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/kustomize/components/shopping-assistant
|
||||
|
||||
## 5. Update the root `kustomization.yaml` file
|
||||
|
||||
Add your newly created component to the root kustomization file so it gets picked up by the deployment cycle.
|
||||
|
||||
The file is available here: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/kustomize/kustomization.yaml
|
||||
|
||||
## 6. Update the root `skaffold.yaml`
|
||||
|
||||
Add your newly created service to the root skaffold file so the images build correctly.
|
||||
|
||||
The file is available here: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/skaffold.yaml
|
||||
|
||||
## 7. Update the Helm chart
|
||||
|
||||
Add your newly created service to the Helm chart templates and default values.
|
||||
|
||||
The chart is available here: https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/helm-chart
|
||||
|
||||
## 8. Update the documentation
|
||||
|
||||
Finally, update the project's documentation to reflect the addition of your new microservice. This may include:
|
||||
|
||||
- Adding a section to the main `README.md` if the service introduces significant new functionality.
|
||||
- Updating the architecture diagrams in the `docs/img` directory.
|
||||
- Adding a new document in the `docs` directory if the service requires detailed explanation.
|
||||
106
docs/cloudshell-tutorial.md
Normal file
106
docs/cloudshell-tutorial.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Online Boutique quickstart
|
||||
|
||||
This tutorial shows you how to deploy **[Online Boutique](https://github.com/GoogleCloudPlatform/microservices-demo)** to a Kubernetes cluster.
|
||||
|
||||
You'll be able to run Online Boutique on:
|
||||
- a local **[minikube](https://minikube.sigs.k8s.io/docs/)** cluster, which comes built in to the Cloud Shell instance
|
||||
- a **[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine)** cluster using a new or existing [Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project)
|
||||
|
||||
Let's get started!
|
||||
|
||||
|
||||
## Kubernetes cluster setup
|
||||
|
||||
Set up a Kubernetes cluster using the instructions below for either **minikube** or **GKE**.
|
||||
|
||||
### Minikube instructions
|
||||
|
||||
Minikube creates a local Kubernetes cluster on Cloud Shell.
|
||||
|
||||
1. Click <walkthrough-editor-spotlight spotlightId="minikube-status-bar">minikube</walkthrough-editor-spotlight> on the status bar located at the bottom of the editor window.
|
||||
|
||||
2. The command palette will prompt you to choose which minikube cluster to control. Select **minikube** and, in the next prompt, click **Start** if the cluster has not already been started.
|
||||
|
||||
3. If prompted, authorize Cloud Shell to make a GCP API call with your credentials.
|
||||
|
||||
*It may take a few minutes for minikube to finish starting.*
|
||||
|
||||
Once minikube has started, you're ready to move on to the next step.
|
||||
|
||||
### GKE instructions
|
||||
|
||||
In order to create a GKE cluster, you'll need to **[create a Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project)** or use an existing project.
|
||||
|
||||
1. Access the command palette by going to **View > Find Command**.
|
||||
|
||||
2. Run the command **"Cloud Code: Create GKE cluster"**.
|
||||
|
||||
3. Select your GCP project.
|
||||
|
||||
4. Apply the following configurations in the GKE wizard:
|
||||
> - Zone: us-central1-b
|
||||
> - Cluster name: onlineboutique
|
||||
> - Node count: 4
|
||||
> - Machine type: e2-standard-2
|
||||
|
||||
5. Click **Create Cluster**. Once your cluster has been created successfully, you can move on to the next step.
|
||||
|
||||
|
||||
## Run on Kubernetes
|
||||
|
||||
Now you can run Online Boutique on your Kubernetes cluster!
|
||||
|
||||
1. Launch the <walkthrough-editor-spotlight spotlightId="cloud-code-status-bar">Cloud Code menu</walkthrough-editor-spotlight> from the status bar and select <walkthrough-editor-spotlight spotlightId="cloud-code-run-on-k8s">Run on Kubernetes</walkthrough-editor-spotlight>.
|
||||
|
||||
2. If prompted to select a Skaffold Profile, select **[default]**.
|
||||
|
||||
3. Select **Yes** to confirm your current context.
|
||||
|
||||
4. If you're using a GKE cluster, you'll need to confirm your container image registry.
|
||||
|
||||
5. If prompted, authorize Cloud Shell to make a GCP API call with your credentials.
|
||||
|
||||
Cloud Code uses configurations defined in <walkthrough-editor-open-file filePath="skaffold.yaml">skaffold.yaml</walkthrough-editor-open-file> to build and deploy the app. *It may take a few minutes for the deploy to complete.*
|
||||
|
||||
6. Once the app is running, the local URLs will be displayed in the <walkthrough-editor-spotlight spotlightId="output">Output</walkthrough-editor-spotlight> terminal.
|
||||
|
||||
7. To access your Online Boutique frontend service, click on the <walkthrough-spotlight-pointer spotlightId="devshell-web-preview-button" target="cloudshell">Web Preview button</walkthrough-spotlight-pointer> in the upper right of the editor window.
|
||||
|
||||
8. Select **Change Port** and enter '4503' as the port, then click **Change and Preview**. Your app will open in a new window.
|
||||
|
||||
|
||||
## Stop the app
|
||||
|
||||
To stop running the app:
|
||||
|
||||
1. Go to the <walkthrough-editor-spotlight spotlightId="activity-bar-debug">Debug view</walkthrough-editor-spotlight>
|
||||
|
||||
2. Click the **Stop** icon.
|
||||
|
||||
3. Select **Yes** to clean up deployed resources.
|
||||
|
||||
You can start, stop, and debug apps from the Debug view.
|
||||
|
||||
### Clean up
|
||||
|
||||
If you've deployed your app to a GKE cluster in your Google Cloud project, you'll want to delete the cluster to avoid incurring charges.
|
||||
|
||||
1. Navigate to the <walkthrough-editor-spotlight spotlightId="activity-bar-cloud-k8s">Cloud Code - Kubernetes view</walkthrough-editor-spotlight> in the Activity bar.
|
||||
|
||||
2. Under the <walkthrough-editor-spotlight spotlightId="cloud-code-gke-explorer">Google Kubernetes Engine Explorer tab</walkthrough-editor-spotlight>, right-click on your cluster and select **Delete Cluster**.
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
<walkthrough-conclusion-trophy></walkthrough-conclusion-trophy>
|
||||
|
||||
Congratulations! You've successfully deployed Online Boutique using Cloud Shell.
|
||||
|
||||
<walkthrough-inline-feedback></walkthrough-inline-feedback>
|
||||
|
||||
##### What's next?
|
||||
|
||||
Try other deployment options for Online Boutique:
|
||||
- **Istio/Cloud Service Mesh**: <walkthrough-editor-open-file filePath="./kustomize/components/service-mesh-istio/README.md">See these instructions</walkthrough-editor-open-file>.
|
||||
|
||||
Learn more about the [Cloud Shell](https://cloud.google.com/shell) IDE environment and the [Cloud Code](https://cloud.google.com/code) extension.
|
||||
12
docs/deploystack.md
Normal file
12
docs/deploystack.md
Normal file
@@ -0,0 +1,12 @@
|
||||
## Deploy Online Boutique with DeployStack
|
||||
|
||||
The "Open in Google Cloud Shell" button below will use [DeployStack](https://cloud.google.com/shell/docs/cloud-shell-tutorials/deploystack/overview) to deploy Online Boutique to a new Google Kubernetes Engine (GKE) cluster.
|
||||
|
||||
<!-- TODO: remove reference to the deploystack-enable branch when it pushes to main -->
|
||||
<a href="https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fmicroservices-demo&shellonly=true&cloudshell_image=gcr.io/ds-artifacts-cloudshell/deploystack_custom_image" target="_new">
|
||||
<img alt="Open in Cloud Shell" src="https://gstatic.com/cloudssh/images/open-btn.svg">
|
||||
</a>
|
||||
|
||||
The button will open up a [Cloud Shell](https://cloud.google.com/shell) session where you will select your Google Cloud project. After project selection, the following will happen automatically:
|
||||
1. a GKE cluster will be created inside the select project
|
||||
2. Online Boutique (and its load generator) will be deployed to that cluster
|
||||
131
docs/development-guide.md
Normal file
131
docs/development-guide.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Development Guide
|
||||
|
||||
This doc explains how to build and run the Online Boutique source code locally using the `skaffold` command-line tool.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Docker for Desktop](https://www.docker.com/products/docker-desktop)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/) (can be installed via `gcloud components install kubectl` for Option 1 - GKE)
|
||||
- [skaffold **2.0.2+**](https://skaffold.dev/docs/install/) (latest version recommended), a tool that builds and deploys Docker images in bulk.
|
||||
- Clone the repository.
|
||||
```sh
|
||||
git clone https://github.com/GoogleCloudPlatform/microservices-demo
|
||||
cd microservices-demo/
|
||||
```
|
||||
- A Google Cloud project with Google Container Registry enabled. (for Option 1 - GKE)
|
||||
- [Minikube](https://minikube.sigs.k8s.io/docs/start/) (optional for Option 2 - Local Cluster)
|
||||
- [Kind](https://kind.sigs.k8s.io/) (optional for Option 2 - Local Cluster)
|
||||
|
||||
## Option 1: Google Kubernetes Engine (GKE)
|
||||
|
||||
> 💡 Recommended if you're using Google Cloud and want to try it on
|
||||
> a realistic cluster. **Note**: If your cluster has Workload Identity enabled,
|
||||
> [see these instructions](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity#enable)
|
||||
|
||||
1. Create a Google Kubernetes Engine cluster and make sure `kubectl` is pointing
|
||||
to the cluster.
|
||||
|
||||
```sh
|
||||
gcloud services enable container.googleapis.com
|
||||
```
|
||||
|
||||
```sh
|
||||
gcloud container clusters create-auto demo --region=us-central1
|
||||
```
|
||||
|
||||
```
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
2. Enable Artifact Registry (AR) on your GCP project and configure the
|
||||
`docker` CLI to authenticate to AR:
|
||||
|
||||
```sh
|
||||
gcloud services enable artifactregistry.googleapis.com
|
||||
```
|
||||
|
||||
```sh
|
||||
gcloud artifacts repositories create microservices-demo \
|
||||
--repository-format=docker \
|
||||
--location=us \
|
||||
```
|
||||
|
||||
```sh
|
||||
gcloud auth configure-docker -q
|
||||
```
|
||||
|
||||
3. In the root of this repository, run:
|
||||
|
||||
```
|
||||
skaffold run --default-repo=us-docker.pkg.dev/PROJECT_ID/microservices-demo
|
||||
```
|
||||
|
||||
Where `PROJECT_ID` is replaced by your Google Cloud project ID.
|
||||
|
||||
This command:
|
||||
|
||||
- Builds the container images.
|
||||
- Pushes them to AR.
|
||||
- Applies the `./kubernetes-manifests` deploying the application to
|
||||
Kubernetes.
|
||||
|
||||
**Troubleshooting:** If you get "No space left on device" error on Google
|
||||
Cloud Shell, you can build the images on Google Cloud Build: [Enable the
|
||||
Cloud Build
|
||||
API](https://console.cloud.google.com/flows/enableapi?apiid=cloudbuild.googleapis.com),
|
||||
then run `skaffold run -p gcb --default-repo=us-docker.pkg.dev/[PROJECT_ID]/microservices-demo` instead.
|
||||
|
||||
4. Find the IP address of your application, then visit the application on your
|
||||
browser to confirm installation.
|
||||
|
||||
kubectl get service frontend-external
|
||||
|
||||
5. Navigate to `http://EXTERNAL-IP` to access the web frontend.
|
||||
|
||||
## Option 2 - Local Cluster
|
||||
|
||||
1. Launch a local Kubernetes cluster with one of the following tools:
|
||||
|
||||
- To launch **Minikube** (tested with Ubuntu Linux). Please, ensure that the
|
||||
local Kubernetes cluster has at least:
|
||||
- 4 CPUs
|
||||
- 4.0 GiB memory
|
||||
- 32 GB disk space
|
||||
|
||||
```shell
|
||||
minikube start --cpus=4 --memory 4096 --disk-size 32g
|
||||
```
|
||||
|
||||
- To launch **Docker for Desktop** (tested with Mac/Windows). Go to Preferences:
|
||||
- choose “Enable Kubernetes”,
|
||||
- set CPUs to at least 3, and Memory to at least 6.0 GiB
|
||||
- on the "Disk" tab, set at least 32 GB disk space
|
||||
|
||||
- To launch a **Kind** cluster:
|
||||
|
||||
```shell
|
||||
kind create cluster
|
||||
```
|
||||
|
||||
2. Run `kubectl get nodes` to verify you're connected to the respective control plane.
|
||||
|
||||
3. Run `skaffold run` (first time will be slow, it can take ~20 minutes).
|
||||
This will build and deploy the application. If you need to rebuild the images
|
||||
automatically as you refactor the code, run `skaffold dev` command.
|
||||
|
||||
4. Run `kubectl get pods` to verify the Pods are ready and running.
|
||||
|
||||
5. Run `kubectl port-forward deployment/frontend 8080:8080` to forward a port to the frontend service.
|
||||
|
||||
6. Navigate to `localhost:8080` to access the web frontend.
|
||||
|
||||
## Adding a new microservice
|
||||
|
||||
In general, the set of core microservices for Online Boutique is fairly complete and unlikely to change in the future, but it can be useful to add an additional optional microservice that can be deployed to complement the core services.
|
||||
|
||||
See the [Adding a new microservice](adding-new-microservice.md) guide for instructions on how to add a new microservice.
|
||||
|
||||
## Cleanup
|
||||
|
||||
If you've deployed the application with `skaffold run` command, you can run
|
||||
`skaffold delete` to clean up the deployed resources.
|
||||
BIN
docs/img/architecture-diagram.png
Normal file
BIN
docs/img/architecture-diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 349 KiB |
BIN
docs/img/memorystore.png
Normal file
BIN
docs/img/memorystore.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 167 KiB |
BIN
docs/img/online-boutique-frontend-1.png
Normal file
BIN
docs/img/online-boutique-frontend-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 MiB |
BIN
docs/img/online-boutique-frontend-2.png
Normal file
BIN
docs/img/online-boutique-frontend-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 664 KiB |
39
docs/product-requirements.md
Normal file
39
docs/product-requirements.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## Product Requirements
|
||||
|
||||
This document contains a list of requirements that every change made to this repository should meet.
|
||||
Every change must:
|
||||
1. Preserve the golden user journey taken by Kubernetes beginners.
|
||||
1. Preserve the simplicity of demos.
|
||||
1. Preserve the simplicity of the GKE quickstart.
|
||||
|
||||
These requirements are about the default deployment (default configuration) of Online Boutique.
|
||||
Changes that will violate any of these rules should not be built into the default configuration of Online Boutique.
|
||||
Such changes should be opt-in only — ideally, as a [Kustomize Component](https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/kustomize) if they align with the [purpose of Online Boutique](/docs/purpose.md).
|
||||
|
||||
### 1. Preserve the golden user journey taken by Kubernetes beginners
|
||||
|
||||
The following statement about Online Boutique should always be true:
|
||||
|
||||
> A user outside of Google can deploy Online Boutique's default configuration on a [_kind_ Kubernetes cluster](https://kind.sigs.k8s.io/).
|
||||
|
||||
This statement describes the golden user journey that we expect new Kubernetes users to take while onboarding to Online Boutique.
|
||||
|
||||
Being able to run Online Boutique on a _kind_ cluster ensures that Online Boutique is free and cloud-agnostic. This is aligned with [Google's mission](https://about.google/) of making information universally accessible and useful. To be specific, Online Boutique should be useful and accessible to developers that are new to Kubernetes.
|
||||
|
||||
### 2. Preserve the simplicity of demos
|
||||
|
||||
New changes should not complicate the primary user journey showcased in live demos and tutorials.
|
||||
|
||||
Today, the primary user journey is as follows:
|
||||
1. Visit Online Boutique on a web browser.
|
||||
2. Select an item from the homepage and add the item to the cart.
|
||||
3. The checkout form is pre-populated with placeholder data (e.g. the shipping address).
|
||||
4. The user checks out and completes the order.
|
||||
|
||||
### 3. Preserve the simplicity of the GKE quickstart
|
||||
|
||||
New changes should not add additional complexity in the [main Online Boutique quickstart](https://github.com/GoogleCloudPlatform/microservices-demo#quickstart-gke).
|
||||
|
||||
In particular, new changes should not add extra required steps or additional required tools in that quickstart.
|
||||
|
||||
Ideally, extensions to Online Boutique's default functionality (such as a new microservice or a new cloud service integration) should be added as a [Kustomize Component](https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/kustomize/components) which users can optionally opt into.
|
||||
15
docs/purpose.md
Normal file
15
docs/purpose.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## Purpose
|
||||
|
||||
Today, the primary purpose of Online Boutique is to demonstrate:
|
||||
|
||||
* [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine)
|
||||
* [Anthos](https://cloud.google.com/anthos)
|
||||
* [Google Cloud Operations](https://cloud.google.com/products/operations)
|
||||
* tools and technologies commonly used alongside the above products
|
||||
|
||||
while being accessible and useful to all new Kubernetes users.
|
||||
|
||||
### Why does the purpose matter?
|
||||
|
||||
We filter and prioritize the work to be done in this repository based on the purpose defined above.
|
||||
If you wish to make changes to this repository that do not align with the above purpose, we encourage you to maintain your own fork of Online Boutique.
|
||||
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