mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-02 04:07:33 +08:00
591 lines
13 KiB
Go
591 lines
13 KiB
Go
// Copyright 2022 The Goploy Authors. All rights reserved.
|
|
// Use of this source code is governed by a GPLv3-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
sq "github.com/Masterminds/squirrel"
|
|
"github.com/zhenorzz/goploy/config"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const projectTable = "`project`"
|
|
|
|
type ProjectScript struct {
|
|
AfterPull struct {
|
|
Mode string `json:"mode"`
|
|
Content string `json:"content"`
|
|
} `json:"afterPull"`
|
|
AfterDeploy struct {
|
|
Mode string `json:"mode"`
|
|
Content string `json:"content"`
|
|
ScriptNames []string `json:"scriptNames"`
|
|
} `json:"afterDeploy"`
|
|
DeployFinish struct {
|
|
Mode string `json:"mode"`
|
|
Content string `json:"content"`
|
|
} `json:"deployFinish"`
|
|
}
|
|
|
|
type Project struct {
|
|
ID int64 `json:"id"`
|
|
NamespaceID int64 `json:"namespaceId"`
|
|
UserID int64 `json:"userId,omitempty"`
|
|
RepoType string `json:"repoType"`
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Label string `json:"label"`
|
|
Path string `json:"path"`
|
|
Environment uint8 `json:"environment"`
|
|
Branch string `json:"branch"`
|
|
SymlinkPath string `json:"symlinkPath"`
|
|
SymlinkBackupNumber uint8 `json:"symlinkBackupNumber"`
|
|
Review uint8 `json:"review"`
|
|
ReviewURL string `json:"reviewURL"`
|
|
Script ProjectScript `json:"script"`
|
|
TransferType string `json:"transferType"`
|
|
TransferOption string `json:"transferOption"`
|
|
DeployServerMode string `json:"deployServerMode"`
|
|
AutoDeploy uint8 `json:"autoDeploy"`
|
|
PublisherID int64 `json:"publisherId"`
|
|
PublisherName string `json:"publisherName"`
|
|
PublishExt string `json:"publishExt"`
|
|
DeployState uint8 `json:"deployState"`
|
|
LastPublishToken string `json:"lastPublishToken"`
|
|
NotifyType uint8 `json:"notifyType"`
|
|
NotifyTarget string `json:"notifyTarget"`
|
|
State uint8 `json:"state"`
|
|
InsertTime string `json:"insertTime"`
|
|
UpdateTime string `json:"updateTime"`
|
|
}
|
|
|
|
// Project deploy state
|
|
const (
|
|
ProjectNotDeploy = 0
|
|
ProjectDeploying = 1
|
|
ProjectSuccess = 2
|
|
ProjectFail = 3
|
|
)
|
|
|
|
// Project deploy type
|
|
const (
|
|
ProjectManualDeploy = 0
|
|
ProjectWebhookDeploy = 1
|
|
)
|
|
|
|
const (
|
|
RepoGit = "git"
|
|
RepoSVN = "svn"
|
|
RepoFTP = "ftp"
|
|
RepoSFTP = "sftp"
|
|
)
|
|
|
|
// Project notify type
|
|
const (
|
|
NotifyWeiXin = 1
|
|
NotifyDingTalk = 2
|
|
NotifyFeiShu = 3
|
|
NotifyCustom = 255
|
|
)
|
|
|
|
type Projects []Project
|
|
|
|
func (p Project) AddRow() (int64, error) {
|
|
script, err := json.Marshal(p.Script)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
result, err := sq.
|
|
Insert(projectTable).
|
|
Columns(
|
|
"namespace_id",
|
|
"name",
|
|
"repo_type",
|
|
"url",
|
|
"label",
|
|
"path",
|
|
"environment",
|
|
"branch",
|
|
"symlink_path",
|
|
"symlink_backup_number",
|
|
"review",
|
|
"review_url",
|
|
"script",
|
|
"transfer_type",
|
|
"transfer_option",
|
|
"deploy_server_mode",
|
|
"notify_type",
|
|
"notify_target",
|
|
).
|
|
Values(
|
|
p.NamespaceID,
|
|
p.Name,
|
|
p.RepoType,
|
|
p.URL,
|
|
p.Label,
|
|
p.Path,
|
|
p.Environment,
|
|
p.Branch,
|
|
p.SymlinkPath,
|
|
p.SymlinkBackupNumber,
|
|
p.Review,
|
|
p.ReviewURL,
|
|
script,
|
|
p.TransferType,
|
|
p.TransferOption,
|
|
p.DeployServerMode,
|
|
p.NotifyType,
|
|
p.NotifyTarget,
|
|
).
|
|
RunWith(DB).
|
|
Exec()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := result.LastInsertId()
|
|
return id, err
|
|
}
|
|
|
|
func (p Project) EditRow() error {
|
|
script, err := json.Marshal(p.Script)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"name": p.Name,
|
|
"repo_type": p.RepoType,
|
|
"url": p.URL,
|
|
"label": p.Label,
|
|
"path": p.Path,
|
|
"environment": p.Environment,
|
|
"branch": p.Branch,
|
|
"symlink_path": p.SymlinkPath,
|
|
"symlink_backup_number": p.SymlinkBackupNumber,
|
|
"review": p.Review,
|
|
"review_url": p.ReviewURL,
|
|
"script": script,
|
|
"transfer_type": p.TransferType,
|
|
"transfer_option": p.TransferOption,
|
|
"deploy_server_mode": p.DeployServerMode,
|
|
"notify_type": p.NotifyType,
|
|
"notify_target": p.NotifyTarget,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
return err
|
|
}
|
|
|
|
func (p Project) SetAutoDeploy() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"auto_deploy": p.AutoDeploy,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
|
|
return err
|
|
}
|
|
|
|
func (p Project) RemoveRow() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"state": Disable,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
return err
|
|
}
|
|
|
|
func (p Project) Publish() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"publisher_id": p.PublisherID,
|
|
"publisher_name": p.PublisherName,
|
|
"deploy_state": p.DeployState,
|
|
"last_publish_token": p.LastPublishToken,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
return err
|
|
}
|
|
|
|
// ResetState set deploy_state to NotDeploy
|
|
func (p Project) ResetState() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"deploy_state": ProjectNotDeploy,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
|
|
return err
|
|
}
|
|
|
|
// DeploySuccess set deploy_state to success
|
|
func (p Project) DeploySuccess() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"deploy_state": ProjectSuccess,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
|
|
return err
|
|
}
|
|
|
|
// DeployFail set deploy_state to fail
|
|
func (p Project) DeployFail() error {
|
|
_, err := sq.
|
|
Update(projectTable).
|
|
SetMap(sq.Eq{
|
|
"deploy_state": ProjectFail,
|
|
}).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
Exec()
|
|
|
|
return err
|
|
}
|
|
|
|
func (p Project) GetLabelList() (labels []string, err error) {
|
|
builder := sq.Select("label").
|
|
From(projectTable).
|
|
Where(sq.Eq{
|
|
"namespace_id": p.NamespaceID,
|
|
"state": Enable,
|
|
}).
|
|
Distinct()
|
|
|
|
if p.UserID > 0 {
|
|
builder = builder.
|
|
Join(fmt.Sprintf("%[1]s on %[1]s.project_id = %s.id", projectUserTable, projectTable)).
|
|
Where(sq.Eq{"user_id": p.UserID})
|
|
}
|
|
|
|
rows, err := builder.
|
|
RunWith(DB).
|
|
Query()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
labelMap := map[string]bool{}
|
|
var label string
|
|
for rows.Next() {
|
|
if err := rows.Scan(&label); err != nil {
|
|
return nil, err
|
|
}
|
|
if label != "" {
|
|
for _, item := range strings.Split(label, ",") {
|
|
labelMap[item] = false
|
|
}
|
|
}
|
|
}
|
|
labels = make([]string, len(labelMap))
|
|
var i int
|
|
for k := range labelMap {
|
|
labels[i] = k
|
|
i++
|
|
}
|
|
return labels, nil
|
|
}
|
|
|
|
func (p Project) GetList() (Projects, error) {
|
|
builder := sq.
|
|
Select(`
|
|
project.id,
|
|
name,
|
|
repo_type,
|
|
url,
|
|
label,
|
|
path,
|
|
environment,
|
|
branch,
|
|
symlink_path,
|
|
symlink_backup_number,
|
|
review,
|
|
review_url,
|
|
script,
|
|
transfer_type,
|
|
transfer_option,
|
|
deploy_server_mode,
|
|
auto_deploy,
|
|
notify_type,
|
|
notify_target,
|
|
project.insert_time,
|
|
project.update_time
|
|
`).
|
|
From(projectTable).
|
|
Where(sq.Eq{
|
|
"namespace_id": p.NamespaceID,
|
|
"state": Enable,
|
|
})
|
|
|
|
if p.UserID > 0 {
|
|
builder = builder.
|
|
Join(projectUserTable + " ON project_user.project_id = project.id").
|
|
Where(sq.Eq{"user_id": p.UserID})
|
|
}
|
|
|
|
rows, err := builder.
|
|
OrderBy("id DESC").
|
|
RunWith(DB).
|
|
Query()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
projects := Projects{}
|
|
for rows.Next() {
|
|
var project Project
|
|
var script []byte
|
|
if err = rows.Scan(
|
|
&project.ID,
|
|
&project.Name,
|
|
&project.RepoType,
|
|
&project.URL,
|
|
&project.Label,
|
|
&project.Path,
|
|
&project.Environment,
|
|
&project.Branch,
|
|
&project.SymlinkPath,
|
|
&project.SymlinkBackupNumber,
|
|
&project.Review,
|
|
&project.ReviewURL,
|
|
&script,
|
|
&project.TransferType,
|
|
&project.TransferOption,
|
|
&project.DeployServerMode,
|
|
&project.AutoDeploy,
|
|
&project.NotifyType,
|
|
&project.NotifyTarget,
|
|
&project.InsertTime,
|
|
&project.UpdateTime,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = json.Unmarshal(script, &project.Script); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
projects = append(projects, project)
|
|
}
|
|
|
|
return projects, nil
|
|
}
|
|
|
|
func (p Project) GetDeployList() (Projects, error) {
|
|
builder := sq.
|
|
Select(`
|
|
project.id,
|
|
project.name,
|
|
project.repo_type,
|
|
project.transfer_type,
|
|
project.url,
|
|
project.label,
|
|
project.publisher_id,
|
|
project.publisher_name,
|
|
IFNULL(publish_trace.ext, '{}'),
|
|
project.environment,
|
|
project.branch,
|
|
project.symlink_path,
|
|
project.review,
|
|
project.script,
|
|
project.last_publish_token,
|
|
project.auto_deploy,
|
|
project.deploy_state,
|
|
project.update_time`).
|
|
From(projectTable).
|
|
LeftJoin(fmt.Sprintf("%[1]s ON %[1]s.project_id = %s.id and %[1]s.token = %s.last_publish_token and type = %d", publishTraceTable, projectTable, Pull)).
|
|
Where(sq.Eq{
|
|
"project.namespace_id": p.NamespaceID,
|
|
"project.state": Enable,
|
|
})
|
|
|
|
if p.UserID > 0 {
|
|
builder = builder.
|
|
LeftJoin(projectUserTable + " ON project_user.project_id = project.id").
|
|
Where(sq.Eq{"project_user.user_id": p.UserID})
|
|
}
|
|
|
|
rows, err := builder.
|
|
OrderBy("project.id DESC").
|
|
RunWith(DB).
|
|
Query()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
projects := Projects{}
|
|
for rows.Next() {
|
|
var project Project
|
|
var script []byte
|
|
if err := rows.Scan(
|
|
&project.ID,
|
|
&project.Name,
|
|
&project.RepoType,
|
|
&project.TransferType,
|
|
&project.URL,
|
|
&project.Label,
|
|
&project.PublisherID,
|
|
&project.PublisherName,
|
|
&project.PublishExt,
|
|
&project.Environment,
|
|
&project.Branch,
|
|
&project.SymlinkPath,
|
|
&project.Review,
|
|
&script,
|
|
&project.LastPublishToken,
|
|
&project.AutoDeploy,
|
|
&project.DeployState,
|
|
&project.UpdateTime); err != nil {
|
|
return projects, err
|
|
}
|
|
|
|
if err = json.Unmarshal(script, &project.Script); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
projects = append(projects, project)
|
|
}
|
|
|
|
return projects, nil
|
|
|
|
}
|
|
|
|
func (p Project) GetData() (Project, error) {
|
|
var project Project
|
|
var script []byte
|
|
err := sq.
|
|
Select(`
|
|
id,
|
|
namespace_id,
|
|
name,
|
|
repo_type,
|
|
url,
|
|
label,
|
|
path,
|
|
environment,
|
|
branch,
|
|
symlink_path,
|
|
symlink_backup_number,
|
|
review,
|
|
review_url,
|
|
script,
|
|
transfer_type,
|
|
transfer_option,
|
|
deploy_server_mode,
|
|
auto_deploy,
|
|
deploy_state,
|
|
notify_type,
|
|
notify_target,
|
|
project.
|
|
last_publish_token,
|
|
insert_time,
|
|
update_time`).
|
|
From(projectTable).
|
|
Where(sq.Eq{"id": p.ID}).
|
|
RunWith(DB).
|
|
QueryRow().
|
|
Scan(
|
|
&project.ID,
|
|
&project.NamespaceID,
|
|
&project.Name,
|
|
&project.RepoType,
|
|
&project.URL,
|
|
&project.Label,
|
|
&project.Path,
|
|
&project.Environment,
|
|
&project.Branch,
|
|
&project.SymlinkPath,
|
|
&project.SymlinkBackupNumber,
|
|
&project.Review,
|
|
&project.ReviewURL,
|
|
&script,
|
|
&project.TransferType,
|
|
&project.TransferOption,
|
|
&project.DeployServerMode,
|
|
&project.AutoDeploy,
|
|
&project.DeployState,
|
|
&project.NotifyType,
|
|
&project.NotifyTarget,
|
|
&project.LastPublishToken,
|
|
&project.InsertTime,
|
|
&project.UpdateTime)
|
|
if err != nil {
|
|
return project, err
|
|
}
|
|
|
|
if err = json.Unmarshal(script, &project.Script); err != nil {
|
|
return project, err
|
|
}
|
|
|
|
return project, nil
|
|
}
|
|
|
|
func (p Project) GetUserProjectData() (Project, error) {
|
|
var project Project
|
|
err := sq.
|
|
Select("project_id, project.name, publisher_id, publisher_name, project.environment, project.branch, project.last_publish_token, project.deploy_state").
|
|
From(projectUserTable).
|
|
LeftJoin(projectTable+" ON project_user.project_id = project.id").
|
|
Where(sq.Eq{
|
|
"project_user.project_id": p.ID,
|
|
"project_user.user_id": p.UserID,
|
|
"project.state": Enable,
|
|
}).
|
|
RunWith(DB).
|
|
QueryRow().
|
|
Scan(&project.ID,
|
|
&project.Name,
|
|
&project.PublisherID,
|
|
&project.PublisherName,
|
|
&project.Environment,
|
|
&project.Branch,
|
|
&project.LastPublishToken,
|
|
&project.DeployState)
|
|
if err != nil {
|
|
return project, err
|
|
}
|
|
return project, nil
|
|
}
|
|
|
|
func (p Project) ReplaceVars(script string) string {
|
|
scriptVars := map[string]string{
|
|
"${PROJECT_ID}": strconv.FormatInt(p.ID, 10),
|
|
"${PROJECT_PATH}": p.Path,
|
|
"${PROJECT_SYMLINK_PATH}": path.Join(p.SymlinkPath, p.LastPublishToken),
|
|
"${PROJECT_NAME}": p.Name,
|
|
"${PROJECT_BRANCH}": p.Branch,
|
|
"${PROJECT_ENV}": strconv.FormatUint(uint64(p.Environment), 10),
|
|
"${PROJECT_LABEL}": p.Label,
|
|
"${REPOSITORY_TYPE}": p.RepoType,
|
|
"${REPOSITORY_URL}": p.URL,
|
|
"${REPOSITORY_PATH}": config.GetProjectPath(p.ID),
|
|
"${PUBLISH_TOKEN}": p.LastPublishToken,
|
|
}
|
|
for key, value := range scriptVars {
|
|
script = strings.Replace(script, key, value, -1)
|
|
}
|
|
return script
|
|
}
|