有没有办法在所有链接的故事和任务完成后自动将史诗状态更改为完成

时间:2016-02-17 21:22:36

标签: jira kanban

我是JIRA和看板的新手。当我制作一部史诗并将一些故事和任务链接到它时,我期待着它。当完成与其相关的所有故事和任务时,史诗的状态将自动改变(例如完成)。但似乎事实并非如此。我可以将史诗从Backlog移动到Done列,即使其链接的任务和故事仍在积压中。有没有办法让JIRA防止这种情况发生?

2 个答案:

答案 0 :(得分:1)

我一直在做类似的事情。我的目的是在状态变为特定状态时,将特定用户的所有相关问题设置为特定用户。

我使用类型工作流的后期功能执行此操作:“将字段值设置为常量或Groovy表达式”

在你的情况下,我会做以下事情:

  • 转到“关闭”转换,然后单击“配置”。
  • 选择帖子功能,并添加我告诉你的类型。
  • 标记仅在条件为真时执行的chekbox
  • 设定你的条件。可能类似于issue.epic =你的史诗。
  • 然后你添加你的脚本,你可以在那里恢复与史诗相关的问题,并检查它们的状态。
  • 创建你的逻辑,这样如果它应该是正常的,你只需使用MutableIssue对象改变状态。
  • 请记住,此脚本将修改一个字段,我猜你不能选择status作为要设置的字段。如果发生这种情况,请选择摘要,然后存储当前值,并使用它来结束脚本,并设置汇总值,与您的汇总值相同。
  • 发布您的工作流程。

对不起,如果不清楚,但很难解释。如果你需要其他的话,请告诉我。

PD:如果您只是想在某个特定时刻而不是每个史诗自动执行此操作,只需添加Script Runner插件,然后在控制台中运行您的脚本。更容易。

此致

答案 1 :(得分:1)

也许它会帮助你: 我使用系统语言设置为“俄语”的jira(并且我不熟悉groovy),这就是为什么下面的脚本包含语言依赖性(如果你使用与我的jira系统语言不同,你应该编辑代码!至少改变)

  1. 使用Scrip Runner插件
  2. 创建“自定义侦听器”并粘贴代码(代码不是很好,但它正在工作):

    import com.atlassian.jira.component.ComponentAccessor;
    import com.atlassian.jira.issue.IssueManager;
    import com.atlassian.jira.issue.Issue;
    import com.atlassian.jira.issue.link.IssueLinkManager;
    import com.atlassian.jira.issue.link.IssueLink;
    import com.atlassian.jira.issue.ModifiedValue;
    import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
    import com.atlassian.jira.issue.customfields.option.Options;
    import com.atlassian.jira.issue.customfields.option.Option;
    import com.atlassian.jira.issue.fields.config.FieldConfig;
    import com.atlassian.jira.issue.customfields.manager.OptionsManager;
    import com.atlassian.jira.ComponentManager;
    
    ComponentManager componentManager = ComponentManager.getInstance();
    def groupMan = ComponentAccessor.getGroupManager()
    def authCon = ComponentAccessor.getJiraAuthenticationContext() 
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
    def changeHolder = new DefaultIssueChangeHolder();
    IssueManager issueManager = ComponentAccessor.getIssueManager();
    OptionsManager optionsManager = componentManager.getComponentInstanceOfType(OptionsManager.class);
    IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
    
    def curUser = authCon.getUser()
    def issue = event.issue
    
    def epicLinkCf = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'Epic Link'}
    if(!epicLinkCf) {log.warn "No Epic Link field"; return}
    log.warn "Existing Epic Link: ${epicLinkCf.getValue(issue)}"
    
    String epicIssue = epicLinkCf.getValue(issue)
    Issue epic = issueManager.getIssueObject(epicIssue) // epicKey is passed into your script
    
    // Check if Epic link is exist
    if(!epic)
        return true
    
    def newEpicState = "Сделано"
    
    log.warn "Epic: " + epic
    List<IssueLink> allOutIssueLink = issueLinkManager.getOutwardLinks(epic.getId());
    for (Iterator<IssueLink> outIterator = allOutIssueLink.iterator(); outIterator.hasNext();) {
        IssueLink issueLink = (IssueLink) outIterator.next();
        log.warn "child link type: " + issueLink.getIssueLinkType().getName()
        // Check status of all issues from epic
        if (issueLink.getIssueLinkType().getName() == "Epic-Story Link") {
            Issue chIssue = issueLink.getDestinationObject();
            log.warn "child state: " + chIssue.getStatusObject().getName()
            if(chIssue.getStatusObject().getName() == "В процессе") {
                newEpicState = "В процессе"
            } else if (chIssue.getStatusObject().getName() != "Закрыто" && newEpicState != "В процессе") {
                newEpicState = "Сделать"
            }
        }
    }
    
    def epicStatusCf = customFieldManager.getCustomFieldObjects(epic).find {it.name == 'Epic Status'}
    log.warn "Current epic status: " + epicStatusCf.getValue(epic)
    FieldConfig epicStatusFieldConfig = epicStatusCf.getRelevantConfig(epic);
    String oldStatus = epicStatusCf.getValue(epic)
    
    log.warn "New epic status: " + newEpicState
    // Set new status if it necessary
    if (oldStatus != newEpicState) {
        Options epicStatusOptions = optionsManager.getOptions(epicStatusFieldConfig);
        Option epicStatusDoneOption = epicStatusOptions.getOptionForValue(newEpicState, null);
        epicStatusCf.updateValue(null, epic, new ModifiedValue(epic.getCustomFieldValue(epicStatusCf),epicStatusDoneOption),changeHolder)
        log.warn "Epic status is updated!"
    }