diff --git a/internal/domain/workflow.go b/internal/domain/workflow.go index 1721ddff..51f446eb 100644 --- a/internal/domain/workflow.go +++ b/internal/domain/workflow.go @@ -76,7 +76,7 @@ type WorkflowNodeConfigForDeploy struct { Provider string `json:"provider"` // 主机提供商 ProviderAccessId string `json:"providerAccessId"` // 主机提供商授权记录 ID ProviderConfig map[string]any `json:"providerConfig"` // 主机提供商额外配置 - SkipOnLastSucceeded bool `json:"skipOnLastSucceeded"` // TODO: 上次部署成功时是否跳过 + SkipOnLastSucceeded bool `json:"skipOnLastSucceeded"` // 上次部署成功时是否跳过 } type WorkflowNodeConfigForNotify struct { diff --git a/internal/workflow/node-processor/apply_node.go b/internal/workflow/node-processor/apply_node.go index 1849f15e..28a7588a 100644 --- a/internal/workflow/node-processor/apply_node.go +++ b/internal/workflow/node-processor/apply_node.go @@ -136,5 +136,5 @@ func (a *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workflo } } - return false, "无历史申请记录" + return false, "" } diff --git a/internal/workflow/node-processor/deploy_node.go b/internal/workflow/node-processor/deploy_node.go index 65b14cf8..48e344ad 100644 --- a/internal/workflow/node-processor/deploy_node.go +++ b/internal/workflow/node-processor/deploy_node.go @@ -99,7 +99,6 @@ func (d *deployNode) Run(ctx context.Context) error { } func (d *deployNode) checkCanSkip(ctx context.Context, lastOutput *domain.WorkflowOutput) (skip bool, reason string) { - // TODO: 可控制是否强制部署 if lastOutput != nil && lastOutput.Succeeded { // 比较和上次部署时的关键配置(即影响证书部署的)参数是否一致 currentNodeConfig := d.node.GetConfigForDeploy() @@ -111,8 +110,10 @@ func (d *deployNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workfl return false, "配置项变化:主机提供商参数" } - return true, "已部署过证书" + if currentNodeConfig.SkipOnLastSucceeded { + return true, "已部署过证书" + } } - return false, "无历史部署记录" + return false, "" } diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index 24207654..5a3fb9f1 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -391,11 +391,11 @@ const ApplyNodeConfigForm = forwardRef} > - +
{t("workflow_node.apply.form.skip_before_expiry_days.prefix")}
{ - return {}; + return { + skipOnLastSucceeded: true, + }; }; const DeployNodeConfigForm = forwardRef( @@ -91,6 +93,7 @@ const DeployNodeConfigForm = forwardRef !!formInst.getFieldValue("provider"), t("workflow_node.deploy.form.provider.placeholder")), providerConfig: z.any(), + skipOnLastSucceeded: z.boolean(), }); const formRule = createSchemaFieldRule(formSchema); const { form: formInst, formProps } = useAntdForm({ @@ -340,6 +343,27 @@ const DeployNodeConfigForm = forwardRef + + + + {t("workflow_node.deploy.form.strategy_config.label")} + + + +
+ + +
{t("workflow_node.deploy.form.skip_on_last_succeeded.prefix")}
+ + + +
{t("workflow_node.deploy.form.skip_on_last_succeeded.suffix")}
+
+
+
); } diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index fd2b44be..b984e525 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -119,6 +119,7 @@ export type WorkflowNodeConfigForDeploy = { provider: string; providerAccessId: string; providerConfig: Record; + skipOnLastSucceeded: boolean; }; export type WorkflowNodeConfigForNotify = { diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index e938af0e..89ab8820 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -67,8 +67,8 @@ "workflow_node.apply.form.strategy_config.label": "Strategy settings", "workflow_node.apply.form.skip_before_expiry_days.label": "Renewal interval", "workflow_node.apply.form.skip_before_expiry_days.placeholder": "Please enter renewal interval", - "workflow_node.apply.form.skip_before_expiry_days.prefix": "Skip when the certificate expiration time exceeds", - "workflow_node.apply.form.skip_before_expiry_days.suffix": "", + "workflow_node.apply.form.skip_before_expiry_days.prefix": "If the certificate expiration time exceeds", + "workflow_node.apply.form.skip_before_expiry_days.suffix": ", skip to re-apply.", "workflow_node.apply.form.skip_before_expiry_days.unit": "days", "workflow_node.apply.form.skip_before_expiry_days.tooltip": "Be careful not to exceed the validity period limit of the CA, otherwise the certificate may never be renewed.", @@ -359,6 +359,12 @@ "workflow_node.deploy.form.webhook_data.guide": "Tips: The Webhook data should be a key-value pair in JSON format. The values in JSON support template variables, which will be replaced by actual values when sent to the Webhook URL.

Supported variables:
${DOMAIN}: The primary domain of the certificate (CommonName).
${DOMAINS}: The domain list of the certificate (SubjectAltNames).
${CERTIFICATE}: The PEM format content of the certificate file.
${PRIVATE_KEY}: The PEM format content of the private key file.", "workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "Please enter a valiod JSON string", "workflow_node.deploy.form.webhook_data_preset.button": "Use preset template", + "workflow_node.deploy.form.strategy_config.label": "Strategy settings", + "workflow_node.deploy.form.skip_on_last_succeeded.label": "Repeated deployment", + "workflow_node.deploy.form.skip_on_last_succeeded.prefix": "If the last deployment was successful, ", + "workflow_node.deploy.form.skip_on_last_succeeded.suffix": " to re-deploy.", + "workflow_node.deploy.form.skip_on_last_succeeded.enabled.on": "skip", + "workflow_node.deploy.form.skip_on_last_succeeded.enabled.off": "not skip", "workflow_node.notify.label": "Notification", "workflow_node.notify.form.subject.label": "Subject", diff --git a/ui/src/i18n/locales/zh/nls.settings.json b/ui/src/i18n/locales/zh/nls.settings.json index a3958e80..c2204d4d 100644 --- a/ui/src/i18n/locales/zh/nls.settings.json +++ b/ui/src/i18n/locales/zh/nls.settings.json @@ -25,7 +25,7 @@ "settings.notification.template.form.message.extra": "支持的变量(${COUNT}: 即将过期张数;${DOMAINS}: 域名列表)", "settings.notification.channels.card.title": "通知渠道", "settings.notification.channel.enabled.on": "启用", - "settings.notification.channel.enabled.off": "未启用", + "settings.notification.channel.enabled.off": "停用", "settings.notification.push_test.button": "推送测试消息", "settings.notification.push_test.pushed": "已推送", "settings.notification.channel.form.bark_server_url.label": "服务器地址", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 043e8cc5..51114fc2 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -67,8 +67,8 @@ "workflow_node.apply.form.strategy_config.label": "执行策略", "workflow_node.apply.form.skip_before_expiry_days.label": "续期间隔", "workflow_node.apply.form.skip_before_expiry_days.placeholder": "请输入续期间隔", - "workflow_node.apply.form.skip_before_expiry_days.prefix": "当距上次申请的证书到期时间前", - "workflow_node.apply.form.skip_before_expiry_days.suffix": "时跳过执行", + "workflow_node.apply.form.skip_before_expiry_days.prefix": "当上次签发的证书到期时间超过", + "workflow_node.apply.form.skip_before_expiry_days.suffix": "时,跳过重新申请。", "workflow_node.apply.form.skip_before_expiry_days.unit": "天", "workflow_node.apply.form.skip_before_expiry_days.tooltip": "注意不要超过 CA 的证书有效期限制,否则证书可能永远不会续期。", @@ -359,6 +359,12 @@ "workflow_node.deploy.form.webhook_data.guide": "小贴士:回调数据是一个 JSON 格式的键值对。其中值支持模板变量,将在被发送到指定的 Webhook URL 时被替换为实际值;其他内容将保持原样。

支持的变量:
${DOMAIN}:证书的主域名(即 CommonName
${DOMAINS}:证书的多域名列表(即 SubjectAltNames
${CERTIFICATE}:证书文件 PEM 格式内容
${PRIVATE_KEY}:私钥文件 PEM 格式内容", "workflow_node.deploy.form.webhook_data.errmsg.json_invalid": "请输入有效的 JSON 格式字符串", "workflow_node.deploy.form.webhook_data_preset.button": "使用预设模板", + "workflow_node.deploy.form.strategy_config.label": "执行策略", + "workflow_node.deploy.form.skip_on_last_succeeded.label": "重复部署", + "workflow_node.deploy.form.skip_on_last_succeeded.prefix": "当上次部署已成功时", + "workflow_node.deploy.form.skip_on_last_succeeded.suffix": "重新部署。", + "workflow_node.deploy.form.skip_on_last_succeeded.enabled.on": "跳过", + "workflow_node.deploy.form.skip_on_last_succeeded.enabled.off": "不跳过", "workflow_node.notify.label": "通知", "workflow_node.notify.form.subject.label": "通知主题",