mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-04-25 02:58:26 +08:00
fix: fix bin tools path
Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
This commit is contained in:
parent
73effdf644
commit
c1f6fc4e63
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@ -43,6 +43,7 @@ jobs:
|
|||||||
# either 'goreleaser' (default) or 'goreleaser-pro':
|
# either 'goreleaser' (default) or 'goreleaser-pro':
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: latest
|
version: latest
|
||||||
|
workdir: ./build/.goreleaser.yaml
|
||||||
args: release --clean
|
args: release --clean
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
|
2
Makefile
2
Makefile
@ -12,7 +12,7 @@ all: tidy gen add-copyright format lint cover build
|
|||||||
# Build set
|
# Build set
|
||||||
|
|
||||||
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server
|
||||||
# TODO: This is version control for the future
|
# TODO: This is version control for the future https://github.com/OpenIMSDK/Open-IM-Server/issues/574
|
||||||
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
1
go.work
1
go.work
@ -2,6 +2,7 @@ go 1.20
|
|||||||
|
|
||||||
use (
|
use (
|
||||||
.
|
.
|
||||||
|
./tools/changelog
|
||||||
./tools/infra
|
./tools/infra
|
||||||
./tools/ncpu
|
./tools/ncpu
|
||||||
)
|
)
|
||||||
|
@ -19,21 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
source $SCRIPTS_ROOT/path_info.sh
|
||||||
source $SCRIPTS_ROOT/function.sh
|
source $SCRIPTS_ROOT/lib/init.sh
|
||||||
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}"
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}"
|
|
||||||
echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
echo -e ""
|
|
||||||
|
|
||||||
echo -e "${BACKGROUND_BLUE}===============> Building all using make build binary files ${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
echo -e ""
|
|
||||||
echo -e "${BOLD_PREFIX}____________________________________________________________ ${COLOR_SUFFIX}"
|
|
||||||
|
|
||||||
|
|
||||||
bin_dir="$BIN_DIR"
|
bin_dir="$BIN_DIR"
|
||||||
logs_dir="$OPENIM_ROOT/logs"
|
logs_dir="$OPENIM_ROOT/logs"
|
||||||
@ -68,43 +55,7 @@ if [ $? -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the current operating system and architecture
|
gen_os_arch
|
||||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
|
|
||||||
# Select the repository home directory based on the operating system and architecture
|
|
||||||
if [[ "$OS" == "darwin" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="darwin/amd64"
|
|
||||||
else
|
|
||||||
REPO_DIR="darwin/386"
|
|
||||||
fi
|
|
||||||
elif [[ "$OS" == "linux" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="linux/amd64"
|
|
||||||
elif [[ "$ARCH" == "arm64" ]]; then
|
|
||||||
REPO_DIR="linux/arm64"
|
|
||||||
elif [[ "$ARCH" == "mips64" ]]; then
|
|
||||||
REPO_DIR="linux/mips64"
|
|
||||||
elif [[ "$ARCH" == "mips64le" ]]; then
|
|
||||||
REPO_DIR="linux/mips64le"
|
|
||||||
elif [[ "$ARCH" == "ppc64le" ]]; then
|
|
||||||
REPO_DIR="linux/ppc64le"
|
|
||||||
elif [[ "$ARCH" == "s390x" ]]; then
|
|
||||||
REPO_DIR="linux/s390x"
|
|
||||||
else
|
|
||||||
REPO_DIR="linux/386"
|
|
||||||
fi
|
|
||||||
elif [[ "$OS" == "windows" ]]; then
|
|
||||||
if [[ "$ARCH" == "x86_64" ]]; then
|
|
||||||
REPO_DIR="windows/amd64"
|
|
||||||
else
|
|
||||||
REPO_DIR="windows/386"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine if all scripts were successfully built
|
# Determine if all scripts were successfully built
|
||||||
BUILD_SUCCESS=true
|
BUILD_SUCCESS=true
|
||||||
|
@ -729,3 +729,43 @@ function remove_space() {
|
|||||||
value=$* # 获取传入的参数
|
value=$* # 获取传入的参数
|
||||||
result=$(echo $value | sed 's/ //g') # 去除空格
|
result=$(echo $value | sed 's/ //g') # 去除空格
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function gen_os_arch() {
|
||||||
|
# Get the current operating system and architecture
|
||||||
|
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
|
||||||
|
# Select the repository home directory based on the operating system and architecture
|
||||||
|
if [[ "$OS" == "darwin" ]]; then
|
||||||
|
if [[ "$ARCH" == "x86_64" ]]; then
|
||||||
|
REPO_DIR="darwin/amd64"
|
||||||
|
else
|
||||||
|
REPO_DIR="darwin/386"
|
||||||
|
fi
|
||||||
|
elif [[ "$OS" == "linux" ]]; then
|
||||||
|
if [[ "$ARCH" == "x86_64" ]]; then
|
||||||
|
REPO_DIR="linux/amd64"
|
||||||
|
elif [[ "$ARCH" == "arm64" ]]; then
|
||||||
|
REPO_DIR="linux/arm64"
|
||||||
|
elif [[ "$ARCH" == "mips64" ]]; then
|
||||||
|
REPO_DIR="linux/mips64"
|
||||||
|
elif [[ "$ARCH" == "mips64le" ]]; then
|
||||||
|
REPO_DIR="linux/mips64le"
|
||||||
|
elif [[ "$ARCH" == "ppc64le" ]]; then
|
||||||
|
REPO_DIR="linux/ppc64le"
|
||||||
|
elif [[ "$ARCH" == "s390x" ]]; then
|
||||||
|
REPO_DIR="linux/s390x"
|
||||||
|
else
|
||||||
|
REPO_DIR="linux/386"
|
||||||
|
fi
|
||||||
|
elif [[ "$OS" == "windows" ]]; then
|
||||||
|
if [[ "$ARCH" == "x86_64" ]]; then
|
||||||
|
REPO_DIR="windows/amd64"
|
||||||
|
else
|
||||||
|
REPO_DIR="windows/386"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
@ -126,7 +126,7 @@ FIND := find . ! -path './utils/*' ! -path './vendor/*' ! -path './third_party/*
|
|||||||
XARGS := xargs -r --no-run-if-empty
|
XARGS := xargs -r --no-run-if-empty
|
||||||
|
|
||||||
# Linux command settings-CODE DIRS Copyright
|
# Linux command settings-CODE DIRS Copyright
|
||||||
CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/db $(ROOT_DIR)/.docker-compose_cfg $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/build $(ROOT_DIR)/deployments
|
CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/db $(ROOT_DIR)/.docker-compose_cfg $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/tools $(ROOT_DIR)/deployments
|
||||||
FINDS := find $(CODE_DIRS)
|
FINDS := find $(CODE_DIRS)
|
||||||
|
|
||||||
# Makefile settings: Select different behaviors by determining whether V option is set
|
# Makefile settings: Select different behaviors by determining whether V option is set
|
||||||
|
@ -22,7 +22,7 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|||||||
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
#Include shell font styles and some basic information
|
||||||
source $SCRIPTS_ROOT/style_info.sh
|
source $SCRIPTS_ROOT/lib/color.sh
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
cd $SCRIPTS_ROOT
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ cd "$SCRIPTS_ROOT"
|
|||||||
|
|
||||||
for i in ${service_names[*]}; do
|
for i in ${service_names[*]}; do
|
||||||
#Check whether the service exists
|
#Check whether the service exists
|
||||||
name="ps |grep -w $i |grep -v grep"
|
name="ps aux |grep -w $i |grep -v grep"
|
||||||
count="${name}| wc -l"
|
count="${name}| wc -l"
|
||||||
if [ $(eval ${count}) -gt 0 ]; then
|
if [ $(eval ${count}) -gt 0 ]; then
|
||||||
pid="${name}| awk '{print \$2}'"
|
pid="${name}| awk '{print \$2}'"
|
||||||
|
15
test/README.md
Normal file
15
test/README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
## Run the Tests
|
||||||
|
|
||||||
|
To run a single test or set of tests, you'll need the [Ginkgo](https://github.com/onsi/ginkgo) tool installed on your
|
||||||
|
machine:
|
||||||
|
|
||||||
|
```console
|
||||||
|
go install github.com/onsi/ginkgo/ginkgo@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ginkgo --help
|
||||||
|
--focus value
|
||||||
|
If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed.
|
||||||
|
|
||||||
|
```
|
38
test/jwt/main.go
Normal file
38
test/jwt/main.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2020 Lingfei Kong <colin404@foxmail.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rawJWT := `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXV0aHoubWFybW90ZWR1LmNvbSIsImV4cCI6MTYwNDEyODQwMywiaWF0IjoxNjA0MTI4NDAyLCJpc3MiOiJpYW1jdGwiLCJraWQiOiJpZDEifQ.Itr5u4C-nTeA01qbjjl7RzuPD-aSQazsJZY_Z25aGnI`
|
||||||
|
|
||||||
|
// Verify the token
|
||||||
|
claims := &jwt.MapClaims{}
|
||||||
|
parsedT, err := jwt.ParseWithClaims(rawJWT, claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// Validate the alg is HMAC signature
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if kid, ok := token.Header["kid"].(string); ok {
|
||||||
|
fmt.Println("kid", kid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return []byte("key1"), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil || !parsedT.Valid {
|
||||||
|
fmt.Println("token valid failed", err)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("ok")
|
||||||
|
}
|
64
test/testdata/README.md
vendored
Normal file
64
test/testdata/README.md
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
# Test Data for OpenIM Server
|
||||||
|
|
||||||
|
This directory (`testdata`) contains various JSON formatted data files that are used for testing the OpenIM Server.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```bash
|
||||||
|
testdata/
|
||||||
|
│
|
||||||
|
├── README.md # 描述该目录下各子目录和文件的作用
|
||||||
|
│
|
||||||
|
├── db/ # 存储模拟的数据库数据
|
||||||
|
│ ├── users.json # 用户的模拟数据
|
||||||
|
│ └── messages.json # 消息的模拟数据
|
||||||
|
│
|
||||||
|
├── requests/ # 存储模拟的请求数据
|
||||||
|
│ ├── login.json # 模拟登陆请求
|
||||||
|
│ ├── register.json # 模拟注册请求
|
||||||
|
│ └── sendMessage.json # 模拟发送消息请求
|
||||||
|
│
|
||||||
|
└── responses/ # 存储模拟的响应数据
|
||||||
|
├── login.json # 模拟登陆响应
|
||||||
|
├── register.json # 模拟注册响应
|
||||||
|
└── sendMessage.json # 模拟发送消息响应
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is an overview of what each subdirectory or file represents:
|
||||||
|
|
||||||
|
- `db/` - This directory contains mock data mimicking the actual database contents.
|
||||||
|
- `users.json` - Represents a list of users in the system. Each entry contains user-specific information such as user ID, username, password hash, etc.
|
||||||
|
- `messages.json` - Contains a list of messages exchanged between users. Each message entry includes the sender's and receiver's user IDs, message content, timestamp, etc.
|
||||||
|
- `requests/` - This directory contains mock requests that a client might send to the server.
|
||||||
|
- `login.json` - Represents a user login request. It includes fields such as username and password.
|
||||||
|
- `register.json` - Mimics a user registration request. Contains details such as username, password, email, etc.
|
||||||
|
- `sendMessage.json` - Simulates a message sending request from a user to another user.
|
||||||
|
- `responses/` - This directory holds the expected server responses for the respective requests.
|
||||||
|
- `login.json` - Represents a successful login response from the server. It typically includes a session token and user-specific information.
|
||||||
|
- `register.json` - Simulates a successful registration response from the server, usually containing the new user's ID, username, etc.
|
||||||
|
- `sendMessage.json` - Depicts a successful message sending response from the server, confirming the delivery of the message.
|
||||||
|
|
||||||
|
## JSON Format
|
||||||
|
|
||||||
|
All the data files in this directory are in JSON format. JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate.
|
||||||
|
|
||||||
|
Here is a simple example of what a JSON file might look like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"username": "user1",
|
||||||
|
"password": "password1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"username": "user2",
|
||||||
|
"password": "password2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, "users" is an array of user objects. Each user object has an "id", "username", and "password".
|
0
test/testdata/db/messages.json
vendored
Normal file
0
test/testdata/db/messages.json
vendored
Normal file
0
test/testdata/db/users.json
vendored
Normal file
0
test/testdata/db/users.json
vendored
Normal file
0
test/testdata/requests/login.json
vendored
Normal file
0
test/testdata/requests/login.json
vendored
Normal file
0
test/testdata/requests/register.json
vendored
Normal file
0
test/testdata/requests/register.json
vendored
Normal file
0
test/testdata/requests/sendMessage.json
vendored
Normal file
0
test/testdata/requests/sendMessage.json
vendored
Normal file
0
test/testdata/responses/login.json
vendored
Normal file
0
test/testdata/responses/login.json
vendored
Normal file
0
test/testdata/responses/register.json
vendored
Normal file
0
test/testdata/responses/register.json
vendored
Normal file
0
test/testdata/responses/sendMessage.json
vendored
Normal file
0
test/testdata/responses/sendMessage.json
vendored
Normal file
308
tools/changelog/changelog.go
Normal file
308
tools/changelog/changelog.go
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
mergeRequest = regexp.MustCompile(`Merge pull request #([\d]+)`)
|
||||||
|
webconsoleBump = regexp.MustCompile(regexp.QuoteMeta("bump(github.com/openshift/origin-web-console): ") + `([\w]+)`)
|
||||||
|
upstreamKube = regexp.MustCompile(`^UPSTREAM: (\d+)+:(.+)`)
|
||||||
|
upstreamRepo = regexp.MustCompile(`^UPSTREAM: ([\w/-]+): (\d+)+:(.+)`)
|
||||||
|
prefix = regexp.MustCompile(`^[\w-]: `)
|
||||||
|
|
||||||
|
assignments = []prefixAssignment{
|
||||||
|
{"cluster up", "cluster"},
|
||||||
|
{" pv ", "storage"},
|
||||||
|
{"haproxy", "router"},
|
||||||
|
{"router", "router"},
|
||||||
|
{"route", "route"},
|
||||||
|
{"authoriz", "auth"},
|
||||||
|
{"rbac", "auth"},
|
||||||
|
{"authent", "auth"},
|
||||||
|
{"reconcil", "auth"},
|
||||||
|
{"auth", "auth"},
|
||||||
|
{"role", "auth"},
|
||||||
|
{" dc ", "deploy"},
|
||||||
|
{"deployment", "deploy"},
|
||||||
|
{"rolling", "deploy"},
|
||||||
|
{"security context constr", "security"},
|
||||||
|
{"scc", "security"},
|
||||||
|
{"pipeline", "build"},
|
||||||
|
{"build", "build"},
|
||||||
|
{"registry", "registry"},
|
||||||
|
{"registries", "image"},
|
||||||
|
{"image", "image"},
|
||||||
|
{" arp ", "network"},
|
||||||
|
{" cni ", "network"},
|
||||||
|
{"egress", "network"},
|
||||||
|
{"network", "network"},
|
||||||
|
{"oc ", "cli"},
|
||||||
|
{"template", "template"},
|
||||||
|
{"etcd", "server"},
|
||||||
|
{"pod", "node"},
|
||||||
|
{"hack/", "hack"},
|
||||||
|
{"e2e", "test"},
|
||||||
|
{"integration", "test"},
|
||||||
|
{"cluster", "cluster"},
|
||||||
|
{"master", "server"},
|
||||||
|
{"packages", "hack"},
|
||||||
|
{"api", "server"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type prefixAssignment struct {
|
||||||
|
term string
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
type commit struct {
|
||||||
|
short string
|
||||||
|
parents []string
|
||||||
|
message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func contains(arr []string, value string) bool {
|
||||||
|
for _, s := range arr {
|
||||||
|
if s == value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.SetFlags(0)
|
||||||
|
if len(os.Args) != 3 {
|
||||||
|
log.Fatalf("Must specify two arguments, FROM and TO")
|
||||||
|
}
|
||||||
|
from := os.Args[1]
|
||||||
|
to := os.Args[2]
|
||||||
|
|
||||||
|
out, err := exec.Command("git", "log", "--topo-order", "--pretty=tformat:%h %p|%s", "--reverse", fmt.Sprintf("%s..%s", from, to)).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hide := make(map[string]struct{})
|
||||||
|
var apiChanges []string
|
||||||
|
var webconsole []string
|
||||||
|
var commits []commit
|
||||||
|
var upstreams []commit
|
||||||
|
var bumps []commit
|
||||||
|
for _, line := range strings.Split(string(out), "\n") {
|
||||||
|
if len(strings.TrimSpace(line)) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(line, "|", 2)
|
||||||
|
hashes := strings.Split(parts[0], " ")
|
||||||
|
c := commit{short: hashes[0], parents: hashes[1:], message: parts[1]}
|
||||||
|
|
||||||
|
if strings.HasPrefix(c.message, "UPSTREAM: ") {
|
||||||
|
hide[c.short] = struct{}{}
|
||||||
|
upstreams = append(upstreams, c)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(c.message, "bump(") {
|
||||||
|
hide[c.short] = struct{}{}
|
||||||
|
bumps = append(bumps, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.parents) == 1 {
|
||||||
|
commits = append(commits, c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := mergeRequest.FindStringSubmatch(line)
|
||||||
|
if len(matches) == 0 {
|
||||||
|
// this may have been a human pressing the merge button, we'll just record this as a direct push
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// split the accumulated commits into any that are force merges (assumed to be the initial set due
|
||||||
|
// to --topo-order) from the PR commits as soon as we see any of our merge parents. Then print
|
||||||
|
// any of the force merges
|
||||||
|
var first int
|
||||||
|
for i := range commits {
|
||||||
|
first = i
|
||||||
|
if contains(c.parents, commits[i].short) {
|
||||||
|
first++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
individual := commits[:first]
|
||||||
|
merged := commits[first:]
|
||||||
|
for _, commit := range individual {
|
||||||
|
if len(commit.parents) > 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := hide[commit.short]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Printf("force-merge: %s %s\n", commit.message, commit.short)
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find either the PR title or the first commit title from the merge commit
|
||||||
|
out, err := exec.Command("git", "show", "--pretty=tformat:%b", c.short).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
var message string
|
||||||
|
para := strings.Split(string(out), "\n\n")
|
||||||
|
if len(para) > 0 && strings.HasPrefix(para[0], "Automatic merge from submit-queue") {
|
||||||
|
para = para[1:]
|
||||||
|
}
|
||||||
|
// this is no longer necessary with the submit queue in place
|
||||||
|
if len(para) > 0 && strings.HasPrefix(para[0], "Merged by ") {
|
||||||
|
para = para[1:]
|
||||||
|
}
|
||||||
|
// post submit-queue, the merge bot will add the PR title, which is usually pretty good
|
||||||
|
if len(para) > 0 {
|
||||||
|
message = strings.Split(para[0], "\n")[0]
|
||||||
|
}
|
||||||
|
if len(message) == 0 && len(merged) > 0 {
|
||||||
|
message = merged[0].message
|
||||||
|
}
|
||||||
|
if len(message) > 0 && len(merged) == 1 && message == merged[0].message {
|
||||||
|
merged = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to calculate a prefix based on the diff
|
||||||
|
if len(message) > 0 && !prefix.MatchString(message) {
|
||||||
|
prefix, ok := findPrefixFor(message, merged)
|
||||||
|
if ok {
|
||||||
|
message = prefix + ": " + message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// github merge
|
||||||
|
|
||||||
|
// has api changes
|
||||||
|
display := fmt.Sprintf("%s [\\#%s](https://github.com/openimsdk/Open-IM-Server/pull/%s)", message, matches[1], matches[1])
|
||||||
|
if hasFileChanges(c.short, "pkg/apistruct/") {
|
||||||
|
apiChanges = append(apiChanges, display)
|
||||||
|
}
|
||||||
|
|
||||||
|
var filtered []commit
|
||||||
|
for _, commit := range merged {
|
||||||
|
if _, ok := hide[commit.short]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filtered = append(filtered, commit)
|
||||||
|
}
|
||||||
|
if len(filtered) > 0 {
|
||||||
|
fmt.Printf("- %s\n", display)
|
||||||
|
for _, commit := range filtered {
|
||||||
|
fmt.Printf(" - %s (%s)\n", commit.message, commit.short)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stick the merge commit in at the beginning of the next list so we can anchor the previous parent
|
||||||
|
commits = []commit{c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// chunk the bumps
|
||||||
|
var lines []string
|
||||||
|
for _, commit := range bumps {
|
||||||
|
if m := webconsoleBump.FindStringSubmatch(commit.message); len(m) > 0 {
|
||||||
|
webconsole = append(webconsole, m[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lines = append(lines, commit.message)
|
||||||
|
}
|
||||||
|
lines = sortAndUniq(lines)
|
||||||
|
for _, line := range lines {
|
||||||
|
fmt.Printf("- %s\n", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// chunk the upstreams
|
||||||
|
lines = nil
|
||||||
|
for _, commit := range upstreams {
|
||||||
|
lines = append(lines, commit.message)
|
||||||
|
}
|
||||||
|
lines = sortAndUniq(lines)
|
||||||
|
for _, line := range lines {
|
||||||
|
fmt.Printf("- %s\n", upstreamLinkify(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(webconsole) > 0 {
|
||||||
|
fmt.Printf("- web: from %s^..%s\n", webconsole[0], webconsole[len(webconsole)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, apiChange := range apiChanges {
|
||||||
|
fmt.Printf(" - %s\n", apiChange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func findPrefixFor(message string, commits []commit) (string, bool) {
|
||||||
|
message = strings.ToLower(message)
|
||||||
|
for _, m := range assignments {
|
||||||
|
if strings.Contains(message, m.term) {
|
||||||
|
return m.prefix, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, c := range commits {
|
||||||
|
if prefix, ok := findPrefixFor(c.message, nil); ok {
|
||||||
|
return prefix, ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasFileChanges(commit string, prefixes ...string) bool {
|
||||||
|
out, err := exec.Command("git", "diff", "--name-only", fmt.Sprintf("%s^..%s", commit, commit)).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
for _, file := range strings.Split(string(out), "\n") {
|
||||||
|
for _, prefix := range prefixes {
|
||||||
|
if strings.HasPrefix(file, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func sortAndUniq(lines []string) []string {
|
||||||
|
sort.Strings(lines)
|
||||||
|
out := make([]string, 0, len(lines))
|
||||||
|
last := ""
|
||||||
|
for _, s := range lines {
|
||||||
|
if last == s {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
last = s
|
||||||
|
out = append(out, s)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func upstreamLinkify(line string) string {
|
||||||
|
if m := upstreamKube.FindStringSubmatch(line); len(m) > 0 {
|
||||||
|
return fmt.Sprintf("UPSTREAM: [#%s](https://github.com/OpenIMSDK/Open-IM-Server/pull/%s):%s", m[1], m[1], m[2])
|
||||||
|
}
|
||||||
|
if m := upstreamRepo.FindStringSubmatch(line); len(m) > 0 {
|
||||||
|
return fmt.Sprintf("UPSTREAM: [%s#%s](https://github.com/%s/pull/%s):%s", m[1], m[2], m[1], m[2], m[3])
|
||||||
|
}
|
||||||
|
return line
|
||||||
|
}
|
3
tools/changelog/go.mod
Normal file
3
tools/changelog/go.mod
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module github.com/OpenIMSDK/Open-IM-Server/tools/changelog
|
||||||
|
|
||||||
|
go 1.20
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
// Copyright © 2023 OpenIM. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user