Серверный скрипт для импорта тасок из JIRA в SDLC SimpleOne
//Нужно создать запиcи с данными названиями в таблице sys_property, и поставить ваши value
let token = ss.getProperty('itg.jira_token');//Корректный токен к проекту JIRA
let pda_project_id = ss.getProperty('itg.project_id');// Запись в таблице pda_project
const projectKey = ss.getProperty('itg.project_key')//Key для проекта в JIRA
let pda_product_module_id = ss.getProperty('itg.product_module_id')//Запись в таблице pda_module_id
let pda_product_id = ss.getProperty('itg.product_id')//Запись в таблице pda_product
//let pda_release_id = "";//расскомментируйте, если нужен release id //Запись в таблице pda_release
let baseBrowserUrl = `https://example.com/browse/`
//Нужно написать типы тасок для импорта
// Sub-task можно не писать, в данном скрипте, они создаются при импорте тасок и привязываются к ним
let wantIssueType = "Task";// [Epic, Bug, Task, Story, Sub-task]
let startNum = "0"
let maxNum = "150"// Пишите корректное количество всех тасок из JIRA
function setTable(issueType) {
const typeMapping = {
'Epic': "pda_epic",
'Bug': "pda_defect",
'Story': "pda_user_story",
'Task': "pda_task",
'Sub-task': "pda_subtask"
};
return typeMapping[issueType] || "Unknown"; // Return the mapped value or "Unknown" if the issue type is not found
}
// Fetch issue keys based on JQL query with specific statuses
const baseUrl = 'https://example.com/rest/api/2';
const statusQuery = 'status in ("Backlog","In Review", "In Progress","Selected for Development")';// PUL
const issueTypeQuery = `issuetype = ${wantIssueType}`
const groupQuery = `project = ${projectKey} AND ${statusQuery} AND ${issueTypeQuery}`;
const encodedGroupQuery = encodeURIComponent(groupQuery);
const jqlQuery = `jql=${encodedGroupQuery}&startAt=${startNum}&maxResults=${maxNum}`;
const request = sws.restRequestV1();
request.setRequestUrl(`${baseUrl}/search?${jqlQuery}`);
request.setRequestMethod('GET');
request.setRequestHeader('Authorization', 'Bearer ' + token);
let subTasks;
const response = request.execute();
let dataJson = JSON.parse(response.getBody());
let issueKeys = [];
dataJson.issues.forEach(issue => {
issueKeys.push(issue.key);
});
fetchAndProcessIssues(issueKeys);
function fetchAndProcessIssues(issueKeys) {
issueKeys.forEach(issueKey => {
let issueUrl = `${baseUrl}/issue/${issueKey}`;
const request = sws.restRequestV1();
request.setRequestUrl(issueUrl);
request.setRequestMethod('GET');
request.setRequestHeader('Authorization', 'Bearer ' + token);
const response = request.execute();
let dataJson = JSON.parse(response.getBody());
let assigneeName = dataJson.fields.assignee ? dataJson.fields.assignee.name : 'Unassigned';
// ss.info(dataJson.fields.subtasks[0]);
// ss.info(JSON.stringify(dataJson,null,2))
let issueFields = {
subtasks: dataJson.fields.subtasks[0],
assignee: assigneeName,
status: dataJson.fields.status ? dataJson.fields.status.name : '',
priority: dataJson.fields.priority.name ? dataJson.fields.priority.name : '',
reporter: dataJson.fields.reporter.emailAddress ? dataJson.fields.reporter.emailAddress : '',
dueDate: dataJson.fields.duedate ? dataJson.fields.duedate : '',
labels: dataJson.fields.labels ? dataJson.fields.labels : [],
environment: dataJson.fields.environment ? dataJson.fields.environment : '',
fixVersions:dataJson.fields.fixVersions.name ? dataJson.fields.fixVersions.name : [],
components:dataJson.fields.components ? dataJson.fields.components : [],
key: dataJson.key ? dataJson.key : "",
description: dataJson.fields.description ? dataJson.fields.description : '',
creator: dataJson.fields.creator ? dataJson.fields.creator.name : '',
summary: dataJson.fields.summary ? dataJson.fields.summary : '',
created: dataJson.fields.created,
updated: dataJson.fields.updated,
epic_link: dataJson.fields.customfield_10014 ? dataJson.fields.customfield_10014 : '',
comments: dataJson.fields.comment ? dataJson.fields.comment.comments : [],
attachments: dataJson.fields.attachment ? dataJson.fields.attachment : [],
};
createTask(issueKey, issueFields);
});
}
function createTask(issueKey, issueFields) {
let insert_table = setTable(wantIssueType);
const issue_table = new SimpleRecord(insert_table);
if (insert_table === "pda_user_story") {// If User Story
issue_table.pda_im_as = "Я как...";
issue_table.pda_want = "Хочу...";
issue_table.pda_in_order_to = "Для того, чтобы...";
issue_table.pda_acceptance_criteria = issueFields.description || " ";// Бывает description пустой
}
if (insert_table != "pda_user_story") {// If User Story
issue_table.description = issueFields.description;
}
issue_table.subject = issueFields.summary;
issue_table.description = issueFields.description;
issue_table.short_description = issueFields.key;
issue_table.assigned_user = getUserByLogin(issueFields.assignee);
issue_table.caller = getUserByLogin(issueFields.creator);
issue_table.opened_at = formatDate(issueFields.created);
issue_table.state = setState(issueFields.status);
issue_table.priority = setPriority(issueFields.priority);
issue_table.pda_project_id = pda_project_id;
// issue_table.pda_release_id = pda_release_id;//Если нужен релих, то нужно раскомментировать
issue_table.pda_product_id = pda_product_id;
issue_table.pda_product_module_id = pda_product_module_id;
issue_table.pda_rank = 10;
issue_table.comments = `${baseBrowserUrl}${issueKey}`;
issue_table.work_notes = `
Reporter: ${issueFields.reporter}
IssueKey: ${issueFields.key}
Updated: ${formatDate(issueFields.updated)}
Created: ${formatDate(issueFields.created)}
Labels: ${issueFields.labels}
Environment: ${issueFields.environment}
FixVersions: ${issueFields.fixVersions}
Components: ${issueFields.components}
Due date: ${issueFields.dueDate}
Epic Link: ${issueFields.epic_link}
`;
const insertedRecordId = issue_table.insert();
if (insertedRecordId === 0) {
ss.info(issue_table.getErrors());
}
if (insert_table === "pda_epic") {//insertedRecordId
const epicIssueKeys = getEpicIssues(issueFields.key);
ss.info(epicIssueKeys);
issue_table.short_description = `Child General Task ${epicIssueKeys}` // Here need Array But Now
let updatedRecord = issue_table.update()
for (let i = 0; i < epicIssueKeys.length; i++) {
getChildTask(epicIssueKeys[i],updatedRecord);
}
}
if (issueFields.subtasks) {
getSubTask(issueFields.subtasks,issueFields,issueFields.key,insertedRecordId)
}
insertComments(issueFields.comments, issue_table, insertedRecordId);
getAttachUrl(issueFields.attachments, issue_table, insertedRecordId);
}
//Функция привязывания сабтаски к таски
function getSubTask(subtasks, issueFields, key, parent_id) {
if (subtasks.key) {
request.setRequestUrl(`https://example.com/rest/api/2/issue/${key}/subtask`);
request.setRequestMethod('GET');
request.setRequestHeader('Authorization', 'Bearer ' + token);
const response = request.execute();
let dataJson = JSON.parse(response.getBody());
dataJson.forEach(subtaskData => {
const subtaskInfo = {
id: subtaskData.id || "",
key: subtaskData.key || "",
summary: subtaskData.fields.summary || "",
status: subtaskData.fields.status.name || "",
};
const subtask = new SimpleRecord("pda_subtask");
subtask.parent_id = parent_id;
subtask.subject = subtaskInfo.summary;
subtask.description = subtaskInfo.summary;
subtask.comments = `https://example.com/browse/${subtaskInfo.key}` || "";
subtask.short_description = subtaskInfo.key;
subtask.assigned_user = getUserByLogin(issueFields.assignee);
subtask.caller = getUserByLogin(issueFields.creator);
subtask.opened_at = formatDate(issueFields.created);
subtask.state = setState(subtaskInfo.status);
subtask.priority = setPriority(issueFields.priority);
subtask.pda_project_id = pda_project_id;
subtask.pda_product_id = pda_product_id;
subtask.pda_product_module_id = pda_product_module_id;
subtask.pda_rank = 10;
subtask.work_notes = `
Reporter: ${issueFields.reporter}
IssueKey: ${issueFields.key}
Updated: ${formatDate(issueFields.updated)}
Created: ${formatDate(issueFields.created)}
Labels: ${issueFields.labels}
Environment: ${issueFields.environment}
FixVersions: ${issueFields.fixVersions}
Components: ${issueFields.components}
Due date: ${issueFields.dueDate}
Epic Link: ${issueFields.epic_link}
`;
subtask.insert();
});
} else {
ss.info('No subtasks found for issue key: ' + key);
}
}
function getEpicIssues(key) {
const childIssuesArr = [];
const request = sws.restRequestV1();
const token = ss.getProperty('itg.jira_token');
request.setRequestUrl(`https://example.com/rest/api/2/search?jql=issuetype%20%3D%20task%20AND%20%22Epic%20Link%22%20%3D%20${key}%20AND%20status%20in%20(%22Backlog%22,%22In%20Review%22,%20%22In%20Progress%22,%22Selected%20for%20Development%22)`);
request.setRequestMethod('GET');
request.setRequestHeader('Authorization', 'Bearer ' + token);
const response = request.execute();
const dataJson = JSON.parse(response.getBody());
dataJson.issues.forEach(issue => {
childIssuesArr.push(issue.key);
});
return childIssuesArr; // Return the array of issue keys
}
function getChildTask(key,updatedRecord){
const forRecord = new SimpleRecord('pda_task')
forRecord.addEncodedQuery(`(short_descriptionLIKE${key})`);
forRecord.setLimit(1);
forRecord.query();
if (forRecord.next()){
// ss.info(forRecord.sys_id)
const task = new SimpleRecord('pda_task');
let current_task = task.get(forRecord.sys_id);
current_task.parent_id = updatedRecord
current_task.update()
}}
function getUserByLogin(login) {
const employee = new SimpleRecord('employee');
employee.addEncodedQuery(`(username=${login})`);
employee.setLimit(1);
employee.query();
while (employee.next()) {
return employee.sys_id;
}
return '';
}
function setState(status) { // 'status in ("Backlog","In Review", "In Progress","Selected for Development")'
const mapping = {
//Статус Jira: Статус SimpleOne
"Backlog": "new",
"In Review": "review",
"In Progress": "development",
"Selected for Development": "backlog",
"Done": "done",//Это только для перенесенных сабтасок, не для тасок
};
return mapping[status] || "";
}
function setPriority(priority) {
const mapping = {//High, Medium, Low
"High": "high",
"Medium": "medium",
"Low": "low"
};
return mapping[priority] || "";
}
function insertComments(comments, issue_table, sys_id) {
const reversedComments = comments.reverse();
return reversedComments.map(comment => {
const body = `
Comment Author Email: ${comment.updateAuthor.emailAddress}
Comment Created At: ${formatDate(comment.updated)}
Comment Body:
\n${comment.body}\n
`;
issue_table.get(sys_id);
issue_table.work_notes = body;
issue_table.update();
}).join('\n');
}
function getAttachUrl(attachments, issue_table, sys_id) {
let stringUrl = '';
attachments.forEach(attachment => {
stringUrl += attachment.content + '\n';
});
issue_table.get(sys_id);
issue_table.work_notes = stringUrl;
issue_table.update();
//ss.info(stringUrl);
}
function formatDate(inputDate) {
const date = new Date(inputDate);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
return formattedDate;
}