Polarion ALM Workflow Scripting GraalJS · · 9 min read

Polarion Workflow Scripts, Save Hooks and the Move to GraalJS

Workflow conditions, workflow functions and save hooks each run at a different moment and suit different rules. This guide covers when to use each, where the scripts live, a worked example, what changes in JavaScript on GraalJS, and how to keep scripts under control in a validated system.

Conditions, Functions and Save Hooks

Polarion workflows move work items and documents between statuses through actions. Scripts attach to that machinery at different points, and choosing the right point decides whether a rule is enforced reliably, explained clearly to the user, and easy to validate.

BEFORE AN ACTION

Workflow Condition

Decides whether an action is available. It should read data and return a result without changing anything. Use it for gates such as "a test case must verify at least one requirement before approval".

Read-only gate
DURING AN ACTION

Workflow Function

Runs when a user performs a specific action. Use it to set or clear fields, create follow-up items, or update linked items as a consequence of that transition.

Transition side effect
ON EVERY SAVE

Save Hook

Runs whenever an object is saved, whatever the user changed and whether or not a workflow action was involved. Use it for rules that must hold at all times, such as field consistency checks.

Always-on rule
ON A SCHEDULE

Scheduled Script

Runs on a timetable with no user action involved. Use it for housekeeping and periodic checks that would be too slow or too broad to run inside a user's save.

Background job

When to Use Each

Start from the rule and ask when it has to hold.

  • The rule applies to one transition. Use a condition when the action should be unavailable until something is true, because the user sees the action disabled with an explanation before trying it. Use a function when the action should cause a change.
  • The rule applies to every save. Use a save hook. A condition on the approval action does nothing to stop someone editing a field after approval; a save hook runs on that later edit too.
  • The rule is expensive or touches many items. Move it out of the user's save and into a scheduled script or a report, so a single save never waits on a query across thousands of items.

Polarion's own workflow configuration already offers built-in conditions and functions, such as required fields and field assignments. Check those first; a configured rule is easier to read, review and validate than a script that does the same thing.

Where Scripts Live and How They Are Referenced

File-based workflow scripts

The long-standing mechanism uses the ScriptCondition and ScriptFunction entries in a workflow action's configuration. Each takes an engine parameter naming the scripting engine and a script parameter naming the script file. The file itself sits in the scripts folder of the Polarion installation on the server file system, for example /opt/polarion/scripts on a default Linux installation or C:\Polarion\scripts on Windows. JavaScript and Groovy are supported.

Polarion passes the call context and the configured arguments into the script as the variables workflowContext and arguments. workflowContext.getTarget() returns the object the workflow is running on. For a condition, the value of the script's last expression is the result.

Scripts managed in Polarion Administration

Polarion 2410 added a scripting framework in Polarion Administration for creating save hook and workflow scripts, with a Script Monitor for following their execution. Polarion 2506 added Scheduled Scripts and allowed save hooks to be configured for specific document and work item types. Before this framework, save hooks typically came from extensions or custom Java plugins. Scripts in the Administration framework receive their target and parameters through a different set of objects than file-based scripts, so read the Scripting SDK documentation for your release before porting a script from one model to the other.

A Condition and a Function in JavaScript

Both examples use the file-based model described above.

Condition: require a link before approval

Attach this as a ScriptCondition on the approval action of a test case workflow. The action stays unavailable until the test case has at least one outgoing verifies link.

// ScriptCondition: allow the action only if the item has at least one
// outgoing link with the role "verifies". Adjust the role ID to your project.
var wi = workflowContext.getTarget();
var requiredRole = "verifies";
var found = false;

var it = wi.getLinkedWorkItemsStructsDirect().iterator();
while (it.hasNext()) {
  var role = it.next().getLinkRole();
  if (role != null && String(role.getId()) === requiredRole) {
    found = true;
  }
}

// The last expression is the result. true makes the action available;
// a non-empty string keeps it unavailable and is shown to the user.
found ? true : "Link this test case to a requirement with 'verifies' first.";

Returning a message keeps the rule self-explanatory: the user sees why the action is blocked without opening a support ticket.

Function: clear a field when an item is reopened

Attach this as a ScriptFunction on a reopen action. It clears a custom field that recorded the build in which the item was verified, because that verification no longer applies.

// ScriptFunction on the "reopen" action. The field ID is an example.
var wi = workflowContext.getTarget();
wi.setCustomField("verifiedInBuild", null);

// Do not call wi.save() here. Polarion saves the target object itself
// after the workflow action completes.

The comment about saving matters. Calling save() on the workflow target inside a function interferes with the save Polarion is already performing. If a function changes a different object, such as a linked work item, that object does need its own save.

Version note. Polarion's scripting APIs, injected variables and engine behaviour vary between releases. Check each call against the SDK documentation for your version, and test every script on a non-production server before deploying it.

