import com.atlassian.jira.JiraDataType;
import com.atlassian.jira.JiraDataTypes
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.query.Query;
import com.atlassian.jira.jql.parser.JqlParseException;
// import com.atlassian.jira.issue.search.SearchQuery
import com.atlassian.jira.jql.operand.QueryLiteral
import com.atlassian.jira.jql.parser.JqlQueryParser
import ru.mail.jira.plugins.groovy.util.lucene.IssueIdCollector;
import com.atlassian.jira.jql.query.QueryCreationContext
import com.atlassian.jira.jql.validator.NumberOfArgumentsValidator
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.util.MessageSet
import com.atlassian.jira.util.MessageSetImpl
import com.atlassian.query.clause.TerminalClause
import com.atlassian.query.operand.FunctionOperand
import ru.mail.jira.plugins.groovy.api.jql.ScriptedJqlValuesFunction
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
class DemoFunction implements ScriptedJqlValuesFunction {
private final Logger logger = LoggerFactory.getLogger(DemoFunction.class);
@Override
public JiraDataType getDataType() {
return JiraDataTypes.ISSUE;
@Override
public MessageSet validate(ApplicationUser searcher, FunctionOperand operand, TerminalClause terminalClause) {
def i18n = ComponentAccessor.getI18nHelperFactory().getInstance(searcher)
def numberValidMessage = new NumberOfArgumentsValidator(1i, i18n).validate(operand);
if (numberValidMessage.hasAnyErrors()) {
return numberValidMessage
def messageSet = new MessageSetImpl();
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
try {
def query = jqlQueryParser.parseQuery(operand.getArgs().get(0))
// messageSet.addMessage(MessageSet.Level.WARNING, "jqlQueryParser :${query}");
} catch (any) {
messageSet.addErrorMessage("not valid jql:${operand.getArgs().get(0)}");
messageSet.addErrorMessage("${any}");
return messageSet
public List<QueryLiteral> getValues(QueryCreationContext queryCreationContext, FunctionOperand functionOperand, TerminalClause terminalClause) {
final List<QueryLiteral> literals = new LinkedList<>();
String jql = functionOperand.getArgs().get(0);
for (MutableIssue issue: getIssuesByJQL(jql, queryCreationContext.getApplicationUser()) ){
literals.add(new QueryLiteral(functionOperand, issue.getKey()));
for (Issue subIssue: issue.getSubTaskObjects()){
literals.add(new QueryLiteral(functionOperand, subIssue.getKey()));
return literals;
private Collection<MutableIssue> getIssuesByJQL(String jql, ApplicationUser user) {
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class);
SearchProvider searchProvider = ComponentAccessor.getComponent(SearchProvider.class);
IssueManager issueManager = ComponentAccessor.getIssueManager();
Query query = jqlQueryParser.parseQuery(jql);
Collection<MutableIssue> issues = new ArrayList<>();
IssueIdCollector collector = new IssueIdCollector();
searchProvider.search(query, user, collector);
logger.error("query:{}, user:{}, collector:{}, IssueIds:{} ", query, user, collector, collector.getIssueIds());
for(String issueId: collector.getIssueIds()){
logger.error("issueId:{}, issue:{}",issueId, issueManager.getIssueObject(new Long(issueId)));
// issues.add(issueManager.getIssueObject(issueId));
issues.add(issueManager.getIssueObject(new Long(issueId)));
return issues;
}catch (JqlParseException jqlParseException){
System.out.println("jqlParseException:" + jqlParseException);
}catch (Exception exception){
System.out.println("exception:" + exception);
return null;
效果如下:
JiraMyGroovy脚本git@github.com:mailru/jira-scripts.git样例代码如下:import com.atlassian.jira.JiraDataType;import com.atlassian.jira.JiraDataTypesimport com.atlassian.jira.component.ComponentAccessorimport com.atlassian.jira.issue.MutableIss...
JIRA的高级搜索功能类似于SQL查询,是使用Jira查询语言(JQL)构建结构化查询来搜索问题。可以指定无法在快速或基本搜索中定义的条件(例如, ORDER BY 子句)。
注意,即使JQL使用类似SQL的语法,它也不是数据库查询语言。
一、如何执行高级搜索?
导航到Issues > Search for Issues
如果存在现有搜索条件,请单击“ New filter” 按钮以重置搜索条
不断的总结,才能不断的提高;不断的思考,才能不断的进步!
上面是我收集的一些视频资源,在这个过程中帮到了我很多。如果你不想再体验一次自学时找不到资料,没人解答问题,坚持几天便放弃的感受的话,可以加入我们群【902061117】,里面有各种软件测试资源和技术讨论。
当然还有面试,面试一般分为技术面和hr面,形式的话很少有群面.
通过故事而不是任务进行交流
上一次我谈论代码段之间的接口 。 今天,我想讨论参与开发软件的人群之间的接口。 有两个基本组:开发软件的人和协调开发的人。 用敏捷术语来说,这些小组一方面是开发团队,另一方面是产品所有者和其他利益相关者。
说相同的语言
这两个小组需要沟通,因此当每个人都讲相同的语言时,他们会做到最好。
首先要说相同的“自然”语言,例如英语。 对于将要给定的大多数团队,但...
使用jira管理Scrum敏捷项目(五)使用jira对项目、产品的全生命周期的管理、迭代前言一、自定义jira看板二、分享我的技术团队中的看板设置总结
jira环境搭建请参考我的另外一篇文章:链接: 使用docker搭建jira环境.
jira是一款非常适合敏捷开发团队使用的一款事务管理软件。很多大型互联网公司都在使用,既然好用,那我们尽管用就好了,小公司就可以按照专栏第一篇文章,搭建一下环境白嫖一把就好了。
在这里简单介绍一下jira的几个特性:
1.需求管理
2.BUG管理、缺陷跟踪
3.任务管理
获取jira任务的信息1.背景2.探究3.解决4.总结
最近做一个demo项目,需要能够显示jira任务的状态信息,所以就稍微探究了一下jira的api和一些发请求的方法。
一开始发现jira提供的jira-client-api中有jiraclient类,通过它很容易就可以获取到对应的任务的信息,但是如果依赖jar,存在一个问题,就是该jar中依赖到的jar都必须要依赖,所以只引入一个client-api.jar是远远不够的,运行时会报错,之后就根据报错去maven仓库搜,再这样操作引入
拖放以重新排序子任务。
“ JIRA子任务可排序”是JIRA子任务的细微增强。这使您可以通过拖放来移动它们,而不是使用烦人的小箭头。将子任务拖动到所需位置后,其位置将透明保存,因此不需要重新加载。
支持语言:English,한국어
- 【设计出图】@{summary} / issueType:"简单任务" component:"@inherit" assignee:"xxx" fixversion:"@inherit" 需求复杂度:"@inherit"
- 【测试用例】@{summary} / issueType:"简单任务" component:"@inherit" assignee:"xxx" fixversion:"