JQL : le guide complet de la recherche dans Jira


Publié par
Balkis KHOUNI

18 octobre 2017

Si vous êtes utilisateur ou administrateur de Jira, vous avez certainement déjà utilisé la fonctionnalité de recherche de l’outil.

Mais en connaissez-vous toutes les subtilités?

Selon votre besoin, vous avez peut-être utilisé la recherche rapide – ce qui revient à sélectionner une option dans un menu déroulant, ou bien fait appel au Jira Query Language (JQL) pour réaliser des requêtes plus complexes.

Dans cet article, nous allons vous apprendre à créer des requêtes avancées utilisant le JQL. Cela vous permettra par exemple de créer des filtres et de vous y abonner, ou encore de vous en servir pour configurer vos tableaux de bord ou vos tableaux Agiles. Avant de nous plonger dans des astuces sur le JQL, revenons sur les différentes manières de rechercher des tickets dans Jira.

 

La recherche dans Jira

Recherche rapide

C’est la fonction de recherche la plus simple à prendre en main. Elle est accessible directement depuis la barre de menu de l’outil et permet de rechercher des tickets. Il existe trois manières d’utiliser cette barre de recherche :

1 – Rechercher à partir de texte libre

Si vous tapez n’importe quel mot (qui n’est pas un mot clef dans Jira), Jira recherchera automatiquement dans les champs Résumé, Description et Commentaires des tickets. Vous serez alors redirigé vers le Navigateur de demandes qui affichera la liste des demandes qui correspondent à votre recherche.

2 – Accéder directement à un ticket

Si vous tapez la clef d’une demande (par exemple TP-146) vous serez redirigé directement vers cette demande. Evidemment, la demande doit déjà exister et vous devez avoir les droits suffisants pour pouvoir la consulter.

3 – Recherche JQL intelligente

Avec ce type de requête, vous pouvez rechercher des demandes spécifiques en tapant de courtes requêtes JQL. Il existe beaucoup de mots clefs et d’astuces que vous pouvez apprendre ici pour optimiser le temps que vous passez à rechercher des informations dans Jira.

Voici un exemple de requête intelligente :

FL Open Story

Si vous avez un projet dont la clef est FL et un statut appelé Open et un type de demande appelé Story, la requête précédente sera traduite par Jira en JQL comme suit :

project = FL AND issuetype = Story AND status = Open

Recherche simple

Effectuer votre recherche via l’interface simplifiée est recommandé si vous n’avez jamais utilisé le Jira Query Language et si voulez simplement pouvoir filtrer vos demandes. Vous pouvez le faire directement depuis le Navigateur de Demandes.

Pour y accéder : dans le menu principal, choisissez Demandes > Chercher des demandes

La barre de recherche simplifiée ressemble à ceci :

 

 

 

Si vous ne la voyez pas, c’est probablement parce que vous êtes en mode Avancé. Pour passer en mode Basique, utilisez le lien basique situé tout à droite dans la barre de recherche. En sélectionnant les différentes options dans les menus déroulants, vous pourrez affiner votre recherche. Vous pouvez aussi ajouter plus de champs à la recherche en utilisant le menu déroulant Suite à côté du bouton Rechercher (la petite loupe).

Recherche avancée

La recherche avancée, elle, est un champs auto-complété qui vous permet d’élaborer une requête complexe en utilisant le JQL.

Toute requête basique peut être traduite en requête JQL en basculant en mode Avancé depuis le mode Basique. Voici quelques raisons qui vous pousseront à vouloir basculer en mode recherche avancée :

  1. Si vous voulez utiliser l’opérateur logique OU
  2. Quand un champs de votre requête n’est pas supporté par le mode Basique. Par exemple, le champs Time to First Response n’étant pas supporté par le mode Basique, vous devrez passer en recherche avancée pour l’utiliser dans votre requête.
  3. Si vous voulez utiliser des fonctions JQL – telles que celles présentées dans la suite de cet article.

Exemples de requêtes JQL fréquemment utilisées

Demandes liées

Toutes les demandes liées

