Migrate to Forge
Overviewβ
Script Master is built on top of the Forge framework. All modules in the app are fully compatible with standard Forge modules, as Script Master essentially acts as a smart wrapper around the Forge SDK.
There are two main types of modules to be aware of:
- Front-end modules β Wrap Forge Custom UI components to handle user interface elements.
- Back-end modules β Manage server-side logic and data processing.
When you write a custom script, Script Master automatically wraps it with the necessary imports for global objects and includes a set of predefined helper functions - so you can focus on writing the core logic.
import api, { authorize, fetch, route } from '@forge/api';
// your script will be executed here
Script Master for Jira β Forge Modules Parityβ
The table below maps Script Master modules to their equivalent Forge modules. This demonstrates how closely Script Master aligns with Forge's native module architecture:
Migrating a Fragment Script to a Pure Forge Appβ
Since Script Master acts as a thin layer over Forge, migrating to a standalone Forge app is not only possible - it's often quite straightforward.
You can continue developing your solution independently without relying on Script Master.
Letβs walk through an example of migrating an Issue Panel fragment to a pure Forge app.
Example: Issue Panel Fragmentβ
Imagine you have a fragment script that retrieves the history of the current issue and extracts the names of all users who've updated it - essentially identifying the issue's contributors.
Here's what such a fragment might look like:
<!-- This example displays issue contributors, listing all users who have edited this issue -->
<!-- REST API in this example https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-changelog-get -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@atlaskit/css-reset" /> <!-- Reset fonts, padding, margins to default in Atlaskit -->
<div>
Contributors: <div id='contributors'>Loading...</div>
</div>
<script type="module">
// Dark theme support
document.querySelector(":root").setAttribute("data-color-mode", theme.colorMode);
document.querySelector(":root").setAttribute("data-theme", `${theme.colorMode}:${theme.colorMode}`);
document.querySelector(":root").insertAdjacentHTML("afterbegin", `<link rel="stylesheet" href="https://forge.cdn.prod.atlassian-dev.net/atlaskit-tokens_${theme.colorMode}.css" />`);
const context = await view.getContext();
const issueKey = context.extension.issue.key;
const response = await requestJira(`/rest/api/3/issue/${issueKey}/changelog`, {
headers: {
'Accept': 'application/json'
}
});
const responseData = await response.json();
const allContributors = responseData.values.map(obj => obj.author.displayName);
const uniqueContributors = new Set(allContributors);
const uniqueContributorsList = Array.from(uniqueContributors).join(', ');
console.error('uniqueContributorsList', uniqueContributorsList);
document.getElementById('contributors').textContent = uniqueContributorsList;
// Resize window
setHeight(document.querySelector(':root').scrollHeight + 'px');
</script>
So it's a mix of HTML for layout and JavaScript for business logic.
Create a Forge Appβ
Start by creating a new Forge app using the forge create command from the Forge CLI.
When prompted, choose the following options:
- Product: Jira
- UI type: Custom UI
- Template:
jira-issue-panel
Then follow the setup steps outlined in:
By the end, you should have a working Forge app with a βHello, Worldβ Issue Panel installed on your Jira Cloud instance.
Migrate the Functionalityβ
To migrate your Script Master fragment script into the newly created Forge app, follow these three steps:
-
Add required imports
Script Master automatically injects global objects into scripts. In Forge, you need to import them manuallyβfor example,import { requestJira, view } from '@forge/bridge';. -
Wrap your business logic
Use theuseEffect(() => { ... }, [])hook to run your logic when the component loads. For example:useEffect(() => { /* your business logic here */ }, []);. -
Add static HTML in the return block
Place your layout inside thereturn (<></>)block. A basic example:return (<div>Hello, contributors!</div>);.
Note:
Itβs a good idea to refactor your logic into small, standalone functions. If your code is already modular, you can usually reuse it with minimal changes.
Once complete, your Forge app will mirror the functionality of your Script Master fragmentβmost static HTML and logic can be transferred directly.
import { requestJira, view } from '@forge/bridge';
import { useEffect } from 'react';
function App() {
useEffect(() => {
(async () => {
const context = await view.getContext();
const issueKey = context.extension.issue.key;
const response = await requestJira(`/rest/api/3/issue/${issueKey}/changelog`, {
headers: {
'Accept': 'application/json'
}
});
const responseData = await response.json();
const allContributors = responseData.values.map(obj => obj.author.displayName);
const uniqueContributors = new Set(allContributors);
const uniqueContributorsList = Array.from(uniqueContributors).join(', ');
document.getElementById('contributors').textContent = uniqueContributorsList;
})();
}, []);
return (
<div>
Contributors: <div id='contributors'>Loading...</div>
</div>
);
}
export default App;
Test Your Appβ
Once your script has been migrated and your app is ready, follow the standard steps to test a Forge app:
-
Build (or auto-build) the Custom UI project inside its folder.
For example, runyarn buildor useyarn devfor live reloads during development. -
Deploy the app to the Forge infrastructure using
forge deploy. -
Install the app to your Jira Cloud instance with
forge install.
After completing these steps, your Forge app should be active on your Jira site, and the Issue Panel will display the list of contributors as expected.
Conclusionβ
Since Script Master uses the same Forge APIs under the hood and simply wraps modules to improve accessibility and usability, migrating is straightforward.
You can start building new customizations for Jira and Confluence Cloud within minutesβwithout worrying about boilerplate or setup.
Of course, this simplicity comes with some trade-offs in flexibility and control, which Forge apps can offer in full.