Como usamos a linguagem Jira Query na prática

Olá a todos!



Meu nome é Sergey Rakov, sou o chefe da divisão B2G da Rostelecom IT. Quero falar sobre a Jira Query Language (JQL): como usá-la na prática, técnicas básicas, quais problemas encontramos e como os resolvemos.



imagem Foto original tirada de deviniti.com/atlassian



Existem muitos rastreadores de tarefas, cada um adequado para resolver alguns problemas e não muito útil para resolver outros. Usamos muitos deles, mas agora nos decidimos pelo Jira - é nossa principal ferramenta. Pessoalmente, gosto muito de sua linguagem JQL, que simplifica muito o trabalho e permite que você tenha uma ferramenta poderosa e flexível para localizar tíquetes prontos para uso.



Fora da caixa, Jira tem pesquisas básicas e avançadas. Essas duas opções de pesquisa podem resolver a maioria dos problemas enfrentados pelo usuário. A pesquisa básica é familiar aos olhos de qualquer pessoa que já tenha usado os serviços de lojas online pelo menos uma vez - funciona de acordo com o mesmo esquema simples. Existem muitos filtros: por projetos, tipos de tarefas, por executor e status. Você também pode adicionar campos adicionais com base em critérios suportados pelo Jira.



Mas surge um problema quando você precisa ir além das consultas básicas. Por exemplo, se quisermos encontrar tarefas que já ocorreram em um determinado artista ou encontrar todas as tarefas, excluindo um projeto. Não é mais possível fazer uma seleção complicada para um projeto com um status de tarefa e executor e mais um executor e outro status de tarefa usando a pesquisa básica.



A pesquisa avançada vem ao resgate. A sintaxe JQL é muito semelhante à SQL. Mas em JQL, não há necessidade de selecionar campos específicos que iremos selecionar, indicar tabelas e bancos de dados dos quais iremos produzir. Especificamos apenas um bloco com condições e trabalhamos com classificação - Jira faz o resto automaticamente.



Tudo que você precisa saber para trabalhar com JQL são os nomes dos campos pelos quais selecionaremos tickets, operadores ( = ,! =, <,>, In, not in, was, is , etc.), keywords ( AND , OR, NOT, EMPTY, ORDER BY , etc.) e funções que estão disponíveis imediatamente no modo avançado ( Now (), CurrentUser (), IssueHistory (), EndOfDay () e outros).



Campos



Jira, quando você digita na barra de pesquisa, ela própria dá dicas de todos os valores possíveis que você está procurando: tanto por campos quanto pelos valores desses campos. Para mim, descobri recentemente um campo de sistema interessante lastViewed . Jira acompanha as visualizações dos seus ingressos.

imagem

Aqui estão duas opções para compor filtros para visualizar tarefas recentes. A primeira é minha opção lastViewed , em que Jira retornará os problemas que eu vi nos últimos sete dias, classificados em ordem decrescente. Este filtro é configurado no meu painel como um gadget e eu o uso com frequência. Como o ticket estava fechado, não lembrava da guia e do número, abri rapidamente, olhei qual era o último ticket.



Existe um filtro padrão Visto recentemente. Ele usa a função IssueHistory () , a classificação também é feita pelo campo lastViewed . O resultado é o mesmo, mas o método, mesmo em Jira, pode ser usado de outra forma. É importante notar que os campos LastViewed e IssueHistory () retornam apenas o seu histórico de navegação - você não pode visualizar o histórico de terceiros dessa forma.



imagem

Na maior parte do tempo em Jira, todos os operadores são padrão. Meus operadores favoritos são WAS , WAS IN , WAS NOT IN , WAS NOT , MUDADO porque trabalham com o tempo. Isso não é possível em bancos de dados convencionais.



imagem



Jira permite trabalhar com dados históricos prontos para uso. Usando o operador WAS , você pode encontrar tíquetes onde o executor estava e é o Usuário1. Se o tíquete estava comigo e depois foi passado para outra pessoa, a solicitação mostrará que esse tíquete uma vez foi meu. É claro que para uma seleção mais detalhada, você precisa adicionar mais algumas condições, mas trataremos disso mais tarde.



No entanto, há uma ressalva: Jira não armazena histórico para campos de texto: nomes de tíquetes e suas descrições. Você não pode escrever lá: “ Traga-me tickets cujo campo Resumo contenha a palavra“ Rostelecom ” ”.