Si vous voulez obtenir la liste de toutes les demandes liées à une demande en particulier, utilisez la fonction JQL linkedIssues(issueKey).

issue in linkedIssues("TP-345")

Demandes liées par type de lien

Si vous souhaitez obtenir la liste des demandes liées à une demande spécifique avec un type de lien donné, utilisez la fonction JQL linkedIssues(issueKey, linkType).

issue in linkedIssues("TP-345", blocks)

Pour obtenir le type du lien, vous aurez besoin d’être administrateur global de JIRA. Allez dans :

  1. Administration > Demandes
  2. Sous la section Caractéristiques des demandes, choisissez Création de liens entre les demandes.
  3. Utilisez la colonne Nom pour obtenir le type de lien.

Vous trouverez la liste de tous les types de lien disponibles dans votre instance Jira à cet endroit.

Les fonctions ci-dessous peuvent se révéler très utiles si vous voulez lister les demandes qui sont liées à une demande spécifique. Cela implique que vous connaissiez la clef la demande.

Toutes les demandes par type de lien

Pour effectuer des requêtes plus avancées, vous aurez besoin d’installer l’app ScriptRunner.

Si vous souhaitez lister toutes les demandes qui ont des demandes liées avec un type de lien spécifique, vous pouvez utiliser la fonction hasLinkType(linkType).

issueFunction in hasLinkType(Blocks)

Lorsqu’on utilise des requêtes JQL ScriptRunner, nous n’utilisons pas l’objet issue, nous utilisons issueFunction, ce qui explique la requête ci-dessus. Celle ci-dessous serait fausse :

issue in hasLinkType(Blocks)

Demande liées à des demandes filtrées

Vous souhaitez obtenir la liste des demandes liées à un groupe de demandes spécifiques (filtre ou demandes) ? Utilisez la fonction :  linkedIssuesOf(Subquery)

issueFunction in linkedIssuesOf("project=IDP")

Vous pouvez spécifier le type de lien si vous souhaitez obtenir la liste des demandes liées à un groupe de demandes spécifiques avec un type de lien particulier. Afin de réaliser cela, utilisez la fonction linkedIssuesOf(Subquery, linkType) .

issueFunction in linkedIssuesOf("project=IDP", Blocks)

Si vous voulez inclure des epics et des sous-tâches, utilisez la fonction : linkedIssuesOfAll(Subquery)

issueFunction in linkedIssuesOfAll("project=IDP")

Quand vous spécifiez le type de lien, les fonctions JQL suivantes retourneront le même résultat :

  • linkedIssuesOfAll(Subquery, linkType)
  • linkedIssuesOf(Subquery, linkType)

Requêtes sur la hiérarchie des demandes

Les requêtes imbriquées sont une des fonctionnalités les plus demandées dans Jira. Bien qu’elles ne soient pas nativement disponibles, vous pouvez toujours les réaliser en utilisant une app comme ScriptRunner.

Il y a de nombreux contextes où vous pouvez avoir besoin de réaliser une requête imbriquée mais le plus courant est lorsque l’on souhaite extraire la hiérarchie des epics.

Commençons avec le bas et remontons dans la hiérarchie.

Rechercher des sous-tâches

L’objet Parent permet d’obtenir la liste des sous-tâches associées à une ou des demandes spécifiques et est disponible nativement dans Jira. Vous aurez cependant besoin de spécifier la clef de la ou des demande(s).

parent = "IDP-4689"

Ou

parent in ("IDP-4689","IDP-4687")

Si vous voulez obtenir la liste des sous-tâches pour un sous-ensemble de demandes (en utilisant une sous-requête), vous aurez besoin d’une app qui implémente cette fonctionnalité dans Jira.

Avec ScriptRunner, nous pouvons réaliser ceci en utilisant issueFunction in subtasksOf().

issueFunction in subtasksOf("project = IDP AND issuetype=Incident")

Rechercher les demandes parentes

Il n’existe pas de fonction JQL native qui vous permette d’accéder aux demandes parents d’un sous-ensemble de sous-tâches. Ci-dessous, nous partageons une option alternative qui utilise l’app ScriptRunner.

