mirror of
				https://github.com/openimsdk/open-im-server.git
				synced 2025-10-29 07:12:14 +08:00 
			
		
		
		
	* feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test changelog file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts test and format Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --------- Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com>
		
			
				
	
	
		
			309 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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
 | |
| }
 |