O segundo exemplo é com o operador CHANGED . Gostaríamos de receber tíquetes nos quais o executor foi trocado após 1º de janeiro de 2020. Você pode usar outras palavras adicionais, por exemplo, ANTES ou sinais>, <, para quem é mais conveniente e uma data específica. No mesmo exemplo, você também pode fazer uma negação e ver em quais tickets os usuários estão travados : o destinatário não foi alterado APÓS '2020-01-01' .



Palavras-chave



imagem

As principais palavras-chave são OR , AND , NOT . Eles funcionam da mesma maneira que os operadores lógicos. Usando OR , obtemos um conjunto completo de tickets de dois projetos A e B. Se precisarmos restringir a seleção, usamos AND . Exemplo - precisamos de tickets do rascunho A, no qual o usuário estava executando Cama e: projeto = A = Cama e o cessionário AND . É o mesmo com a negação.



Funções



De acordo com a documentação, existem 47 funções no Jira, mas nunca usei todas elas. Aqui estão alguns, na minha opinião, os principais:



imagem



now () é uma função popular que permite encontrar tickets que, por exemplo, expiraram.



currentUser () retorna o usuário atual. Jira contém filtros pré-configurados que usam esse recurso. Com currentUser (), você pode fazer pesquisas genéricas. Foi assim que fiz um painel universal para toda a equipe de desenvolvimento: coloquei gadgets no painel e em cada um indiquei currentUser () em vez de um usuário específico . Este painel será exclusivo para cada usuário conectado, embora a configuração seja a mesma.



unreleasedVersions () é uma função que retorna tickets que estão em versões não lançadas. Mas não devolve bilhetes sem versão definida.



startOfDay () retorna o início do dia atual. Existem funções para semana, mês e ano. O mesmo se aplica à função de fechamento endOfDay () . Eles permitem que você se livre de datas específicas, você pode definir argumentos para eles: se você escrever startOfDay (-1) , o início do dia anterior será retornado. Se você deixar tudo como está, o início do dia atual será exibido - a saída será a hora. Essas funções ajudam a evitar hardcode, nós as usamos muito.



De issueHistory ()Já dei um exemplo, esta função retorna uma lista apenas de suas visualizações.



linkedIssues () é uma função que permite encontrar tickets que estão vinculados a um ticket específico.



Estas são as funções mais simples. Mas vamos mergulhar um pouco mais fundo e olhar para conexões mais complexas.



assignee was currentUser()

AND fixVersion was in
unreleasedVersions()

AND created > startOfYear()

      
      





Um exemplo um pouco sintético, mas mesmo assim. Esta é uma única solicitação dividida em três blocos. Depois de concluir a primeira parte da solicitação, receberemos tickets dos quais já fui um executor ou atualmente sou. É muito importante que WAS não só existisse, mas ainda existisse.



Na segunda parte, a filtragem é adicionada: vamos filtrar os escopos recebidos de meus tickets que já estiveram em versões não lançadas no momento. Ou seja, se houvesse um ticket nessa versão inédita e ele ainda não tenha sido lançado no momento, mas depois eu transferi o ticket para outra versão, e ele já foi lançado, então o ticket será incluído nesta seleção.



A terceira condição é a data de criação. Filtramos apenas os tickets criados desde o início do ano atual.



ScriptRunner



Este é um plugin que aprimora muito os recursos do Jira. Geralmente é usado para automatizar processos, mas também adiciona muitas funcionalidades adicionais ao JQL. ScriptRunner foi nosso primeiro plugin que entregamos assim que mudamos para Jira - no final de 2018. Pedi muito ativamente para instalar este plugin, porque sem ele não poderia coletar dados em links com epopeias. Por exemplo, muitas vezes precisei devolver todos os tíquetes épicos para uma solicitação específica ou todos os tíquetes épicos de subconsultas. ScriptRunner permite que você faça tudo isso com sucesso.



Para usar funções ScriptRunner, você precisa adicionar uma palavra adicional issueFunction em ou não em JQL . A seguir vem a função, por exemplo epicsOf () - Retorna epopeias para tickets que correspondem às condições da subconsulta. A subconsulta vem na segunda linha entre parênteses e vamos examiná-la mais de perto.



