Forge Developer

Beta

Forge Developer

Beta

Rate this page:

Modules

Within the manifest.yml file, the modules dictionary defines the functions that contain your app's logic, and the different extensions your app uses to integrate with Atlassian products.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
modules:
  macro:
    - key: hello-world-macro
      function: hello-world-macro-func
      title: Hello world macro!
      description: Inserts hello world!
  webtrigger:
    - key: webtrigger-sync
      function: my-forge-app-sync-func
    - key: my-webtrigger-async
      function: my-async-func
  trigger:
    - key: issue-creation-trigger
      events:
        - avi:activity:created:issue
        - avi:activity:updated:issue
      function: issue-trigger-func
  jira:workflowValidator:
    - key: my-forge-workflow-validator
      name: My example Forge workflow validator
      description: The description of my example Forge workflow validator
      function: my-forge-validator-function
  function:
    - key: my-forge-app-sync-func
      handler: index.runSync
    - key: my-async-func
      handler: index.runAsync
    - key: hello-world-macro-func
      handler: macro.run
    - key: issue-trigger-func
      handler: jira.issueCreationTrigger
    - key: my-forge-validator-function
      handler: index.runValidate

Function

The function module is where the app's behavior is defined. Other modules specify the function module that defines the actions to take.

Properties

PropertyTypeRequiredDescription
key

string

Yes

A key for the module, which other modules can refer to. Must be unique within the manifest and have a maximum of 23 characters.

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

handler

string

Yes

A pointer to the function responsible for handling invocations.

Expected format: file.function

For example, jira.issueCreationTrigger calls the issueCreationTrigger function defined in jira.js in the app's src directory.

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

Confluence content action

The confluence:contentAction module adds a menu item to the more actions (…) menu for pages and blogs. When the menu item is clicked, the module’s function renders a modal dialog. See the ContentAction component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the content action. This function renders the modal dialog for the component.
titlestringYesThe title of the content action, which is displayed as a menu item.
descriptionstringThe description of the content action.

Confluence content byline item

The confluence:contentBylineItem module adds an entry to the content byline section, which is the part of the content under the title that includes metadata about contributors and more. The title of the module renders as a list item. When a user clicks the content byline item, the Forge app renders in an inline dialog.

In the app, the ContentBylineItem should be used along with InlineDialog UI components.

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_-]+$

functionstringYesA reference to the function module that defines the content byline item.
titlestringYesThe title of the content byline item, which is displayed as a list item.
tooltipstringNoThe tooltip of the content byline item, which is displayed on hover.
descriptionstringNoThe description of the content byline item.

Confluence context menu

The confluence:contextMenu module displays an entry in the context menu when a user selects some text on a page or blog. All modules are grouped under the dropdown button in the menu. The title of the module renders as a menu item. When a user clicks the context menu item, the Forge app renders in an inline dialog.

The selected text is passed to the Forge app as a part of extensionContext, and is retrieved using the useProductContext hook. In the app, the ContextMenu should be used along with InlineDialog UI components. See the Dictionary app for an example.

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_-]+$

functionstringYesA reference to the function module that defines the context menu app.
titlestringYesThe title of the context menu app, displayed as a menu item.
descriptionstringThe description of the context menu app.

Confluence global settings

The confluence:globalSettings module adds a link to the left navigation menu in Confluence global settings. Clicking the link shows the module's content. You can use the storage API with the confluence:globalSettings to store Confluence global settings in your Forge app storage. See the GlobalSettings component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the global settings.
titlestringYesThe title of the global settings, which is displayed as the title of the link and header of the page.

Confluence homepage feed

The confluence:homepageFeed module displays content in the right panel of the Confluence Home page. Each module represents a separate section in the panel, and the title of each module is used as a section title. When a user clicks an app title, the corresponding section is expanded, and the Forge app is rendered as content.

In the app, the HomepageFeed component should be used as a top-level component.

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_-]+$

functionstringYesA reference to the function module that defines the homepage feed app.
titlestringYesThe title of the homepage feed app, displayed as a section title.
descriptionstringThe description of the homepage feed app.

Confluence space settings

The confluence:spaceSettings module adds a tab inside the integration settings of a Confluence space. Clicking the tab shows the module's content. See the SpaceSettings component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the space settings.
titlestringYesThe title of the space settings, which is displayed as the title of the tab.

Jira custom field

The jira:customField module creates a new custom field in Jira, which makes it easier for users to add information to issues, specific to their teams' needs.

Data storage

Custom field values are stored in Jira using issue properties.

