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

执行issueService.transition后Jira问题状态未更新的排查求助

Jira工作流自动流转脚本问题排查

问题描述

我希望Jira问题能自动按以下状态流转:

  • 从Open到Fixed
  • 从Fixed到Tested
  • 从Tested到Completed

但执行代码行def transitionResult = issueService.transition(currentUser, transitionValidationResult)后,问题状态并未更新。日志的warn语句始终显示问题处于OPEN状态,而非预期的依次变为Fixed、Tested、Completed。例如执行transition后的日志输出:

2022-08-13 00:54:54,877+0200 https-openssl-nio-443-exec-14 WARN mouh 54x25796x1 1uq4h23 10.248.75.214 /secure/CommentAssignIssue.jspa [c.o.scriptrunner.runner.ScriptBindingsManager] MOUNA 13 IssueConstantImpl[[GenericEntity:Status][sequence,4][statuscategory,4][name,Open][iconurl,/images/icons/statuses/open.png][description,null][id,1]]

以下是原代码:

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.Issue;
import java.util.HashMap;
import java.util.List;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.workflow.WorkflowManager
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.changehistory.ChangeHistoryItem
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService.IssueValidationResult
import com.atlassian.jira.user.ApplicationUser
def log = Logger.getLogger("atlassian-jira.log")
if (issue.getStatus().getSimpleStatus().getId().equals("1")) {
  log.warn("MOUNA 1");
  int transitionFromOpentoFixed = 71;
  int transitionFromFixedToTested = 111;
  int transitionFromTestedToCompleted = 131;
  log.warn("MOUNA 100 transitionFromOpentoFixed " + issue.getStatus());
  transition(transitionFromOpentoFixed);
  log.warn("MOUNA 101 transitionFromFixedToTested " + issue.getStatus());
  transition(transitionFromFixedToTested);
  log.warn("MOUNA 102 transitionFromTestedToCompleted " + issue.getStatus());
  transition(transitionFromTestedToCompleted);
}


void transition(int transitionToBeDone) {
  def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
  log.warn("MOUNA 5 STATUS " + issue.getStatus());
  log.warn("MOUNA 6 ");
  String issueKey = issue.getKey()
  log.warn("MOUNA 7 ");
  IssueService issueService = ComponentAccessor.getIssueService()
  log.warn("MOUNA 8");
  def transitionValidationResult
  log.warn("MOUNA 9 ");
  def issueInputParameters = issueService.newIssueInputParameters()
  transitionValidationResult = issueService.validateTransition(currentUser, issue.id, transitionToBeDone, issueInputParameters)
  log.warn("MOUNA 10");
  if (transitionValidationResult.isValid()) {
    log.warn("MOUNA 11 transition is valid");
    def transitionResult = issueService.transition(currentUser, transitionValidationResult)
    log.warn("MOUNA 12 ");
    if (transitionResult.isValid()) {
      log.warn("MOUNA 13 " + issue.getStatus());
    } else {
      log.warn("MOUNA 14 transitionResult not valid");
    }
  }
}

问题根源

原脚本存在两个核心问题:

  1. 内存中issue对象未刷新:执行issueService.transition()后,数据库中的问题状态已更新,但当前内存中的issue对象还是初始的Open状态,后续日志打印的是旧状态,且下一次流转验证会基于旧状态,导致无法触发后续流转(比如transitionFromFixedToTested要求问题处于Fixed状态,但内存中还是Open)。
  2. 连续流转未做状态校验:直接连续调用三个transition,未确认前一次流转是否成功,也未获取最新的问题状态,导致后续流转的验证逻辑直接失败。

修复后的代码

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.IssueService

def log = Logger.getLogger("atlassian-jira.log")
def issueManager = ComponentAccessor.getIssueManager()
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// 仅当问题处于Open状态(ID=1)时执行自动流转
if (issue.getStatusId() == "1") {
    log.warn("MOUNA 1: 开始执行自动流转");
    // 定义流转ID顺序:Open→Fixed, Fixed→Tested, Tested→Completed
    def transitions = [71, 111, 131]
    
    def currentIssue = issue
    transitions.each { transitionId ->
        log.warn("MOUNA 当前状态: " + currentIssue.getStatus().getName());
        // 执行单次流转并获取更新后的Issue对象
        currentIssue = executeTransition(currentUser, currentIssue, transitionId, log)
        
        // 若流转失败,终止后续操作
        if (!currentIssue) {
            log.warn("MOUNA 流转ID " + transitionId + " 执行失败,终止流程");
            return
        }
    }
}

/**
 * 执行单个工作流流转,并返回更新后的Issue对象
 */
Issue executeTransition(ApplicationUser user, Issue issue, int transitionId, Logger log) {
    def issueService = ComponentAccessor.getIssueService()
    def issueInputParameters = issueService.newIssueInputParameters()
    
    // 验证流转合法性
    def validationResult = issueService.validateTransition(user, issue.id, transitionId, issueInputParameters)
    if (!validationResult.isValid()) {
        log.warn("MOUNA 流转验证失败: " + validationResult.getErrorCollection().getErrorMessages())
        return null
    }
    
    // 执行流转操作
    def transitionResult = issueService.transition(user, validationResult)
    if (!transitionResult.isValid()) {
        log.warn("MOUNA 流转执行失败: " + transitionResult.getErrorCollection().getErrorMessages())
        return null
    }
    
    // 从数据库重新加载最新的Issue对象,确保状态是最新的
    return issueManager.getIssueObject(issue.id)
}

关键修复点

  • 重新加载Issue对象:每次流转完成后,通过issueManager.getIssueObject(issue.id)从数据库拉取最新状态,确保后续流转基于正确的当前状态。
  • 循环处理流转:用循环遍历流转ID,每次流转后检查结果,失败则终止流程,避免无效操作。
  • 简化状态检查:直接使用issue.getStatusId()替代getStatus().getSimpleStatus().getId(),代码更简洁高效。
  • 增加错误日志:打印验证和执行失败的具体错误信息,便于快速排查问题。

内容的提问来源于stack exchange,提问作者منى

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:09:19