goploy/service/SyncService.go

614 lines
21 KiB
Go
Raw Normal View History

2020-08-04 14:28:25 +08:00
package service
import (
"bytes"
"encoding/json"
"errors"
"github.com/zhenorzz/goploy/core"
"github.com/zhenorzz/goploy/model"
"github.com/zhenorzz/goploy/utils"
"github.com/zhenorzz/goploy/ws"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path"
"strconv"
"strings"
2021-02-11 20:00:48 +08:00
"sync"
2020-08-04 14:28:25 +08:00
)
2021-02-11 20:00:48 +08:00
// Gsync -
type Gsync struct {
2020-08-04 14:28:25 +08:00
UserInfo model.User
Project model.Project
ProjectServers model.ProjectServers
CommitID string
2020-12-03 17:05:03 +08:00
Branch string
2020-08-04 14:28:25 +08:00
}
type syncMessage struct {
serverName string
projectID int64
detail string
state int
}
2021-02-11 20:00:48 +08:00
// Exec Gsync
func (gsync Gsync) Exec() {
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(gsync.Project.ID, 10)+" deploy start")
2020-08-04 14:28:25 +08:00
publishTraceModel := model.PublishTrace{
2021-02-11 20:00:48 +08:00
Token: gsync.Project.LastPublishToken,
ProjectID: gsync.Project.ID,
ProjectName: gsync.Project.Name,
PublisherID: gsync.UserInfo.ID,
PublisherName: gsync.UserInfo.Name,
2020-08-04 14:28:25 +08:00
Type: model.Pull,
}
var gitCommitInfo utils.Commit
var err error
2021-02-11 20:00:48 +08:00
if len(gsync.CommitID) == 0 {
gitCommitInfo, err = gitFollow(gsync.Project, "origin/"+gsync.Project.Branch)
2020-08-04 14:28:25 +08:00
} else {
2021-02-11 20:00:48 +08:00
gitCommitInfo, err = gitFollow(gsync.Project, gsync.CommitID)
2020-08-04 14:28:25 +08:00
}
if err != nil {
2021-02-11 20:00:48 +08:00
gsync.Project.DeployFail()
2020-08-04 14:28:25 +08:00
publishTraceModel.Detail = err.Error()
publishTraceModel.State = model.Fail
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.DeployFail, Message: err.Error()},
2020-08-04 14:28:25 +08:00
}
if _, err := publishTraceModel.AddRow(); err != nil {
core.Log(core.ERROR, err.Error())
}
2021-03-22 14:10:15 +08:00
notify(gsync.Project, gsync.ProjectServers, gitCommitInfo, model.ProjectFail, err.Error())
2020-08-04 14:28:25 +08:00
return
}
2021-02-11 20:00:48 +08:00
if gsync.Branch != "" {
gitCommitInfo.Branch = gsync.Branch
2020-12-03 17:05:03 +08:00
} else {
2021-02-11 20:00:48 +08:00
gitCommitInfo.Branch = "origin/" + gsync.Project.Branch
2020-12-03 17:05:03 +08:00
}
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
Message: ws.ProjectMessage{
2021-02-11 20:00:48 +08:00
ProjectID: gsync.Project.ID,
ProjectName: gsync.Project.Name,
2020-12-03 17:05:03 +08:00
State: ws.GitDone,
Message: "Get commit info",
Ext: gitCommitInfo,
},
}
2020-08-04 14:28:25 +08:00
ext, _ := json.Marshal(gitCommitInfo)
publishTraceModel.Ext = string(ext)
publishTraceModel.State = model.Success
if _, err := publishTraceModel.AddRow(); err != nil {
core.Log(core.ERROR, err.Error())
2021-01-06 17:29:25 +08:00
return
}
2021-02-11 20:00:48 +08:00
if totalFileNumber, err := (model.ProjectFile{ProjectID: gsync.Project.ID}).GetTotalByProjectID(); err != nil {
2021-01-06 17:29:25 +08:00
core.Log(core.ERROR, err.Error())
return
} else if totalFileNumber > 0 {
2021-02-11 20:00:48 +08:00
if err := utils.CopyDir(core.GetProjectFilePath(gsync.Project.ID), core.GetProjectPath(gsync.Project.ID)); err != nil {
2021-01-06 17:29:25 +08:00
core.Log(core.ERROR, err.Error())
return
}
2020-08-04 14:28:25 +08:00
}
2021-01-06 17:29:25 +08:00
2021-02-11 20:00:48 +08:00
if gsync.Project.AfterPullScript != "" {
2020-08-04 14:28:25 +08:00
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.AfterPullScript, Message: "Run pull script"},
2020-08-04 14:28:25 +08:00
}
2021-02-11 20:00:48 +08:00
outputString, err := runAfterPullScript(gsync.Project)
2020-08-04 14:28:25 +08:00
publishTraceModel.Type = model.AfterPull
ext, _ := json.Marshal(struct {
Script string `json:"script"`
2021-02-11 20:00:48 +08:00
}{gsync.Project.AfterPullScript})
2020-08-04 14:28:25 +08:00
publishTraceModel.Ext = string(ext)
if err != nil {
2021-02-11 20:00:48 +08:00
gsync.Project.DeployFail()
2020-08-04 14:28:25 +08:00
publishTraceModel.Detail = err.Error()
publishTraceModel.State = model.Fail
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.DeployFail, Message: err.Error()},
2020-08-04 14:28:25 +08:00
}
if _, err := publishTraceModel.AddRow(); err != nil {
core.Log(core.ERROR, err.Error())
}
2021-03-22 14:10:15 +08:00
notify(gsync.Project, gsync.ProjectServers, gitCommitInfo, model.ProjectFail, err.Error())
2020-08-04 14:28:25 +08:00
return
}
publishTraceModel.Detail = outputString
publishTraceModel.State = model.Success
if _, err := publishTraceModel.AddRow(); err != nil {
core.Log(core.ERROR, err.Error())
}
}
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.Rsync, Message: "Rsync"},
2020-08-04 14:28:25 +08:00
}
2021-02-11 20:00:48 +08:00
ch := make(chan syncMessage, len(gsync.ProjectServers))
for _, projectServer := range gsync.ProjectServers {
go remoteSync(ch, gsync.UserInfo, gsync.Project, projectServer)
2020-08-04 14:28:25 +08:00
}
message := ""
2021-02-11 20:00:48 +08:00
for i := 0; i < len(gsync.ProjectServers); i++ {
2020-08-04 14:28:25 +08:00
syncMessage := <-ch
if syncMessage.state == model.ProjectFail {
message += syncMessage.serverName + " error message: " + syncMessage.detail
}
}
2021-02-12 23:05:06 +08:00
close(ch)
2020-08-04 14:28:25 +08:00
if message == "" {
2021-02-11 20:00:48 +08:00
gsync.Project.DeploySuccess()
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(gsync.Project.ID, 10)+" deploy success")
2020-08-04 14:28:25 +08:00
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.DeploySuccess, Message: "Success"},
2020-08-04 14:28:25 +08:00
}
2021-03-22 14:10:15 +08:00
notify(gsync.Project, gsync.ProjectServers, gitCommitInfo, model.ProjectSuccess, message)
2020-08-04 14:28:25 +08:00
} else {
2021-02-11 20:00:48 +08:00
gsync.Project.DeployFail()
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(gsync.Project.ID, 10)+" deploy fail")
2020-08-04 14:28:25 +08:00
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-11 20:00:48 +08:00
Message: ws.ProjectMessage{ProjectID: gsync.Project.ID, ProjectName: gsync.Project.Name, State: ws.DeployFail, Message: message},
2020-08-04 14:28:25 +08:00
}
2021-03-22 14:10:15 +08:00
notify(gsync.Project, gsync.ProjectServers, gitCommitInfo, model.ProjectFail, message)
2021-02-11 20:00:48 +08:00
}
if gsync.Project.SymlinkPath != "" {
var wg sync.WaitGroup
for _, projectServer := range gsync.ProjectServers {
wg.Add(1)
2021-02-12 16:21:05 +08:00
go func(projectServer model.ProjectServer) {
2021-02-11 20:00:48 +08:00
defer wg.Done()
removeExpiredBackup(gsync.Project, projectServer)
}(projectServer)
}
wg.Wait()
2020-08-04 14:28:25 +08:00
}
return
}
2020-12-03 17:05:03 +08:00
func gitFollow(project model.Project, target string) (utils.Commit, error) {
commit := utils.Commit{}
2020-09-04 09:36:23 +08:00
if err := (Repository{ProjectID: project.ID}.Create()); err != nil {
2020-12-03 17:05:03 +08:00
return commit, err
2020-08-04 14:28:25 +08:00
}
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2020-09-04 09:36:23 +08:00
Message: ws.ProjectMessage{ProjectID: project.ID, ProjectName: project.Name, State: ws.GitCreate, Message: "git create"},
2020-08-04 14:28:25 +08:00
}
2020-09-04 17:19:53 +08:00
git := utils.GIT{Dir: core.GetProjectPath(project.ID)}
2020-08-04 14:28:25 +08:00
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
Message: ws.ProjectMessage{ProjectID: project.ID, ProjectName: project.Name, State: ws.GitClean, Message: "git clean"},
}
2020-12-07 22:17:04 +08:00
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+" git add .")
if err := git.Add("."); err != nil {
core.Log(core.ERROR, err.Error()+", detail: "+git.Err.String())
return commit, errors.New(git.Err.String())
}
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+" git reset --hard")
if err := git.Reset("--hard"); err != nil {
2020-08-04 14:28:25 +08:00
core.Log(core.ERROR, err.Error()+", detail: "+git.Err.String())
2020-12-03 17:05:03 +08:00
return commit, errors.New(git.Err.String())
2020-08-04 14:28:25 +08:00
}
2020-12-03 17:05:03 +08:00
// the length of commit id is 40
if len(target) != 40 {
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2021-02-23 14:02:41 +08:00
Message: ws.ProjectMessage{ProjectID: project.ID, ProjectName: project.Name, State: ws.GitFetch, Message: "git fetch"},
2020-12-03 17:05:03 +08:00
}
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+" git fetch")
if err := git.Fetch(); err != nil {
core.Log(core.ERROR, err.Error()+", detail: "+git.Err.String())
return commit, errors.New(git.Err.String())
}
2020-08-04 14:28:25 +08:00
}
ws.GetHub().Data <- &ws.Data{
Type: ws.TypeProject,
2020-12-03 17:05:03 +08:00
Message: ws.ProjectMessage{ProjectID: project.ID, ProjectName: project.Name, State: ws.GitCheckout, Message: "git checkout"},
2020-08-04 14:28:25 +08:00
}
2020-12-03 17:05:03 +08:00
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+" git checkout -B goploy "+target)
if err := git.Checkout("-B", "goploy", target); err != nil {
2020-08-04 14:28:25 +08:00
core.Log(core.ERROR, err.Error()+", detail: "+git.Err.String())
2020-12-03 17:05:03 +08:00
return commit, errors.New(git.Err.String())
2020-08-04 14:28:25 +08:00
}
2020-12-03 17:05:03 +08:00
commit, err := gitCommitLog(project)
if err != nil {
return commit, err
2020-08-04 14:28:25 +08:00
}
2020-12-03 17:05:03 +08:00
return commit, err
2020-08-04 14:28:25 +08:00
}
func gitCommitLog(project model.Project) (utils.Commit, error) {
2020-09-04 17:19:53 +08:00
git := utils.GIT{Dir: core.GetProjectPath(project.ID)}
2020-08-04 14:28:25 +08:00
2020-11-04 19:43:18 +08:00
if err := git.Log("--stat", "--pretty=format:`start`%H`%an`%at`%s`%d`", "-n", "1"); err != nil {
2020-08-04 14:28:25 +08:00
core.Log(core.ERROR, err.Error()+", detail: "+git.Err.String())
return utils.Commit{}, errors.New(git.Err.String())
}
commitList := utils.ParseGITLog(git.Output.String())
return commitList[0], nil
}
func runAfterPullScript(project model.Project) (string, error) {
2020-09-04 17:19:53 +08:00
srcPath := core.GetProjectPath(project.ID)
2020-08-04 14:28:25 +08:00
scriptName := "goploy-after-pull." + utils.GetScriptExt(project.AfterPullScriptMode)
scriptFullName := path.Join(srcPath, scriptName)
scriptMode := "bash"
if len(project.AfterPullScriptMode) != 0 {
scriptMode = project.AfterPullScriptMode
}
ioutil.WriteFile(scriptFullName, []byte(project.AfterPullScript), 0755)
2021-01-22 19:14:00 +08:00
handler := exec.Command(scriptMode, scriptFullName)
2020-08-04 14:28:25 +08:00
handler.Dir = srcPath
var outbuf, errbuf bytes.Buffer
handler.Stdout = &outbuf
handler.Stderr = &errbuf
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+project.AfterPullScript)
if err := handler.Run(); err != nil {
core.Log(core.ERROR, errbuf.String())
return "", errors.New(errbuf.String())
}
os.Remove(scriptName)
return outbuf.String(), nil
}
2021-03-22 14:10:15 +08:00
func remoteSync(msgChIn chan<- syncMessage, userInfo model.User, project model.Project, projectServer model.ProjectServer) {
2020-08-04 14:28:25 +08:00
remoteMachine := projectServer.ServerOwner + "@" + projectServer.ServerIP
destDir := project.Path
ext, _ := json.Marshal(struct {
ServerID int64 `json:"serverId"`
ServerName string `json:"serverName"`
}{projectServer.ServerID, projectServer.ServerName})
publishTraceModel := model.PublishTrace{
Token: project.LastPublishToken,
ProjectID: project.ID,
ProjectName: project.Name,
PublisherID: userInfo.ID,
PublisherName: userInfo.Name,
Type: model.Deploy,
Ext: string(ext),
}
2020-11-05 14:43:03 +08:00
// write after deploy script for rsync
if len(project.AfterDeployScript) != 0 {
scriptName := path.Join(core.GetProjectPath(project.ID), "goploy-after-deploy."+utils.GetScriptExt(project.AfterDeployScriptMode))
2021-03-26 17:00:18 +08:00
ioutil.WriteFile(scriptName, []byte(ReplaceScriptVars(project.AfterDeployScript, project)), 0755)
2020-11-05 14:43:03 +08:00
}
2020-08-04 14:28:25 +08:00
rsyncOption, _ := utils.ParseCommandLine(project.RsyncOption)
2020-11-16 19:22:26 +08:00
rsyncOption = append([]string{"--exclude", "goploy-after-pull.sh", "--include", "goploy-after-deploy.sh"}, rsyncOption...)
2021-02-12 23:05:06 +08:00
rsyncOption = append(rsyncOption, "-e", "ssh -p "+strconv.Itoa(projectServer.ServerPort)+" -o StrictHostKeyChecking=no")
2020-08-04 14:28:25 +08:00
if len(project.SymlinkPath) != 0 {
destDir = path.Join(project.SymlinkPath, project.Name, project.LastPublishToken)
}
2020-09-04 17:19:53 +08:00
srcPath := core.GetProjectPath(project.ID) + "/"
2021-03-10 15:12:21 +08:00
// rsync path can not contain colon
// windows like C:\
if strings.Contains(srcPath, ":\\") {
srcPath = "/cygdrive/" + strings.Replace(srcPath, ":\\", "/", 1)
}
2020-08-04 14:28:25 +08:00
destPath := remoteMachine + ":" + destDir
2021-04-08 18:36:35 +08:00
rsyncOption = append(rsyncOption, "--rsync-path=mkdir -p "+destDir+" && rsync", srcPath, destPath)
2020-08-04 14:28:25 +08:00
cmd := exec.Command("rsync", rsyncOption...)
var outbuf, errbuf bytes.Buffer
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
core.Log(core.TRACE, "projectID:"+strconv.FormatInt(project.ID, 10)+" rsync "+strings.Join(rsyncOption, " "))
2020-10-23 14:43:49 +08:00
if err := cmd.Run(); err != nil {
core.Log(core.ERROR, "err: "+err.Error()+", detail: "+errbuf.String())
2021-03-10 15:12:21 +08:00
publishTraceModel.Detail = "err: " + err.Error() + ", detail: " + errbuf.String()
2020-08-04 14:28:25 +08:00
publishTraceModel.State = model.Fail
publishTraceModel.AddRow()
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2020-08-04 14:28:25 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
2021-03-10 15:12:21 +08:00
detail: "err: " + err.Error() + ", detail: " + errbuf.String(),
2020-08-04 14:28:25 +08:00
state: model.ProjectFail,
}
return
}
2020-10-23 14:43:49 +08:00
ext, _ = json.Marshal(struct {
ServerID int64 `json:"serverId"`
ServerName string `json:"serverName"`
Command string `json:"command"`
}{projectServer.ServerID, projectServer.ServerName, "rsync " + strings.Join(rsyncOption, " ")})
publishTraceModel.Ext = string(ext)
publishTraceModel.Detail = outbuf.String()
publishTraceModel.State = model.Success
publishTraceModel.AddRow()
2020-08-04 14:28:25 +08:00
var afterDeployCommands []string
if len(project.SymlinkPath) != 0 {
afterDeployCommands = append(afterDeployCommands, "ln -sfn "+destDir+" "+project.Path)
// change the destination folder time, make sure it can not be clean
afterDeployCommands = append(afterDeployCommands, "touch -m "+destDir)
}
if len(project.AfterDeployScript) != 0 {
scriptMode := "bash"
2020-10-23 14:43:49 +08:00
if len(project.AfterDeployScriptMode) != 0 {
2020-08-04 14:28:25 +08:00
scriptMode = project.AfterDeployScriptMode
}
2020-11-16 19:22:26 +08:00
afterDeployScriptPath := path.Join(project.Path, "goploy-after-deploy."+utils.GetScriptExt(project.AfterDeployScriptMode))
afterDeployCommands = append(afterDeployCommands, scriptMode+" "+afterDeployScriptPath)
afterDeployCommands = append(afterDeployCommands, "rm -f "+afterDeployScriptPath)
2020-08-04 14:28:25 +08:00
}
// no symlink and deploy script
if len(afterDeployCommands) == 0 {
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2020-08-04 14:28:25 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
state: model.ProjectSuccess,
}
return
}
publishTraceModel.Type = model.AfterDeploy
ext, _ = json.Marshal(struct {
ServerID int64 `json:"serverId"`
ServerName string `json:"serverName"`
Script string `json:"script"`
}{projectServer.ServerID, projectServer.ServerName, strings.Join(afterDeployCommands, ";")})
publishTraceModel.Ext = string(ext)
2021-02-12 23:05:06 +08:00
client, dialError := utils.DialSSH(projectServer.ServerOwner, projectServer.ServerPassword, projectServer.ServerPath, projectServer.ServerIP, projectServer.ServerPort)
2021-02-12 16:21:05 +08:00
if dialError != nil {
core.Log(core.ERROR, dialError.Error())
publishTraceModel.Detail = dialError.Error()
2020-08-04 14:28:25 +08:00
publishTraceModel.State = model.Fail
publishTraceModel.AddRow()
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2020-08-04 14:28:25 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
2021-02-12 16:21:05 +08:00
detail: dialError.Error(),
state: model.ProjectFail,
}
return
}
session, sessionErr := client.NewSession()
if sessionErr != nil {
core.Log(core.ERROR, sessionErr.Error())
publishTraceModel.Detail = sessionErr.Error()
publishTraceModel.State = model.Fail
publishTraceModel.AddRow()
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2021-02-12 16:21:05 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
detail: sessionErr.Error(),
2020-08-04 14:28:25 +08:00
state: model.ProjectFail,
}
return
2020-10-23 14:43:49 +08:00
}
var sshOutbuf, sshErrbuf bytes.Buffer
session.Stdout = &sshOutbuf
session.Stderr = &sshErrbuf
if err := session.Run(strings.Join(afterDeployCommands, ";")); err != nil {
core.Log(core.ERROR, "err: "+err.Error()+", detail: "+sshErrbuf.String())
publishTraceModel.Detail = err.Error()
2020-08-04 14:28:25 +08:00
publishTraceModel.State = model.Fail
publishTraceModel.AddRow()
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2020-08-04 14:28:25 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
2020-10-23 14:43:49 +08:00
detail: err.Error(),
2020-08-04 14:28:25 +08:00
state: model.ProjectFail,
}
return
}
2020-10-23 14:43:49 +08:00
publishTraceModel.Detail = sshOutbuf.String()
publishTraceModel.State = model.Success
publishTraceModel.AddRow()
defer session.Close()
2021-03-22 14:10:15 +08:00
msgChIn <- syncMessage{
2020-08-04 14:28:25 +08:00
serverName: projectServer.ServerName,
projectID: project.ID,
state: model.ProjectSuccess,
}
return
}
2021-03-22 14:10:15 +08:00
// commit id
// commit message
// server ip & name
// deploy user name
// deploy time
func notify(project model.Project, projectServers model.ProjectServers, commitInfo utils.Commit, deployState int, detail string) {
serverList := ""
for _, projectServer := range projectServers {
if projectServer.ServerName != projectServer.ServerIP {
serverList += projectServer.ServerName + "(" + projectServer.ServerIP + ")"
} else {
serverList += projectServer.ServerIP
}
serverList += ", "
}
serverList = strings.TrimRight(serverList, ", ")
2021-02-12 23:05:06 +08:00
if project.NotifyType == model.NotifyWeiXin {
2020-08-04 14:28:25 +08:00
type markdown struct {
Content string `json:"content"`
}
type message struct {
Msgtype string `json:"msgtype"`
Markdown markdown `json:"markdown"`
}
2021-03-22 14:10:15 +08:00
content := "Deploy: <font color=\"warning\">" + project.Name + "</font>\n"
content += "Publisher: <font color=\"comment\">" + project.PublisherName + "</font>\n"
content += "Branch: <font color=\"comment\">" + commitInfo.Branch + "</font>\n"
content += "CommitSHA: <font color=\"comment\">" + commitInfo.Commit + "</font>\n"
content += "CommitMessage: <font color=\"comment\">" + commitInfo.Message + "</font>\n"
content += "ServerList: <font color=\"comment\">" + serverList + "</font>\n"
2020-08-04 14:28:25 +08:00
if deployState == model.ProjectFail {
2021-03-22 14:10:15 +08:00
content += "State: <font color=\"red\">fail</font> \n"
2020-08-15 13:38:06 +08:00
content += "> Detail: <font color=\"comment\">" + detail + "</font>"
2020-08-04 14:28:25 +08:00
} else {
2021-03-22 14:10:15 +08:00
content += "State: <font color=\"green\">success</font>"
2020-08-04 14:28:25 +08:00
}
msg := message{
Msgtype: "markdown",
Markdown: markdown{
Content: content,
},
}
b, _ := json.Marshal(msg)
_, err := http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
if err != nil {
core.Log(core.ERROR, "projectID:"+strconv.FormatInt(project.ID, 10)+" "+err.Error())
}
} else if project.NotifyType == model.NotifyDingTalk {
2020-09-09 21:31:21 +08:00
type markdown struct {
Title string `json:"title"`
Text string `json:"text"`
}
2020-08-04 14:28:25 +08:00
type message struct {
2020-09-09 21:31:21 +08:00
Msgtype string `json:"msgtype"`
Markdown markdown `json:"markdown"`
2020-08-04 14:28:25 +08:00
}
2021-03-22 14:10:15 +08:00
text := "#### Deploy" + project.Name + " \n "
text += "#### Publisher" + project.PublisherName + " \n "
text += "#### Branch" + commitInfo.Branch + " \n "
text += "#### CommitSHA" + commitInfo.Commit + " \n "
text += "#### CommitMessage" + commitInfo.Message + " \n "
text += "#### ServerList" + serverList + " \n "
2020-08-04 14:28:25 +08:00
if deployState == model.ProjectFail {
2021-03-22 14:10:15 +08:00
text += "#### State <font color=\"red\">fail</font> \n "
2020-08-15 13:38:06 +08:00
text += "> Detail: <font color=\"comment\">" + detail + "</font>"
2020-08-04 14:28:25 +08:00
} else {
2021-03-22 14:10:15 +08:00
text += "#### State <font color=\"green\">success</font>"
2020-08-04 14:28:25 +08:00
}
msg := message{
Msgtype: "markdown",
2020-09-09 21:31:21 +08:00
Markdown: markdown{
Title: project.Name,
Text: text,
},
2020-08-04 14:28:25 +08:00
}
b, _ := json.Marshal(msg)
_, err := http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
if err != nil {
core.Log(core.ERROR, "projectID:"+strconv.FormatInt(project.ID, 10)+" "+err.Error())
}
} else if project.NotifyType == model.NotifyFeiShu {
type message struct {
Title string `json:"title"`
Text string `json:"text"`
}
text := ""
2021-03-22 14:10:15 +08:00
text += "Publisher: " + project.PublisherName + "\n"
text += "Branch: " + commitInfo.Branch + "\n"
text += "CommitSHA: " + commitInfo.Commit + "\n"
text += "CommitMessage: " + commitInfo.Message + "\n"
text += "ServerList: " + serverList + "\n"
2020-08-04 14:28:25 +08:00
if deployState == model.ProjectFail {
2020-08-15 13:38:06 +08:00
text += "State: fail\n "
text += "Detail: " + detail
2020-08-04 14:28:25 +08:00
} else {
2020-08-15 13:38:06 +08:00
text += "State: success"
2020-08-04 14:28:25 +08:00
}
msg := message{
2020-08-15 13:38:06 +08:00
Title: "Deploy:" + project.Name,
2020-08-04 14:28:25 +08:00
Text: text,
}
b, _ := json.Marshal(msg)
_, err := http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
if err != nil {
core.Log(core.ERROR, "projectID:"+strconv.FormatInt(project.ID, 10)+" "+err.Error())
}
} else if project.NotifyType == model.NotifyCustom {
type message struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
2021-03-22 14:10:15 +08:00
ProjectID int64 `json:"projectId"`
ProjectName string `json:"projectName"`
Publisher string `json:"publisher"`
Branch string `json:"branch"`
CommitSHA string `json:"commitSHA"`
CommitMessage string `json:"commitMessage"`
ServerList string `json:"serverList"`
2020-08-04 14:28:25 +08:00
} `json:"data"`
}
code := 0
if deployState == model.ProjectFail {
code = 1
}
msg := message{
Code: code,
Message: detail,
}
msg.Data.ProjectID = project.ID
msg.Data.ProjectName = project.Name
2021-03-22 14:10:15 +08:00
msg.Data.Publisher = project.PublisherName
msg.Data.Branch = commitInfo.Branch
msg.Data.CommitSHA = commitInfo.Commit
msg.Data.CommitMessage = commitInfo.Message
msg.Data.ServerList = serverList
2020-08-04 14:28:25 +08:00
b, _ := json.Marshal(msg)
_, err := http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
if err != nil {
core.Log(core.ERROR, "projectID:"+strconv.FormatInt(project.ID, 10)+" "+err.Error())
}
}
}
//keep the latest 10 project
func removeExpiredBackup(project model.Project, projectServer model.ProjectServer) {
2021-02-12 23:05:06 +08:00
client, err := utils.DialSSH(projectServer.ServerOwner, projectServer.ServerPassword, projectServer.ServerPath, projectServer.ServerIP, projectServer.ServerPort)
2021-02-12 16:21:05 +08:00
if err != nil {
core.Log(core.ERROR, err.Error())
return
}
session, err := client.NewSession()
if err != nil {
core.Log(core.ERROR, err.Error())
2020-08-04 14:28:25 +08:00
return
}
defer session.Close()
var sshOutbuf, sshErrbuf bytes.Buffer
session.Stdout = &sshOutbuf
session.Stderr = &sshErrbuf
destDir := path.Join(project.SymlinkPath, project.Name)
2021-02-12 16:21:05 +08:00
if err = session.Run("cd " + destDir + ";ls -t | awk 'NR>10' | xargs rm -rf"); err != nil {
core.Log(core.ERROR, err.Error())
2020-08-04 14:28:25 +08:00
}
}
2020-11-04 19:43:18 +08:00
2021-03-26 17:00:18 +08:00
func ReplaceScriptVars(script string, project model.Project) string {
2020-11-04 19:43:18 +08:00
scriptVars := map[string]string{
"${PROJECT_PATH}": project.Path,
"${PROJECT_SYMLINK_PATH}": path.Join(project.SymlinkPath, project.LastPublishToken),
"${PROJECT_NAME}": project.Name,
}
for key, value := range scriptVars {
script = strings.Replace(script, key, value, -1)
}
return script
}