You can use the issue property key defined in the manifest to set and update the values directly using the Issue properties REST API. By doing this, you have more control over the field values, and you can update multiple issues in one request. This is especially important for read-only fields, as it's the only way of updating them.

Otherwise, custom fields (those that aren't read-only) can also be modified using the UI or with the Edit issue REST API.

Read-only fields

Read-only fields are those that have the read-only set to true in their definition in the manifest. They aren't editable by users, neither through the UI nor the Edit issue REST API. The only way to set their value is by editing their corresponding issue property.

They are great for showing values derived from the issue state. While you can show anything using issue panels or issue glances, custom fields might be a better choice if you need all their benefits, like JQL search, configuration on screens, or being part of the issue import and export.

The value of such fields has to be calculated beforehand and set on the issue property. One pattern to achieve this would be to listen to product triggers for events that might affect the values and update the values accordingly whenever necessary.

Check out this example app to see a read-only field in action: Attachment Count Custom Field.

Data types

Each field has to be based on a selected data type. The data type controls what kind of values are stored in the issue property, the field's behavior in JQL, and the default rendering behavior.

Available data types are:

  • string - values are stored as plain strings. JQL offers autocomplete and exact comparison.
  • number - values are stored as numbers (double-precision 64-bit IEEE 754 floating points).
  • user - values are stored as strings that represent Atlassian account IDs. The field behaves like any other user field in Jira when you interact with it in the UI or the REST API.
  • group - values are stored as strings that represent Atlassian group names. The field behaves like any other group field in Jira when you interact with it in the UI or the REST API.
Collection types

In addition to a single value, Forge custom fields can store collections of values. This is done by declaring the collection property, which specifies the collection type. For example, to create a field that stores a list of strings, declare it as:

1
2
type: string
collection: list

The field behaves according to its base type, but the values are stored and returned as a list.

The following types can be part of a collection:

  • string
  • group
  • user

Note, using any other type in combination with collection:list prevents the field from appearing in Jira, even if the app is installed successfully.

Field lifecycle

A locked instance of each field defined in the manifest is created upon deployment. Whenever a field is added to the app, or an existing field is modified or removed, you need to redeploy the app to make these changes appear in Jira.

It may take some time for the custom field to be created in Jira. Try visiting or refreshing the custom fields page after a few minutes if your field is not visible.

The created field has its key set to {app-id-uuid}__{environment}__{extension-key}, where:

  • {app-id-uuid} is the tail part of your app ID defined in the manifest (for example: ari:cloud:ecosystem::app/{app-id-uuid}).
  • {environment} is the environment in which the app is installed.
  • {extension_key} is the key of the custom field extension defined in the manifest.

This key can be used to uniquely identify the field in Jira REST APIs.

The field disappears when the app is uninstalled or if the field is removed from the manifest. If the app is reinstalled, or the field is restored, the field will reappear with all the previous data intact.

Rendering

Forge apps can optionally provide their own rendering of the field by specifying the function property.

The rendering function must return a CustomField Forge UI component. Inside the function, you can obtain the current value of the field from the useProductContext hook, like this:

1
const { platformContext: { fieldValue } } = useProductContext();

Default rendering, appropriate to the field's data type, is used if the function is not provided.

Check out this example app to see custom rendering in action: Issue Progress Custom Field.

Editing

Forge apps can optionally provide their own editing experience of the field by specifying the edit property.

The edit function must return a CustomFieldEdit Forge UI component. Inside the function, you can obtain the current value of the field from the useProductContext hook, like this:

1
const { platformContext: { fieldValue } } = useProductContext();

Default editing, appropriate to the field's data type, is used if the edit function is not provided.

Check out this example app to see custom editing in action: Risk assessment custom field.

Properties

PropertyTypeRequiredDescription
key

string

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

This key becomes a part of the custom field key as described in the Field lifecycle section.

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

namestringYesThe name of the field.
descriptionstringYesThe description of the field.
dataobjectYesDetails about the data stored in the field, including, the type of data, how to store it, and how to validate it.
data:
 type
stringYesThe type of the field data. Available values are:
  • string
  • number
  • user
  • group
data:
 collection
none|list (default: none)No The kind of collection that the field values should be stored in. See collection types for more details.
data:
 storage
objectYes Details about where to store the data of the field. The data can only be stored in an issue property.
data:
 storage:
  issueProperty:
   key
stringYesThe key of the issue property that stores the value of the field. Make sure this key is unique to avoid potential clashes with properties from other apps. For example, you can use the name of your app or your company as a prefix for this key.
data:
 storage:
  issueProperty:
   path
stringNo

Only allowed if readOnly is true.
The path within the JSON object that’s stored in the issue property. The value extracted from the JSON object using the given path will be used as the value of the field.

For example, you may store the following JSON object in an issue property under key issueStats:
1
2
3
4
5
6
{
   "attachments": {
     "count": 4,
     "extensions": ["txt", "pdf"]
   }
}
For a read-only field that displays the attachment count (4 in this case), part of the declaration related to where the value is stored would look like this:
1
2
3
issueProperty:
    key: issueStats
    path: attachments.count
This only applies to read-only fields. Editable fields must store the field value in the property directly.
data:
 validation:
  expression
stringA Jira expression that validates the field's value before it's set. The expression must return a boolean value. Note that the value is validated only when edited through the UI or issue APIs. Setting the issue property directly won't trigger the validation.

The expression is evaluated with the following context variables:

  • user (User): The current user.
  • issue (Issue): The edited issue.
  • project (Project): The project to which the issue belongs.
  • value: The value that’s being set on the field. The type of this variable depends on the data type of the field and can be one of the following:
    • String (if the data type is string)
    • Number (if the data type is number)
    • User (if the data type is user)

data:
 validation:
  message
stringThe error message to show when the validation fails.
readOnlystringYesWhether or not the field is read-only. Read-only fields can't be edited by users.
functionstringA reference to the function module that provides the field rendering. This function must return the CustomField component.
edit:
 function
string A reference to the function module that provides the field editing experience.

Example

The following example declares a number-type field whose values must be numbers between 0 and 100:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
jira:customField:
  - key: issue-progress
    name: Issue progress
    description: The progress of the issue, on a scale from 0 to 100.
    data:
      type: number
      storage:
        issueProperty:
          key: issueProgressForgeField
      validation:
        expression: value == null || (value >= 0 && value <= 100)
        message: The value must be a number between 0 and 100.
    readOnly: false
    function: renderIssueProgress
    edit: 
      function: editIssueProgress

Jira issue action

The jira:issueAction module adds a menu item to the more actions (…) menu on the issue view. When the menu item is clicked, the module’s function renders a modal dialog.

This module can be used in Jira Core, Jira Software, and Jira Service Desk. It works in the new issue view but not the old issue view. See the IssueAction component documentation for an example.

Properties

PropertyTypeRequiredDescription
key

string

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

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

functionstringYesA reference to the function module that defines the issue action. This function must return the IssueAction component, which renders the modal dialog for its content.
titlestringYesThe title of the issue action, which is displayed as a menu item.

Jira issue activity

The jira:issueActivity module adds a item to the Activity panel of Jira issues.

This module can be used in Jira Core, Jira Software, and Jira Service Desk. It works in the new issue view but not the old issue view. See the IssueActivity component documentation for an example.

Properties

PropertyTypeRequiredDescription
key

string

Pattern: ^[a-zA-Z0-9_\\-\\.]+$\

YesA key for the module, which other modules can refer to. Must be unique within the manifest.
functionstringYesA reference to the function module that defines the issue activity. This function must return the IssueActivity component.
titlestringYesThe title of the issue activity, which is displayed as a tab item.

Jira issue glance

The jira:issueGlance module adds an issue glance to Jira, which is content that is shown/hidden in an issue by clicking a button. The button for the issue glance is placed alongside fields such as Assignee and Labels. Clicking the button opens the content provided by the Forge app, so that it fills the right sidebar.

This module can be used in Jira Core, Jira Software, and Jira Service Desk. It works in the new issue view but not the old issue view. See the IssueGlance component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the issue glance. This function must return the IssueGlance component.
titlestringYesThe title of the issue glance, which is displayed above its label.
labelstringYesThe text shown on the button for the issue glance.
statusobjectThe badge or lozenge shown next to the label. If status is not specified, then no badge or lozenge is shown. See status properties.

Status properties

PropertyTypeRequiredDescription
type'badge' | 'lozenge'YesThe UI element used to display the status.
valueobjectYes

This property is an object representing the status value. See status value properties.

Status value properties

PropertyTypeRequiredDescription
labelstringYesThe text to display in the status.

If type is 'badge', this property is a number specified as a string (for example, '3').

Note, this value is static and can only be changed by updating the manifest.
type'default' | 'inprogress' | 'moved' | 'new' | 'removed' | 'success'

If type is 'lozenge', this value controls the appearance of the status.

Note, this value is static and can only be changed by updating the manifest.

Jira issue panel

The jira:issuePanel module adds an issue panel to Jira, which is content that is shown above the Activity panel on a Jira issue.

This module can be used in Jira Core, Jira Software, and Jira Service Desk. It works in the new issue view but not the old issue view. See the IssuePanel component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the issue panel. This function must return the IssuePanel component.
titlestringYesThe title of the issue panel, which is displayed above the panel.
iconstringThe URL of the icon that will be displayed as a button. When the button is clicked, an issue panel displays.

Jira workflow validator

The jira:workflowValidator module creates a workflow validator that can be configured on workflow transitions in classic projects.

Validating with lambda functions

The function configured for the validator is invoked on every transition that the validator has been added to. When the function is invoked, it is passed an argument that contains information about the transition, that is:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "issue": {
    "key": "issue key"
  },
  "transition": {
    "from": {
      "id": "status id"
    },
    "to": {
      "id": "status id"
    }
  }
}

