Copy Tempo DC worklogs to Tempo Cloud for a single issue


Get Started

Not the template you're looking for? Browse more.

About the template


This template demonstrats how to find all worklogs for a specified issue from Tempo Data Center instance and then how to copy them over to Tempo Cloud instance. Get started to learn more.

About ScriptRunner Connect


What is ScriptRunner Connect?

ScriptRunner Connect is an AI assisted code-first (JavaScript/TypeScript) integration platform (iPaaS) for building complex integrations and automations.

Can I try it out for free?

Yes. ScriptRunner Connect comes with a forever free tier.

Can I customize the integration logic?

Absolutely. The main value proposition of ScriptRunner Connect is that you'll get full access to the code that is powering the integration, which means you can make any changes to the the integration logic yourself.

Can I change the integration to communicate with additional apps?

Yes. Since ScriptRunner Connect specializes in enabling complex integrations, you can easily change the integration logic to connect to as many additional apps as you need, no limitations.

What if I don't feel comfortable making changes to the code?

First you can try out our AI assistant which can help you understand what the code does, and also help you make changes to the code. Alternatively you can hire our professionals to make the changes you need or build new integrations from scratch.

Do I have to host it myself?

No. ScriptRunner Connect is a fully managed SaaS (Software-as-a-Service) product.

What about security?

ScriptRunner Connect is ISO 27001 and SOC 2 certified. Learn more about our security.

Template Content


README

Scripts

TypeScriptCopyWorklogs

README


๐Ÿ“‹ Overview

This template demonstrats how to find all worklogs for a specified issue from Tempo Data Center instance and then how to copy them over to Tempo Cloud instance.

๐Ÿ–Š๏ธ Setup

  • Configure API Connections by creating connectors for Jira Cloud, Jira On-Premise, Tempo Cloud and Tempo On-Premise, or use existing ones.
  • Navigate to CopyWorklogs script and change the SOURCE_ISSUE and TARGET_ISSUE to appropriate values. Optionally change other parameters to appropriate values as well.

๐Ÿš€ Usage

Trigger CopyWorklogs script manually, which after successful run should copy over all the Tempo worklogs for the specified issue.

API Connections


./api/jira/cloud@managed-api/jira-cloud-v3-sr-connect
TypeScriptCopyWorklogs

import JiraCloud from './api/jira/cloud';
import TempoCloud from './api/tempo/cloud';
import JiraOnPremise from './api/jira/on-premise';
import TempoOnPremise from './api/tempo/on-premise';
import { UserAsResponse } from '@managed-api/jira-cloud-v3-core/definitions/UserAsResponse';
import { TempoWorklogV4BeanAsResponse } from '@managed-api/tempo-timesheets-on-premise-v4-core/definitions/TempoWorklogV4BeanAsResponse';
import dayjs from 'dayjs';
import { throttleAll } from 'promise-throttle-all';

// Global parameters, make sure you have these parameters changed to correct values
const SOURCE_ISSUE_KEY = 'SOURCE-1';
const TARGET_ISSUE_KEY = 'TARGET-1';
const FROM_DATE = '1970-01-01';
const TO_DATE = '2030-01-01';
const CONCURRENCY = 10; // Controls how many concurrent jobs can be processed at any given time

/**
 * This function finds all the worklogs for specified issue from Tempo On-Premise and then copies over those worklogs to Tempo Cloud
 * Run this script manually any time you woud like to have worklogs copied over
 * PS! Currently this script does not delete existing worklogs or compare if the worklog already exists
 */
export default async function (event: any, context: Context): Promise<void> {
    console.log('Getting users from Jira Cloud...');
    // Find all the users from Jira Cloud
    const targetUsers = await getUsers();
    console.log(`Found ${targetUsers.length} Jira Cloud users`);

    // Find worklogs for given issue key
    const worklogs = await TempoOnPremise.Worklog.findWorklogs({
        body: {
            from: FROM_DATE,
            to: TO_DATE,
            taskKey: [SOURCE_ISSUE_KEY]
        }
    });

    // Copy over all the worklogs concurrently, but use 'throttleAll' function to limit the max concurrency
    await throttleAll(CONCURRENCY, worklogs.map(w => () => copyWorklog(targetUsers, w)));
}

async function copyWorklog(targetUsers: UserAsResponse[], worklog: TempoWorklogV4BeanAsResponse) {
    try {
        // Find the source user from Jira On-Premise with the user key
        const sourceUser = await JiraOnPremise.User.getUser({
            key: worklog.updater
        });

        // Find the target user from Jira Cloud with matching e-mail address
        const targerUser = targetUsers.find(e => e.emailAddress === sourceUser.emailAddress);

        // Check if the user was found
        if (!targerUser || !targerUser.accountId) {
            // If not then throw an error
            throw Error(`No target user found with email: ${targerUser}`);
        }

        // Parse the worklog started date with dayjs
        const createdDate = dayjs(worklog.started);

        // Find the target issue from Jira Cloud
        const targetIssue = await JiraCloud.Issue.getIssue({
            issueIdOrKey: TARGET_ISSUE_KEY
        });

        // Create a new worklog in Tempo Cloud
        const newWorklog = await TempoCloud.Worklog.createWorklog({
            body: {
                authorAccountId: targerUser.accountId,
                issueId: +(targetIssue.id ?? '0'),
                description: worklog.comment,
                startDate: createdDate.format('YYYY-MM-DD'),
                startTime: createdDate.format('HH:mm:ss'),
                timeSpentSeconds: worklog.timeSpentSeconds ?? 0,
                remainingEstimateSeconds: worklog.issue?.estimatedRemainingSeconds
            }
        });

        // And print out the details
        console.log('Worklog copied', {
            oldId: worklog.tempoWorklogId,
            newId: newWorklog.tempoWorklogId,
            author: targerUser.emailAddress,
            date: worklog.dateCreated,
            timeSpent: worklog.timeSpent
        });
    } catch (e) {
        // If anything went wrong, log it to console
        console.error('Failed to copy worklog', worklog, e);
    }
}

// Function to retrieve all the users from Jira Cloud (traverses paginated results)
async function getUsers() {
    const allUsers: UserAsResponse[] = [];
    const maxResults = 50;
    let startAt = 0;

    do {
        const users = await JiraCloud.User.getUsers({
            startAt,
            maxResults
        });

        allUsers.push(...users);

        if (users.length === maxResults) {
            startAt += maxResults;
        } else {
            startAt = 0
        }
    } while (startAt > 0);

    return allUsers;
}
Documentation ยท Support ยท Suggestions & feature requests