mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-28 06:19:20 +08:00
☀️ feat: Enhancing OpenIM with Integrated E2E Testing and CI/CD Enhancements (#1359)
* cicd: robot automated Change * feat: add api test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add api test make file Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add openim e2e test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add openim e2e test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * fix: Fixed some unused scripts and some names Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * docs: optimize openim docs Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add prom address Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add openim info test * feat: add openim images config path Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * fix: fix tim file rename * fix: fix tim file rename * fix: fix tim file rename * fix: fix tim file rename * fix: add openim test e2e * feat: add openim test .keep Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: add openim test .keep Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: openim test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: openim test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> * feat: openim test Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --------- Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> Co-authored-by: cubxxw <cubxxw@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Contrib Documentation Index
|
||||
|
||||
## 📚 General Information
|
||||
- [📄 README](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/README.md) - General introduction to the contribution documentation.
|
||||
- [📑 Development Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/development.md) - Guidelines for setting up a development environment.
|
||||
|
||||
## 🛠 Setup and Installation
|
||||
- [🌍 Environment Setup](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/environment.md) - Instructions on setting up the development environment.
|
||||
- [🐳 Docker Installation Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-docker.md) - Steps to install Docker for container management.
|
||||
- [🔧 OpenIM Linux System Installation](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/install-openim-linux-system.md) - Guide for installing OpenIM on a Linux system.
|
||||
|
||||
## 💻 Development Practices
|
||||
- [👨💻 Code Conventions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/code-conventions.md) - Coding standards to follow for consistency.
|
||||
- [📐 Directory Structure](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/directory.md) - Explanation of the repository's directory layout.
|
||||
- [🔀 Git Workflow](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/git-workflow.md) - The workflow for using Git in this project (note the file extension error).
|
||||
- [💾 GitHub Workflow](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/github-workflow.md) - Workflow guidelines for GitHub.
|
||||
|
||||
## 🧪 Testing and Deployment
|
||||
- [⚙️ CI/CD Actions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/cicd-actions.md) - Continuous integration and deployment configurations.
|
||||
- [🚀 Offline Deployment](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/offline-deployment.md) - How to deploy the application offline.
|
||||
|
||||
## 🔧 Utilities and Tools
|
||||
- [📦 Protoc Tools](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/protoc-tools.md) - Protobuf compiler-related utilities.
|
||||
- [🔨 Utility Go](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-go.md) - Go utilities and helper functions.
|
||||
- [🛠 Makefile Utilities](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-makefile.md) - Makefile scripts for automation.
|
||||
- [📜 Script Utilities](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/util-scripts.md) - Utility scripts for development.
|
||||
|
||||
## 📋 Standards and Conventions
|
||||
- [🚦 Commit Guidelines](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/commit.md) - Standards for writing commit messages.
|
||||
- [✅ Testing Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/test.md) - Guidelines and conventions for writing tests.
|
||||
- [📈 Versioning](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/version.md) - Version management for the project.
|
||||
|
||||
## 🖼 Additional Resources
|
||||
- [🌐 API Reference](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/api.md) - Detailed API documentation.
|
||||
- [📚 Go Code Standards](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/go-code.md) - Go programming language standards.
|
||||
- [🖼 Image Guidelines](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/images.md) - Guidelines for image assets.
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
- [🔍 Error Code Reference](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/error-code.md) - List of error codes and their meanings.
|
||||
- [🐚 Bash Logging](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/bash-log.md) - Logging standards for bash scripts.
|
||||
- [📈 Logging Conventions](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/logging.md) - Conventions for application logging.
|
||||
- [🛠 Local Actions Guide](https://github.com/openimsdk/open-im-server/tree/main/docs/contrib/local-actions.md) - How to perform local actions for troubleshooting.
|
||||
@@ -0,0 +1,5 @@
|
||||
## Interface Standards
|
||||
|
||||
Our project, OpenIM, adheres to the [OpenAPI 3.0](https://spec.openapis.org/oas/latest.html) interface standards.
|
||||
|
||||
> Chinese translation: [OpenAPI Specification Chinese Translation](https://fishead.gitbook.io/openapi-specification-zhcn-translation/3.0.0.zhcn)
|
||||
@@ -0,0 +1,47 @@
|
||||
## OpenIM Logging System: Design and Usage
|
||||
|
||||
**PATH:** `scripts/lib/logging.sh`
|
||||
|
||||
### Introduction
|
||||
|
||||
OpenIM, an intricate project, requires a robust logging mechanism to diagnose issues, maintain system health, and provide insights. A custom-built logging system embedded within OpenIM ensures consistent and structured logs. Let's delve into the design of this logging system and understand its various functions and their usage scenarios.
|
||||
|
||||
### Design Overview
|
||||
|
||||
1. **Initialization**: The system begins by determining the verbosity level through the `OPENIM_VERBOSE` variable. If it's not set, a default value of 5 is assigned. This verbosity level dictates the depth of the log details.
|
||||
2. **Log File Setup**: Logs are stored in the directory specified by `OPENIM_OUTPUT`. If this variable isn't explicitly set, it defaults to the `_output` directory relative to the script location. Each log file is named based on the date to facilitate easy identification.
|
||||
3. **Logging Function**: The `echo_log()` function plays a pivotal role by writing messages to both the console (stdout) and the log file.
|
||||
4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `ENABLE_LOGGING=flase`.
|
||||
|
||||
### Key Functions & Their Usages
|
||||
|
||||
1. **Error Handling**:
|
||||
- `openim::log::errexit()`: Activated when a command exits with an error. It prints a call tree showing the sequence of functions leading to the error and then calls `openim::log::error_exit()` with relevant information.
|
||||
- `openim::log::install_errexit()`: Sets up the trap for catching errors and ensures that the error handler (`errexit`) gets propagated to various script constructs like functions, expansions, and subshells.
|
||||
2. **Logging Levels**:
|
||||
- `openim::log::error()`: Logs error messages with a timestamp. The log message starts with '!!!' to indicate its severity.
|
||||
- `openim::log::info()`: Provides informational messages. The display of these messages is governed by the verbosity level (`OPENIM_VERBOSE`).
|
||||
- `openim::log::progress()`: Designed for logging progress messages or creating progress bars.
|
||||
- `openim::log::status()`: Logs status messages with a timestamp, prefixing each entry with '+++' for easy identification.
|
||||
- `openim::log::success()`: Highlights successful operations with a bright green prefix. It's ideal for visually signifying operations that completed successfully.
|
||||
3. **Exit and Stack Trace**:
|
||||
- `openim::log::error_exit()`: Logs an error message, dumps the call stack, and exits the script with a specified exit code.
|
||||
- `openim::log::stack()`: Prints out a stack trace, showing the call hierarchy leading to the point where this function was invoked.
|
||||
4. **Usage Information**:
|
||||
- `openim::log::usage() & openim::log::usage_from_stdin()`: Both functions provide a mechanism to display usage instructions. The former accepts arguments directly, while the latter reads them from stdin.
|
||||
5. **Test Function**:
|
||||
- `openim::log::test_log()`: This function is a test suite to verify that all logging functions are operating as expected.
|
||||
|
||||
### Usage Scenario
|
||||
|
||||
Imagine a situation where an OpenIM operation fails, and you need to ascertain the cause. With the logging system in place, you can:
|
||||
|
||||
- Check the log file for the specific day to find error messages with the '!!!' prefix.
|
||||
- View the call tree and stack trace to trace back the sequence of operations leading to the failure.
|
||||
- Use the verbosity level to filter out unnecessary details and focus on the crux of the issue.
|
||||
|
||||
This systematic and structured approach greatly simplifies the debugging process, making system maintenance more efficient.
|
||||
|
||||
### Conclusion
|
||||
|
||||
OpenIM's logging system is a testament to the importance of structured and detailed logging in complex projects. By using this logging mechanism, developers and system administrators can streamline troubleshooting and ensure the seamless operation of the OpenIM project.
|
||||
@@ -0,0 +1,129 @@
|
||||
# Continuous Integration and Automation
|
||||
|
||||
Every change on the OpenIM repository, either made through a pull request or direct push, triggers the continuous integration pipelines defined within the same repository. Needless to say, all the OpenIM contributions can be merged until all the checks pass (AKA having green builds).
|
||||
|
||||
- [Continuous Integration and Automation](#continuous-integration-and-automation)
|
||||
- [CI Platforms](#ci-platforms)
|
||||
- [GitHub Actions](#github-actions)
|
||||
- [Running locally](#running-locally)
|
||||
|
||||
## CI Platforms
|
||||
|
||||
Currently, there are two different platforms involved in running the CI processes:
|
||||
|
||||
- GitHub actions
|
||||
- Drone pipelines on CNCF infrastructure
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
All the existing GitHub Actions are defined as YAML files under the `.github/workflows` directory. These can be grouped into:
|
||||
|
||||
- **PR Checks**. These actions run all the required validations upon PR creation and update. Covering the DCO compliance check, `x86_64` test batteries (unit, integration, smoke), and code coverage.
|
||||
- **Repository automation**. Currently, it only covers issues and epic grooming.
|
||||
|
||||
Everything runs on GitHub's provided runners; thus, the tests are limited to run in `x86_64` architectures.
|
||||
|
||||
|
||||
## Running locally
|
||||
|
||||
A contributor should verify their changes locally to speed up the pull request process. Fortunately, all the CI steps can be on local environments, except for the publishing ones, through either of the following methods:
|
||||
|
||||
**User Makefile:**
|
||||
```bash
|
||||
root@PS2023EVRHNCXG:~/workspaces/openim/Open-IM-Server# make help 😊
|
||||
|
||||
Usage: make <TARGETS> <OPTIONS> ...
|
||||
|
||||
Targets:
|
||||
|
||||
all Run tidy, gen, add-copyright, format, lint, cover, build 🚀
|
||||
build Build binaries by default 🛠️
|
||||
multiarch Build binaries for multiple platforms. See option PLATFORMS. 🌍
|
||||
tidy tidy go.mod ✨
|
||||
vendor vendor go.mod 📦
|
||||
style code style -> fmt,vet,lint 💅
|
||||
fmt Run go fmt against code. ✨
|
||||
vet Run go vet against code. ✅
|
||||
lint Check syntax and styling of go sources. ✔️
|
||||
format Gofmt (reformat) package sources (exclude vendor dir if existed). 🔄
|
||||
test Run unit test. 🧪
|
||||
cover Run unit test and get test coverage. 📊
|
||||
updates Check for updates to go.mod dependencies 🆕
|
||||
imports task to automatically handle import packages in Go files using goimports tool 📥
|
||||
clean Remove all files that are created by building. 🗑️
|
||||
image Build docker images for host arch. 🐳
|
||||
image.multiarch Build docker images for multiple platforms. See option PLATFORMS. 🌍🐳
|
||||
push Build docker images for host arch and push images to registry. 📤🐳
|
||||
push.multiarch Build docker images for multiple platforms and push images to registry. 🌍📤🐳
|
||||
tools Install dependent tools. 🧰
|
||||
gen Generate all necessary files. 🧩
|
||||
swagger Generate swagger document. 📖
|
||||
serve-swagger Serve swagger spec and docs. 🚀📚
|
||||
verify-copyright Verify the license headers for all files. ✅
|
||||
add-copyright Add copyright ensure source code files have license headers. 📄
|
||||
release release the project 🎉
|
||||
help Show this help info. ℹ️
|
||||
help-all Show all help details info. ℹ️📚
|
||||
|
||||
Options:
|
||||
|
||||
DEBUG Whether or not to generate debug symbols. Default is 0. ❓
|
||||
|
||||
BINS Binaries to build. Default is all binaries under cmd. 🛠️
|
||||
This option is available when using: make {build}(.multiarch) 🧰
|
||||
Example: make build BINS="openim-api openim_cms_api".
|
||||
|
||||
PLATFORMS Platform to build for. Default is linux_arm64 and linux_amd64. 🌍
|
||||
This option is available when using: make {build}.multiarch 🌍
|
||||
Example: make multiarch PLATFORMS="linux_s390x linux_mips64
|
||||
linux_mips64le darwin_amd64 windows_amd64 linux_amd64 linux_arm64".
|
||||
|
||||
V Set to 1 enable verbose build. Default is 0. 📝
|
||||
```
|
||||
|
||||
|
||||
How to Use Makefile to Help Contributors Build Projects Quickly 😊
|
||||
|
||||
The `make help` command is a handy tool that provides useful information on how to utilize the Makefile effectively. By running this command, contributors will gain insights into various targets and options available for building projects swiftly.
|
||||
|
||||
Here's a breakdown of the targets and options provided by the Makefile:
|
||||
|
||||
**Targets 😃**
|
||||
|
||||
1. `all`: This target runs multiple tasks like `tidy`, `gen`, `add-copyright`, `format`, `lint`, `cover`, and `build`. It ensures comprehensive project building.
|
||||
2. `build`: The primary target that compiles binaries by default. It is particularly useful for creating the necessary executable files.
|
||||
3. `multiarch`: A target that builds binaries for multiple platforms. Contributors can specify the desired platforms using the `PLATFORMS` option.
|
||||
4. `tidy`: This target cleans up the `go.mod` file, ensuring its consistency.
|
||||
5. `vendor`: A target that updates the project dependencies based on the `go.mod` file.
|
||||
6. `style`: Checks the code style using tools like `fmt`, `vet`, and `lint`. It ensures a consistent coding style throughout the project.
|
||||
7. `fmt`: Formats the code using the `go fmt` command, ensuring proper indentation and formatting.
|
||||
8. `vet`: Runs the `go vet` command to identify common errors in the code.
|
||||
9. `lint`: Validates the syntax and styling of Go source files using a linter.
|
||||
10. `format`: Reformats the package sources using `gofmt`. It excludes the vendor directory if it exists.
|
||||
11. `test`: Executes unit tests to ensure the functionality and stability of the code.
|
||||
12. `cover`: Performs unit tests and calculates the test coverage of the code.
|
||||
13. `updates`: Checks for updates to the project's dependencies specified in the `go.mod` file.
|
||||
14. `imports`: Automatically handles import packages in Go files using the `goimports` tool.
|
||||
15. `clean`: Removes all files generated during the build process, effectively cleaning up the project directory.
|
||||
16. `image`: Builds Docker images for the host architecture.
|
||||
17. `image.multiarch`: Similar to the `image` target, but it builds Docker images for multiple platforms. Contributors can specify the desired platforms using the `PLATFORMS` option.
|
||||
18. `push`: Builds Docker images for the host architecture and pushes them to a registry.
|
||||
19. `push.multiarch`: Builds Docker images for multiple platforms and pushes them to a registry. Contributors can specify the desired platforms using the `PLATFORMS` option.
|
||||
20. `tools`: Installs the necessary tools or dependencies required by the project.
|
||||
21. `gen`: Generates all the required files automatically.
|
||||
22. `swagger`: Generates the swagger document for the project.
|
||||
23. `serve-swagger`: Serves the swagger specification and documentation.
|
||||
24. `verify-copyright`: Verifies the license headers for all project files.
|
||||
25. `add-copyright`: Adds copyright headers to the source code files.
|
||||
26. `release`: Releases the project, presumably for distribution.
|
||||
27. `help`: Displays information about available targets and options.
|
||||
28. `help-all`: Shows detailed information about all available targets and options.
|
||||
|
||||
**Options 😄**
|
||||
|
||||
1. `DEBUG`: A boolean option that determines whether or not to generate debug symbols. The default value is 0 (false).
|
||||
2. `BINS`: Specifies the binaries to build. By default, it builds all binaries under the `cmd` directory. Contributors can provide a list of specific binaries using this option.
|
||||
3. `PLATFORMS`: Specifies the platforms to build for. The default platforms are `linux_arm64` and `linux_amd64`. Contributors can specify multiple platforms by providing a space-separated list of platform names.
|
||||
4. `V`: A boolean option that enables verbose build output when set to 1 (true). The default value is 0 (false).
|
||||
|
||||
With these targets and options in place, contributors can efficiently build projects using the Makefile. Happy coding! 🚀😊
|
||||
@@ -24,7 +24,48 @@
|
||||
- Do not use uppercase characters, underscores, or dashes in package names.
|
||||
- Please consider parent directory name when choosing a package name. For example, `pkg/controllers/autoscaler/foo.go` should say `package autoscaler` not `package autoscalercontroller`.
|
||||
- Unless there's a good reason, the `package foo` line should match the name of the directory in which the `.go` file exists.
|
||||
- Importers can use a different name if they need to disambiguate.
|
||||
- Importers can use a different name if they need to disambiguate.Ⓜ️
|
||||
|
||||
## OpenIM Naming Conventions Guide
|
||||
|
||||
Welcome to the OpenIM Naming Conventions Guide. This document outlines the best practices and standardized naming conventions that our project follows to maintain clarity, consistency, and alignment with industry standards, specifically taking cues from the Google Naming Conventions.
|
||||
|
||||
### 1. General File Naming
|
||||
|
||||
Files within the OpenIM project should adhere to the following rules:
|
||||
|
||||
+ Both hyphens (`-`) and underscores (`_`) are acceptable in file names.
|
||||
+ Underscores (`_`) are preferred for general files to enhance readability and compatibility.
|
||||
+ For example: `data_processor.py`, `user_profile_generator.go`
|
||||
|
||||
### 2. Special File Types
|
||||
|
||||
#### a. Script and Markdown Files
|
||||
|
||||
+ Bash scripts and Markdown files should use hyphens (`-`) to facilitate better searchability and compatibility in web browsers.
|
||||
+ For example: `deploy-script.sh`, `project-overview.md`
|
||||
|
||||
#### b. Uppercase Markdown Documentation
|
||||
|
||||
+ Markdown files with uppercase names, such as `README`, may include underscores (`_`) to separate words if necessary.
|
||||
+ For example: `README_SETUP.md`, `CONTRIBUTING_GUIDELINES.md`
|
||||
|
||||
### 3. Directory Naming
|
||||
|
||||
+ Directories must use hyphens (`-`) exclusively to maintain a clean and organized file structure.
|
||||
+ For example: `image-assets`, `user-data`
|
||||
|
||||
### 4. Configuration Files
|
||||
|
||||
+ Configuration files, including but not limited to `.yaml` files, should use hyphens (`-`).
|
||||
+ For example: `app-config.yaml`, `logging-config.yaml`
|
||||
|
||||
### Best Practices
|
||||
|
||||
+ Keep names concise but descriptive enough to convey the file's purpose or contents at a glance.
|
||||
+ Avoid using spaces in names; use hyphens or underscores instead to improve compatibility across different operating systems and environments.
|
||||
+ Stick to lowercase naming where possible for consistency and to prevent issues with case-sensitive systems.
|
||||
+ Include version numbers or dates in file names if the file is subject to updates, following the format: `project-plan-v1.2.md` or `backup-2023-03-15.sql`.
|
||||
|
||||
## Directory and file conventions
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
## Commit Standards
|
||||
|
||||
Our project, OpenIM, follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) standards.
|
||||
|
||||
> Chinese translation: [Conventional Commits: A Specification Making Commit Logs More Human and Machine-friendly](https://tool.lu/en_US/article/2ac/preview)
|
||||
|
||||
In addition to adhering to these standards, we encourage all contributors to the OpenIM project to ensure that their commit messages are clear and descriptive. This helps in maintaining a clean and meaningful project history. Each commit message should succinctly describe the changes made and, where necessary, the reasoning behind those changes.
|
||||
|
||||
To facilitate a streamlined process, we also recommend using appropriate commit type based on Conventional Commits guidelines such as `fix:` for bug fixes, `feat:` for new features, and so forth. Understanding and using these conventions helps in generating automatic release notes, making versioning easier, and improving overall readability of commit history.
|
||||
@@ -0,0 +1,3 @@
|
||||
## Catalog Service Interface Specification
|
||||
|
||||
+ [https://github.com/kubecub/go-project-layout](https://github.com/kubecub/go-project-layout)
|
||||
@@ -136,13 +136,13 @@ For convenience, configuration through modifying environment variables is recomm
|
||||
export PASSWORD="openIM123"
|
||||
```
|
||||
|
||||
+ USER
|
||||
+ OPENIM_USER
|
||||
|
||||
+ **Description**: Username for mysql, mongodb, redis, and minio.
|
||||
+ **Default**: `root`
|
||||
|
||||
```bash
|
||||
export USER="root"
|
||||
export OPENIM_USER="root"
|
||||
```
|
||||
|
||||
+ API_URL
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
## Error Code Standards
|
||||
|
||||
Error codes are one of the important means for users to locate and solve problems. When an application encounters an exception, users can quickly locate and resolve the problem based on the error code and the description and solution of the error code in the documentation.
|
||||
|
||||
### Error Code Naming Standards
|
||||
|
||||
- Follow CamelCase notation;
|
||||
- Error codes are divided into two levels. For example, `InvalidParameter.BindError`, separated by a `.`. The first-level error code is platform-level, and the second-level error code is resource-level, which can be customized according to the scenario;
|
||||
- The second-level error code can only use English letters or numbers ([a-zA-Z0-9]), and should use standard English word spelling, standard abbreviations, RFC term abbreviations, etc.;
|
||||
- The error code should avoid multiple definitions of the same semantics, for example: `InvalidParameter.ErrorBind`, `InvalidParameter.BindError`.
|
||||
|
||||
### First-Level Common Error Codes
|
||||
|
||||
| Error Code | Error Description | Error Type |
|
||||
| ---------------- | ------------------------------------------------------------ | ---------- |
|
||||
| InternalError | Internal error | 1 |
|
||||
| InvalidParameter | Parameter error (including errors in parameter type, format, value, etc.) | 0 |
|
||||
| AuthFailure | Authentication / Authorization error | 0 |
|
||||
| ResourceNotFound | Resource does not exist | 0 |
|
||||
| FailedOperation | Operation failed | 2 |
|
||||
|
||||
> Error Type: 0 represents the client, 1 represents the server, 2 represents both the client / server.
|
||||
@@ -0,0 +1,284 @@
|
||||
---
|
||||
title: "GitHub Workflow"
|
||||
weight: 6
|
||||
description: |
|
||||
This document is an overview of the GitHub workflow used by the
|
||||
open-im-server project. It includes tips and suggestions on keeping your
|
||||
local environment in sync with upstream and how to maintain good
|
||||
commit hygiene.
|
||||
---
|
||||
|
||||

|
||||
|
||||
## 1. Fork in the cloud
|
||||
|
||||
1. Visit https://github.com/openimsdk/open-im-server
|
||||
2. Click `Fork` button (top right) to establish a cloud-based fork.
|
||||
|
||||
## 2. Clone fork to local storage
|
||||
|
||||
Per Go's [workspace instructions][go-workspace], place open-im-server' code on your
|
||||
`GOPATH` using the following cloning procedure.
|
||||
|
||||
[go-workspace]: https://golang.org/doc/code.html#Workspaces
|
||||
|
||||
In your shell, define a local working directory as `working_dir`. If your `GOPATH` has multiple paths, pick
|
||||
just one and use it instead of `$GOPATH`. You must follow exactly this pattern,
|
||||
neither `$GOPATH/src/github.com/${your github profile name}/`
|
||||
nor any other pattern will work.
|
||||
|
||||
```sh
|
||||
export working_dir="$(go env GOPATH)/src/k8s.io"
|
||||
```
|
||||
|
||||
If you already do Go development on github, the `k8s.io` directory
|
||||
will be a sibling to your existing `github.com` directory.
|
||||
|
||||
Set `user` to match your github profile name:
|
||||
|
||||
```sh
|
||||
export user=<your github profile name>
|
||||
```
|
||||
|
||||
Both `$working_dir` and `$user` are mentioned in the figure above.
|
||||
|
||||
Create your clone:
|
||||
|
||||
```sh
|
||||
mkdir -p $working_dir
|
||||
cd $working_dir
|
||||
git clone https://github.com/$user/open-im-server.git
|
||||
# or: git clone git@github.com:$user/open-im-server.git
|
||||
|
||||
cd $working_dir/open-im-server
|
||||
git remote add upstream https://github.com/openimsdk/open-im-server.git
|
||||
# or: git remote add upstream git@github.com:openimsdk/open-im-server.git
|
||||
|
||||
# Never push to upstream master
|
||||
git remote set-url --push upstream no_push
|
||||
|
||||
# Confirm that your remotes make sense:
|
||||
git remote -v
|
||||
```
|
||||
|
||||
## 3. Create a Working Branch
|
||||
|
||||
Get your local master up to date. Note that depending on which repository you are working from,
|
||||
the default branch may be called "main" instead of "master".
|
||||
|
||||
```sh
|
||||
cd $working_dir/open-im-server
|
||||
git fetch upstream
|
||||
git checkout master
|
||||
git rebase upstream/master
|
||||
```
|
||||
|
||||
Create your new branch.
|
||||
|
||||
```sh
|
||||
git checkout -b myfeature
|
||||
```
|
||||
|
||||
You may now edit files on the `myfeature` branch.
|
||||
|
||||
### Building open-im-server
|
||||
|
||||
This workflow is process-specific. For quick-start build instructions for [openimsdk/open-im-server](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/util-makefile.md)
|
||||
|
||||
## 4. Keep your branch in sync
|
||||
|
||||
You will need to periodically fetch changes from the `upstream`
|
||||
repository to keep your working branch in sync. Note that depending on which repository you are working from,
|
||||
the default branch may be called 'main' instead of 'master'.
|
||||
|
||||
Make sure your local repository is on your working branch and run the
|
||||
following commands to keep it in sync:
|
||||
|
||||
```sh
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
```
|
||||
|
||||
Please don't use `git pull` instead of the above `fetch` and
|
||||
`rebase`. Since `git pull` executes a merge, it creates merge commits. These make the commit history messy
|
||||
and violate the principle that commits ought to be individually understandable
|
||||
and useful (see below).
|
||||
|
||||
You might also consider changing your `.git/config` file via
|
||||
`git config branch.autoSetupRebase always` to change the behavior of `git pull`, or another non-merge option such as `git pull --rebase`.
|
||||
|
||||
## 5. Commit Your Changes
|
||||
|
||||
You will probably want to regularly commit your changes. It is likely that you will go back and edit,
|
||||
build, and test multiple times. After a few cycles of this, you might
|
||||
[amend your previous commit](https://www.w3schools.com/git/git_amend.asp).
|
||||
|
||||
```sh
|
||||
git commit
|
||||
```
|
||||
|
||||
## 6. Push to GitHub
|
||||
|
||||
When your changes are ready for review, push your working branch to
|
||||
your fork on GitHub.
|
||||
|
||||
```sh
|
||||
git push -f <your_remote_name> myfeature
|
||||
```
|
||||
|
||||
## 7. Create a Pull Request
|
||||
|
||||
1. Visit your fork at `https://github.com/<user>/open-im-server`
|
||||
2. Click the **Compare & Pull Request** button next to your `myfeature` branch.
|
||||
3. Check out the pull request process for more details and
|
||||
advice.
|
||||
|
||||
_If you have upstream write access_, please refrain from using the GitHub UI for
|
||||
creating PRs, because GitHub will create the PR branch inside the main
|
||||
repository rather than inside your fork.
|
||||
|
||||
### Get a code review
|
||||
|
||||
Once your pull request has been opened it will be assigned to one or more
|
||||
reviewers. Those reviewers will do a thorough code review, looking for
|
||||
correctness, bugs, opportunities for improvement, documentation and comments,
|
||||
and style.
|
||||
|
||||
Commit changes made in response to review comments to the same branch on your
|
||||
fork.
|
||||
|
||||
Very small PRs are easy to review. Very large PRs are very difficult to review.
|
||||
|
||||
### Squash commits
|
||||
|
||||
After a review, prepare your PR for merging by squashing your commits.
|
||||
|
||||
All commits left on your branch after a review should represent meaningful milestones or units of work. Use commits to add clarity to the development and review process.
|
||||
|
||||
Before merging a PR, squash the following kinds of commits:
|
||||
|
||||
- Fixes/review feedback
|
||||
- Typos
|
||||
- Merges and rebases
|
||||
- Work in progress
|
||||
|
||||
Aim to have every commit in a PR compile and pass tests independently if you can, but it's not a requirement. In particular, `merge` commits must be removed, as they will not pass tests.
|
||||
|
||||
To squash your commits, perform an [interactive rebase](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History):
|
||||
|
||||
1. Check your git branch:
|
||||
|
||||
```
|
||||
git status
|
||||
```
|
||||
|
||||
The output should be similar to this:
|
||||
|
||||
```
|
||||
On branch your-contribution
|
||||
Your branch is up to date with 'origin/your-contribution'.
|
||||
```
|
||||
|
||||
2. Start an interactive rebase using a specific commit hash, or count backwards from your last commit using `HEAD~<n>`, where `<n>` represents the number of commits to include in the rebase.
|
||||
|
||||
```
|
||||
git rebase -i HEAD~3
|
||||
```
|
||||
|
||||
The output should be similar to this:
|
||||
|
||||
```
|
||||
pick 2ebe926 Original commit
|
||||
pick 31f33e9 Address feedback
|
||||
pick b0315fe Second unit of work
|
||||
|
||||
# Rebase 7c34fc9..b0315ff onto 7c34fc9 (3 commands)
|
||||
#
|
||||
# Commands:
|
||||
# p, pick <commit> = use commit
|
||||
# r, reword <commit> = use commit, but edit the commit message
|
||||
# e, edit <commit> = use commit, but stop for amending
|
||||
# s, squash <commit> = use commit, but meld into previous commit
|
||||
# f, fixup <commit> = like "squash", but discard this commit's log message
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
3. Use a command line text editor to change the word `pick` to `squash` for the commits you want to squash, then save your changes and continue the rebase:
|
||||
|
||||
```
|
||||
pick 2ebe926 Original commit
|
||||
squash 31f33e9 Address feedback
|
||||
pick b0315fe Second unit of work
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
The output after saving changes should look similar to this:
|
||||
|
||||
```
|
||||
[detached HEAD 61fdded] Second unit of work
|
||||
Date: Thu Mar 5 19:01:32 2020 +0100
|
||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
...
|
||||
|
||||
Successfully rebased and updated refs/heads/master.
|
||||
```
|
||||
4. Force push your changes to your remote branch:
|
||||
|
||||
```
|
||||
git push --force
|
||||
```
|
||||
|
||||
For mass automated fixups such as automated doc formatting, use one or more
|
||||
commits for the changes to tooling and a final commit to apply the fixup en
|
||||
masse. This makes reviews easier.
|
||||
|
||||
An alternative to this manual squashing process is to use the Prow and Tide based automation that is configured in GitHub: adding a comment to your PR with `/label tide/merge-method-squash` will trigger the automation so that GitHub squash your commits onto the target branch once the PR is approved. Using this approach simplifies things for those less familiar with Git, but there are situations in where it's better to squash locally; reviewers will have this in mind and can ask for manual squashing to be done.
|
||||
|
||||
By squashing locally, you control the commit message(s) for your work, and can separate a large PR into logically separate changes.
|
||||
For example: you have a pull request that is code complete and has 24 commits. You rebase this against the same merge base, simplifying the change to two commits. Each of those two commits represents a single logical change and each commit message summarizes what changes. Reviewers see that the set of changes are now understandable, and approve your PR.
|
||||
|
||||
## Merging a commit
|
||||
|
||||
Once you've received review and approval, your commits are squashed, your PR is ready for merging.
|
||||
|
||||
Merging happens automatically after both a Reviewer and Approver have approved the PR. If you haven't squashed your commits, they may ask you to do so before approving a PR.
|
||||
|
||||
## Reverting a commit
|
||||
|
||||
In case you wish to revert a commit, use the following instructions.
|
||||
|
||||
_If you have upstream write access_, please refrain from using the
|
||||
`Revert` button in the GitHub UI for creating the PR, because GitHub
|
||||
will create the PR branch inside the main repository rather than inside your fork.
|
||||
|
||||
- Create a branch and sync it with upstream. Note that depending on which repository you are working from, the default branch may be called 'main' instead of 'master'.
|
||||
```sh
|
||||
# create a branch
|
||||
git checkout -b myrevert
|
||||
|
||||
# sync the branch with upstream
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
```
|
||||
- If the commit you wish to revert is a *merge commit*, use this command:
|
||||
```sh
|
||||
# SHA is the hash of the merge commit you wish to revert
|
||||
git revert -m 1 <SHA>
|
||||
```
|
||||
If it is a *single commit*, use this command:
|
||||
```sh
|
||||
# SHA is the hash of the single commit you wish to revert
|
||||
git revert <SHA>
|
||||
```
|
||||
|
||||
- This will create a new commit reverting the changes. Push this new commit to your remote.
|
||||
```sh
|
||||
git push <your_remote_name> myrevert
|
||||
```
|
||||
|
||||
- Finally, [create a Pull Request](#7-create-a-pull-request) using this branch.
|
||||
@@ -0,0 +1,902 @@
|
||||
## OpenIM development specification
|
||||
We have very high standards for code style and specification, and we want our products to be polished and perfect
|
||||
|
||||
## 1. Code style
|
||||
|
||||
### 1.1 Code format
|
||||
|
||||
- Code must be formatted with `gofmt`.
|
||||
- Leave spaces between operators and operands.
|
||||
- It is recommended that a line of code does not exceed 120 characters. If the part exceeds, please use an appropriate line break method. But there are also some exception scenarios, such as import lines, code automatically generated by tools, and struct fields with tags.
|
||||
- The file length cannot exceed 800 lines.
|
||||
- Function length cannot exceed 80 lines.
|
||||
- import specification
|
||||
- All code must be formatted with `goimports` (it is recommended to set the code Go code editor to: run `goimports` on save).
|
||||
- Do not use relative paths to import packages, such as `import ../util/net`.
|
||||
- Import aliases must be used when the package name does not match the last directory name of the import path, or when multiple identical package names conflict.
|
||||
|
||||
```go
|
||||
// bad
|
||||
"github.com/dgrijalva/jwt-go/v4"
|
||||
|
||||
//good
|
||||
jwt "github.com/dgrijalva/jwt-go/v4"
|
||||
```
|
||||
- Imported packages are suggested to be grouped, and anonymous package references use a new group, and anonymous package references are explained.
|
||||
|
||||
```go
|
||||
import (
|
||||
// go standard package
|
||||
"fmt"
|
||||
|
||||
// third party package
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
// Anonymous packages are grouped separately, and anonymous package references are explained
|
||||
// import mysql driver
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
|
||||
// inner package
|
||||
)
|
||||
```
|
||||
|
||||
### 1.2 Declaration, initialization and definition
|
||||
|
||||
When multiple variables need to be used in a function, the `var` declaration can be used at the beginning of the function. Declaration outside the function must use `var`, do not use `:=`, it is easy to step on the scope of the variable.
|
||||
|
||||
```go
|
||||
var (
|
||||
Width int
|
||||
Height int
|
||||
)
|
||||
```
|
||||
|
||||
- When initializing a structure reference, please use `&T{}` instead of `new(T)` to make it consistent with structure initialization.
|
||||
|
||||
```go
|
||||
// bad
|
||||
sptr := new(T)
|
||||
sptr.Name = "bar"
|
||||
|
||||
// good
|
||||
sptr := &T{Name: "bar"}
|
||||
```
|
||||
|
||||
- The struct declaration and initialization format takes multiple lines and is defined as follows.
|
||||
|
||||
```go
|
||||
type User struct{
|
||||
Username string
|
||||
Email string
|
||||
}
|
||||
|
||||
user := User{
|
||||
Username: "belm",
|
||||
Email: "nosbelm@qq.com",
|
||||
}
|
||||
```
|
||||
|
||||
- Similar declarations are grouped together, and the same applies to constant, variable, and type declarations.
|
||||
|
||||
```go
|
||||
// bad
|
||||
import "a"
|
||||
import "b"
|
||||
|
||||
//good
|
||||
import (
|
||||
"a"
|
||||
"b"
|
||||
)
|
||||
```
|
||||
|
||||
- Specify container capacity where possible to pre-allocate memory for the container, for example:
|
||||
|
||||
```go
|
||||
v := make(map[int]string, 4)
|
||||
v := make([]string, 0, 4)
|
||||
```
|
||||
|
||||
- At the top level, use the standard var keyword. Do not specify a type unless it is different from the type of the expression.
|
||||
|
||||
```go
|
||||
// bad
|
||||
var s string = F()
|
||||
|
||||
func F() string { return "A" }
|
||||
|
||||
// good
|
||||
var s = F()
|
||||
// Since F already explicitly returns a string type, we don't need to explicitly specify the type of _s
|
||||
// still of that type
|
||||
|
||||
func F() string { return "A" }
|
||||
```
|
||||
|
||||
- Use `_` as a prefix for unexported top-level constants and variables.
|
||||
|
||||
```go
|
||||
// bad
|
||||
const (
|
||||
defaultHost = "127.0.0.1"
|
||||
defaultPort = 8080
|
||||
)
|
||||
|
||||
// good
|
||||
const (
|
||||
_defaultHost = "127.0.0.1"
|
||||
_defaultPort = 8080
|
||||
)
|
||||
```
|
||||
|
||||
- Embedded types (such as mutexes) should be at the top of the field list within the struct, and there must be a blank line separating embedded fields from regular fields.
|
||||
|
||||
```go
|
||||
// bad
|
||||
type Client struct {
|
||||
version int
|
||||
http.Client
|
||||
}
|
||||
|
||||
//good
|
||||
type Client struct {
|
||||
http.Client
|
||||
|
||||
version int
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 Error Handling
|
||||
|
||||
- `error` is returned as the value of the function, `error` must be handled, or the return value assigned to explicitly ignore. For `defer xx.Close()`, there is no need to explicitly handle it.
|
||||
|
||||
```go
|
||||
func load() error {
|
||||
// normal code
|
||||
}
|
||||
|
||||
// bad
|
||||
load()
|
||||
|
||||
//good
|
||||
_ = load()
|
||||
```
|
||||
|
||||
- When `error` is returned as the value of a function and there are multiple return values, `error` must be the last parameter.
|
||||
|
||||
```go
|
||||
// bad
|
||||
func load() (error, int) {
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
func load() (int, error) {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
- Perform error handling as early as possible and return as early as possible to reduce nesting.
|
||||
|
||||
```go
|
||||
// bad
|
||||
if err != nil {
|
||||
// error code
|
||||
} else {
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
if err != nil {
|
||||
// error handling
|
||||
return err
|
||||
}
|
||||
// normal code
|
||||
```
|
||||
|
||||
- If you need to use the result of the function call outside if, you should use the following method.
|
||||
|
||||
```go
|
||||
// bad
|
||||
if v, err := foo(); err != nil {
|
||||
// error handling
|
||||
}
|
||||
|
||||
// good
|
||||
v, err := foo()
|
||||
if err != nil {
|
||||
// error handling
|
||||
}
|
||||
```
|
||||
|
||||
- Errors should be judged independently, not combined with other logic.
|
||||
|
||||
```go
|
||||
// bad
|
||||
v, err := foo()
|
||||
if err != nil || v == nil {
|
||||
// error handling
|
||||
return err
|
||||
}
|
||||
|
||||
//good
|
||||
v, err := foo()
|
||||
if err != nil {
|
||||
// error handling
|
||||
return err
|
||||
}
|
||||
|
||||
if v == nil {
|
||||
// error handling
|
||||
return errors. New("invalid value v")
|
||||
}
|
||||
```
|
||||
|
||||
- If the return value needs to be initialized, use the following method.
|
||||
|
||||
```go
|
||||
v, err := f()
|
||||
if err != nil {
|
||||
// error handling
|
||||
return // or continue.
|
||||
}
|
||||
```
|
||||
|
||||
- Bug description suggestions
|
||||
- Error descriptions start with a lowercase letter and do not end with punctuation, for example:
|
||||
```go
|
||||
// bad
|
||||
errors.New("Redis connection failed")
|
||||
errors.New("redis connection failed.")
|
||||
|
||||
// good
|
||||
errors.New("redis connection failed")
|
||||
```
|
||||
- Tell users what they can do, not what they can't.
|
||||
- When declaring a requirement, use must instead of should. For example, `must be greater than 0, must match regex '[a-z]+'`.
|
||||
- When declaring that a format is incorrect, use must not. For example, `must not contain`.
|
||||
- Use may not when declaring an action. For example, `may not be specified when otherField is empty, only name may be specified`.
|
||||
- When quoting a literal string value, indicate the literal in single quotes. For example, `ust not contain '..'`.
|
||||
- When referencing another field name, specify that name in backticks. For example, must be greater than `request`.
|
||||
- When specifying unequal, use words instead of symbols. For example, `must be less than 256, must be greater than or equal to 0 (do not use larger than, bigger than, more than, higher than)`.
|
||||
- When specifying ranges of numbers, use inclusive ranges whenever possible.
|
||||
- Go 1.13 or above is recommended, and the error generation method is `fmt.Errorf("module xxx: %w", err)`.
|
||||
|
||||
### 1.4 panic processing
|
||||
|
||||
- Panic is prohibited in business logic processing.
|
||||
- In the main package, panic is only used when the program is completely inoperable, for example, the file cannot be opened, the database cannot be connected, and the program cannot run normally.
|
||||
- In the main package, use `log.Fatal` to record errors, so that the program can be terminated by the log, or the exception thrown by the panic can be recorded in the log file, which is convenient for troubleshooting.
|
||||
- An exportable interface must not panic.
|
||||
- It is recommended to use error instead of panic to convey errors in the package.
|
||||
|
||||
### 1.5 Unit Tests
|
||||
|
||||
- The unit test filename naming convention is `example_test.go`.
|
||||
- Write a test case for every important exportable function.
|
||||
- Because the functions in the unit test file are not external, the exportable structures, functions, etc. can be uncommented.
|
||||
- If `func (b *Bar) Foo` exists, the single test function can be `func TestBar_Foo`.
|
||||
|
||||
### 1.6 Type assertion failure handling
|
||||
|
||||
- A single return value from a type assertion will panic for an incorrect type. Always use the "comma ok" idiom.
|
||||
|
||||
```go
|
||||
// bad
|
||||
t := n.(int)
|
||||
|
||||
//good
|
||||
t, ok := n.(int)
|
||||
if !ok {
|
||||
// error handling
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Naming convention
|
||||
|
||||
The naming convention is a very important part of the code specification. A uniform, short, and precise naming convention can greatly improve the readability of the code and avoid unnecessary bugs.
|
||||
|
||||
### 2.1 Package Naming
|
||||
|
||||
- The package name must be consistent with the directory name, try to use a meaningful and short package name, and do not conflict with the standard library.
|
||||
- Package names are all lowercase, without uppercase or underscores, and use multi-level directories to divide the hierarchy.
|
||||
- Item names can connect multiple words with dashes.
|
||||
- Do not use plurals for the package name and the directory name where the package is located, for example, `net/url` instead of `net/urls`.
|
||||
- Don't use broad, meaningless package names like common, util, shared or lib.
|
||||
- The package name should be simple and clear, such as net, time, log.
|
||||
|
||||
### 2.2 Function Naming
|
||||
|
||||
- The function name is in camel case, and the first letter is uppercase or lowercase according to the access control decision,For example: `MixedCaps` or `mixedCaps`.
|
||||
- Code automatically generated by code generation tools (such as `xxxx.pb.go`) and underscores used to group related test cases (such as `TestMyFunction_WhatIsBeingTested`) exclude this rule.
|
||||
|
||||
In accordance with the naming conventions adopted by OpenIM and drawing reference from the Google Naming Conventions as per the guidelines available at https://google.github.io/styleguide/go/, the following expectations for naming practices within the project are set forth:
|
||||
|
||||
1. **File Names:**
|
||||
+ Both hyphens (`-`) and underscores (`_`) are permitted when naming files.
|
||||
+ A preference is established for the use of underscores (`_`), suggesting it as the best practice in general scenarios.
|
||||
2. **Script and Markdown Files:**
|
||||
+ For shell scripts (bash files) and Markdown (`.md`) documents, the use of hyphens (`-`) is recommended.
|
||||
+ This recommendation is based on the improved searchability and compatibility in web browsers when hyphens are used in names.
|
||||
3. **Directories:**
|
||||
+ A consistent approach is mandated for naming directories, exclusively using hyphens (`-`) to separate words within directory names.
|
||||
|
||||
|
||||
### 2.3 File Naming
|
||||
|
||||
- Keep the filename short and meaningful.
|
||||
- Filenames should be lowercase and use underscores to separate words.
|
||||
|
||||
### 2.4 Structure Naming
|
||||
|
||||
- The camel case is adopted, and the first letter is uppercase or lowercase according to the access control, such as `MixedCaps` or `mixedCaps`.
|
||||
- Struct names should not be verbs, but should be nouns, such as `Node`, `NodeSpec`.
|
||||
- Avoid using meaningless structure names such as Data and Info.
|
||||
- The declaration and initialization of the structure should take multiple lines, for example:
|
||||
|
||||
```go
|
||||
// User multi-line declaration
|
||||
type User struct {
|
||||
name string
|
||||
Email string
|
||||
}
|
||||
|
||||
// multi-line initialization
|
||||
u := User{
|
||||
UserName: "belm",
|
||||
Email: "nosbelm@qq.com",
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 Interface Naming
|
||||
|
||||
- The interface naming rules are basically consistent with the structure naming rules:
|
||||
- Interface names of individual functions suffixed with "er"" (e.g. Reader, Writer) can sometimes lead to broken English, but that's okay.
|
||||
- The interface name of the two functions is named after the two function names, eg ReadWriter.
|
||||
- An interface name for more than three functions, similar to a structure name.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
// Seeking to an offset before the start of the file is an error.
|
||||
// Seeking to any positive offset is legal, but the behavior of subsequent
|
||||
// I/O operations on the underlying object are implementation-dependent.
|
||||
type Seeker interface {
|
||||
Seek(offset int64, whence int) (int64, error)
|
||||
}
|
||||
|
||||
// ReadWriter is the interface that groups the basic Read and Write methods.
|
||||
type ReadWriter interface {
|
||||
reader
|
||||
Writer
|
||||
}
|
||||
```
|
||||
|
||||
### 2.6 Variable Naming
|
||||
|
||||
- Variable names must follow camel case, and the initial letter is uppercase or lowercase according to the access control decision.
|
||||
- In relatively simple (few objects, highly targeted) environments, some names can be abbreviated from full words to single letters, for example:
|
||||
- user can be abbreviated as u;
|
||||
- userID can be abbreviated as uid.
|
||||
- When using proper nouns, the following rules need to be followed:
|
||||
- If the variable is private and the proper noun is the first word, use lowercase, such as apiClient.
|
||||
- In other cases, the original wording of the noun should be used, such as APIClient, repoID, UserID.
|
||||
|
||||
Some common nouns are listed below.
|
||||
|
||||
```
|
||||
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||
var LintGonicMapper = GonicMapper{
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SSH": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
```
|
||||
|
||||
- If the variable type is bool, the name should start with Has, Is, Can or Allow, for example:
|
||||
|
||||
```go
|
||||
var has Conflict bool
|
||||
var isExist bool
|
||||
var can Manage bool
|
||||
var allowGitHook bool
|
||||
```
|
||||
|
||||
- Local variables should be as short as possible, for example, use buf to refer to buffer, and use i to refer to index.
|
||||
- The code automatically generated by the code generation tool can exclude this rule (such as the Id in `xxx.pb.go`)
|
||||
|
||||
### 2.7 Constant naming
|
||||
|
||||
- The constant name must follow the camel case, and the initial letter is uppercase or lowercase according to the access control decision.
|
||||
- If it is a constant of enumeration type, you need to create the corresponding type first:
|
||||
|
||||
```go
|
||||
// Code defines an error code type.
|
||||
type Code int
|
||||
|
||||
// Internal errors.
|
||||
const (
|
||||
// ErrUnknown - 0: An unknown error occurred.
|
||||
ErrUnknown Code = iota
|
||||
// ErrFatal - 1: An fatal error occurred.
|
||||
ErrFatal
|
||||
)
|
||||
```
|
||||
|
||||
### 2.8 Error naming
|
||||
|
||||
- The Error type should be written in the form of FooError.
|
||||
|
||||
```go
|
||||
type ExitError struct {
|
||||
// ....
|
||||
}
|
||||
```
|
||||
|
||||
- The Error variable is written in the form of ErrFoo.
|
||||
|
||||
```go
|
||||
var ErrFormat = errors. New("unknown format")
|
||||
```
|
||||
|
||||
## 3. Comment specification
|
||||
|
||||
- Each exportable name must have a comment, which briefly introduces the exported variables, functions, structures, interfaces, etc.
|
||||
- All single-line comments are used, and multi-line comments are prohibited.
|
||||
- Same as the code specification, single-line comments should not be too long, and no more than 120 characters are allowed. If it exceeds, please use a new line to display, and try to keep the format elegant.
|
||||
- A comment must be a complete sentence, starting with the content to be commented and ending with a period, `the format is // name description.`. For example:
|
||||
|
||||
```go
|
||||
// bad
|
||||
// logs the flags in the flagset.
|
||||
func PrintFlags(flags *pflag. FlagSet) {
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
// PrintFlags logs the flags in the flagset.
|
||||
func PrintFlags(flags *pflag. FlagSet) {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
- All commented out code should be deleted before submitting code review, otherwise, it should explain why it is not deleted, and give follow-up processing suggestions.
|
||||
|
||||
- Multiple comments can be separated by blank lines, as follows:
|
||||
|
||||
```go
|
||||
// Package superman implements methods for saving the world.
|
||||
//
|
||||
// Experience has shown that a small number of procedures can prove
|
||||
// helpful when attempting to save the world.
|
||||
package superman
|
||||
```
|
||||
|
||||
### 3.1 Package Notes
|
||||
|
||||
- Each package has one and only one package-level annotation.
|
||||
- Package comments are uniformly commented with // in the format of `// Package <package name> package description`, for example:
|
||||
|
||||
```go
|
||||
// Package genericclioptions contains flags which can be added to you command, bound, completed, and produce
|
||||
// useful helper functions.
|
||||
package genericclioptions
|
||||
```
|
||||
|
||||
### 3.2 Variable/Constant Comments
|
||||
|
||||
- Each variable/constant that can be exported must have a comment description, `the format is // variable name variable description`, for example:
|
||||
|
||||
```go
|
||||
// ErrSigningMethod defines invalid signing method error.
|
||||
var ErrSigningMethod = errors. New("Invalid signing method")
|
||||
```
|
||||
- When there is a large block of constant or variable definition, you can comment a general description in front, and then comment the definition of the constant in detail before or at the end of each line of constant, for example:
|
||||
```go
|
||||
// Code must start with 1xxxxx.
|
||||
const (
|
||||
// ErrSuccess - 200: OK.
|
||||
ErrSuccess int = iota + 100001
|
||||
|
||||
// ErrUnknown - 500: Internal server error.
|
||||
ErrUnknown
|
||||
|
||||
// ErrBind - 400: Error occurred while binding the request body to the struct.
|
||||
ErrBind
|
||||
|
||||
// ErrValidation - 400: Validation failed.
|
||||
ErrValidation
|
||||
)
|
||||
```
|
||||
### 3.3 Structure Annotation
|
||||
|
||||
- Each structure or interface that needs to be exported must have a comment description, the format is `// structure name structure description.`.
|
||||
- The name of the exportable member variable in the structure, if the meaning is not clear, a comment must be given and placed before the member variable or at the end of the same line. For example:
|
||||
|
||||
```go
|
||||
// User represents a user restful resource. It is also used as gorm model.
|
||||
type User struct {
|
||||
// Standard object's metadata.
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Nickname string `json:"nickname" gorm:"column:nickname"`
|
||||
Password string `json:"password" gorm:"column:password"`
|
||||
Email string `json:"email" gorm:"column:email"`
|
||||
Phone string `json:"phone" gorm:"column:phone"`
|
||||
IsAdmin int `json:"isAdmin,omitempty" gorm:"column:isAdmin"`
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 Method Notes
|
||||
|
||||
Each function or method that needs to be exported must have a comment, the format is // function name function description., for examplelike:
|
||||
|
||||
```go
|
||||
// BeforeUpdate run before update database record.
|
||||
func (p *Policy) BeforeUpdate() (err error) {
|
||||
// normal code
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 Type annotations
|
||||
|
||||
- Each type definition and type alias that needs to be exported must have a comment description, the format is `// type name type description.`, for example:
|
||||
|
||||
```go
|
||||
// Code defines an error code type.
|
||||
type Code int
|
||||
```
|
||||
|
||||
## 4. Type
|
||||
|
||||
### 4.1 Strings
|
||||
|
||||
- Empty string judgment.
|
||||
|
||||
```go
|
||||
// bad
|
||||
if s == "" {
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
if len(s) == 0 {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
- `[]byte`/`string` equality comparison.
|
||||
|
||||
```go
|
||||
// bad
|
||||
var s1 []byte
|
||||
var s2 []byte
|
||||
...
|
||||
bytes.Equal(s1, s2) == 0
|
||||
bytes.Equal(s1, s2) != 0
|
||||
|
||||
//good
|
||||
var s1 []byte
|
||||
var s2 []byte
|
||||
...
|
||||
bytes. Compare(s1, s2) == 0
|
||||
bytes. Compare(s1, s2) != 0
|
||||
```
|
||||
|
||||
- Complex strings use raw strings to avoid character escaping.
|
||||
|
||||
```go
|
||||
// bad
|
||||
regexp.MustCompile("\\.")
|
||||
|
||||
//good
|
||||
regexp.MustCompile(`\.`)
|
||||
```
|
||||
|
||||
### 4.2 Slicing
|
||||
|
||||
- Empty slice judgment.
|
||||
|
||||
```go
|
||||
// bad
|
||||
if len(slice) = 0 {
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
if slice != nil && len(slice) == 0 {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
The above judgment also applies to map and channel.
|
||||
|
||||
- Declare a slice.
|
||||
|
||||
```go
|
||||
// bad
|
||||
s := []string{}
|
||||
s := make([]string, 0)
|
||||
|
||||
//good
|
||||
var s[]string
|
||||
```
|
||||
|
||||
- slice copy.
|
||||
|
||||
```go
|
||||
// bad
|
||||
var b1, b2 []byte
|
||||
for i, v := range b1 {
|
||||
b2[i] = v
|
||||
}
|
||||
for i := range b1 {
|
||||
b2[i] = b1[i]
|
||||
}
|
||||
|
||||
//good
|
||||
copy(b2, b1)
|
||||
```
|
||||
|
||||
- slice added.
|
||||
|
||||
```go
|
||||
// bad
|
||||
var a, b []int
|
||||
for _, v := range a {
|
||||
b = append(b, v)
|
||||
}
|
||||
|
||||
//good
|
||||
var a, b []int
|
||||
b = append(b, a...)
|
||||
```
|
||||
|
||||
### 4.3 Structure
|
||||
|
||||
- struct initialization.
|
||||
|
||||
The struct is initialized in multi-line format.
|
||||
|
||||
```go
|
||||
type user struct {
|
||||
Id int64
|
||||
name string
|
||||
}
|
||||
|
||||
u1 := user{100, "Colin"}
|
||||
|
||||
u2 := user{
|
||||
Id: 200,
|
||||
Name: "Lex",
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Control Structure
|
||||
|
||||
### 5.1 if
|
||||
|
||||
- if accepts the initialization statement, the convention is to create local variables in the following way.
|
||||
|
||||
```go
|
||||
if err := loadConfig(); err != nil {
|
||||
// error handling
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
- if For variables of bool type, true and false judgments should be made directly.
|
||||
|
||||
```go
|
||||
var isAllow bool
|
||||
if isAllow {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 for
|
||||
|
||||
- Create local variables using short declarations.
|
||||
|
||||
```go
|
||||
sum := 0
|
||||
for i := 0; i < 10; i++ {
|
||||
sum += 1
|
||||
}
|
||||
```
|
||||
|
||||
- Don't use defer in for loop, defer will only be executed when the function exits.
|
||||
|
||||
```go
|
||||
// bad
|
||||
for file := range files {
|
||||
fd, err := os. Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd. Close()
|
||||
// normal code
|
||||
}
|
||||
|
||||
//good
|
||||
for file := range files {
|
||||
func() {
|
||||
fd, err := os. Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd. Close()
|
||||
// normal code
|
||||
}()
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 range
|
||||
|
||||
- If only the first item (key) is needed, discard the second.
|
||||
|
||||
```go
|
||||
for keyIndex := range keys {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
|
||||
- If only the second item is required, underline the first item.
|
||||
|
||||
```go
|
||||
sum := 0
|
||||
for _, value := range array {
|
||||
sum += value
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 switch
|
||||
|
||||
- must have default.
|
||||
|
||||
```go
|
||||
switch os := runtime.GOOS; os {
|
||||
case "linux":
|
||||
fmt.Println("Linux.")
|
||||
case "darwin":
|
||||
fmt.Println("OS X.")
|
||||
default:
|
||||
fmt.Printf("%s.\n", os)
|
||||
}
|
||||
```
|
||||
|
||||
### 5.5 goto
|
||||
- Business code prohibits the use of goto.
|
||||
- Try not to use frameworks or other low-level source code.
|
||||
|
||||
## 6. Functions
|
||||
|
||||
- Incoming variables and return variables start with a lowercase letter.
|
||||
- The number of function parameters cannot exceed 5.
|
||||
- Function grouping and ordering
|
||||
- Functions should be sorted in rough calling order.
|
||||
- Functions in the same file should be grouped by receiver.
|
||||
- Try to use value transfer instead of pointer transfer.
|
||||
- The incoming parameters are map, slice, chan, interface, do not pass pointers.
|
||||
|
||||
### 6.1 Function parameters
|
||||
|
||||
- If the function returns two or three arguments of the same type, or if the meaning of the result is not clear from the context, use named returns, otherwise it is not recommended to use named returns, for example:
|
||||
|
||||
```go
|
||||
func coordinate() (x, y float64, err error) {
|
||||
// normal code
|
||||
}
|
||||
```
|
||||
- Both incoming and returned variables start with a lowercase letter.
|
||||
- Try to pass by value instead of pointer.
|
||||
- The number of parameters cannot exceed 5.
|
||||
- Multiple return values can return up to three, and if there are more than three, please use struct.
|
||||
|
||||
### 6.2 defer
|
||||
|
||||
- When resources are created, resources should be released immediately after defer (defer can be used boldly, the performance of defer is greatly improved in Go1.14 version, and the performance loss of defer can be ignored even in performance-sensitive businesses).
|
||||
- First judge whether there is an error, and then defer to release resources, for example:
|
||||
|
||||
```go
|
||||
rep, err := http. Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
```
|
||||
|
||||
### 6.3 Method Receiver
|
||||
|
||||
- It is recommended to use the lowercase of the first English letter of the class name as the name of the receiver.
|
||||
- Don't use a single character in the name of the receiver when the function exceeds 20 lines.
|
||||
- The name of the receiver cannot use confusing names such as me, this, and self.
|
||||
|
||||
### 6.4 Nesting
|
||||
- The nesting depth cannot exceed 4 levels.
|
||||
|
||||
### 6.5 Variable Naming
|
||||
- The variable declaration should be placed before the first use of the variable as far as possible, following the principle of proximity.
|
||||
- If the magic number appears more than twice, it is forbidden to use it and use a constant instead, for example:
|
||||
|
||||
```go
|
||||
// PI...
|
||||
const Price = 3.14
|
||||
|
||||
func getAppleCost(n float64) float64 {
|
||||
return Price * n
|
||||
}
|
||||
|
||||
func getOrangeCost(n float64) float64 {
|
||||
return Price * n
|
||||
}
|
||||
```
|
||||
|
||||
## 7. GOPATH setting specification
|
||||
- After Go 1.11, the GOPATH rule has been weakened. Existing code (many libraries must have been created before 1.11) must conform to this rule. It is recommended to keep the GOPATH rule to facilitate code maintenance.
|
||||
- Only one GOPATH is recommended, multiple GOPATHs are not recommended. If multiple GOPATHs are used, the bin directory where compilation takes effect is under the first GOPATH.
|
||||
|
||||
## 8. Dependency Management
|
||||
|
||||
- Go 1.11 and above must use Go Modules.
|
||||
- When using Go Modules as a dependency management project, it is not recommended to submit the vendor directory.
|
||||
- When using Go Modules as a dependency management project, the go.sum file must be submitted.
|
||||
|
||||
### 9. Best Practices
|
||||
|
||||
- Minimize the use of global variables, but pass parameters, so that each function is "stateless". This reduces coupling and facilitates division of labor and unit testing.
|
||||
- Verify interface compliance at compile time, for example:
|
||||
|
||||
```go
|
||||
type LogHandler struct {
|
||||
h http.Handler
|
||||
log *zap. Logger
|
||||
}
|
||||
var_http.Handler = LogHandler{}
|
||||
```
|
||||
- When the server processes a request, it should create a context, save the relevant information of the request (such as requestID), and pass it in the function call chain.
|
||||
|
||||
### 9.1 Performance
|
||||
- string represents an immutable string variable, modifying string is a relatively heavy operation, and basically needs to re-apply for memory. Therefore, if there is no special need, use []byte more when you need to modify.
|
||||
- Prefer strconv over fmt.
|
||||
|
||||
### 9.2 Precautions
|
||||
|
||||
- append Be careful about automatically allocating memory, append may return a newly allocated address.
|
||||
- If you want to directly modify the value of the map, the value can only be a pointer, otherwise the original value must be overwritten.
|
||||
- map needs to be locked during concurrency.
|
||||
- The conversion of interface{} cannot be checked during compilation, it can only be checked at runtime, be careful to cause panic.
|
||||
@@ -0,0 +1,98 @@
|
||||
# OpenIM Image Management Strategy and Pulling Guide
|
||||
|
||||
OpenIM is an efficient, stable, and scalable instant messaging framework that provides convenient deployment methods through Docker images. OpenIM manages multiple image sources, hosted respectively on GitHub (ghcr), Alibaba Cloud, and Docker Hub. This document is aimed at detailing the image management strategy of OpenIM and providing the steps for pulling these images.
|
||||
|
||||
|
||||
## Image Management Strategy
|
||||
|
||||
OpenIM's versions correspond to GitHub's tag versions. Each time we release a new version and tag it on GitHub, an automated process is triggered that pushes the new Docker image version to the following three platforms:
|
||||
|
||||
1. **GitHub (ghcr.io):** We use GitHub Container Registry (ghcr.io) to host OpenIM's Docker images. This allows us to better integrate with the GitHub source code repository, providing better version control and continuous integration/deployment (CI/CD) features. You can view all GitHub images [here](https://github.com/orgs/OpenIMSDK/packages).
|
||||
2. **Alibaba Cloud (registry.cn-hangzhou.aliyuncs.com):** For users in Mainland China, we also host OpenIM's Docker images on Alibaba Cloud to provide faster pull speeds. You can view all Alibaba Cloud images on this [page](https://cr.console.aliyun.com/cn-hangzhou/instances/repositories) of Alibaba Cloud Image Service (note that you need to log in to your Alibaba Cloud account first).
|
||||
3. **Docker Hub (docker.io):** Docker Hub is the most commonly used Docker image hosting platform, and we also host OpenIM's images there to facilitate developers worldwide. You can view all Docker Hub images on the [OpenIM's Docker Hub page](https://hub.docker.com/r/openim).
|
||||
|
||||
## Base images design
|
||||
|
||||
+ [https://github.com/openim-sigs/openim-base-image](https://github.com/openim-sigs/openim-base-image)
|
||||
|
||||
## OpenIM Image Design and Usage Guide
|
||||
|
||||
OpenIM offers a comprehensive and flexible system of Docker images, available across multiple repositories. We actively maintain these images across different platforms, namely GitHub's ghcr.io, Alibaba Cloud, and Docker Hub. However, we highly recommend ghcr.io for deployment.
|
||||
|
||||
### Available Versions
|
||||
|
||||
We provide multiple versions of our images to meet different project requirements. Here's a quick overview of what you can expect:
|
||||
|
||||
1. `main`: This image corresponds to the latest version of the main branch in OpenIM. It is updated frequently, making it perfect for users who want to stay at the cutting edge of our features.
|
||||
2. `release-v3.*`: This is the image that corresponds to the latest version of OpenIM's stable release branch. It's ideal for users who prefer a balance between new features and stability.
|
||||
3. `v3.*.*`: These images are specific to each tag in OpenIM. They are preserved in their original state and are never overwritten. These are the go-to images for users who need a specific, unchanging version of OpenIM.
|
||||
|
||||
### Multi-Architecture Images
|
||||
|
||||
In order to cater to a wider range of needs, some of our images are provided with multiple architectures under `OS / Arch`. These images offer greater compatibility across different operating systems and hardware architectures, ensuring that OpenIM can be deployed virtually anywhere.
|
||||
|
||||
**Example:**
|
||||
|
||||
+ [https://github.com/OpenIMSDK/chat/pkgs/container/openim-chat/113925695?tag=v1.1.0](https://github.com/OpenIMSDK/chat/pkgs/container/openim-chat/113925695?tag=v1.1.0)
|
||||
|
||||
|
||||
## Methods and Steps for Pulling Images
|
||||
|
||||
When pulling OpenIM's Docker images, you can choose the most suitable source based on your geographic location and network conditions. Here are the steps to pull OpenIM images from each source:
|
||||
|
||||
### Select image
|
||||
|
||||
1. Choose the image repository platform you prefer. As previously mentioned, we recommend [OpenIM ghcr.io](https://github.com/orgs/OpenIMSDK/packages).
|
||||
|
||||
2. Choose the image name and image version that suits your needs. Refer to the description above for more details.
|
||||
|
||||
|
||||
### Install image
|
||||
|
||||
1. First, make sure Docker is installed on your machine. If not, you can refer to the [Docker official documentation](https://docs.docker.com/get-docker/) for installation.
|
||||
|
||||
2. Open the terminal and run the following commands to pull the images:
|
||||
|
||||
For OpenIM Server:
|
||||
|
||||
- Pull from GitHub:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/openimsdk/openim-server:latest
|
||||
```
|
||||
|
||||
- Pull from Alibaba Cloud:
|
||||
|
||||
```bash
|
||||
docker pull registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:latest
|
||||
```
|
||||
|
||||
- Pull from Docker Hub:
|
||||
|
||||
```bash
|
||||
docker pull docker.io/openim/openim-server:latest
|
||||
```
|
||||
|
||||
For OpenIM Chat:
|
||||
|
||||
- Pull from GitHub:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/openimsdk/openim-chat:latest
|
||||
```
|
||||
|
||||
- Pull from Alibaba Cloud:
|
||||
|
||||
```bash
|
||||
docker pull registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-chat:latest
|
||||
```
|
||||
|
||||
- Pull from Docker Hub:
|
||||
|
||||
```bash
|
||||
docker pull docker.io/openim/openim-chat:latest
|
||||
```
|
||||
|
||||
3. Run the `docker images` command to confirm that the image has been successfully pulled.
|
||||
|
||||
This concludes OpenIM's image management strategy and the steps for pulling images. If you have any questions, please feel free to ask.
|
||||
@@ -0,0 +1,20 @@
|
||||
## Log Standards
|
||||
|
||||
### Log Standards
|
||||
|
||||
- The unified log package `github.com/openimsdk/open-im-server/internal/pkg/log` should be used for all logging;
|
||||
- Use structured logging formats: `log.Infow`, `log.Warnw`, `log.Errorw`, etc. For example: `log.Infow("Update post function called")`;
|
||||
- All logs should start with an uppercase letter and should not end with a `.`. For example: `log.Infow("Update post function called")`;
|
||||
- Use past tense. For example, use `Could not delete B` instead of `Cannot delete B`;
|
||||
- Adhere to log level standards:
|
||||
- Debug level logs use `log.Debugw`;
|
||||
- Info level logs use `log.Infow`;
|
||||
- Warning level logs use `log.Warnw`;
|
||||
- Error level logs use `log.Errorw`;
|
||||
- Panic level logs use `log.Panicw`;
|
||||
- Fatal level logs use `log.Fatalw`.
|
||||
- Log settings:
|
||||
- Development and test environments: The log level is set to `debug`, the log format can be set to `console` / `json` as needed, and caller is enabled;
|
||||
- Production environment: The log level is set to `info`, the log format is set to `json`, and caller is enabled. (**Note**: In the early stages of going online, to facilitate troubleshooting, the log level can be set to `debug`)
|
||||
- When logging, avoid outputting sensitive information, such as passwords, keys, etc.
|
||||
- If you are calling a logging function in a function/method with a `context.Context` parameter, it is recommended to use `log.L(ctx).Infow()` for logging.
|
||||
@@ -26,11 +26,11 @@ docker pull minio/minio
|
||||
|
||||
## 2. OpenIM & Chat Images
|
||||
|
||||
**For detailed understanding of version management and storage of OpenIM and Chat**: [version.md](https://github.com/openimsdk/open-im-server/blob/main/docs/conversions/version.md)
|
||||
**For detailed understanding of version management and storage of OpenIM and Chat**: [version.md](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/version.md)
|
||||
|
||||
### OpenIM Image
|
||||
|
||||
- Get image version info: [images.md](https://github.com/openimsdk/open-im-server/blob/main/docs/conversions/images.md)
|
||||
- Get image version info: [images.md](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md)
|
||||
- Depending on the required version, execute the following command:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
# OpenIM RPC Service Test Control Script Documentation
|
||||
|
||||
This document serves as a comprehensive guide to understanding and utilizing the `test.sh` script for testing OpenIM RPC services. The `test.sh` script is a collection of bash functions designed to test various aspects of the OpenIM RPC services, ensuring that each part of the API is functioning as expected.
|
||||
|
||||
+ Scripts:https://github.com/OpenIMSDK/Open-IM-Server/tree/main/scripts/install/test.sh
|
||||
|
||||
For some complex, bulky functional tests, performance tests, and various e2e tests, We are all in the current warehouse to https://github.com/OpenIMSDK/Open-IM-Server/tree/main/test or https://github.com/openim-sigs/test-infra directory In the.
|
||||
|
||||
+ About OpenIM Feature [Test Docs](https://docs.google.com/spreadsheets/d/1zELWkwxgOOZ7u5pmYCqqaFnvZy2SVajv/edit?usp=sharing&ouid=103266350914914783293&rtpof=true&sd=true)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
The `test.sh` script is located within the `./scripts/install/` directory of the OpenIM service's codebase. To use the script, navigate to this directory from your terminal:
|
||||
|
||||
```bash
|
||||
cd ./scripts/install/
|
||||
chmod +x test.sh
|
||||
```
|
||||
|
||||
### Running the Entire Test Suite
|
||||
|
||||
To execute all available tests, you can either call the script directly or use the `make` command:
|
||||
|
||||
```
|
||||
./test.sh openim::test::test
|
||||
```
|
||||
|
||||
Or, if you have a `Makefile` that defines the `test-api` target:
|
||||
|
||||
```bash
|
||||
make test-api
|
||||
```
|
||||
|
||||
Alternatively, you can invoke specific test functions by passing them as arguments:
|
||||
|
||||
```
|
||||
./test.sh openim::test::<function_name>
|
||||
```
|
||||
|
||||
This `make` command should be equivalent to running `./test.sh openim::test::test`, provided that the `Makefile` is configured accordingly.
|
||||
|
||||
|
||||
|
||||
### Executing Individual Test Functions
|
||||
|
||||
If you wish to run a specific set of tests, you can call the relevant function by passing it as an argument to the script. Here are some examples:
|
||||
|
||||
**Message Tests:**
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::msg
|
||||
```
|
||||
|
||||
**Authentication Tests:**
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::auth
|
||||
```
|
||||
|
||||
**User Tests:**
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::user
|
||||
```
|
||||
|
||||
**Friend Tests:**
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::friend
|
||||
```
|
||||
|
||||
**Group Tests:**
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::group
|
||||
```
|
||||
|
||||
Each of these commands will run the test suite associated with the specific functionality of the OpenIM service.
|
||||
|
||||
|
||||
|
||||
### Detailed Function Test Examples
|
||||
|
||||
T**esting Message Sending and Receiving:**
|
||||
|
||||
To test message functionality, the `openim::test::msg` function is called. It will register a user, send a message, and clear messages to ensure that the messaging service is operational.
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::msg
|
||||
```
|
||||
|
||||
**Testing User Registration and Account Checks:**
|
||||
|
||||
The `openim::test::user` function will create new user accounts and perform a series of checks on these accounts to verify that user registration and account queries are functioning properly.
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::user
|
||||
```
|
||||
|
||||
**Testing Friend Management:**
|
||||
|
||||
By invoking `openim::test::friend`, the script will test adding friends, checking friendship status, managing friend requests, and handling blacklisting.
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::friend
|
||||
```
|
||||
|
||||
**Testing Group Operations:**
|
||||
|
||||
The `openim::test::group` function tests group creation, member addition, information retrieval, and member management within groups.
|
||||
|
||||
```bash
|
||||
./test.sh openim::test::group
|
||||
```
|
||||
|
||||
### Log Output
|
||||
|
||||
Each test function will output logs to the terminal to confirm the success or failure of the tests. These logs are crucial for identifying issues and verifying that each part of the service is tested thoroughly.
|
||||
|
||||
Each function logs its success upon completion, which aids in debugging and understanding the test flow. The success message is standardized across functions:
|
||||
|
||||
```
|
||||
openim::log::success "<Test suite name> completed successfully."
|
||||
```
|
||||
|
||||
By following the guidelines and instructions outlined in this document, you can effectively utilize the `test.sh` script to test and verify the OpenIM RPC services' functionality.
|
||||
|
||||
|
||||
|
||||
## Function feature
|
||||
|
||||
| Function Name | Corresponding API/Action | Function Purpose |
|
||||
| ---------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------ |
|
||||
| `openim::test::msg` | Messaging Operations | Tests all aspects of messaging, including sending, receiving, and managing messages. |
|
||||
| `openim::test::auth` | Authentication Operations | Validates the authentication process and session management, including token handling and forced logout. |
|
||||
| `openim::test::user` | User Account Operations | Covers testing for user account creation, retrieval, updating, and overall management. |
|
||||
| `openim::test::friend` | Friend Relationship Operations | Ensures friend management functions correctly, including requests, listing, and blacklisting. |
|
||||
| `openim::test::group` | Group Management Operations | Checks group-related functionalities like creation, invitation, information retrieval, and member management. |
|
||||
| `openim::test::send_msg` | Send Message API | Simulates sending a message from one user to another or within a group. |
|
||||
| `openim::test::revoke_msg` | Revoke Message API (TODO) | (Planned) Will test the revocation of a previously sent message. |
|
||||
| `openim::test::user_register` | User Registration API | Registers a new user in the system to validate the registration process. |
|
||||
| `openim::test::check_account` | Account Check API | Checks if an account exists for a given user ID. |
|
||||
| `openim::test::user_clear_all_msg` | Clear All Messages API | Clears all messages for a given user to validate message history management. |
|
||||
| `openim::test::get_token` | Token Retrieval API | Retrieves an authentication token to validate token management. |
|
||||
| `openim::test::force_logout` | Force Logout API | Forces a logout for a test user to validate session control. |
|
||||
| `openim::test::check_user_account` | User Account Existence Check API | Confirms the existence of a test user's account. |
|
||||
| `openim::test::get_users` | Get Users API | Retrieves a list of users to validate user query functionality. |
|
||||
| `openim::test::get_users_info` | Get User Information API | Obtains detailed information for a given user. |
|
||||
| `openim::test::get_users_online_status` | Get User Online Status API | Checks the online status of a user to validate presence functionality. |
|
||||
| `openim::test::update_user_info` | Update User Information API | Updates a user's information to validate account update capabilities. |
|
||||
| `openim::test::get_subscribe_users_status` | Get Subscribed Users' Status API | Retrieves the status of users that a test user has subscribed to. |
|
||||
| `openim::test::subscribe_users_status` | Subscribe to Users' Status API | Subscribes a test user to a set of user statuses. |
|
||||
| `openim::test::set_global_msg_recv_opt` | Set Global Message Receiving Option API | Sets the message receiving option for a test user. |
|
||||
| `openim::test::is_friend` | Check Friendship Status API | Verifies if two users are friends within the system. |
|
||||
| `openim::test::add_friend` | Send Friend Request API | Sends a friend request from one user to another. |
|
||||
| `openim::test::get_friend_list` | Get Friend List API | Retrieves the friend list of a test user. |
|
||||
| `openim::test::get_friend_apply_list` | Get Friend Application List API | Retrieves friend applications for a test user. |
|
||||
| `openim::test::get_self_friend_apply_list` | Get Self-Friend Application List API | Retrieves the friend applications that the user has applied for. |
|
||||
| `openim::test::add_black` | Add User to Blacklist API | Adds a user to the test user's blacklist to validate blacklist functionality. |
|
||||
| `openim::test::remove_black` | Remove User from Blacklist API | Removes a user from the test user's blacklist. |
|
||||
| `openim::test::get_black_list` | Get Blacklist API | Retrieves the blacklist for a test user. |
|
||||
| `openim::test::create_group` | Group Creation API | Creates a new group with test users to validate group creation. |
|
||||
| `openim::test::invite_user_to_group` | Invite User to Group API | Invites a user to join a group to test invitation functionality. |
|
||||
| `openim::test::transfer_group` | Group Ownership Transfer API | Tests the transfer of group ownership from one member to another. |
|
||||
| `openim::test::get_groups_info` | Get Group Information API | Retrieves information for specified groups to validate group query functionality. |
|
||||
| `openim::test::kick_group` | Kick User from Group API | Simulates kicking a user from a group to test group membership management. |
|
||||
| `openim::test::get_group_members_info` | Get Group Members Information API | Obtains detailed information for members of a specified group. |
|
||||
| `openim::test::get_group_member_list` | Get Group Member List API | Retrieves a list of members for a given group to ensure member listing is functional. |
|
||||
| `openim::test::get_joined_group_list` | Get Joined Group List API | Retrieves a list of groups that a user has joined to validate user's group memberships. |
|
||||
| `openim::test::set_group_member_info` | Set Group Member Information API | Updates the information for a group member to test the update functionality. |
|
||||
| `openim::test::mute_group` | Mute Group API | Tests the ability to mute a group, disabling message notifications for its members. |
|
||||
| `openim::test::cancel_mute_group` | Cancel Mute Group API | Tests the ability to cancel the mute status of a group, re-enabling message notifications. |
|
||||
| `openim::test::dismiss_group` | Dismiss Group API | Tests the ability to dismiss and delete a group from the system. |
|
||||
| `openim::test::cancel_mute_group_member` | Cancel Mute Group Member API | Tests the ability to cancel mute status for a specific group member. |
|
||||
| `openim::test::join_group` | Join Group API (TODO) | (Planned) Will test the functionality for a user to join a specified group. |
|
||||
| `openim::test::set_group_info` | Set Group Information API | Tests the ability to update the group information, such as the name or description. |
|
||||
| `openim::test::quit_group` | Quit Group API | Tests the functionality for a user to leave a specified group. |
|
||||
| `openim::test::get_recv_group_applicationList` | Get Received Group Application List API | Retrieves the list of group applications received by a user to validate application management. |
|
||||
| `openim::test::group_application_response` | Group Application Response API (TODO) | (Planned) Will test the functionality to respond to a group join request. |
|
||||
| `openim::test::get_user_req_group_applicationList` | Get User Requested Group Application List API | Retrieves the list of group applications requested by a user to validate tracking of user's applications. |
|
||||
| `openim::test::mute_group_member` | Mute Group Member API | Tests the ability to mute a specific member within a group, disabling their ability to send messages. |
|
||||
| `openim::test::get_group_users_req_application_list` | Get Group Users Request Application List API | Retrieves a list of user requests for group applications to validate group request management. |
|
||||
@@ -0,0 +1,215 @@
|
||||
# OpenIM Branch Management and Versioning: A Blueprint for High-Grade Software Development
|
||||
|
||||
[📚 **OpenIM TOC**](#openim-branch-management-and-versioning-a-blueprint-for-high-grade-software-development)
|
||||
- [Unfolding the Mechanism of OpenIM Version Maintenance](#unfolding-the-mechanism-of-openim-version-maintenance)
|
||||
- [Main Branch: The Heart of OpenIM Development](#main-branch-the-heart-of-openim-development)
|
||||
- [Release Branch: The Beacon of Stability](#release-branch-the-beacon-of-stability)
|
||||
- [Tag Management: The Cornerstone of Version Control](#tag-management-the-cornerstone-of-version-control)
|
||||
- [Release Management: A Guided Tour](#release-management-a-guided-tour)
|
||||
- [Milestones, Branching, and Addressing Major Bugs](#milestones-branching-and-addressing-major-bugs)
|
||||
- [Version Skew Policy](#version-skew-policy)
|
||||
- [Applying Principles: A Git Workflow Example](#applying-principles-a-git-workflow-example)
|
||||
- [Docker Images Version Management](#docker-images-version-management)
|
||||
|
||||
|
||||
At OpenIM, we acknowledge the profound impact of implementing a robust and efficient version management system, hence we abide by the established standards of [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/).
|
||||
|
||||
Our software blueprint orchestrates a tripartite version management system that integrates the `main` branch, the `release` branch, and `tag` management. These constituents operate in synchrony to preserve the reliability and traceability of our software across various stages of development.
|
||||
|
||||
## Unfolding the Mechanism of OpenIM Version Maintenance
|
||||
|
||||
Our version maintenance protocol revolves around two primary branches, namely: `main` and `release`. We resort to Semantic Versioning 2.0.0 for marking distinctive versions of our software, representing substantial milestones in its evolution.
|
||||
|
||||
In the OpenIM repository, version identification strictly complies with the `MAJOR.MINOR.PATCH` protocol. Herein:
|
||||
|
||||
- The `MAJOR` version indicates a shift arising from incompatible changes to the API.
|
||||
- The `MINOR` version suggests the addition of features in a backward-compatible manner.
|
||||
- The `PATCH` version flags backward-compatible bug fixes.
|
||||
|
||||
## Main Branch: The Heart of OpenIM Development
|
||||
|
||||
The `main` branch is the operational heart of our development process. Housing the most recent and advanced features, this branch serves as the nerve center for all enhancements and updates. It encapsulates the freshest, though possibly unstable, facets of the software. Visit our `main` branch [here](https://github.com/openimsdk/open-im-server/tree/main).
|
||||
|
||||
## Release Branch: The Beacon of Stability
|
||||
|
||||
For every major release, we curate a corresponding `release` branch, e.g., `release-v3.1`. This branch symbolizes an embodiment of stability and ensures an updated version of the software, providing a dependable option for users favoring stability over nascent, yet possibly unstable, features. Visit the `release-v3.1` branch [here](https://github.com/openimsdk/open-im-server/tree/release-v3.1).
|
||||
|
||||
## Tag Management: The Cornerstone of Version Control
|
||||
|
||||
In OpenIM's version control system, the role of `tags` stands paramount. Owing to their immutable nature, tags can be effectively utilized to retrieve a specific version of the software. Explore our library of tags [here](https://github.com/openimsdk/open-im-server/tags).
|
||||
|
||||
Our Docker image versions are intimately entwined with these tripartite components. For instance, a Docker image tag may correspond to `ghcr.io/openimsdk/openim-server:v3.1.0`, a release to `ghcr.io/openimsdk/openim-server:release-v3.0`, and the main branch to `ghcr.io/openimsdk/openim-server:main` or `ghcr.io/openimsdk/openim-server:latest`.
|
||||
|
||||
To further clarify, the semantics of our version numbers are as follows:
|
||||
|
||||
- **Revision version number**: This represents bug fixes or code optimizations. Typically, it entails no new feature additions and ensures backward compatibility.
|
||||
- **Build version number**: Auto-generated by the system, each code submission prompts an automatic increment by 1.
|
||||
- **Version modifiers**: These hint at the software's development stage and stability. Some commonly used modifiers are `alpha`, `beta`, `rc`, `ga`, `r/release/or nothing`, and `lts`.
|
||||
- `alpha`: An internal testing version with numerous bugs, typically used for communication among developers.
|
||||
- `beta`: A test version with numerous bugs, generally used for testing by eager community members, who provide feedback to the developers.
|
||||
- `rc`: Release candidate, which is to be released as the official version. It's the last test version before the official version.
|
||||
- `ga`: General Availability, the first stable release.
|
||||
- `r/release/or nothing`: The final release version, intended for general users.
|
||||
- `lts`: Long Term Support, the official will specify the maintenance year for this version and will fix all bugs discovered in this version.
|
||||
|
||||
Whenever a project undergoes a partial functional addition, the minor version number increments by 1, resetting the revision version number to 0. In contrast, any major project overhaul results in an increment by 1 in the major version number. The build number, typically auto-generated during the compilation process, only requires format definition, thereby eliminating manual control.
|
||||
|
||||
## Release Management: A Guided Tour
|
||||
|
||||
Our GitHub repository at https://github.com/openimsdk/open-im-server/releases associates a release with each tag, with a distinction between Pre-release and Latest, determined by the branch source. Every significant feature launch prompts the issue of a `release` branch, such as `release-v3.2`, as a beacon of stability and Latest release.
|
||||
|
||||
Pre-releases correspond to releases from the `main` branch, denoting tags with Version modifiers such as `v3.2.1-beta.0`, `v3.2.1-rc.1`, etc. If you are seeking the most recent, albeit possibly unstable, release with new features, these tags, originating from the latest `main` branch code, are your go-to.
|
||||
|
||||
Conversely, if stability is your primary concern, you should opt for the release tagged Latest, denoted by tags without Version modifiers, such as `v3.2.1`, `v3.2.2` etc. These tags are linked to the latest stable maintenance branch, like `release-v3.2`.
|
||||
|
||||
## Milestones, Branching, and Addressing Major Bugs
|
||||
|
||||
**About:**
|
||||
|
||||
+ [OpenIM Milestones](https://github.com/openimsdk/open-im-server/milestones)
|
||||
+ [OpenIM Tags](https://github.com/openimsdk/open-im-server/tags)
|
||||
+ [OpenIM Branches](https://github.com/openimsdk/open-im-server/branches)
|
||||
|
||||
We create a new branch, such as `release-v3.1`, for each significant milestone (e.g., v3.1.0), housing all relevant code for that release. All enhancements and bug fixes targeting the subsequent version (e.g., v3.2.0) are integrated into this branch.
|
||||
|
||||
`PATCH` versions (represented by Z in `X.Y.Z`) are primarily propelled by bug fixes, and their release may be either priority-driven or scheduled. In contrast, `MINOR` versions (represented by Y in `X.Y.Z`) are contingent upon the project's roadmap, milestone completion, or a pre-established timeline, always maintaining backward-compatible APIs.
|
||||
|
||||
When dealing with major bugs, we selectively merge the fix into the affected version (e.g., v3.1 or the `release-v3.1` branch), as well as the `main` branch. This dual pronged strategy ensures that users on older versions receive crucial bug fixes, while also keeping the `main` branch updated.
|
||||
|
||||
We reinforce our approach to branch management and versioning with stringent testing protocols. Automated tests and code review sessions form vital components of maintaining a robust and reliable codebase.
|
||||
|
||||
## Version Skew Policy
|
||||
|
||||
This document describes the maximum version skew supported between various openim components. Specific cluster deployment tools may place additional restrictions on version skew.
|
||||
|
||||
|
||||
### Supported version skew
|
||||
|
||||
In highly-available (HA) clusters, the newest and oldest `openim-api` instances must be within one minor version.
|
||||
|
||||
### OpenIM Versioning, Branching, and Tag Strategy
|
||||
|
||||
Similar to Kubernetes, OpenIM has a strict versioning, branching, and tag strategy to ensure compatibility among its various services and components. This document outlines the policies, especially focusing on the version skew supported between OpenIM's components. Given that the current version is v3.3, the policy references will be centered around this version.
|
||||
|
||||
#### Supported Version Skew
|
||||
|
||||
##### openim-api
|
||||
|
||||
In highly-available (HA) clusters, the newest and oldest `openim-api` instances must be within one minor version.
|
||||
|
||||
Example:
|
||||
|
||||
+ Newest `openim-api` is at v3.3
|
||||
+ Other `openim-api` instances are supported at v3.3 and v3.2
|
||||
|
||||
##### openim-rpc-* Components
|
||||
|
||||
All `openim-rpc-*` components (e.g., `openim-rpc-auth`, `openim-rpc-conversation`, etc.) should adhere to the following rules:
|
||||
|
||||
1. They must not be newer than `openim-api`.
|
||||
2. They may be up to one minor version older than `openim-api`.
|
||||
|
||||
Example:
|
||||
|
||||
+ `openim-api` is at v3.3
|
||||
+ All `openim-rpc-*` components are supported at v3.3 and v3.2
|
||||
|
||||
Note: If version skew exists between `openim-api` instances in an HA cluster, this narrows the allowed `openim-rpc-*` components versions.
|
||||
|
||||
##### Other OpenIM Services
|
||||
|
||||
Other OpenIM services such as `openim-cmdutils`, `openim-crontask`, `openim-msggateway`, etc. should adhere to the following rules:
|
||||
|
||||
1. These services must not be newer than `openim-api`.
|
||||
2. They are expected to match the `openim-api` minor version but may be up to one minor version older (to allow live upgrades).
|
||||
|
||||
Example:
|
||||
|
||||
+ `openim-api` is at v3.3
|
||||
+ `openim-msggateway`, `openim-cmdutils`, and other services are supported at v3.3 and v3.2
|
||||
|
||||
#### Supported Component Upgrade Order
|
||||
|
||||
The version skew policy has implications on the order in which components should be upgraded. Below is the recommended order to transition an existing cluster from version v3.2 to v3.3:
|
||||
|
||||
##### openim-api
|
||||
|
||||
Pre-requisites:
|
||||
|
||||
1. In a single-instance cluster, the existing `openim-api` instance is v3.2.
|
||||
2. In an HA cluster, all `openim-api` instances are at v3.2 or v3.3.
|
||||
3. All `openim-rpc-*` and other OpenIM services communicating with this server are at version v3.2.
|
||||
|
||||
Upgrade Procedure:
|
||||
|
||||
1. Upgrade `openim-api` to v3.3.
|
||||
|
||||
##### openim-rpc-* Components
|
||||
|
||||
Pre-requisites:
|
||||
|
||||
1. The `openim-api` instances these components communicate with are at v3.3.
|
||||
|
||||
Upgrade Procedure:
|
||||
|
||||
2. Upgrade all `openim-rpc-*` components to v3.3.
|
||||
|
||||
##### Other OpenIM Services
|
||||
|
||||
Pre-requisites:
|
||||
|
||||
1. The `openim-api` instances these services communicate with are at v3.3.
|
||||
|
||||
Upgrade Procedure:
|
||||
|
||||
2. Upgrade other OpenIM services such as `openim-msggateway`, `openim-cmdutils`, etc., to v3.3.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Just like Kubernetes, it's essential for OpenIM to have a strict versioning and upgrade policy to ensure seamless operation and compatibility among its various services. Adhering to the policies outlined above will help in achieving this goal.
|
||||
|
||||
|
||||
## Applying Principles: A Git Workflow Example
|
||||
|
||||
The workflow to address a bug fix might follow these steps:
|
||||
|
||||
```bash
|
||||
# Checkout the branch for the version that needs the bug fix
|
||||
git checkout release-v3.1
|
||||
|
||||
# Create a new branch for the bug fix
|
||||
git checkout -b bug/bug-name
|
||||
|
||||
# ... Make changes, commit your work ...
|
||||
|
||||
# Push the branch to your remote repository
|
||||
git push origin bug/bug-name
|
||||
|
||||
# After the pull request is merged into the release-v3.1 branch,
|
||||
# checkout and update your main branch
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
# Merge or rebase the changes from release-v3.1 into main
|
||||
git merge release-v3.1
|
||||
|
||||
# Push the updates to the main branch
|
||||
git push origin main
|
||||
```
|
||||
## Release Process
|
||||
|
||||
```
|
||||
Publishing v3.2.0: A Step-by-Step Guide
|
||||
(1) Create the tag v3.2.0-alpha.0 from the main branch.
|
||||
(2) Bugs are fixed on the main branch. Once the bugs are resolved, tag the main branch as v3.2.0-rc.0.
|
||||
(3) After further testing, if v3.2.0-rc.0 is deemed stable, create a branch named release-v3.2 from the tag v3.2.0-rc.0.
|
||||
(4) From the release-v3.2 branch, create the tag v3.2.0. At this point, the official release of v3.2.0 is complete.
|
||||
|
||||
After the release of v3.2.0, if urgent bugs are discovered, fix them on the release-v3.2 branch. Then, submit two pull requests (PRs) to both the main and release-v3.2 branches. Tag the release-v3.2 branch as v3.2.1.
|
||||
```
|
||||
|
||||
Throughout this process, active communication within the team is pivotal to maintaining transparency and consensus on changes.
|
||||
|
||||
## Docker Images Version Management
|
||||
|
||||
For more details on managing Docker image versions, visit [OpenIM Docker Images Administration](https://github.com/openimsdk/open-im-server/blob/main/docs/contrib/images.md).
|
||||
Reference in New Issue
Block a user