Runtime

Migrating from the legacy runtime

Apps created and last deployed before April 17, 2024 may still be running on a legacy version of the Forge runtime. We strongly recommend that you migrate your app to the latest version of the Forge runtime.

For information about legacy runtime concepts like the sandbox environment and snapshot context, see Legacy runtime reference.

Breaking changes

To minimise the effort of adopting the latest runtime version, we worked on ensuring backwards compatibility with the legacy runtime. However, you may need to refactor your app to address some breaking changes between runtime versions.

Node.js LTS version

The legacy runtime runs on an environment that mimics Node.js 14. The latest runtime uses Node.js 18, and we intend to support newer versions that achieve "long-term support" (LTS) status. If your app is affected by any breaking changes between both versions, you’ll need to address these.

API Redirects to external domains

App requests to Atlassian product APIs that return HTTP redirects to external domains will now be considered egress. As such, those domains must be declared in the application manifest. This will require users to re-consent to using the app.

See Runtime egress permissions for detailed instructions.

We are currently assessing which domains should be exempt from this egress declaration. For example, api.media.atlassian.com will likely be exempted in the future, as it is an Atlassian-owned domain (and as such, should not require disclosure to customers if the app communicates with it).

New invocation semantics

The legacy runtime used a v8 JavaScript isolate sandbox. This sandbox is bootstrapped for every invocation, providing a clean context for each invocation of your app.

The latest Forge runtime handles isolation (and, by extension, security) at the VM layer, making the sandbox unnecessary. As such, we removed this sandbox; this, incidentally, moderately improves Forge’s invocation performance.

Expanded developer responsibilities

Without the v8 JavaScript isolate sandbox, the current runtime no longer guarantees that local state in your Forge functions is cleared for each invocation. This introduces new responsibilities for you as a developer to ensure that customer data does not persist across app invocations. These responsibilities are laid out in our shared responsibility model.

To comply with these new developer responsibilities, review your app code to ensure that:

  • Your app must not persist customer data or sensitive content in global state, in memory or on disk, between subsequent invocations.
  • Your app must not copy customer data or sensitive content from one installation to another, unless it has been explicitly permitted by the customer.

Snapshot removal

The snapshotting feature is no longer supported in the new native Node.js runtime, as it is no longer required. This feature was enabled by default in the legacy runtime. If your app uses the snapshots flag in your manifest.yml file, you'll need to remove it.

When snapshotting is enabled, the current runtime invokes any globally-scoped JavaScript code at deployment time rather than invocation time.

With the new native Node.js runtime, your app may be re-initialised if it wasn’t used for a long time, or if it needs to execute multiple times simultaneously. If your app requires globally-scoped code to be executed exactly once per deployment, this change in invocation semantics may require changes to your app.

Delayed code execution

The latest Forge runtime might keep executing the code after the function returns. For example:

1
2
resolver.define("example", () => {
  setTimeout(() => {
    fetch("...");
  }, 5000);
});

In this example, timers and other asynchronous code may continue executing even after the Forge function returns a response.

Default Content-Type header

When making API calls through requestJira, requestConfluence and requestBitbucket, outbound HTTP requests will assume a Content-type: application/json if a content type isn’t specified. However, this default will not be applied to requests to external domains using the fetch function or other HTTP clients.

HTTPS only

All external connections must be done through HTTPS; plain HTTP or TCP connections are not allowed. In addition, these connections will be implemented over a custom proxy which will only allow the following https.request options (or equivalents from third-party packages):

  • auth
  • headers
  • host
  • method
  • port
    • Only 80, 8080, 443, 8443, 8444, 7990, 8090, 8085 and 8060.
  • path

Sending a request with a body still works, as long as you specify the correct Content-Type: header (for example, Content-Type: application/json for a JSON body).

Set runtime version

You can use the app.runtime.name setting of the manifest file to set which version of the Forge runtime your app should be deployed.

To keep your app on the Forge runtime legacy version while addressing any breaking changes, set app.runtime.name to sandbox then re-deploy your app:

1
2
app:
  id: "ari:cloud:ecosystem::app/406d303d-0393-4ec4-ad7c-1435be94583a"
  runtime:
    name: sandbox

Once you’re ready to migrate your app to the latest runtime version, set name to nodejs18.x then re-deploy your app:

1
2
app:
  id: "ari:cloud:ecosystem::app/406d303d-0393-4ec4-ad7c-1435be94583a"
  runtime:
    name: nodejs18.x

Rate this page: