This is Part 1 of 3. Part 2. Part 3.
Getting started with Forge to build Jira apps
Forge is the new app development platform for building Jira apps and Confluence apps.
I started to play with Forge back in 2020 as no developer I was working with had time available. This is how my first app development experience began. This is what I did in the beginning:
Read the getting started page: Getting Started
Installed: Forge CLI
Ran through the tutorials for Jira: Build a Jira hello world app
Checked the developer references: Manifest
Checked the example apps: Example apps
Back in 2020 Forge was new and pretty limited, this was before general availability (GA). Only part of the documentation available today existed. Important functionality was missing, but for what I wanted to do it was worth still worthwhile to give it a try and invest the time to learn something Atlassian seemed to want to develop further.
The tutorials were straightforward, everything went well. But an app example that displays “Hello World” on an issue panel in Jira isn’t that useful. You can’t do anything with it.
It is best to have an idea in mind of what you want to build. If you work with Atlassian tools and know them well, maybe even administrating them, you can probably think of use cases for apps that could enhance the functionality of Jira or Confluence. Something small is enough, the key is to work on something with real world utility.
From server app to Forge using UI Kit
For me I realized that there was no cloud version for Epic Clone (One of the Jira apps I designed and helped to build). It made for a perfect starting point to do something useful with Forge – migration of a server app to cloud.
The server version of Epic Clone can be used in epics to clone the entire epic and all the issues in an epic in one action. Even to a different project.
When clicking on more → Clone Epic Template in an epic, a servlet opens where users can configure what to clone, select the target project and edit certain fields.
UI Implementation of Jira apps
To use the servlet concept in cloud wasn’t possible and also Forge didn’t provide a module for it. Therefore, the decision was to use the issue action module and display the apps content in a modal dialog. This seemed to work as we knew it wouldn’t be possible to include all features of the server version from the beginning. The content displayed would also fit on a modal.
Starting with a blank modal I checked what is available in Forge UI Kit to implement and display different fields that would be needed for cloning. I became familiar with:
UI Kit Form
Text input possibilities
User picker field
I added them step by step to my modal to get to a first draft of the form I wanted to display to app users later to configure their template clone. The documentation is great for that purpose. I found the information I needed to set up the form (UI kit components).
Hitting UI Kit limitations
The arrangement of all the form fields was a challenge as it should look clear and compact and not confusing for the user. We decided to display the fields in a table so we could use several columns.
Here we came across the first limitation with UI kit while building Jira apps. It wasn’t possible to set vertical alignment in the table cells. I wanted to do that as not all fields with description displayed next to each other had the same height. It didn’t stop us from moving forward, but the arrangement wasn’t perfect. This is how it looked like:
The child issues to be cloned should be displayed on a second screen that should be visible when the user entered data on the first screen and then pushed the next button. We achieved that by using a useState hook and definition of a “form state” variable that was updated whenever a button on the modal has been clicked. The concept and usage of such hooks was completely new for me, and it took some time to get familiar with it.
On the second screen we faced another limitation of UI kit as it wasn’t possible to display the issue type icon of the child issues between checkbox and summary inline. It would have been great as it is clear from the icon what issue type it is. As it wasn’t possible to implement, we displayed the issue type as text. It looked like this:
After implementing all those fields and the different forms, I started to implement the actual cloning procedure. It wasn’t that difficult and could be implemented quicker than the UI part. However, when running the first tests also on larger issues, I came across several problems.
For some issues, the modal just didn’t load, and an error was logged that the payload for the request is too high. I had to clean up what was loaded and removed everything that isn’t absolutely necessary for cloning. As I didn’t consider before what was actually needed, just everything was loaded, so all projects with their configuration and available issue types, all types of Jira fields necessary for creation of the different issue types. For some of those, the information was loaded even twice, so it was clear where this error message was coming from.
Cloning failed especially for issues with many child issues as the invocation timeout was reached during cloning. The timeout was set to 10 seconds at the beginning which was challenging. The solution was to call requests concurrently and run them in parallel. A concept I had to get familiar with. It helped get the cloning done within the 10 seconds. Today, the invocation timeout has been increased to 25s which is an improvement and provides more time for the actions your app is doing.
Although those issues have been challenging and produced many errors during testing, they can also be seen as positive. It required me to make the app lean and fast, and to load only what is necessary. If you only have 10 seconds until an action needs to be completed, that also means that the user will have to only wait 10 seconds until the cloning (in this case) is completed. This is especially important as the user doesn’t get any feedback on the actual progress of the operation, like it is the case here with UI Kit. It is important that users don’t have to wait too long until the process is completed. Otherwise, they might think that something is wrong or that the app isn’t useful for what they want to achieve.
The above-mentioned improvements for execution time and payload were necessary as the app didn’t work otherwise. Other improvements have been made to make the apps code more structured and better to understand. At the beginning, we wrote the entire code in one file (index.jsx). In order to have a better structure, the apps code has then been separated into the following files:
index: modal dialog with form and different screens
components: single form fields (UI kit components)
fetchdata: rest APIs to get information like projects, issue data, fields, etc.
core: main cloning function, which is called from the index file
Features we didn’t have for server
There was one additional improvement we made, which even resulted in an additional feature compared to the server version of the app and which came due to a limitation in Forge in the beginning.
When we started developing, it wasn’t possible to add display conditions to the issue action module, so it was visible to everyone in every Jira issue (today it is possible). Due to that, we weren’t able to limit access to this cloning feature only to epic issue type like in the server version. We thought it might be a useful feature also for other issue types with child issues to clone them to different projects (not possible with the default clone functionality) and to decide which child issues to clone and which not. Due to the lack of display conditions, we even enhanced the functionality of the app. Sometimes limitations lead to improvements.
My Dev Day 2021 interview on migrating the app
If you are interested in more details on the migration of our server app to cloud using Forge UI kit to build Jira apps, check the following video from Dev Day 2021 with an interview where I shared my experiences. It includes a short app demo.