diff --git a/pkg/microservice/aslan/core/common/repository/models/settings.go b/pkg/microservice/aslan/core/common/repository/models/settings.go index 8041f93823..f8d3bacbf5 100644 --- a/pkg/microservice/aslan/core/common/repository/models/settings.go +++ b/pkg/microservice/aslan/core/common/repository/models/settings.go @@ -28,6 +28,7 @@ type SystemSetting struct { Privacy *PrivacySettings `bson:"privacy" json:"privacy"` Language string `bson:"language" json:"language"` ServerURL string `bson:"server_url" json:"server_url"` + WorkflowHook *WorkflowHookSettings `bson:"workflow_hook" json:"workflow_hook"` ReleasePlanHook *ReleasePlanHookSettings `bson:"release_plan_hook" json:"release_plan_hook"` UpdateTime int64 `bson:"update_time" json:"update_time"` } @@ -81,6 +82,13 @@ type ReleasePlanHookSettings struct { HookEvents []ReleasePlanHookEvent `json:"hook_events" bson:"hook_events"` } +type WorkflowHookSettings struct { + Enable bool `json:"enable" bson:"enable"` + HookAddress string `json:"hook_address" bson:"hook_address"` + HookSecret string `json:"hook_secret" bson:"hook_secret"` + HookEvents []WorkflowHookEvent `json:"hook_events" bson:"hook_events"` +} + func (r *ReleasePlanHookSettings) ToHookSettings() *HookSettings { return &HookSettings{ Enable: r.Enable, @@ -98,6 +106,13 @@ const ( ReleasePlanHookEventAllJobDone ReleasePlanHookEvent = "all_job_done" ) +type WorkflowHookEvent string + +const ( + WorkflowHookEventStartExecute WorkflowHookEvent = "start_execute" + WorkflowHookEventCompleteExecute WorkflowHookEvent = "complete_execute" +) + func (SystemSetting) TableName() string { return "system_setting" } diff --git a/pkg/microservice/aslan/core/common/repository/mongodb/settings.go b/pkg/microservice/aslan/core/common/repository/mongodb/settings.go index 36aa5d583e..168ec8a65a 100644 --- a/pkg/microservice/aslan/core/common/repository/mongodb/settings.go +++ b/pkg/microservice/aslan/core/common/repository/mongodb/settings.go @@ -223,3 +223,36 @@ func (c *SystemSettingColl) GetReleasePlanHookSetting() (*models.ReleasePlanHook return resp.ReleasePlanHook, nil } + +func (c *SystemSettingColl) UpdateWorkflowHookSetting(hookSetting *models.WorkflowHookSettings) error { + id, _ := primitive.ObjectIDFromHex(setting.LocalClusterID) + query := bson.M{"_id": id} + + change := bson.M{"$set": bson.M{"workflow_hook": hookSetting}} + + _, err := c.UpdateOne(context.TODO(), query, change) + return err +} + +func (c *SystemSettingColl) GetWorkflowHookSetting() (*models.WorkflowHookSettings, error) { + query := bson.M{} + resp := &models.SystemSetting{} + + err := c.FindOne(context.TODO(), query).Decode(resp) + if err != nil { + if err == mongo.ErrNoDocuments { + return &models.WorkflowHookSettings{ + Enable: false, + }, nil + } + return nil, err + } + + if resp.WorkflowHook == nil { + return &models.WorkflowHookSettings{ + Enable: false, + }, nil + } + + return resp.WorkflowHook, nil +} diff --git a/pkg/microservice/aslan/core/common/service/instantmessage/workflow_task.go b/pkg/microservice/aslan/core/common/service/instantmessage/workflow_task.go index 15ef5af21e..b1d5b7b1c9 100644 --- a/pkg/microservice/aslan/core/common/service/instantmessage/workflow_task.go +++ b/pkg/microservice/aslan/core/common/service/instantmessage/workflow_task.go @@ -746,6 +746,18 @@ func getStageTaskByName(stages []*models.StageTask, stageName string) *models.St return nil } +func buildWorkflowNotifyReleasePlan(releasePlan *models.ReleasePlanRef) *webhooknotify.WorkflowNotifyReleasePlan { + if releasePlan == nil { + return nil + } + + return &webhooknotify.WorkflowNotifyReleasePlan{ + ID: releasePlan.ID, + Name: releasePlan.Name, + Index: releasePlan.Index, + } +} + func (w *Service) getApproveNotificationContent(notify *models.NotifyCtl, task *models.WorkflowTask) (string, string, *LarkCard, *webhooknotify.WorkflowNotify, error) { project, err := templaterepo.NewProductColl().Find(task.ProjectName) if err != nil { @@ -774,6 +786,7 @@ func (w *Service) getApproveNotificationContent(notify *models.NotifyCtl, task * WorkflowDisplayName: task.WorkflowDisplayName, ProjectName: task.ProjectName, ProjectDisplayName: project.ProjectName, + ReleasePlan: buildWorkflowNotifyReleasePlan(task.ReleasePlan), Status: task.Status, Remark: task.Remark, Error: task.Error, @@ -782,7 +795,6 @@ func (w *Service) getApproveNotificationContent(notify *models.NotifyCtl, task * EndTime: task.EndTime, TaskCreator: task.TaskCreator, TaskCreatorID: task.TaskCreatorID, - TaskCreatorPhone: task.TaskCreatorPhone, TaskCreatorEmail: task.TaskCreatorEmail, } @@ -931,6 +943,56 @@ func (w *Service) getNotificationContent(notify *models.NotifyCtl, task *models. return w.getNotificationContentWithOptions(notify, task, nil) } +func (w *Service) BuildWorkflowWebhookNotify(task *models.WorkflowTask) (*webhooknotify.WorkflowNotify, error) { + _, _, _, webhookNotify, err := w.getNotificationContentWithOptions(&models.NotifyCtl{WebHookType: setting.NotifyWebHookTypeWebook}, task, nil) + if err != nil { + return nil, err + } + if webhookNotify == nil { + return nil, fmt.Errorf("failed to build workflow webhook payload for workflow %s, taskID: %d", task.WorkflowName, task.TaskID) + } + + return webhookNotify, nil +} + +func (w *Service) SendSystemWorkflowHook(task *models.WorkflowTask, hookSetting *models.WorkflowHookSettings, hookEvent models.WorkflowHookEvent) error { + if task == nil || !isWorkflowHookEventEnabled(hookSetting, hookEvent) { + return nil + } + + webhookNotify, err := w.BuildWorkflowWebhookNotify(task) + if err != nil { + return err + } + + return webhooknotify.NewClient(hookSetting.HookAddress, hookSetting.HookSecret).SendWorkflowWebhook(webhookNotify, workflowHookEventToWebhookEvent(hookEvent)) +} + +func isWorkflowHookEventEnabled(hookSetting *models.WorkflowHookSettings, hookEvent models.WorkflowHookEvent) bool { + if hookSetting == nil || !hookSetting.Enable { + return false + } + + for _, configuredEvent := range hookSetting.HookEvents { + if configuredEvent == hookEvent { + return true + } + } + + return false +} + +func workflowHookEventToWebhookEvent(hookEvent models.WorkflowHookEvent) webhooknotify.WebHookNotifyEvent { + switch hookEvent { + case models.WorkflowHookEventStartExecute: + return webhooknotify.WebHookNotifyEventWorkflowStartExecute + case models.WorkflowHookEventCompleteExecute: + return webhooknotify.WebHookNotifyEventWorkflowCompleteExecute + default: + return webhooknotify.WebHookNotifyEventWorkflow + } +} + type workflowNotificationOptions struct { StatusTextKeyOverride string PendingStageName string @@ -973,6 +1035,7 @@ func (w *Service) getNotificationContentWithOptions(notify *models.NotifyCtl, ta WorkflowDisplayName: task.WorkflowDisplayName, ProjectName: task.ProjectName, ProjectDisplayName: project.ProjectName, + ReleasePlan: buildWorkflowNotifyReleasePlan(task.ReleasePlan), Status: task.Status, Remark: task.Remark, Error: task.Error, @@ -981,7 +1044,6 @@ func (w *Service) getNotificationContentWithOptions(notify *models.NotifyCtl, ta EndTime: task.EndTime, TaskCreator: task.TaskCreator, TaskCreatorID: task.TaskCreatorID, - TaskCreatorPhone: task.TaskCreatorPhone, TaskCreatorEmail: task.TaskCreatorEmail, TaskType: task.Type, } @@ -1465,7 +1527,7 @@ func (w *Service) sendNotification(title, content string, notify *models.NotifyC } case setting.NotifyWebHookTypeWebook: webhookclient := webhooknotify.NewClient(notify.WebhookNotificationConfig.Address, notify.WebhookNotificationConfig.Token) - err := webhookclient.SendWorkflowWebhook(webhookNotify) + err := webhookclient.SendWorkflowWebhook(webhookNotify, webhooknotify.WebHookNotifyEventWorkflow) if err != nil { return fmt.Errorf("failed to send notification to webhook, address %s, token: %s, error: %v", notify.WebhookNotificationConfig.Address, notify.WebhookNotificationConfig.Token, err) } diff --git a/pkg/microservice/aslan/core/common/service/webhooknotify/client.go b/pkg/microservice/aslan/core/common/service/webhooknotify/client.go index da6d0202ca..6fc2a7149b 100644 --- a/pkg/microservice/aslan/core/common/service/webhooknotify/client.go +++ b/pkg/microservice/aslan/core/common/service/webhooknotify/client.go @@ -36,19 +36,19 @@ func NewClient(address, token string) *webhookNotifyclient { } } -func (c *webhookNotifyclient) SendWorkflowWebhook(webhookNotify *WorkflowNotify) error { +func (c *webhookNotifyclient) SendWorkflowWebhook(webhookNotify *WorkflowNotify, event WebHookNotifyEvent) error { notify := &WebHookNotify{ ObjectKind: WebHookNotifyObjectKindWorkflow, - Event: WebHookNotifyEventWorkflow, + Event: event, Workflow: webhookNotify, } return c.sendWebhook(notify) } -func (c *webhookNotifyclient) SendReleasePlanWebhook(webhookNotify *ReleasePlanHookBody) error { +func (c *webhookNotifyclient) SendReleasePlanWebhook(webhookNotify *ReleasePlanHookBody, event WebHookNotifyEvent) error { notify := &WebHookNotify{ ObjectKind: WebHookNotifyObjectKindReleasePlan, - Event: WebHookNotifyEventReleasePlan, + Event: event, ReleasePlan: webhookNotify, } return c.sendWebhook(notify) diff --git a/pkg/microservice/aslan/core/common/service/webhooknotify/types.go b/pkg/microservice/aslan/core/common/service/webhooknotify/types.go index 2c898d62e9..00509f9ec8 100644 --- a/pkg/microservice/aslan/core/common/service/webhooknotify/types.go +++ b/pkg/microservice/aslan/core/common/service/webhooknotify/types.go @@ -38,8 +38,13 @@ const ( type WebHookNotifyEvent string const ( - WebHookNotifyEventWorkflow WebHookNotifyEvent = "workflow" - WebHookNotifyEventReleasePlan WebHookNotifyEvent = "release_plan" + WebHookNotifyEventWorkflow WebHookNotifyEvent = "workflow" + WebHookNotifyEventWorkflowStartExecute WebHookNotifyEvent = "start_execute" + WebHookNotifyEventWorkflowCompleteExecute WebHookNotifyEvent = "complete_execute" + WebHookNotifyEventReleasePlan WebHookNotifyEvent = "release_plan" + WebHookNotifyEventFinishPlanning WebHookNotifyEvent = "finish_planning" + WebHookNotifyEventReleasePlanStartExecute WebHookNotifyEvent = "start_execute" + WebHookNotifyEventAllJobDone WebHookNotifyEvent = "all_job_done" ) type WebHookNotifyObjectKind string @@ -62,6 +67,7 @@ type WorkflowNotify struct { ProjectDisplayName string `json:"project_display_name"` WorkflowName string `json:"workflow_name"` WorkflowDisplayName string `json:"workflow_display_name"` + ReleasePlan *WorkflowNotifyReleasePlan `json:"release_plan,omitempty"` Status config.Status `json:"status"` Remark string `json:"remark"` DetailURL string `json:"detail_url"` @@ -72,11 +78,16 @@ type WorkflowNotify struct { Stages []*WorkflowNotifyStage `json:"stages"` TaskCreator string `json:"task_creator"` TaskCreatorID string `json:"task_creator_id"` - TaskCreatorPhone string `json:"task_creator_phone"` TaskCreatorEmail string `json:"task_creator_email"` TaskType config.CustomWorkflowTaskType `json:"task_type"` } +type WorkflowNotifyReleasePlan struct { + ID string `json:"id"` + Name string `json:"name"` + Index int64 `json:"index"` +} + type WorkflowNotifyStage struct { Name string `json:"name"` Status config.Status `json:"status"` diff --git a/pkg/microservice/aslan/core/common/service/workflowcontroller/system_hook.go b/pkg/microservice/aslan/core/common/service/workflowcontroller/system_hook.go new file mode 100644 index 0000000000..5db99b7632 --- /dev/null +++ b/pkg/microservice/aslan/core/common/service/workflowcontroller/system_hook.go @@ -0,0 +1,36 @@ +/* +Copyright 2025 The KodeRover Authors. + +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 workflowcontroller + +import ( + commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models" + commonrepo "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb" + "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/service/instantmessage" +) + +func SendSystemWorkflowHook(task *commonmodels.WorkflowTask, hookEvent commonmodels.WorkflowHookEvent) error { + hookSetting, err := commonrepo.NewSystemSettingColl().GetWorkflowHookSetting() + if err != nil { + return err + } + + if err := instantmessage.NewWeChatClient().SendSystemWorkflowHook(task, hookSetting, hookEvent); err != nil { + return err + } + + return nil +} diff --git a/pkg/microservice/aslan/core/common/service/workflowcontroller/workflow.go b/pkg/microservice/aslan/core/common/service/workflowcontroller/workflow.go index f14cd7a50b..9ef0ec1b5d 100644 --- a/pkg/microservice/aslan/core/common/service/workflowcontroller/workflow.go +++ b/pkg/microservice/aslan/core/common/service/workflowcontroller/workflow.go @@ -556,6 +556,7 @@ func (c *workflowCtl) updateWorkflowTask() { } c.workflowTask.Remark = "" + shouldSendCompleteHook := c.workflowTask.Finished() && taskInColl.EndTime == 0 && c.workflowTask.EndTime > 0 c.workflowTaskMutex.Lock() if err := commonrepo.NewworkflowTaskv4Coll().Update(c.workflowTask.ID.Hex(), c.workflowTask); err != nil { @@ -570,6 +571,11 @@ func (c *workflowCtl) updateWorkflowTask() { if err := instantmessage.NewWeChatClient().SendWorkflowTaskNotifications(c.workflowTask); err != nil { c.logger.Errorf("send workflow task notification failed, error: %v", err) } + if shouldSendCompleteHook { + if err := SendSystemWorkflowHook(c.workflowTask, commonmodels.WorkflowHookEventCompleteExecute); err != nil { + c.logger.Errorf("send system workflow complete hook failed, workflow: %s, taskID: %d, error: %v", c.workflowTask.WorkflowName, c.workflowTask.TaskID, err) + } + } q := ConvertTaskToQueue(c.workflowTask) if err := Remove(q); err != nil { c.logger.Errorf("remove queue task: %s:%d error: %v", c.workflowTask.WorkflowName, c.workflowTask.TaskID, err) diff --git a/pkg/microservice/aslan/core/release_plan/service/release_plan.go b/pkg/microservice/aslan/core/release_plan/service/release_plan.go index e1f519b2fe..7458ca6b48 100644 --- a/pkg/microservice/aslan/core/release_plan/service/release_plan.go +++ b/pkg/microservice/aslan/core/release_plan/service/release_plan.go @@ -1734,7 +1734,7 @@ func sendReleasePlanHook(plan *models.ReleasePlan, systemHookSetting *commonmode return err } - err = webhooknotify.NewClient(systemHookSetting.HookAddress, systemHookSetting.HookSecret).SendReleasePlanWebhook(hookBody) + err = webhooknotify.NewClient(systemHookSetting.HookAddress, systemHookSetting.HookSecret).SendReleasePlanWebhook(hookBody, releasePlanHookEventToWebhookEvent(hookBody.EventName)) if err != nil { err = errors.Wrap(err, "send release plan hook") log.Error(err) @@ -1745,6 +1745,19 @@ func sendReleasePlanHook(plan *models.ReleasePlan, systemHookSetting *commonmode return nil } +func releasePlanHookEventToWebhookEvent(hookEvent commonmodels.ReleasePlanHookEvent) webhooknotify.WebHookNotifyEvent { + switch hookEvent { + case commonmodels.ReleasePlanHookEventFinishPlanning: + return webhooknotify.WebHookNotifyEventFinishPlanning + case commonmodels.ReleasePlanHookEventStartExecute: + return webhooknotify.WebHookNotifyEventReleasePlanStartExecute + case commonmodels.ReleasePlanHookEventAllJobDone: + return webhooknotify.WebHookNotifyEventAllJobDone + default: + return webhooknotify.WebHookNotifyEventReleasePlan + } +} + func convertReleasePlanToHookBody(plan *models.ReleasePlan, hookEvent commonmodels.ReleasePlanHookEvent) (*webhooknotify.ReleasePlanHookBody, error) { hookBody := &webhooknotify.ReleasePlanHookBody{ ID: plan.ID, diff --git a/pkg/microservice/aslan/core/system/handler/router.go b/pkg/microservice/aslan/core/system/handler/router.go index 2bd3aa14cc..4183635355 100644 --- a/pkg/microservice/aslan/core/system/handler/router.go +++ b/pkg/microservice/aslan/core/system/handler/router.go @@ -267,6 +267,12 @@ func (*Router) Inject(router *gin.RouterGroup) { server.PUT("/url", SetSystemServerURL) } + workflowHook := router.Group("workflowHook") + { + workflowHook.GET("", GetWorkflowHookSetting) + workflowHook.PUT("", UpdateWorkflowHookSetting) + } + // --------------------------------------------------------------------------------------- // external system API // --------------------------------------------------------------------------------------- diff --git a/pkg/microservice/aslan/core/system/handler/workflow_hook.go b/pkg/microservice/aslan/core/system/handler/workflow_hook.go new file mode 100644 index 0000000000..5fd55d62cc --- /dev/null +++ b/pkg/microservice/aslan/core/system/handler/workflow_hook.go @@ -0,0 +1,96 @@ +/* +Copyright 2025 The KodeRover Authors. + +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 handler + +import ( + "fmt" + + "github.com/gin-gonic/gin" + + commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models" + "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/util" + "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/system/service" + internalhandler "github.com/koderover/zadig/v2/pkg/shared/handler" + e "github.com/koderover/zadig/v2/pkg/tool/errors" +) + +// @Summary 获取系统工作流 WebHook 配置 +// @Description 获取系统工作流 WebHook 配置 +// @Tags system +// @Accept json +// @Produce json +// @Success 200 {object} models.WorkflowHookSettings +// @Router /api/aslan/system/workflowHook [get] +func GetWorkflowHookSetting(c *gin.Context) { + ctx, err := internalhandler.NewContextWithAuthorization(c) + defer func() { internalhandler.JSONResponse(c, ctx) }() + + if err != nil { + ctx.RespErr = fmt.Errorf("authorization Info Generation failed: err %s", err) + ctx.UnAuthorized = true + return + } + + if !ctx.Resources.IsSystemAdmin { + ctx.UnAuthorized = true + return + } + + if err := util.CheckZadigEnterpriseLicense(); err != nil { + ctx.RespErr = err + return + } + + ctx.Resp, ctx.RespErr = service.GetWorkflowHookSetting() +} + +// @Summary 更新系统工作流 WebHook 配置 +// @Description 更新系统工作流 WebHook 配置 +// @Tags system +// @Accept json +// @Produce json +// @Param body body models.WorkflowHookSettings true "body" +// @Success 200 +// @Router /api/aslan/system/workflowHook [put] +func UpdateWorkflowHookSetting(c *gin.Context) { + ctx, err := internalhandler.NewContextWithAuthorization(c) + defer func() { internalhandler.JSONResponse(c, ctx) }() + + if err != nil { + ctx.RespErr = fmt.Errorf("authorization Info Generation failed: err %s", err) + ctx.UnAuthorized = true + return + } + + if !ctx.Resources.IsSystemAdmin { + ctx.UnAuthorized = true + return + } + + if err := util.CheckZadigEnterpriseLicense(); err != nil { + ctx.RespErr = err + return + } + + req := new(commonmodels.WorkflowHookSettings) + if err := c.ShouldBindJSON(req); err != nil { + ctx.RespErr = e.ErrInvalidParam.AddDesc(err.Error()) + return + } + + ctx.RespErr = service.UpdateWorkflowHookSetting(req) +} diff --git a/pkg/microservice/aslan/core/system/service/workflow_hook.go b/pkg/microservice/aslan/core/system/service/workflow_hook.go new file mode 100644 index 0000000000..c67ce42199 --- /dev/null +++ b/pkg/microservice/aslan/core/system/service/workflow_hook.go @@ -0,0 +1,30 @@ +/* +Copyright 2025 The KodeRover Authors. + +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 service + +import ( + commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models" + commonrepo "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb" +) + +func GetWorkflowHookSetting() (*commonmodels.WorkflowHookSettings, error) { + return commonrepo.NewSystemSettingColl().GetWorkflowHookSetting() +} + +func UpdateWorkflowHookSetting(hookSetting *commonmodels.WorkflowHookSettings) error { + return commonrepo.NewSystemSettingColl().UpdateWorkflowHookSetting(hookSetting) +} diff --git a/pkg/microservice/aslan/core/workflow/service/workflow/workflow_task_v4.go b/pkg/microservice/aslan/core/workflow/service/workflow/workflow_task_v4.go index 5e95e09336..3bff0a6920 100644 --- a/pkg/microservice/aslan/core/workflow/service/workflow/workflow_task_v4.go +++ b/pkg/microservice/aslan/core/workflow/service/workflow/workflow_task_v4.go @@ -672,6 +672,9 @@ func CreateWorkflowTaskV4(args *CreateWorkflowTaskV4Args, workflow *commonmodels if err := instantmessage.NewWeChatClient().SendWorkflowTaskNotifications(workflowTask); err != nil { log.Errorf("send workflow task notification failed, error: %v", err) } + if err := runtimeWorkflowController.SendSystemWorkflowHook(workflowTask, commonmodels.WorkflowHookEventStartExecute); err != nil { + log.Errorf("send system workflow start hook failed, workflow: %s, taskID: %d, error: %v", workflowTask.WorkflowName, workflowTask.TaskID, err) + } if err := runtimeWorkflowController.CreateTask(workflowTask); err != nil { log.Errorf("create workflow task error: %v", err) @@ -1006,9 +1009,14 @@ func RetryWorkflowTaskV4(workflowName string, taskID int64, logger *zap.SugaredL task.Status = config.StatusCreated task.StartTime = time.Now().Unix() + task.EndTime = 0 + task.Error = "" if err := instantmessage.NewWeChatClient().SendWorkflowTaskNotifications(task); err != nil { log.Errorf("send workflow task notification failed, error: %v", err) } + if err := runtimeWorkflowController.SendSystemWorkflowHook(task, commonmodels.WorkflowHookEventStartExecute); err != nil { + log.Errorf("send system workflow start hook failed on retry, workflow: %s, taskID: %d, error: %v", task.WorkflowName, task.TaskID, err) + } if err := runtimeWorkflowController.UpdateTask(task); err != nil { log.Errorf("retry workflow task error: %v", err) @@ -1278,6 +1286,8 @@ func ManualExecWorkflowTaskV4(workflowName string, taskID int64, stageName strin } task.Status = config.StatusCreated + task.EndTime = 0 + task.Error = "" if err := instantmessage.NewWeChatClient().SendWorkflowTaskNotifications(task); err != nil { log.Errorf("send workflow task notification failed, error: %v", err) }