Bitbucket modules
Common modules
Compass modules
Confluence modules
Jira modules
Jira Service Management modules

This section describes a Forge preview feature. Preview features are deemed stable; however, they remain under active development and may be subject to shorter deprecation windows. Preview features are suitable for early adopters in production environments.

We release preview features so partners and developers can study, test, and integrate them prior to General Availability (GA). For more information, see Forge release phases: EAP, Preview, and GA.

Jira workflow validator (preview)

The jira:workflowValidator module defines a validator that can be added to workflow transitions in company-managed projects (see: Advanced workflow configuration).

Validators check that any input made to the transition is valid before the transition is performed. In this case, input also refers to data entered by the user on the transition screen. If a validator fails, the issue does not progress to the destination status of the transition, the transition's post functions are not executed, and the error message of the failed validator is shown.

Validators added by Forge apps are implemented with:

  • Jira expressions that are provided upfront in the manifest or built dynamically on the configuration page
  • lambda functions

Validating with Jira expressions

The issue validated by the Jira expression includes changes made on the transition screen, which makes this way of defining validators particularly suitable for cases where the state to validate can be modified during the transition.

A workflow validator only evaluates to true if the provided Jira expression evaluates to true. It will evaluate to false in all other cases, including:

  • the Jira expression fails to evaluate because of errors or returns anything other than a Boolean value (in this case, an avi:jira:failed:expression event is sent)
  • the app providing the workflow validator is uninstalled

If the expression returns a string value, that value will be shown as the error message on the transition.

Example

A validator that checks if the issue is assigned would look like this:

1
2
jira:workflowValidator:
  - key: my-forge-workflow-validator
    name: Issue is assigned validator
    description: This validator allows the transition where the issue has an assignee.
    expression: issue.assignee != null
    errorMessage: "The transition failed because no one is assigned to the task. Assign the task to a user and try again."

Context variables

The following context variables are available to expressions:

Additionally, these are available for Jira Service Desk transitions:

  • customerRequest (CustomerRequest): The customer request that is about to be transitioned.
  • serviceDesk (ServiceDesk): The service desk the customer request belongs to.

Adding validator configuration with custom UI

Expression-based workflow validators often require some degree of the configuration of their behavior. For example, you may want to allow a state transition only if the issue has a particular label, and you want the project administrator to configure that label. For this purpose, three additional properties in the manifest allow you to declare the custom UI resources that will show:

  • the form that is shown when a workflow validator is first created
  • the form that is shown when a workflow validator is edited
  • the read-only view or summary of the configuration

The create and edit pages should present a form with configuration relevant to the validator. In order to persist this information in Jira, the page needs to use the workflowRules API.

When evaluating the validator, the configuration saved that way will be available to the Jira expression under the config context variable.

The config context variable is stored under the extension.validatorConfig key in the context object returned from the getContext API in the custom UI bridge.

Example

To create a validator that displays the custom UI, declare it in the manifest as follows:

1
2
jira:workflowValidator:
  - key: my-forge-workflow-validator
    name: Issue summary contains text validator
    description: This validator allows the transition where the summary of an issue contains the text defined on the workflow validator configuration page.
    expression: "issue.summary.includes(config['key']) == true"
    edit:
      resource: edit-resource
    create:
      resource: create-resource
    view:
      resource: view-resource
resources:
  - key: create-resource
    path: static/create/build
  - key: edit-resource
    path: static/edit/build
  - key: view-resource
    path: static/view/build
permissions:
  scopes:
    - manage:jira-configuration

To get the product context in the create, edit, and view resources defined in the manifest, use view.getContext function.

1
2
import { view } from '@forge/bridge';

function App() {
  const [context, setContext] = useState();
  const [config, setConfig] = useState();

  useEffect(() => {
    view.getContext().then(ctx => {
      setContext(ctx);
      setConfig(ctx.extension.validatorConfig)
    });
  }, []);
}

To save the user input to the config context variable, pass the callback function returning stringified JSON to the workflowRules.onConfigure function.

