Workflow Post Function#

Execute custom JavaScript code when work items transition through workflow states in Jira.


Overview#

Workflow Post Functions allow you to run custom JavaScript code after a workflow transition is completed. This is useful for automating actions that should happen when a work item moves from one status to another.

For more information about Jira workflows, see:


Prerequisites#

Before creating a Workflow Post Function, ensure you have:

  1. Jira Administrator permissions - Required to edit workflows
  2. Automan installed - The app must be installed on your Jira instance

Adding a Post Function to a Workflow#

Step 1: Navigate to Workflow Settings#

  1. Go to Project Settings > Workflows (or Jira Settings > Work Items > Workflows for global access)
  2. Edit workflow

Step 2: Select a Transition#

  1. In the workflow editor, click on the transition where you want to add the post function
  2. Select Perform actions from the transition properties panel

Step 3: Add Automan Post Function#

  1. Click Add post function
  2. Select Custom JS Post Function from the list
  3. Click Select

Step 4: Write Your Script#

The Automan code editor will open where you can write your JavaScript code:

  1. Write your JavaScript code in the editor
  2. Click Add or Update to save the post function
  3. Important: Click Publish Draft to publish your workflow changes

Context Variables#

When your post function executes, you have access to the following context through the event object:

event Object Structure#

{
  // Work item being transitioned
  issue: {
    id: "10001",
    key: "PROJ-123"
  },

  // Transition details
  transition: {
    id: "21",
    name: "In Progress",
    from: { id: "1", name: "To Do" },
    to: { id: "2", name: "In Progress" }
  },

  // Post function configuration
  postFunction: {
    id: "abc-123-def"
  },

  // User who triggered the transition
  atlassianId: "5a0000000000000000000001"
}

Examples#

Example 1: Add a Comment on Transition#

const issueKey = event.issue.key;
const transitionName = event.transition.name;

// Create a comment noting the transition
await requestJira(
  route`/rest/api/3/issue/${issueKey}/comment`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      body: {
        type: "doc",
        version: 1,
        content: [{
          type: "paragraph",
          content: [{
            type: "text",
            text: `Work item transitioned via "${transitionName}"`
          }]
        }]
      }
    })
  }
);

console.log("Comment added to", issueKey);

Example 2: Update a Custom Field#

const issueKey = event.issue.key;

// Update a custom field (replace customfield_10001 with your field ID)
await requestJira(
  route`/rest/api/3/issue/${issueKey}`,
  {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      fields: {
        customfield_10001: new Date().toISOString()
      }
    })
  }
);

console.log("Custom field updated on", issueKey);

Example 3: Create a Subtask on Transition#

const issueKey = event.issue.key;
const projectKey = event.issue.fields.project.key;

// Create a subtask
await requestJira(
  route`/rest/api/3/issue`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      fields: {
        project: { key: projectKey },
        parent: { key: issueKey },
        summary: "Review task created from transition",
        issuetype: { name: "Subtask" }
      }
    })
  }
);

console.log("Subtask created for", issueKey);

Example 4: Update Assignee#

const issueKey = event.issue.key;
const toStatus = event.transition.to.name;

// If moving to "In Review", assign to a specific user
if (toStatus === "In Review") {
  const reviewerAccountId = process.env.REVIEWER_ACCOUNT_ID;

  await requestJira(
    route`/rest/api/3/issue/${issueKey}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: {
        fields: {
          assignee: {
            "accountId": reviewerAccountId
          }
        }
      }
    }
  );

  console.log("Assigned work item to reviewer");
}

Best Practices#

  1. Keep scripts focused - Each post function should do one thing well
  2. Log meaningful information - Use console.log() to help with debugging
  3. Use environment variables - Store API keys and configuration in environment variables
  4. Test before deploying - Test your scripts in the Definitions tab before using in production

Execution Time#

Post functions have a limited execution time. Long-running operations may time out. For complex operations, consider breaking the work into smaller pieces.

API Rate Limits#

Be mindful of Jira API rate limits when making multiple API calls within a single post function.


Troubleshooting#

Script Not Executing#

  1. Verify the workflow changes have been published (not just saved as draft)
  2. Check that the post function is attached to the correct transition
  3. Review execution logs in the Executions tab

Access Denied Errors#

  1. Ensure Automan has the necessary permissions
  2. When using impersonation - check if the user has permission to perform the API actions

Finding the Execution Logs#

  1. Navigate to Apps > Automan
  2. Go to the Executions tab
  3. Click on an execution to view detailed logs