Si vous voulez obtenir les demandes parents d’une sous-requête, vous pouvez utiliser la fonction parentOf().

 

issueFunction in parentsOf("project=IDP and issuetype=Incident")

Rechercher des epics ou des stories

Retrouver les stories associées à une epic

Nativement, il est possible de rechercher les stories associées à des epics en utilisant le champs personnalisé Epic Link.

"Epic Link" in (SCUR-24,SCUR-25)
La limitation ici est que vous devez spécifier les clefs des epics parentes.

Lorsque vous avez besoin d’effectuer une requête plus générique où vous définissez les epics dans une sous-requête, vous pouvez utiliser l’application ScriptRunner. La fonction à utiliser est linkedIssuesOf(Subquery).

issueFunction in linkedIssuesOf("issuetype = Epic", "is epic of")

Extraire les epics associées à des stories

Il n’existe pas de fonction native qui permet d’obtenir les epics associées à un sous-ensemble de demandes (stories). Cependant, toujours avec ScriptRunner, vous pourrez y parvenir en utilisant la fonction epicsOf(Subquery). 

issueFunction in epicsOf("project = IDP AND issuetype=Incident")

Obtenir une liste d’epics et des stories associées

Il est possible d’obtenir via les fonctions natives de Jira les epics et leurs stories en utilisant le champs personnalisé Epic Link avec des opérateurs logiques.

"Epic Link" in (SCUR-24, SCUR-25) OR issuekey in (SCUR-24, SCUR-24)
La limitation est que vous devez spécifier les clefs des epics concernées.

Si vous utilisez ScriptRunner, vous pourrez élaborer une requête plus générique en utilisant la fonction  linkedIssuesOf(Subquery).

(project = IDP AND issuetype = Epic) OR issueFunction in linkedIssuesOf("project = IDP AND issuetype = Epic", "is epic of")

La première partie filtre les epics :

(project = IDP AND issuetype = Epic)

La seconde partie filtre les stories dans les epics ci-dessus :

issueFunction in linkedIssuesOf("project = IDP AND issuetype = Epic", "is epic of")

Epics, stories et sous-tâches

Il n’existe pas de fonction native pour obtenir les 3 niveaux de hiérarchie en utilisant une requête JQL. Le défi ici est donc d’obtenir les sous-tâches des stories retournées par la première partie de la requête.

Cependant, cela peut être fait avec ScriptRunner. 

(project = IDP AND issuetype = Epic) OR issueFunction in linkedIssuesOf("project = IDP AND issuetype = Epic", "is epic of") OR issueFunction in subtasksOf("issueFunction in linkedIssuesOf('project = IDP AND issuetype = Epic', 'is epic of')")

Découpons cette requête pour que vous compreniez ce qu’il se passe.

Requête Rôle
 (project = IDP AND issuetype = Epic) Obtenir la liste des epics
 issueFunction in linkedIssuesOf(« project = IDP AND issuetype = Epic », « is epic of ») Obtenir les stories associées à ces epics
 issueFunction in subtasksOf(« issueFunction in linkedIssuesOf(‘project = IDP AND issuetype = Epic’, ‘is epic of’) ») Obtenir les sous-tâches associées à ces stories

Utilisateur courant

Le contexte Utilisateur Courant (fonction currentUser()) est utilisé de manière très spécifique . Elle peut être utilisée avec les champs suivants :

  • Rapporteur (reporter)
  • Assigné (assignee)
  • Observateur (watcher)
  • Votant (voter)
  • Tout champs personnalisé de type Sélectionneur d’utilisateurs (simple ou multiple)

Voici un exemple d’utilisation :

assignee = currentUser()

Cependant, la requête suivante, utilisée pour obtenir des tickets dont l’utilisateur courant fait partie des Approbateurs (chamsp utilisateur multiple) est fausse et générera une erreur :

currentUser() in « Approvers (CR) »

Même s’il s’agit d’un champs Sélectionneur d’utilisateurs (multiple), voici ce que vous aurez besoin de faire à la place :

"Approvers (CR)" = currentUser()

Appartenance à un groupe d’utilisateurs

