2021-12-28 20:42:51 +08:00
|
|
|
|
package config_handler
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/json"
|
2021-12-30 20:06:10 +08:00
|
|
|
|
"errors"
|
2021-12-28 20:42:51 +08:00
|
|
|
|
"strings"
|
|
|
|
|
|
2021-12-30 20:06:10 +08:00
|
|
|
|
"git.icechen.cn/pkg/drone_plugin/consts"
|
|
|
|
|
|
2021-12-28 20:42:51 +08:00
|
|
|
|
"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{}
|
|
|
|
|
|
2021-12-29 23:23:35 +08:00
|
|
|
|
type Handler interface {
|
|
|
|
|
ToDestinationConfig() (string, error)
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-28 20:42:51 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-30 20:06:10 +08:00
|
|
|
|
// 2. 是否部署
|
|
|
|
|
// 2.1 非 monorepo 的直接返回
|
2021-12-28 20:42:51 +08:00
|
|
|
|
if cfg.Type != TypeMonorepo {
|
|
|
|
|
// 返回 nil 按照 204 处理
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
2021-12-30 20:06:10 +08:00
|
|
|
|
// 2.2 无部署环境报错返回,阻断部署
|
|
|
|
|
if getDeployEnv(req) == consts.EnvNone {
|
|
|
|
|
return nil, errors.New("ignore event")
|
|
|
|
|
}
|
2021-12-28 20:42:51 +08:00
|
|
|
|
|
|
|
|
|
// 3. 获取提交文件树
|
|
|
|
|
modifiedFileList, err := getGitClient(req).GetCommitModifiedFileList()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Error(err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. 根据文件树以及原始配置文件的信息,组装需要构建的服务的ci信息
|
|
|
|
|
// 4.1 api
|
2022-01-06 17:54:17 +08:00
|
|
|
|
modifiedApiList := getModifiedApi(cfg.Api, modifiedFileList, foundAppByMessage(req.Build.Message), foundAppByParams(req.Build.Params))
|
2021-12-30 20:06:10 +08:00
|
|
|
|
destinationApi, err := modifiedApiList.toDestinationConfig(cfg.Name, getDeployEnv(req), cfg.toServiceEnv())
|
2021-12-29 19:40:57 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Error(err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2021-12-28 20:42:51 +08:00
|
|
|
|
|
|
|
|
|
// 4.2 service
|
2022-01-06 17:54:17 +08:00
|
|
|
|
modifiedServiceList := getModifiedService(cfg.Service, modifiedFileList, foundAppByMessage(req.Build.Message), foundAppByParams(req.Build.Params))
|
2021-12-30 20:06:10 +08:00
|
|
|
|
destinationService, err := modifiedServiceList.toDestinationConfig(cfg.Name, getDeployEnv(req), cfg.toServiceEnv())
|
2021-12-29 19:40:57 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
logrus.Error(err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2021-12-28 20:42:51 +08:00
|
|
|
|
|
2022-01-04 19:37:59 +08:00
|
|
|
|
if len(modifiedApiList) == 0 && len(modifiedServiceList) == 0 {
|
2022-01-09 17:42:16 +08:00
|
|
|
|
// 返回空
|
|
|
|
|
return &drone.Config{
|
|
|
|
|
Data: "",
|
|
|
|
|
Kind: "",
|
2022-01-09 17:50:16 +08:00
|
|
|
|
}, errors.New("skipping build")
|
2022-01-04 19:37:59 +08:00
|
|
|
|
}
|
2021-12-29 20:28:37 +08:00
|
|
|
|
retData := destinationApi + "\n\n" + destinationService
|
2021-12-29 21:22:42 +08:00
|
|
|
|
n := strings.LastIndex(retData, "---")
|
|
|
|
|
if n > 0 {
|
|
|
|
|
retData = retData[:n]
|
|
|
|
|
}
|
2021-12-29 20:28:37 +08:00
|
|
|
|
logrus.Info(retData)
|
2021-12-28 20:42:51 +08:00
|
|
|
|
// 5. 组装所有ci信息并输出
|
2021-12-29 19:40:57 +08:00
|
|
|
|
return &drone.Config{
|
2021-12-29 20:28:37 +08:00
|
|
|
|
Data: retData,
|
2021-12-29 19:40:57 +08:00
|
|
|
|
Kind: "pipeline",
|
|
|
|
|
}, nil
|
2021-12-28 20:42:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getGitClient(req *config.Request) git.Client {
|
|
|
|
|
return git.New(req.Repo.Namespace, req.Repo.Name, req.Build.After, req.Repo.Config)
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-30 20:06:10 +08:00
|
|
|
|
func getDeployEnv(req *config.Request) consts.Env {
|
|
|
|
|
switch req.Build.Event {
|
|
|
|
|
case "push":
|
2022-01-06 16:39:12 +08:00
|
|
|
|
fallthrough
|
|
|
|
|
case "custom":
|
2021-12-30 20:06:10 +08:00
|
|
|
|
if req.Build.Target == "master" {
|
|
|
|
|
return consts.EnvTest
|
|
|
|
|
}
|
|
|
|
|
case "tag":
|
|
|
|
|
return consts.EnvProduction
|
|
|
|
|
}
|
|
|
|
|
return consts.EnvNone
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 17:54:17 +08:00
|
|
|
|
func getModifiedApi(api ApiList, modifiedFileList []string, appByMessage []string, appByParams []string) ApiList {
|
2021-12-29 19:40:57 +08:00
|
|
|
|
ret := make(ApiList, 0)
|
2021-12-28 20:42:51 +08:00
|
|
|
|
tempIndex := NewSet()
|
|
|
|
|
for i, a := range api {
|
|
|
|
|
for _, file := range modifiedFileList {
|
2021-12-29 20:50:41 +08:00
|
|
|
|
if strings.HasPrefix(file, a.Root) {
|
2021-12-28 20:42:51 +08:00
|
|
|
|
tempIndex.Add(i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, i := range tempIndex.ToSlice() {
|
|
|
|
|
ret = append(ret, api[i])
|
|
|
|
|
}
|
2022-01-06 17:54:17 +08:00
|
|
|
|
ret = append(ret, getDeployApiByAppSlice(api, append(appByMessage, appByParams...))...)
|
2021-12-28 20:42:51 +08:00
|
|
|
|
return ret
|
|
|
|
|
}
|
2021-12-29 19:40:57 +08:00
|
|
|
|
|
2022-01-06 17:54:17 +08:00
|
|
|
|
func getDeployApiByAppSlice(api ApiList, appSlice []string) ApiList {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
ret := make(ApiList, 0)
|
2022-01-06 17:54:17 +08:00
|
|
|
|
for _, app := range appSlice {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
for _, a := range api {
|
2022-01-06 17:54:17 +08:00
|
|
|
|
if "api-"+a.Name == strings.TrimSpace(app) {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
ret = append(ret, a)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 17:54:17 +08:00
|
|
|
|
func getModifiedService(service ServiceList, modifiedFileList []string, appByMessage []string, appByParams []string) ServiceList {
|
2021-12-29 19:40:57 +08:00
|
|
|
|
ret := make(ServiceList, 0)
|
|
|
|
|
tempIndex := NewSet()
|
|
|
|
|
for i, s := range service {
|
|
|
|
|
for _, file := range modifiedFileList {
|
2021-12-29 20:50:41 +08:00
|
|
|
|
if strings.HasPrefix(file, s.Root) {
|
2021-12-29 19:40:57 +08:00
|
|
|
|
tempIndex.Add(i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, i := range tempIndex.ToSlice() {
|
|
|
|
|
ret = append(ret, service[i])
|
|
|
|
|
}
|
2022-01-06 17:54:17 +08:00
|
|
|
|
ret = append(ret, getDeployServiceByAppSlice(service, append(appByMessage, appByParams...))...)
|
2022-01-04 20:32:45 +08:00
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-06 17:54:17 +08:00
|
|
|
|
func getDeployServiceByAppSlice(service ServiceList, appSlice []string) ServiceList {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
ret := make(ServiceList, 0)
|
2022-01-06 17:54:17 +08:00
|
|
|
|
for _, app := range appSlice {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
for _, s := range service {
|
2022-01-06 17:54:17 +08:00
|
|
|
|
if "service-"+s.Name == strings.TrimSpace(app) {
|
2022-01-04 20:32:45 +08:00
|
|
|
|
ret = append(ret, s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-29 19:40:57 +08:00
|
|
|
|
return ret
|
|
|
|
|
}
|
2022-01-04 20:32:45 +08:00
|
|
|
|
|
|
|
|
|
func foundAppByMessage(message string) []string {
|
|
|
|
|
i := strings.Index(message, "[")
|
|
|
|
|
if i >= 0 {
|
|
|
|
|
j := strings.Index(message[i:], "]")
|
|
|
|
|
if j >= 0 {
|
2022-01-06 17:56:42 +08:00
|
|
|
|
return append(strings.Split(message[i+1:j+i], ","), foundAppByMessage(message[j+i:])...)
|
2022-01-04 20:32:45 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return []string{}
|
|
|
|
|
}
|
2022-01-06 17:54:17 +08:00
|
|
|
|
|
|
|
|
|
func foundAppByParams(params map[string]string) []string {
|
|
|
|
|
app, has := params["app"]
|
|
|
|
|
if has {
|
|
|
|
|
return strings.Split(app, ",")
|
|
|
|
|
}
|
|
|
|
|
return []string{}
|
|
|
|
|
}
|