Introducing Jira Expressions

Hi Krzysztof,
awesome news, thank you so much!

Are expressing available on server?

This feature is available exclusively on Jira Cloud.

Indeed, it doesn’t make much sense on Jira Server.

The problem Jira expressions are trying to solve is that certain classes of extension points require fast and reliable computations (e.g. workflow or web conditions). With Jira expressions, such extension points can now be offered to third-party apps.

But that problem doesn’t exist on Jira Server, since you can already enhance Jira Server in whatever way you need with P2 plugins running on the same JVM.

2 Likes

Thanks for the clarification.

Hi,
@kkercz I have a requirement where I need to check the status of all the linked issues of a given type before changing status of an issue/task. Can this check be added using Jira expression?

Hi @anushas26,

It should be possible. The expression would look like this:

issue.links
     .filter(link => issue.type.id == X) // only check links of the given type
     .filter(link => link.direction == 'outward') // let's say we only care about outgoing links
     .map(link => link.linkedIssue) // get the issue from each link
     .every(issue => issue.status.id == Y) // check that every linked issue has status Y

Now, once you have the expression ready, you could create a Connect app with a workflow validator powered by this expression and configure it on your workflow transitions.

Thank you. Will try this. Can we also check both inward and outward issue in the same expression?

Hi,
I tried this:
issue.links
.filter(link => type.id == “Blocks”) // only check links of the given type
.filter(link => link.direction == ‘inward’) // let’s say we only care about outgoing links
.map(link => link.linkedIssue) // get the issue from each link
.every(issue => issue.status.id == “In development”)

But am getting below error:
The result is false, so the transition would not be allowed.

View Results

Evaluation failed: "type" - identifier not available in context

I had a typo in my example, it should have been .filter(link => link.type.id == “Blocks”).

Can we also check both inward and outward issue in the same expression?

Sure. You can see all properties available for the issue link object here: https://developer.atlassian.com/cloud/jira/platform/jira-expressions-type-reference/#issuelink.

Thank you. Its working now.
I used name instead of id in this line of code .filter(link => link.type.name == “Blocks”) .

Hi @kkercz, does Jira Expression support (or have any plan to support) conditional expression? For example,
issue.resolution != null? issue.resolution.name : ""
Background: We’re making a kind of DSL in our app, which will be translated into Jira Expression. So users can write something like "resolution is ‘Fix’ " without worrying about the null check.

Yes, conditional expressions are supported, so your example would work.

By the way, another way to write it would be:

issue.resolution && issue.resolution.name || ""

Background: We’re making a kind of DSL in our app, which will be translated into Jira Expression. So users can write something like "resolution is ‘Fix’ " without worrying about the null check.

Oh, that’s exciting! Let me know if you have any more questions. And check out the documentation if you haven’t yet: https://developer.atlassian.com/cloud/jira/platform/jira-expressions/

2 Likes

That’s awesome, thanks @kkercz. I did look into the documentation at the beginning, however I missed that piece of information and got the wrong impression that the feature was not supported. Then today the bug showed up.

BTW, this is what our DSL looks like : Workflow Rules | Typezoo
I’m looking to play more (may be adding some editor support?) with the expression language as it appears to be a perfect base language for our DSL and most of the use cases are perfectly supported. Nice work! I’m sure there will be questions when more features are added.

1 Like

Hi @kkercz, problem pops up quickly:) Is there an easy way to stringify a complex object in Jira Expression? The toString method seems to be only available in some types. And object + “” doesn’t work well for complex object.
I could probably leverage the above conditional expression to check the type and convert the object into string accordingly. But the generated code is likely to be lengthy.

Background: I’m adding custom field support in my statically typed DSL and the editor relies on types for auto-completion at editing time. However it turns out to be tricky to incorporate the type information of the custom field if it is json or whatever complex object . So stringify is a workaround to allow users to be able to do some check in this case. I’ll probably enhance my language to be a bit more dynamic to handle such situation later.

I’m afraid there is no stringify in Jira expressions. But I see how it could be useful. Feel free to create a feature request in the ACJIRA project for it!

However, there is a feature you might find useful: an API to statically type check expressions (Analyse Jira expression). With it, you can get to know the type of every custom field. For example, let’s say customfield_10010 is the sprint custom field. If you call:

POST /rest/api/2/expression/analyse?check=type

{
  "expressions": [
  	"issue.customfield_10010"
  ]
}

Then the response will be:

{
    "results": [
        {
            "expression": "issue.customfield_10010",
            "valid": true,
            "type": "List<Any>"
        }
    ]
}

Which tells you that the value of custom field customfield_10010 is a list. Unfortunately it won’t tell you the type of items on that list, but it’s a start. For some fields it will give you more exact types than for the others. You can call this for all custom fields on a Jira instance to get to know their types in Jira expressions.

Maybe you could make use of this somehow in your DSL editor?

Thanks for the quick confirmation. I was thinking to use “getFields” rest api to fetch all custom fields upfront. The feature your suggest looks better. I will do some experiments to see how it can be integrated.

We are excited to incorporate Jira Expressions into our Apps… However, we are having some difficulty calling the endpoint using the Connect Javascript API.

const bodyData = {
        expression: "{ issue: issues.flatMap(issue => { issueTimeline: issue.properties['ai-tone-timeline']}) }",
            context: {
            issues: {
                jql: {
                    maxResults: 100,
                    query: "project in (AIHD, SP)",
                    startAt: 0,
                    validation: "strict"
                }
            },
        }
     };

    return new Promise((resolve, reject) => {
        AP.request({
            url: '/rest/api/3/expression/eval',
            type: 'POST',
            data: bodyData,
            success: function(tones:any){
                const projectTones: IProjectTones = JSON.parse(tones);
                console.log("Project Tones", projectTones);
                resolve(projectTones);
            },
            error: function(xhr: any, statusText: any, errorThrown: any){
                console.log("Status Text", statusText);
                console.log("Error Thrown", errorThrown);
                reject(statusText);
            }
        });
    })

The same expression successfully returns a result from the backend but no matter how much we tweak the format of the body data we receive a 415 (unsupported media type) error. Any guidance would be greatly appreciated

1 Like

Shouldn’t the data property value be JSON.stringify(bodyData)? Another thing is that perhaps you are missing contentType, according to the docs it’s “required when data is supplied”.

1 Like

Thanks for the pointer @kkercz… got it working with:

data: JSON.stringify(bodyData),
contentType: 'application/json',
2 Likes

Hello @kkercz! Thanks for the useful feature.

AFAICS I can only get/read issue fields/properties, etc. via expressions API, but I wonder if I could update or edit issues with this API?

In our app we need to make a bulk update of a certain field for a set of issues. Can we do this via expression API?

Thanks in advance

1 Like