issueFunction in epicsOf
("worklogDate >= startOfWeek(-1) AND worklogDate <= endOfWeek(-1)")
AND project in (".B2G")
      
      





No primeiro exemplo, estamos procurando épicos com baixas de tempo da última semana. Hack de vida para líderes e gerentes de equipe: se você se esqueceu de preencher as planilhas de ponto e não se lembra do que fez na semana passada, ao atender a essa solicitação, você verá em que epopeias a equipe trabalhou. E muito provavelmente, você também trabalhou neles, porque a equipe claramente veio com perguntas. Em geral, essa consulta ajuda a lembrar o que você estava fazendo e está tudo bem para pintar.



A própria consulta começa a ser executada a partir dos parênteses, ou seja, a partir da subconsulta worklogDate - a data de débito. Além disso, há uma especificação > = startOfWeek (-1) - o início da semana. Mas preste atenção no número -1: significa que não precisamos desta segunda-feira, mas da última. E também worklogDate <= endOfWeek (-1), ou seja, é menos do que o final da semana passada. Essa solicitação emitirá tickets, não importa o que - bugs, tarefas, histórias de usuários - para os quais os funcionários cancelaram o tempo de segunda a domingo na semana passada.



O truque é que as funções startOfWeek () e endOfWeek () permitem que você se livre da data. Independentemente do tempo durante o qual eu faça essa solicitação na semana atual, ela me retornará o mesmo escopo épico. Assim que esta semana acabar, ele vai devolver os épicos. Surpreendentemente, nem todo mundo usa essa oportunidade: recentemente estudei solicitações abertas que são compartilhadas publicamente e vi muitas datas fixas lá. E há a suspeita de que essas datas mudam constantemente. E o que posso dizer, no começo eu mesmo fiz.



Ao executar a subconsulta, obtemos o conjunto usual de tickets. Em seguida, vem a função epicsOf , que nos dá uma lista das epopeias associadas a esses ingressos. E depois tem a filtragem por projeto, porque eu só preciso de epopeias para meu projeto, e todo mundo não é interessante.



O próximo pedido é para epopeias com baixas neste ano, mas sem contratos. Essa solicitação surgiu devido ao fato de usarmos o Jira não apenas como rastreador de tarefas, mas também para contabilidade financeira. Há um projeto separado para contratos, que executamos na forma de tickets, e o usamos como um sistema de gerenciamento eletrônico de documentos: os status estão mudando constantemente, vinculamos contratos com épicos, sabemos quantas pessoas cancelaram em qual epopeia, sabemos quanto custa e, em seguida, nós definimos o custo do trabalho para cada contrato. Além disso, por meio de contratos, os custos de mão de obra são transferidos para o Redmine 2.0. Ou seja, baixamos para Jira e, em seguida, os scripts automáticos transferem nossos custos para o Redmine 2.0 de acordo com esses contratos.



Quando essa automação começou a funcionar, comecei a receber solicitações de colegas do tipo: tem epopeias cujos custos trabalhistas não podem ser repassados ​​para o Redmine, porque lá não há contratos. Vamos considerar a solicitação com mais detalhes.



issueFunction in epicsOf("worklogDate >= startOfYear()")
AND issueFunction not in hasLinkType(Contract)
AND project in (".B2G")
      
      







O pedido em anexo significa que estamos interessados ​​nos bilhetes que foram cobrados para este ano. A função epicsOf segue do exemplo anterior e nos dá uma lista de epopeias. Em seguida, queremos filtrar pela presença de contratos.



Um contrato entre colchetes é um tipo de link interno que conecta contratos a épicos. hasLinkType () é uma função em ScriptRunner que retorna tickets com este tipo de link. Mas preciso de tickets que não contenham esse tipo de relacionamento e, portanto, uso a negação não em.



Quando a primeira condição foi cumprida, ganhei uma série de épicos que foram relevantes este ano. Além disso, épicos sem contratos foram filtrados, e no final - para um projeto específico "Video.B2G". Assim, consegui todos os épicos para trabalhar.



E, no final, gostaria de sugerir passar em um pequeno teste de três perguntas sobre o tema deste post. Demorará 2 minutos. Depois de passar, você verá sua avaliação.

Link de enquete
Eu ficaria feliz em esclarecer algo ou responder perguntas nos comentários, se você tiver alguma.

Obrigado.



All Articles