From Nashorn to GraalJS

Nashorn, the JavaScript engine that shipped with Java 8, was deprecated in JDK 11 and removed from the JDK in Java 15. Current Polarion releases run JavaScript on GraalJS, the GraalVM JavaScript engine. Most plain JavaScript runs unchanged; the differences sit in how scripts reach Java classes and handle Java objects, which is exactly what Polarion scripts do most.

Java classes need Java.type

Nashorn and Rhino let scripts reach classes through package names such as java.util.ArrayList. GraalJS expects Java.type() by default. Helpers such as JavaImporter, and Rhino-style importClass or importPackage, depend on compatibility modes; replace them with Java.type() calls.

// Nashorn style: fails on GraalJS without a compatibility mode
var legacyList = new java.util.ArrayList();

// GraalJS style
var ArrayList = Java.type("java.util.ArrayList");
var ids = new ArrayList();
ids.add("PRJ-101");
ids.add("PRJ-102");

// Walk Java collections with their own methods
for (var i = 0; i < ids.size(); i++) {
  var id = String(ids.get(i));
}

// Copy to a JavaScript array when you need array functions
var jsIds = Java.from(ids);
var summary = jsIds.join(", ");

Collections, arrays and strings

  • Treat Java collections as Java objects. Use size(), get(i) and iterator() on lists returned by Polarion. Avoid relying on JavaScript array behaviour such as .length, .map() or .forEach() on them; copy with Java.from() when you need those.
  • Convert arrays going into Java. When a Java method expects a typed array, convert explicitly with Java.to(jsArray, "java.lang.String[]").
  • Be explicit with strings. Wrap values from Java in String() before comparing with ===, as the condition example does. It costs nothing and removes a class of surprises.
  • Remove Nashorn-only constructs. Nashorn accepted non-standard syntax such as for each loops and provided ScriptObjectMirror. Rewrite these in standard JavaScript.

GraalJS is also stricter by default about what scripts may access, and its Nashorn compatibility mode, where available, has security trade-offs. Fix scripts to work in the default mode.

Testing and Logging Workflow Scripts

  • Test on a copy. Use a non-production server with a copy of the project configuration and representative data. Workflow scripts depend on field IDs, link roles and statuses, and those differ between projects.
  • Test both outcomes. For a condition, test the case where the action should be available and the case where it should not, and check the message the user sees. For a function, check the fields after the transition and the item history.
  • Test with real roles. Run transitions as users with the permissions your teams actually have. A script that works for an administrator can fail for a project member who cannot read a linked item.
  • Log deliberately. In the Administration framework, use the Script Monitor to follow execution. For file-based scripts, write diagnostic output to a log your administrators can read, keep messages short, and never log credentials or the contents of controlled records.
  • Keep scripts small. A save hook runs inside every save. Keep it fast, avoid broad queries, and move heavy work to scheduled scripts.
  • Retest on upgrade. Treat each Polarion upgrade as a change to every script's runtime. Rerun the script test set on the new version before upgrading production.

Governing Scripts in Validated Environments

In a regulated deployment, a workflow script that gates an approval or sets a field on a controlled record is part of the validated system. It needs the same discipline as any other configuration item.

  • Version control. The scripts folder lives on the server file system, outside the project repository. Keep every script in your own version control, deploy from tagged versions, and make the server copy match a known revision.
  • Change control. Raise a change request for each script change, record the reason and the impact assessment, and approve before deployment. Include the workflow configuration change that references the script in the same change.
  • Requirements and traceability. Write down what each script must do as a requirement, link the tests to it, and keep the evidence. Polarion can hold those requirements and tests itself.
  • Risk-based regression testing. Scripts that gate approvals, electronic signatures or release decisions deserve scripted regression tests. Lower-risk scripts can be covered with lighter testing; our article on computer software assurance for Polarion covers how to make that call.
  • Access. Restrict who can edit scripts and workflow configuration, and review that list periodically.

Scripts, Hooks and Java Extensions

Some rules outgrow scripts: they need structured configuration, Java-level performance, or a single tested component shared across many projects. Our Java 21 Save Hook is being built for that case, with declarative validation rules, field population on save and workflow enforcement on a Java 21 runtime.

For conditions, functions, save hooks and GraalJS migrations of existing scripts, our Polarion scripting service delivers versioned, tested and documented scripts, with the records a validated environment needs.

CS
Corbinsoft Editorial Polarion ALM Specialists · Certified Siemens Digital Industries Software Partner

Corbinsoft is a Polarion-only practice based in Austin, Texas. We write Velocity, GraalJS JavaScript, Groovy and Java customisations for teams working in regulated industries, and we implement and validate Polarion for medical device, automotive, aerospace and energy organisations.

Migrating or auditing your workflow scripts?

Our Polarion developers review, port and test conditions, functions and save hooks, with the documentation your quality system expects.