Custom Jobs
Custom Scheduled Jobs are user-defined scripts that run on a recurring schedule. You write the script and ScriptForge executes it automatically during each scheduled cycle.
Creating a Custom Job
- Navigate to Apps → ScriptForge → Scheduled Jobs
- Click Create Job
- Configure:
- Name: A clear name (e.g., "Weekly stale issue cleanup")
- Description: What it does and why
- Schedule: Set the interval (hourly minimum)
- Script: Your JavaScript code
- Enabled: Toggle on
- Click Save
Writing Job Scripts
Job scripts have the same HAPI access as the Script Console. They run as the app (service account) with full access to all projects.
Key differences from console scripts:
- No interactive output — use
console.logfor logging (captured in execution history) - Must complete within ~22 seconds
- Should be idempotent — if the same job runs twice, the result should be consistent
Examples
Auto-archive completed sprints' issues
// Move all "Done" issues older than 14 days to "Archived" status
const done = WorkItems.search(
'status = Done AND updated < -14d AND resolution is not EMPTY'
);
let count = 0;
await done.forEach(async (issue) => {
try {
await issue.transition('Archived');
count++;
} catch (e) {
console.warn(`Could not archive ${issue.key}: ${e.message}`);
}
});
return `Archived ${count} issues`;
Sync entity properties for reporting
// Update a "lastProcessed" timestamp on all active project issues
const active = WorkItems.search('status != Done AND status != Closed');
const now = new Date().toISOString();
await active.forEach(async (issue) => {
const props = issue.getEntityProperties();
await props.setString('lastProcessed', now);
});
Unassign inactive assignees
// If an issue has been "In Progress" for 14+ days with no updates, unassign it
const stuck = WorkItems.search(
'status = "In Progress" AND updated < -14d AND assignee is not EMPTY'
);
await stuck.forEach(async (issue) => {
await issue.update(b => b.setAssignee(null));
await issue.addComment('Unassigned due to 14 days of inactivity. Please re-assign if still active.');
});
Monitoring
Check the Execution History filtered to "Scheduled Job" to see:
- When each job last ran
- Whether it succeeded or failed
- Console output and errors
- How long it took
Tips
- Keep jobs focused — one job per task. Don't combine unrelated operations.
- Use
try/catchinside loops so one failing issue doesn't abort the entire batch. - Log meaningful output (
console.log) so you can debug issues from the execution history. - Test your script in the Script Console first before setting it as a scheduled job.