drone_plugin/config_handler/config_handler.go

184 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package config_handler
import (
"context"
"encoding/json"
"errors"
"strings"
"git.icechen.cn/pkg/drone_plugin/consts"
"git.icechen.cn/pkg/drone_plugin/git"
"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin/config"
"github.com/sirupsen/logrus"
)
// New returns a new conversion plugin.
func New() config.Plugin {
return &plugin{}
}
type plugin struct{}
type Handler interface {
ToDestinationConfig() (string, error)
}
func (p *plugin) Find(ctx context.Context, req *config.Request) (*drone.Config, error) {
resp, err := json.Marshal(req)
if err != nil {
logrus.Error(err)
return nil, err
}
logrus.Infof("%s", string(resp))
// 1. 获取原始配置文件信息
cfg, err := getRealConfig(getGitClient(req))
if err != nil {
logrus.Error(err)
return nil, err
}
// 2. 是否部署
// 2.1 非 monorepo 的直接返回
if cfg.Type != TypeMonorepo {
// 返回 nil 按照 204 处理
return nil, nil
}
// 2.2 无部署环境报错返回,阻断部署
if getDeployEnv(req) == consts.EnvNone {
return nil, errors.New("ignore event")
}
// 3. 获取提交文件树
modifiedFileList, err := getGitClient(req).GetCommitModifiedFileList()
if err != nil {
logrus.Error(err)
return nil, err
}
// 4. 根据文件树以及原始配置文件的信息组装需要构建的服务的ci信息
// 4.1 api
modifiedApiList := getModifiedApi(cfg.Api, modifiedFileList, req.Build.Message)
destinationApi, err := modifiedApiList.toDestinationConfig(cfg.Name, getDeployEnv(req), cfg.toServiceEnv())
if err != nil {
logrus.Error(err)
return nil, err
}
// 4.2 service
modifiedServiceList := getModifiedService(cfg.Service, modifiedFileList, req.Build.Message)
destinationService, err := modifiedServiceList.toDestinationConfig(cfg.Name, getDeployEnv(req), cfg.toServiceEnv())
if err != nil {
logrus.Error(err)
return nil, err
}
if len(modifiedApiList) == 0 && len(modifiedServiceList) == 0 {
// 返回 nil 按照 204 处理
return nil, nil
}
retData := destinationApi + "\n\n" + destinationService
n := strings.LastIndex(retData, "---")
if n > 0 {
retData = retData[:n]
}
logrus.Info(retData)
// 5. 组装所有ci信息并输出
return &drone.Config{
Data: retData,
Kind: "pipeline",
}, nil
}
func getGitClient(req *config.Request) git.Client {
return git.New(req.Repo.Namespace, req.Repo.Name, req.Build.After, req.Repo.Config)
}
func getDeployEnv(req *config.Request) consts.Env {
switch req.Build.Event {
case "push":
if req.Build.Target == "master" {
return consts.EnvTest
}
case "tag":
return consts.EnvProduction
}
return consts.EnvNone
}
func getModifiedApi(api ApiList, modifiedFileList []string, message string) ApiList {
ret := make(ApiList, 0)
tempIndex := NewSet()
for i, a := range api {
for _, file := range modifiedFileList {
if strings.HasPrefix(file, a.Root) {
tempIndex.Add(i)
}
}
}
for _, i := range tempIndex.ToSlice() {
ret = append(ret, api[i])
}
ret = append(ret, getDeployApiByCommitMessage(api, message)...)
return ret
}
func getDeployApiByCommitMessage(api ApiList, message string) ApiList {
ret := make(ApiList, 0)
foundApp := foundAppByMessage(message)
for _, app := range foundApp {
for _, a := range api {
if a.Name == app {
ret = append(ret, a)
}
}
}
return ret
}
func getModifiedService(service ServiceList, modifiedFileList []string, message string) ServiceList {
ret := make(ServiceList, 0)
tempIndex := NewSet()
for i, s := range service {
for _, file := range modifiedFileList {
if strings.HasPrefix(file, s.Root) {
tempIndex.Add(i)
}
}
}
for _, i := range tempIndex.ToSlice() {
ret = append(ret, service[i])
}
ret = append(ret, getDeployServiceByCommitMessage(service, message)...)
return ret
}
func getDeployServiceByCommitMessage(service ServiceList, message string) ServiceList {
ret := make(ServiceList, 0)
foundApp := foundAppByMessage(message)
for _, app := range foundApp {
for _, s := range service {
if s.Name == app {
ret = append(ret, s)
}
}
}
return ret
}
func foundAppByMessage(message string) []string {
i := strings.Index(message, "[")
if i >= 0 {
j := strings.Index(message[i:], "]")
if j >= 0 {
return append([]string{message[i+1 : j+i]}, foundAppByMessage(message[j+i:])...)
}
}
return []string{}
}