Workflow Post Functions
Post Functions execute after a workflow transition completes successfully. They perform automated actions — updating fields, creating sub-tasks, sending notifications, or any other operation. Since the transition has already happened, post function failures don't block the workflow.
How Post Functions Work
- User performs a transition (and it passes all conditions and validators)
- The issue moves to the new status
- ScriptForge executes the post function script
- Results are logged to execution history
If the post function throws an error, the issue remains in its new status — the transition is not rolled back.
Built-In Post Function Actions
ScriptForge provides 9 pre-built post function actions that require no scripting — just configuration:
1. Add to Sprint
Move the issue into a specific sprint when the transition occurs.
2. Remove from Sprint
Remove the issue from its current sprint.
3. Assign Issue
Set the assignee to a specific user or the current user.
4. Clone Issue
Create a copy of the issue in the same or different project.
5. Create Sub-Task
Automatically create a sub-task under the current issue with a configured summary and type.
6. Fast-Track Transition
Immediately transition the issue to another status after this transition completes. Useful for skipping intermediate statuses (e.g., "Resolved" → auto-transition to "Closed").
7. Modify Work Item
Update fields on the current issue — set priority, labels, assignee, custom fields, etc.
8. Run Script
Execute a custom JavaScript script (full HAPI access). This is the most flexible option.
9. Send Notification
Send an email or in-app notification to specified users or groups.
10. Transition Parent
When a sub-task is transitioned, automatically transition the parent issue to a specified status (e.g., when all sub-tasks are done, move the parent to "Done").
Custom Post Function Scripts
For logic beyond the built-in actions, use Run Script:
Example: Auto-create a review task when moving to "In Review"
const issue = await WorkItems.getByKey(context.issueKey);
await WorkItems.create(issue.projectKey, 'Task', b => {
b.setSummary(`Review: ${issue.summary}`);
b.setDescription(`Please review ${issue.key} before it can be released.`);
b.setAssignee(issue.getCustomFieldValue('Reviewer'));
});
Example: Update parent issue status when all sub-tasks are done
const issue = await WorkItems.getByKey(context.issueKey);
// This is a sub-task — check siblings
const parent = await WorkItems.getByKey(issue.parentKey);
const subtasks = await parent.getSubTaskObjects();
const allDone = subtasks.every(sub => sub.status === 'Done');
if (allDone) {
await parent.transition('Done');
await parent.addComment('All sub-tasks completed. Auto-transitioning to Done.');
}
Example: Copy field values to linked issues
const issue = await WorkItems.getByKey(context.issueKey);
const fixVersion = issue.getCustomFieldValue('Fix Version');
// Find all issues this one blocks, and set the same fix version
const blocked = WorkItems.search(
`issue in linkedIssues("${issue.key}", "blocks")`
);
await blocked.forEach(async (linked) => {
await linked.update(b => {
b.setCustomFieldValue('Fix Version', fixVersion);
});
});
Example: Add a time-stamped comment on transition
const issue = await WorkItems.getByKey(context.issueKey);
const user = await Users.getLoggedInUser();
const now = new Date().toISOString();
await issue.addComment(
`Transitioned to "${issue.status}" by ${user.displayName} at ${now}`
);
Configuration
- Edit the workflow transition
- Add a ScriptForge Post Function
- Choose a built-in action OR select "Run Script" for custom logic
- Configure parameters or write your script
- Save the workflow
Tips
- Post functions run after the transition — they cannot prevent it
- Use them for side effects: notifications, field updates, linked issue management
- You can chain multiple post functions on a single transition — they execute in order
- For critical actions, add logging (
console.log) so you can verify execution in history