Есть ли способ автоматически изменить эпическое состояние на выполненное, когда все связанные истории и задачи выполнены?

Я новичок в JIRA и Kanban. Я ожидал этого, когда создам эпопею и свяжу с ней какие-то истории и задания. Статус эпоса автоматически изменится (например, на выполненное), когда все истории и задачи, связанные с ним, будут выполнены. Но, похоже, это не так. Я могу переместить эпос из журнала невыполненных работ в столбец «Готово», даже если связанные с ним задачи и истории все еще находятся в очереди. Есть ли способ заставить JIRA предотвратить это?


person Ubaidah    schedule 17.02.2016    source источник


Ответы (2)


Я работал над чем-то подобным. Мое намерение состояло в том, чтобы назначить все связанные задачи другого конкретного пользователя, когда статус меняется на определенное состояние.

Я сделал это с помощью постфункции рабочего процесса типа: «Установить значение поля на константу или выражение Groovy».

В вашей ситуации я бы сделал следующее:

  • перейдите к переходу «Закрыть» и нажмите кнопку «Настроить».
  • выберите постфункции и добавьте тип, который я вам сказал.
  • отметьте чекбокс, который говорит выполнять, только если условие истинно
  • установите свое условие. Наверное, что-то вроде issue.epic = your epic.
  • Затем вы добавляете свой сценарий, в котором вы восстанавливаете все проблемы, связанные с эпосом, и проверяете их статус.
  • Создайте свою логику так, чтобы, если все было так, как должно быть, вы просто меняли статус, используя объект MutableIssue.
  • помните, что поле будет изменено этим скриптом, и я предполагаю, что вы не можете выбрать статус в качестве поля для установки. Если это произойдет, выберите «Сводка» и сохраните текущее значение, используйте его для завершения сценария и установите итоговое значение, такое же, как и у вас.
  • Опубликуйте свой рабочий процесс.

Извините, если непонятно, но сложно объяснить. Дайте мне знать, если вам понадобится что-нибудь еще.

PD: Если вы просто хотите сделать это в определенный момент, а не для каждого эпика автоматически, просто добавьте плагин Script Runner и запустите свой скрипт в консоли. Намного легче.

С Уважением

person Oldskultxo    schedule 18.02.2016
comment
Я попробую то, что ты сказал. Я не знал, что мы можем написать скрипт в JIRA - person Ubaidah; 18.02.2016
comment
Да, я использую отличные скрипты. Возможно, понадобится плагин scriprunner. Я не помню банкомат. Дайте нам знать - person Oldskultxo; 19.02.2016
comment
Я не могу найти в пользовательском интерфейсе никакой части, связанной с переходом Close или постфункцией. Не могли бы вы сказать, где я могу это найти, в конфигурации платы или конфигурации проекта? Извините :) как я уже сказал, я новичок в JIRA - person Ubaidah; 22.02.2016
comment
Извините меня. Я сказал, что близкий переход относится к последнему переходу рабочего процесса проблемы. Вы должны найти что-то похожее, перейдя в раздел администрирования ›проблемы› рабочие процессы ›редактировать› здесь вы выбираете переход, а затем ищите пост-функции - person Oldskultxo; 22.02.2016

Может быть, это вам поможет: я использовал 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!"
    }
    
person tagedr    schedule 14.07.2016