Si vous souhaitez obtenir la liste de tickets dont l’assigné, le rapporteur ou toute valeur d’un champs personnalisé de type User Picker fait partie d’un groupe spécifique dans Jira, vous pouvez utilisez la fonction membersOf(GroupName)

assignee in membersOf("jira-administrators")

Portfolio et ScriptRunner for Jira

Il est intéressant de pouvoir réaliser des requêtes JQL en fonction de la configuration de Portfolio for Jira. Il existe deux apps qui fournissent des fonctions JQL en lien avec Portfolio for Jira :

  • Portfolio for Jira
  • ScriptRunner for Jira

En fonction de la complexité de la requête que vous souhaitez réaliser, vous aurez ou non besoin de ScriptRunner.

Portfolio for Jira

Si vous avez installé Portfolio for Jira, vous pourrez utiliser le champs personnalisé Parent Link :

"Parent Link" in ("project=IDP")

De cette manière, vous obtenez toutes les demandes qui ont un parent (dans le contexte de Portfolio for Jira) du projet dont la clef est IDP.

ScriptRunner

Dans le cas où vous souhaitez utiliser des fonctions JQL avancées, vous pouvez utiliser ScriptRunner.

Pour que ces fonctions JQL ScriptRunner apparaissent, vous aurez évidemment besoin d’avoir installé Portfolio for Jira.

Assurez-vous d’avoir une version de ScriptRunner assez récente pour avoir accès à ces fonctions : elles sont présentes à partir de la version 5.0.11 . 

Cette app ajoutera les fonctions JQL suivantes à votre instance :

Fonction JQL Description
portfolioChildrenOf(Subquery)

Trouve les demandes enfants des demandes spécifiées dans la sous-requête.

Par enfant, nous faisons référence à la hiérarchie configurée dans Portfolio for Jira.

Si vous voulez voir votre hiérarchie, faites comme ceci :

  1. Connectez-vous en tant qu’administrateur à Jira
  2. Allez dans le menu  Apps
  3. Dans la section PORTFOLIO FOR JIRA, cliquez sur le lien Configuration de la Hiérarchie Portfolio.
portfolioParentsOf(Subquery) Retrouve les demandes parentes d’une sous-requête.

Là encore, via Parent, nous faisons référence à la hiérarchie configurée dans Portfolio for Jira.

Exemple

En supposant que vous avez la hiérarchie de demandes suivante configurée dans Portfolio for Jira:

→ Initiative

→ Epic

→ Story

Si vous voulez accéder à toutes les epics situées sous des initiatives qui sont dans un statut spécifique, vous aurez besoin de réaliser la requête suivante :

issueFunction in portfolioChildrenOf("status='To Do'") and issuetype=Epic

Dans le cas où vous voudriez ajouter les stories associées à la requête précédente, vous devrez modifier votre requête de la façon suivante :


(issueFunction in portfolioChildrenOf("status='To Do'") and issuetype=Epic) OR (issueFunction in linkedIssuesOf("issueFunction in portfolioChildrenOf('status=\\'To Do\\'') and issuetype=Epic", "is epic of"))

Comme il s’agit d’une requête imbriquée, cela peut vite devenir confus. Vous devrez faire attention à échapper les apostrophes et les guillemets comme nous l’avons fait avec \\’To Do\\’ bit.

Si vous voulez obtenir toutes les initiatives liées à un groupe d’epics, faites comme ceci :

issueFunction in portfolioParentsOf("issuetype=Epic and project=FL") and issuetype=Initiative
Pour toutes les requêtes liées à Portfolio, rappelez-vous qu’elles ne fonctionneront que sur les changements sur lesquels vous vous êtes engagés dans votre plan Portfolio.

Aller plus loin avec le JQL

Vous pouvez déjà réaliser de nombreuses requêtes complexes avec les fonctions JQL natives mais il existe aussi des apps pour vous permettre d’aller plus loin.

J’espère que cet article vous aura été utile, mais si vous vous posez encore des questions sur comment écrire vos requêtes JQL, n’hésitez pas à les poser en commentaire de cet article !