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('事前文字列'); }); ]]>