The validator returns an object containing two properties:

  • result - a boolean value indicating whether or not 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.

For example:

1
2
3
4
{
  "result": false,
  "errorMessage": "An error message explaining why the validator rejected the transition"
}

Validating with Jira expressions

It’s possible to provide a Jira expression instead of a function if you’re only checking the state of the current issue.

For example, a validator that checks if the issue is assigned would look like this:

1
2
3
4
5
6
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."

The issue validated by the 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.

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, shown when adding the validator to a transition.
functionstringThe validator requires either the function or the expression in your Forge app. Only one of the two properties must be present in your Forge app.A reference to the function module that evaluates the validator.
expressionstringThe expression used to validate whether or not the transition should be allowed.

The expression is evaluated with the following context variables:
  • user (User): The current user.
  • issue (Issue): The transitioned issue. Includes changes made on the transition screen.
  • project (Project): The project to which the issue belongs.
errorMessagestringThe error message to show when the validation fails. If `errorMessage` is not provided, the default error message will be displayed.

Macro

The macro module inserts dynamic content into the user interface via an editor. Currently, the macro module works in Confluence, where the macro is added to a page via the quick insert menu of the editor. The macro module is implemented by a Forge function. See the Macro component documentation for an example.

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_-]+$

functionstringYesA reference to the function module that defines the macro.
titlestringYesThe title of the macro. In Confluence, this is displayed in the editor.
descriptionstringThe description of the macro. In Confluence, this is displayed in the editor.
config{ function: string }Contains a function property, which references the function module that defines the macro configuration.