1
2
import { workflowRules } from '@forge/jira-bridge';

const onConfigureFn = async () => {
  var config = {
    'key': 'value'
  };

  return JSON.stringify(config);
};

// calling onConfigure from async function
try {
  await workflowRules.onConfigure(onConfigureFn);
} catch (e) {
  // Handle the error.
}

// calling onConfigure from non-async function
workflowRules
    .onConfigure(onConfigureFn)
    .catch(e => {
        // Handle the error.
    });

Overriding Jira expression

Additionally, you can override the entire Jira expression from the manifest. To do that, include the expression property in the returned JSON. For example:

1
2
const onConfigureFn = async () => {
  var config = {
    "expression": "dynamically built expression"
  };

  return JSON.stringify(config);
};

Validating with lambda functions

A function must be declared in the manifest and configured for a given validator. It is then invoked on every transition to which the validator has been added. When the function is invoked, an argument it passed to it with the following information about the transition:

1
2
{
  "issue": {
    "key": "issue key"
  },
  "transition": {
    "from": {
      "id": "status id"
    },
    "to": {
      "id": "status id"
    }
  }
}

The function returns an object containing two properties:

  • result - a Boolean value indicating whether the transition is allowed
  • errorMessage - the error message to show if the result is false. Otherwise, this property is ignored and doesn't have to be included

Example

To create a validator that allows transitions only for issues in the project with key PRO, declare it like this in the manifest:

1
2
jira:workflowValidator:
  - key: my-forge-workflow-validator
    name: Project is PRO validator
    description: This validator will allow the transition only if the project is PRO.
    function: validate
function:
  - key: validate
    handler: status.validate

To implement the actual logic in the src/status.js file:

1
2
export const validate = args => {
  const issueKey = args.issue.key;

  return {
    result: issueKey.startsWith('PRO'),
    errorMessage: 'Only PRO project can use this flow'
  };
}

In the jira:workflowValidator module, calls to an Atlassian API must be made as the app developer by using api.asApp() method.

Properties

PropertyTypeRequiredDescription
key

string

Yes

A key for the module, which other modules can refer to. Must be unique within the manifest.

Regex: ^[a-zA-Z0-9_-]+$

namestringYesThe name of the validator displayed in the workflow configuration.
descriptionstringYesThe description of the validator displayed when adding the validator to a transition.
functionstringRequired if using UI Kit 1.A reference to the function module that defines the module. Only used in UI Kit 1.
expressionstring The expression used to validate whether the transition should be allowed.

The expression can return either a boolean value or a string. Returning a string overrides the error message defined in the manifest – the returned string is shown to the user as the error message instead.

The expression is evaluated with the context variables.

This expression can be overridden using the configuration page. If you return configuration with the expression property, then that expression will be used to evaluate the validator instead of the expression defined here.

errorMessagestring | { expression: string } No The error message to show when the validation in Jira expression validator fails. If errorMessage is not provided, the default error message will be displayed.

This can be either a static message, or an object containing the expression property, with a Jira expression that returns the error message dynamically, based on the current transition or configuration.

create{ resource: string }No A reference to the static resources entry that allows you to configure the expression-based workflow validator on creation.

See Resources for more details.

edit{ resource: string }No A reference to the static resources entry that allows to edit the expression-based workflow validator.

See Resources for more details.

view{ resource: string }No A reference to the static resources entry that allows to view the summary of the expression-based validator configuration.

See Resources for more details.

resolver{ function: string } or
{ endpoint: string }
Yes

Set the function property if you are using a hosted function module for your resolver.

Set the endpoint property if you are using Forge remote (preview) to integrate with a remote back end.

Jira expressions events

Whenever an app-registered Forge workflow validator based on a Jira expression fails while executing, an avi:jira:failed:expression event is sent.

You can subscribe to this event in Forge apps. If you want to use this feature you have to include the OAuth scope manage:jira-configuration in the app manifest.

Rate this page: