You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jira Epic关闭校验Groovy脚本如何仅校验指定链接类型issue

Jira Epic关闭关联校验脚本调整方案

需求背景

  • 现有Groovy脚本部署在Jira Epic工作流的关闭过渡校验环节,实现逻辑为:仅当Epic下所有关联issue均处于Done状态时,才允许执行Epic关闭操作
  • 当前脚本存在的问题:会遍历Epic所有类型的向外关联链接做状态校验,需要收窄校验范围,仅对*"Issues in epic"*这一特定关联类型的issue生效

原参考脚本

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.link.IssueLinkManager
import com.opensymphony.workflow.InvalidInputException
 
// 日志调试相关依赖
import org.apache.log4j.Level
import org.apache.log4j.Logger
 
// 脚本标识,用于日志检索
String scriptCode = "Check all issues in Epics are Done -"
 
Logger logger = log
logger.setLevel( Level.ERROR )
logger.debug( "$scriptCode Triggered by $issue.key" )

def passesCondition = true
if (issue.issueType.name == 'Epic')
   {
     IssueLinkManager issueLinkManager = ComponentAccessor.issueLinkManager
     def found = issueLinkManager.getOutwardLinks(issue.id).any
       {
       it?.destinationObject?.getStatus().getName() != 'Done' &&
           it?.destinationObject?.getIssueType().getName()  != 'Epic'
       }    
       logger.debug( "$scriptCode Found =  $found " )
       if (found) {
           logger.debug( "$scriptCode return false" )
           passesCondition = false
           invalidInputException = new InvalidInputException("Please make sure all linked issues are in 'Done' status")
       } else {
           logger.debug( "$scriptCode return true" )
       passesCondition = true
       }
   }
// 非Epic类型问题直接放行
   else
   {
       logger.debug( "$scriptCode Not Epic return true")
       passesCondition = true
   }

修改后代码

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkManager
import com.opensymphony.workflow.InvalidInputException
import org.apache.log4j.Level
import org.apache.log4j.Logger

String scriptCode = "Check all issues in Epics are Done -"
Logger logger = log
logger.setLevel(Level.ERROR)
logger.debug("$scriptCode Triggered by $issue.key")

def passesCondition = true
if (issue.issueType.name == 'Epic') {
    IssueLinkManager issueLinkManager = ComponentAccessor.issueLinkManager
    // 仅校验Epic归属关联下未完成的issue
    def hasUnDoneChildIssue = issueLinkManager.getOutwardLinks(issue.id).any { link ->
        // 匹配"Issues in epic"对应链接类型,过滤其他关联
        link.issueLinkType.name == 'Epic-Story Link'
        // 排除特殊场景下关联到其他Epic的情况
        && link.destinationObject.issueType.name != 'Epic'
        // 判断关联issue是否未完成
        && link.destinationObject.status.name != 'Done'
    }
    logger.debug("$scriptCode Undone epic child issue found: $hasUnDoneChildIssue")
    if (hasUnDoneChildIssue) {
        passesCondition = false
        invalidInputException = new InvalidInputException("Please make sure all issues in epic are in 'Done' status before closing Epic")
    }
} else {
    logger.debug("$scriptCode Current issue is not Epic, skip validation")
    passesCondition = true
}

修改说明

  • 核心调整:在链接遍历的判断条件中新增链接类型匹配规则,Jira内置的Epic归属关联(即界面显示的*"Issues in epic"*)对应的出向链接类型名为Epic-Story Link,只有匹配到该类型的链接才会进入后续状态校验,其他关联类型(如关联缺陷、阻塞关系、关联文档等)全部跳过
  • 移除了冗余的安全调用符:getOutwardLinks接口返回的链接集合不存在null元素,不需要额外加?.做非空判断
  • 优化了错误提示文案,明确告知用户是Epic下的归属issue未完成,避免歧义

如果你的Jira实例自定义修改过Epic关联的链接名称,可以进入Jira后台「问题链接」配置页,找到对应"Issues in epic"的链接类型名称,替换代码中Epic-Story Link字符串即可。

内容的提问来源于stack exchange,提问作者User1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:18:20