Scheduled trigger

The scheduledTrigger module repeatedly invokes a function on a scheduled interval. Each trigger is scheduled to start shortly after it is created, which is at 10 minutes after app installation, and at one minute after app deployment. It then runs hourly after that.

On each app deployment or app installation, all existing scheduled triggers are removed. After that, any scheduled triggers declared in the manifest are recreated.

Scheduled triggers run without a user context, which means the principal field of the context argument doesn't represent a user. If a function invoked from a scheduled trigger returns a value, it is ignored. If the function throws an error, nothing will happen, and the function invocation will not be retried. The function will be invoked the next time the schedule is due.

Apps can declare up to three scheduled triggers in their manifest.

See Extending your app with a scheduled trigger for step-by-step instructions on how to use this module type.

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_-]+$

functionstringYesA reference to the function module that defines the behavior.
interval'hour'YesThe interval at which to invoke the function.

Trigger

The trigger module invokes a function when a product event is fired. For example, as the result of an issue being created in Jira.

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_-]+$

functionstringYesA reference to the function module that defines the behavior.
eventsArray<string>YesA list of product events that trigger the function.

Web trigger

The webtrigger module invokes a function as the result of an HTTP request. To obtain a URL to call a web trigger, define a webtrigger module then run forge webtrigger in the Forge CLI.

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_-]+$

functionstringYesA reference to the function module that defines the behavior.

Example web trigger URL

1
https://406d303d-0393-4ec4-ad7c-1435be94583a.hello.atlassian-dev.net/x0/eyJjdHgiOiJhcmk6Y2xvdWQ6Y29uZmx1ZW5jZTo6c2l0ZS9EVU1NWS0xNThjODIwNC1mZjNiLTQ3YzItYWRiYi1hMDkwNmNjYzcyMmIiLCJleHQiOiJhcmk6Y2xvdWQ6ZWNvc3lzdGVtOjpleHRlbnNpb24vNDA2ZDMwM2QtMDM5My00ZWM0LWFkN2MtMTQzNWJlOTQ1ODNhL2ZjMTI1ZTY3LTY0MTItNGVjNi04OTRhLWU5OTVjZjcyZDcyYS9zdGF0aWMvd2VidHJpZ2dlci1zeW5jIn0

Rate this page: