3
2
2024-08-20
(C) Questetra, Inc. (MIT License)
This item creates a repository on GitHub.
この工程は、GitHub にリポジトリを作成します。
https://support.questetra.com/bpmn-icons/service-task-github-repository-create/
https://support.questetra.com/ja/bpmn-icons/service-task-github-repository-create/
-
-
-
-
-
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABM9JREFUWEfF
V2tQlFUYfs4ugiKgePkTiE3gCIssGWRhg1EwaE2OUZNjVDIFEwyJM12MSZKgokkNUdZNMhwCCg0p
Bi8UxGVRblkgLHFJ12ZipImBLiAOg7h7mvfT/dz99lt2sR+8v3bPe3vOez0fw/+gqKgoF1LX6XQ3
79YMc1bxvuBgP2ZSRjHGH4SJqcCwGsCi2/pj4PgVCt7HOfuJK4y633p7B52x7RBAgCo0GCYeD4bn
AKxyxiiAy+A4CQUrM/R1986kYxdAWFjYvH8nb6YoOE/igNpJx1ZiDNCbGCtcvMCloKOjY1rOhiyA
ALXal93gb3PG0u7GsVSHca7hrmyfQa+/asOTHpBzTCMLQKIj5wqFAiaTyZGYmX8M85AlBWEVAQr7
+PUbufZu7uvrg+SkV3B/aAj8VqyAu7u7AGB09C8MXLqEH+oacKK8wi4gioTXQtc3LdNhBcBfFZrG
OM+Xs7AjNRlpqSmgW89Evw8OIiExGUNDf8iKccZ2Xunr1piZIgCqdsZ5mbTgvL0Xo7ysFPeu9HM2
1EJU9uXm4VhRiY0OFSZnLN7cHXcABKpzwLBbqlH1zddQBQU67dxScGv8dlzs6rbV5fjIMKDPIIYA
gIaMwqSsk/b5i/Hb8N677wgGJicnsSfrA6S9loKVfn7CLaempqBUKuHq6gqj0Sjkf8H8+Xgmboug
MzY2hnWPRMkV6mWTwhhDw0oA4B+k3s6AYkuoi7y80N7cCBcXYdqCchuzabPwe/nyZRgZGRXFyanS
RYmJieuIeGgdSoo+F3nfVlYhPSPTJgocSLjSry8RAASoQjTgbIelVPy2rcjOFKIk0MjoKNZviHaY
Crr93pz3Rbmx8XGEPxxpq8f4YUNfT9otAIHqejA8bil1+GAuNsbGiEd0C7qNI6IuudDaBIqgmQJD
1sJolMwLjgbDgD76FoAgNU0oH0vjjbXVoL4nonyvXrPWkW+Rn5+3H09sjBX/U1u2trVL9YcM/Xpf
Riv16vDf/wDwsJT45eIFuLm5CUdUYIEhDzgN4OOcbDwb97Qor9EWIF97RKo/YejXe9oF0Ha+AcuW
LhWV1j8abVV4M6GpPHkca4JVoshb6btRdfqsPAB7Kag48SVC1SGiErUYtaEjWrLEGy26OrF7SD7y
sVj8OTwsnwJ7RUgdQJ1gSY4KkSJGwH187hHV7KbPqghl2pBGcPv5RmH2U89T7xNRO3Z2diEjMxvU
YkQ0sOK2bBbCLt0V39XUYufru2wDZ9mGcoOINPI+2YunntyE6elpYcq99MLzgiGacOERG0SjSS8n
IH3XGzZOqHvCIyJx7dqEDc9qENkbxR4eC9FUXwMvT090detxvLwCqwL8cfpMNfr6B0SjFJ3Wpnob
J3n5WnxacFSubKxH8e06kF1GVFS11aeEwUKjVt/TA925ZhQVl4qG6V3Q/XOblSPtkaM4qNHK16x0
GQkA7Kxj4lE9fFH4mbgVzzW3IPHVVNG4p6cHOn9sEf7Tgtp/4BCKS7+SdW53HZP0TA8S4lNbfpi9
B1WnzqKw6M7uooX1/ZlK1NTW4cAhje3YtYBi90FCMo6eZPLxdP7U4ZNMSMUsHqXOuxYkHT9KzQbn
9FluBjGnHyaWoZ2zTzNpfufs43SWhTZr8f8AaTovPzYDLOEAAAAASUVORK5CYII=
{
const auth = httpClient.createAuthSettingToken('Personal Access Token', 'github-token-12345');
configs.putObject('conf_Auth', auth);
configs.put('conf_Org', org);
configs.put('conf_Name', name);
configs.put('conf_Visibility', visibility);
configs.put('conf_License', license);
configs.put('conf_GitIgnore', gitIgnore);
configs.put('conf_Description', description);
configs.put('conf_Homepage', homepage);
const topicsDef = engine.createDataDefinition('トピック(文字型)', 1, 'q_topics_string', 'STRING_TEXTAREA');
engine.setData(topicsDef, topics);
configs.putObject('conf_Topics', topicsDef);
const urlDef = engine.createDataDefinition('URL', 11, 'q_url', 'STRING_TEXTFIELD');
engine.setData(urlDef, '事前文字列');
configs.putObject('conf_Url', urlDef);
return urlDef;
};
/**
* 異常系のテスト
* @param errorMsg
*/
const assertError = (errorMsg) => {
let failed = false;
try {
main();
} catch (e) {
failed = true;
expect(e.message).toEqual(errorMsg);
}
if (!failed) {
fail('No error was thrown.');
}
};
/**
* リポジトリの名前が空でエラー
*/
test('Repository Name is blank', () => {
prepareConfigs('', '', 'public', '', '', '', '', '');
assertError('Repository Name is blank.');
});
/**
* トピックを文字型データ項目で指定し、数が多すぎる
*/
test('Too many topics - STRING', () => {
let topics = '';
for (let i = 0; i < MAX_TOPIC_NUM + 1; i++) {
topics += `topic${i+1}\n`;
}
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', topics);
assertError(`The maximum number of topics is ${MAX_TOPIC_NUM}.`);
});
/**
* トピックを文字型データ項目で指定し、長すぎる文字列を含む
*/
test('Topic name too long - STRING', () => {
const topics = 'a'.repeat(MAX_TOPIC_LENGTH + 1);
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', topics);
assertError(`Each topic must be within ${MAX_TOPIC_LENGTH} characters.`);
});
/**
* トピックを文字型データ項目で指定し、不正な文字を含む
*/
test('Invalid topic name - STRING', () => {
const topics = 'topic1\nTopic2'; // 大文字を含めることはできない
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', topics);
assertError('Topics can only include lowercase letters, numbers, and hyphens.');
});
/**
* トピックを選択型データ項目で指定
* @param prefix
* @param num
*/
const prepareTopicsWithSelect = (prefix, num) => {
const selects = new java.util.ArrayList();
for (let i = 0; i < num; i++) {
const id = `${prefix}-${i+1}`;
const item = engine.createItem(id, `${id} を選択`);
selects.add(item);
}
const topicsDef = engine.createDataDefinition('トピック(選択型)', 2, 'q_topics_select', 'SELECT_CHECKBOX');
engine.setData(topicsDef, selects);
configs.putObject('conf_Topics', topicsDef);
};
/**
* トピックを選択型データ項目で指定し、数が多すぎる
*/
test('Too many topics - SELECT', () => {
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', 'dummy');
prepareTopicsWithSelect('topic', MAX_TOPIC_NUM + 1);
assertError(`The maximum number of topics is ${MAX_TOPIC_NUM}.`);
});
/**
* トピックを選択型データ項目で指定し、長すぎる文字列を含む
*/
test('Topic name too long - SELECT', () => {
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', 'dummy');
const prefix = 'a'.repeat(MAX_TOPIC_LENGTH);
prepareTopicsWithSelect(prefix, 1);
assertError(`Each topic must be within ${MAX_TOPIC_LENGTH} characters.`);
});
/**
* トピックを選択型データ項目で指定し、不正な文字を含む
*/
test('Invalid topic name - SELECT', () => {
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', 'dummy');
prepareTopicsWithSelect('topic#', 1); // ハイフン以外の記号を含めることはできない
assertError('Topics can only include lowercase letters, numbers, and hyphens.');
});
/**
* ユーザのリポジトリ作成の POST リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param request.contentType
* @param request.body
* @param name
* @param visibility
* @param license
* @param gitIgnore
* @param description
* @param homepage
*/
const assertCreateRepoForUserRequest = ({ url, method, headers, contentType, body }, name, private, license, gitIgnore, description, homepage) => {
expect(url).toEqual('https://api.github.com/user/repos');
expect(method).toEqual('POST');
expect(headers['Authorization']).toEqual('Bearer github-token-12345');
expect(contentType).toEqual('application/json');
const bodyObj = JSON.parse(body);
expect(bodyObj.name).toEqual(name);
expect(bodyObj.private).toEqual(private);
expect(bodyObj.license_template).toEqual(license);
expect(bodyObj.gitignore_template).toEqual(gitIgnore);
expect(bodyObj.description).toEqual(description);
expect(bodyObj.homepage).toEqual(homepage);
};
/**
* ユーザのリポジトリ作成の POST リクエストでエラー
*/
test('Fail in creating a repo for the user', () => {
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', '');
httpClient.setRequestHandler((request) => {
assertCreateRepoForUserRequest(request, 'Test-Repository', false, undefined, undefined, '', '');
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError('Failed to create a repository for the user. status: 400');
});
/**
* 組織のリポジトリ作成の POST リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param request.contentType
* @param request.body
* @param org
* @param name
* @param visibility
* @param license
* @param gitIgnore
* @param description
* @param homepage
*/
const assertCreateRepoForOrgRequest = ({ url, method, headers, contentType, body }, org, name, visibility, license, gitIgnore, description, homepage) => {
expect(url).toEqual(`https://api.github.com/orgs/${encodeURIComponent(org)}/repos`);
expect(method).toEqual('POST');
expect(headers['Authorization']).toEqual('Bearer github-token-12345');
expect(contentType).toEqual('application/json');
const bodyObj = JSON.parse(body);
expect(bodyObj.name).toEqual(name);
expect(bodyObj.visibility).toEqual(visibility);
expect(bodyObj.license_template).toEqual(license);
expect(bodyObj.gitignore_template).toEqual(gitIgnore);
expect(bodyObj.description).toEqual(description);
expect(bodyObj.homepage).toEqual(homepage);
};
/**
* 組織のリポジトリ作成の POST リクエストでエラー
*/
test('Fail in creating a repo for the organization', () => {
prepareConfigs('Test-Org', 'Test-Repository', 'public', '', '', '', '', '');
httpClient.setRequestHandler((request) => {
assertCreateRepoForOrgRequest(request, 'Test-Org', 'Test-Repository', 'public', undefined, undefined, '', '');
return httpClient.createHttpResponse(404, 'application/json', '{}');
});
assertError('Failed to create a repository for the organization. status: 404');
});
/**
* リポジトリ作成の API レスポンスを作成
* @param owner
* @param name
*/
const createResponse = (owner, name) => {
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({
"full_name": `${owner}/${name}`,
"html_url": `https://github.com/${owner}/${name}`
}));
};
/**
* ユーザのリポジトリ作成成功 - 公開、トピック指定なし
*/
test('Succeed in creating a repo for the user - public, without topics', () => {
const urlDef = prepareConfigs('', 'Test-Repository-1', 'public', '', '', '', '', '');
httpClient.setRequestHandler((request) => {
assertCreateRepoForUserRequest(request, 'Test-Repository-1', false, undefined, undefined, '', '');
return createResponse('Test-User-1', 'Test-Repository-1');
});
expect(main()).toEqual(undefined);
expect(engine.findData(urlDef)).toEqual('https://github.com/Test-User-1/Test-Repository-1');
});
/**
* トピック設定の PUT リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param request.contentType
* @param request.body
* @param fullName
* @param topics
*/
const assertSetTopicsRequest = ({ url, method, headers, contentType, body }, fullName, topics) => {
expect(url).toEqual(`https://api.github.com/repos/${fullName}/topics`);
expect(method).toEqual('PUT');
expect(headers['Authorization']).toEqual('Bearer github-token-12345');
expect(contentType).toEqual('application/json');
const bodyObj = JSON.parse(body);
expect(bodyObj.names).toEqual(topics);
};
/**
* トピック設定の PUT リクエストでエラー
*/
test('Fail in setting topics', () => {
prepareConfigs('', 'Test-Repository', 'public', '', '', '', '', 'topic-1');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRepoForUserRequest(request, 'Test-Repository', false, undefined, undefined, '', '');
reqCount++;
return createResponse('Test-User', 'Test-Repository');
}
assertSetTopicsRequest(request, 'Test-User/Test-Repository', ['topic-1']);
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError('Failed to set topics. status: 400');
});
/**
* ユーザのリポジトリ作成成功 - 非公開、トピック指定あり
*/
test('Succeed in creating a repo for the user - private, with topics', () => {
const license = 'Apache-2.0';
const gitIgnore = 'Node';
const description = 'This is a test repository.';
const homepage = 'https://example.com/test-repo-2';
const topics = 'topic-1\ntopic-2\n\ntopic-3\n';
const urlDef = prepareConfigs('', 'Test-Repository-2', 'private', license, gitIgnore, description, homepage, topics);
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRepoForUserRequest(request, 'Test-Repository-2', true, license, gitIgnore, description, homepage);
reqCount++;
return createResponse('Test-User-1', 'Test-Repository-2');
}
assertSetTopicsRequest(request, 'Test-User-1/Test-Repository-2', ['topic-1', 'topic-2', 'topic-3']);
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
expect(main()).toEqual(undefined);
expect(engine.findData(urlDef)).toEqual('https://github.com/Test-User-1/Test-Repository-2');
});
/**
* 組織のリポジトリ作成成功 - 公開、トピックを選択型データ項目で指定
*/
test('Succeed in creating a repo for the organization - public, with topics', () => {
const license = 'GPL-3.0';
const gitIgnore = 'C++';
const description = 'This is a test repository created in the organization.';
const homepage = 'https://example.com/test-repo-3';
const urlDef = prepareConfigs('Test-Org-1', 'Test-Repository-3', 'public', license, gitIgnore, description, homepage, 'dummy-topic');
prepareTopicsWithSelect('topic', MAX_TOPIC_NUM);
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRepoForOrgRequest(request, 'Test-Org-1', 'Test-Repository-3', 'public', license, gitIgnore, description, homepage);
reqCount++;
return createResponse('Test-Org-1', 'Test-Repository-3');
}
assertSetTopicsRequest(
request,
'Test-Org-1/Test-Repository-3',
[
'topic-1', 'topic-2', 'topic-3', 'topic-4', 'topic-5', 'topic-6', 'topic-7', 'topic-8', 'topic-9', 'topic-10',
'topic-11', 'topic-12', 'topic-13', 'topic-14', 'topic-15', 'topic-16', 'topic-17', 'topic-18', 'topic-19', 'topic-20'
]
);
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
expect(main()).toEqual(undefined);
expect(engine.findData(urlDef)).toEqual('https://github.com/Test-Org-1/Test-Repository-3');
});
/**
* 組織のリポジトリ作成成功 - 非公開、トピックを選択型データ項目で指定し、未選択
*/
test('Succeed in creating a repo for the organization - private, without topics', () => {
const urlDef = prepareConfigs('Test-Org-2', 'Test-Repository-4', 'private', '', '', '', '', 'dummy-topic');
prepareTopicsWithSelect('topic', 0);
httpClient.setRequestHandler((request) => {
assertCreateRepoForOrgRequest(request, 'Test-Org-2', 'Test-Repository-4', 'private', undefined, undefined, '', '');
return createResponse('Test-Org-2', 'Test-Repository-4');
});
expect(main()).toEqual(undefined);
expect(engine.findData(urlDef)).toEqual('https://github.com/Test-Org-2/Test-Repository-4');
});
/**
* 組織のリポジトリ作成成功 - 非公開、トピックのデータ項目、URL 保存先データ項目の指定なし
*/
test('Succeed in creating a repo for the organization - private, no data item selected', () => {
const license = 'MIT';
const description = 'This is a test repository created in the organization.';
const urlDef = prepareConfigs('Test-Org-2', 'Test-Repository-5', 'private', license, '', description, '', 'dummy-topic');
configs.put('conf_Topics', '');
configs.put('conf_Url', '');
httpClient.setRequestHandler((request) => {
assertCreateRepoForOrgRequest(request, 'Test-Org-2', 'Test-Repository-5', 'private', 'MIT', undefined, description, '');
return createResponse('Test-Org-2', 'Test-Repository-5');
});
expect(main()).toEqual(undefined);
expect(engine.findData(urlDef)).toEqual('事前文字列');
});
]]>