From 107c445f65568742561d97eec09dc83f7d735c68 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 25 Mar 2025 11:26:32 -0500 Subject: [PATCH 01/15] create form elements to submit PR Signed-off-by: Isaac Milarsky --- index.html | 2 +- js/generateFormComponents.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index ed04630..6bc61cd 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ - + diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index e386038..284e9b3 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -296,6 +296,24 @@ async function createFormComponents() { components = createAllComponents(jsonData); + components.push({ + "label": "GitHub API Key (optional)", + "disableSortingAndFiltering": false, + "tableView": true, + "key": "textField", + "type": "textfield", + "input": true + }); + + components.push({ + "label": "Git URL (optional)", + "disableSortingAndFiltering": false, + "tableView": true, + "key": "textField", + "type": "textfield", + "input": true + }); + // Add submit button to form components.push({ type: "button", @@ -306,6 +324,24 @@ async function createFormComponents() { tableView: false, }); + + + + // Add Create PR button to form + // Add submit button to form + /* + components.push({ + type: "button", + label: "Generate code.json metadata and push to Repository", + key: "submit", + disableOnInvalid: false, + input: true, + tableView: false, + }); + */ + + + console.log(components); return components; From ecc7a789ba8ff68995987f888873a841f0931259 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 25 Mar 2025 11:34:10 -0500 Subject: [PATCH 02/15] create PR parse object Signed-off-by: Isaac Milarsky --- index.html | 1 + js/formDataToJson.js | 9 +++++++++ js/generateFormComponents.js | 9 --------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 6bc61cd..3029412 100644 --- a/index.html +++ b/index.html @@ -57,6 +57,7 @@ + diff --git a/js/formDataToJson.js b/js/formDataToJson.js index f517caf..10aa01f 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -91,6 +91,15 @@ async function copyToClipboard(event){ document.execCommand("copy") } +// Creates PR on requested project +async function createProjectPR(event){ + event.preventDefault(); + + var textArea = document.getElementById("json-result"); + var codeJSONObj = textArea.value.parse() + console.log(codeJSONObj) +} + // Triggers local file download async function downloadFile(event) { event.preventDefault(); diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index 284e9b3..df2e365 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -305,15 +305,6 @@ async function createFormComponents() { "input": true }); - components.push({ - "label": "Git URL (optional)", - "disableSortingAndFiltering": false, - "tableView": true, - "key": "textField", - "type": "textfield", - "input": true - }); - // Add submit button to form components.push({ type: "button", From a48c133d760ed5872d6f33d2d2ff1548ac200698 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 25 Mar 2025 12:32:36 -0500 Subject: [PATCH 03/15] add parsing of the github api key Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 19 +++++++++++++++++-- js/generateFormComponents.js | 18 +----------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index 10aa01f..4d88e75 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -78,6 +78,10 @@ async function createCodeJson(data) { delete data.submit; const codeJson = await populateCodeJson(data); + window.gh_api_key = data['gh_api_key'] + console.log("TEST") + console.log(window.gh_api_key) + const jsonString = JSON.stringify(codeJson, null, 2); document.getElementById("json-result").value = jsonString; } @@ -96,8 +100,19 @@ async function createProjectPR(event){ event.preventDefault(); var textArea = document.getElementById("json-result"); - var codeJSONObj = textArea.value.parse() - console.log(codeJSONObj) + var codeJSONObj = JSON.parse(textArea.value) + + if('gh_api_key' in window) + { + var apiKey = window.gh_api_key + console.log(apiKey) + } + else + { + console.error("No API key found!") + alert("No Api Key in submitted data!") + } + //console.log(codeJSONObj) } // Triggers local file download diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index df2e365..590b21a 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -300,7 +300,7 @@ async function createFormComponents() { "label": "GitHub API Key (optional)", "disableSortingAndFiltering": false, "tableView": true, - "key": "textField", + "key": "gh_api_key", "type": "textfield", "input": true }); @@ -317,22 +317,6 @@ async function createFormComponents() { - - // Add Create PR button to form - // Add submit button to form - /* - components.push({ - type: "button", - label: "Generate code.json metadata and push to Repository", - key: "submit", - disableOnInvalid: false, - input: true, - tableView: false, - }); - */ - - - console.log(components); return components; From 7a5e55e595f45aa6d5e09c479f963ed81ac7467f Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 25 Mar 2025 14:24:20 -0500 Subject: [PATCH 04/15] Create methods to create a new branch on a project, add the code.json file to that branch, and then create a PR into that project Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 184 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 178 insertions(+), 6 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index 4d88e75..fbb4f50 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -95,22 +95,194 @@ async function copyToClipboard(event){ document.execCommand("copy") } +const NEW_BRANCH = 'code-json-branch'; + +function getOrgAndRepoArgsGitHub(url) +{ + const pattern = /https:\/\/github\.com\/([^\/]+)\/([^\/]+)/; + const match = url.match(pattern); + + if(match) + { + const owner = match[1]; + const repo = match[2]; + return {owner,repo}; + } + else + { + throw new Error('Invalid URL!'); + } +} + + +async function createBranchOnProject(projectURL, token) +{ + const {owner, repo} = getOrgAndRepoArgsGitHub(projectURL); + + const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs/heads/main}`, + { + method: 'GET', + headers: { + 'Authorization': 'token '.concat(token), + }, + } + ); + + const data = await response.json(); + + if (response.ok) + { + const sha = data.object.sha; + + const createBranchApiUrl = `https://api.github.com/repos/${owner}/${repo}/git/refs`; + + // Create the new branch from the base branch + const newBranchResponse = await fetch(createBranchApiUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `token ${token}`, + }, + body: JSON.stringify({ + ref: `refs/heads/${NEW_BRANCH}`, // Name of the new branch + sha: sha, // SHA of the base branch (main) + }), + }); + + const newBranchData = await newBranchResponse.json(); + + if ( newBranchResponse.ok ) + { + console.log('New branch created successfully: ', newBranchData); + return true; + } + else + { + console.error('Error creating new branch: ', newBranchData); + return false; + } + } + else + { + console.error('Error fetching base branch info:', data); + return false; + } +} + + +async function addFileToBranch(projectURL, token, codeJSONObj) +{ + const {owner, repo} = getOrgAndRepoArgsGitHub(projectURL); + const FILE_PATH = 'code.json' + const createFileApiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${FILE_PATH}`; + const encodedContent = Buffer.from(codeJSONObj).toString('base64'); + + const response = await fetch(createFileApiUrl, + { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'token'.concat(token), + }, + body: JSON.stringify({ + message: "Add codejson to project", + content: encodedContent, + branch: NEW_BRANCH, + }), + } + ); + + const data = await response.json() + + if ( response.ok ) + { + console.log('File added successfully: ', data); + return true; + } + else + { + console.error('Error adding file: ', data); + return false; + } +} + +async function createPR(projectURL, token) +{ + const {owner, repo} = getOrgAndRepoArgsGitHub(projectURL); + const createPrApiUrl = `https://api.github.com/repos/${owner}/${repo}/pulls`; + const response = await fetch(createPrApiUrl, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'token '.concat(token), + }, + body: JSON.stringify({ + title: "Add code.json to Project", + body: "Add generated code.json file to project. Code.json was generated via a form.io form site.", + head: NEW_BRANCH, + base: 'main', + + }), + } + ); + + const data = await response.json(); + + if (response.ok) + { + console.log('Pull request created successfully: ', data); + return true; + } + else + { + console.error("Error creating PR!: ", data); + return false; + } +} + // Creates PR on requested project async function createProjectPR(event){ event.preventDefault(); - var textArea = document.getElementById("json-result"); - var codeJSONObj = JSON.parse(textArea.value) + var textArea = document.getElementById("json-result");//Step 1 + var codeJSONObj = JSON.parse(textArea.value) if('gh_api_key' in window) { - var apiKey = window.gh_api_key - console.log(apiKey) + var apiKey = window.gh_api_key; + + if ('repositoryURL' in codeJSONObj) + { + var prCreated = false; + //Step 1 + const branchCreated = await createBranchOnProject(codeJSONObj.repositoryURL,apiKey); + if (branchCreated) + { + const fileAdded = await addFileToBranch(codeJSONObj.repositoryURL, apiKey, textArea.value); + + if (fileAdded) + { + prCreated = await createPR(codeJSONObj.repositoryURL, apiKey); + if(prCreated) + { + console.log("PR successfully created!"); + alert("PR has been created!"); + } + } + } + } + else + { + console.error("No URL found!"); + alert("No URL given for project!"); + } + } else { - console.error("No API key found!") - alert("No Api Key in submitted data!") + console.error("No API key found!"); + alert("No Api Key in submitted data!"); } //console.log(codeJSONObj) } From 501a64ea0bd4bd2969e85eb17338595e9a951597 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Fri, 28 Mar 2025 15:51:13 -0500 Subject: [PATCH 05/15] fix issues Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index fbb4f50..f192e51 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -119,7 +119,7 @@ async function createBranchOnProject(projectURL, token) { const {owner, repo} = getOrgAndRepoArgsGitHub(projectURL); - const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs/heads/main}`, + const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/refs/heads/main`, { method: 'GET', headers: { @@ -175,7 +175,8 @@ async function addFileToBranch(projectURL, token, codeJSONObj) const {owner, repo} = getOrgAndRepoArgsGitHub(projectURL); const FILE_PATH = 'code.json' const createFileApiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${FILE_PATH}`; - const encodedContent = Buffer.from(codeJSONObj).toString('base64'); + const encodedContent = btoa(codeJSONObj); + console.log("Content: ", encodedContent); const response = await fetch(createFileApiUrl, { From f98fde8972975cf81fc2480fb19a40183522a7e2 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Wed, 2 Apr 2025 11:30:32 -0500 Subject: [PATCH 06/15] ironed out last few bugs Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index f192e51..142c507 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -177,16 +177,22 @@ async function addFileToBranch(projectURL, token, codeJSONObj) const createFileApiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${FILE_PATH}`; const encodedContent = btoa(codeJSONObj); console.log("Content: ", encodedContent); + console.log("Branch: ", NEW_BRANCH); const response = await fetch(createFileApiUrl, { method: 'PUT', headers: { - 'Content-Type': 'application/json', - 'Authorization': 'token'.concat(token), + 'Accept': 'application/vnd.github+json', + 'Authorization': 'Bearer '.concat(token), + 'X-GitHub-Api-Version': "2022-11-28" }, body: JSON.stringify({ message: "Add codejson to project", + committer: { + name: "CodeJSON formsite", + email: "opensource@cms.hhs.gov" + }, content: encodedContent, branch: NEW_BRANCH, }), @@ -217,6 +223,7 @@ async function createPR(projectURL, token) headers: { 'Content-Type': 'application/json', 'Authorization': 'token '.concat(token), + 'X-GitHub-Api-Version': "2022-11-28" }, body: JSON.stringify({ title: "Add code.json to Project", From 0cdd709d5b145c3d160dfb15bbdb578058461126 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Wed, 2 Apr 2025 11:31:52 -0500 Subject: [PATCH 07/15] add comment to api key form text box Signed-off-by: Isaac Milarsky --- js/generateFormComponents.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index 590b21a..2bb34f5 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -296,6 +296,7 @@ async function createFormComponents() { components = createAllComponents(jsonData); + //Form text box to input GitHub API Key components.push({ "label": "GitHub API Key (optional)", "disableSortingAndFiltering": false, From d38793017a1d462a9632e5b6905cfa0ca478cb49 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Wed, 2 Apr 2025 11:39:08 -0500 Subject: [PATCH 08/15] make branch name random Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index 142c507..471d529 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -95,7 +95,7 @@ async function copyToClipboard(event){ document.execCommand("copy") } -const NEW_BRANCH = 'code-json-branch'; +const NEW_BRANCH = 'code-json-branch' + Math.random().toString(36).substring(2, 10); function getOrgAndRepoArgsGitHub(url) { From 3e9274fde4ec9c9f08655cf26b7fe0a842512845 Mon Sep 17 00:00:00 2001 From: decause-gov <107957201+decause-gov@users.noreply.github.com> Date: Thu, 3 Apr 2025 14:51:35 -0400 Subject: [PATCH 09/15] Update snyk-security.yml added debug flag to see what's going on --- .github/workflows/snyk-security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/snyk-security.yml b/.github/workflows/snyk-security.yml index 578dcae..f0c10c8 100644 --- a/.github/workflows/snyk-security.yml +++ b/.github/workflows/snyk-security.yml @@ -54,7 +54,7 @@ jobs: # Runs Snyk Code (SAST) analysis and uploads result into GitHub. # Use || true to not fail the pipeline - name: Snyk Code test - run: snyk code test --sarif > snyk-code.sarif # || true + run: snyk code test -d --sarif > snyk-code.sarif # || true # Runs Snyk Open Source (SCA) analysis and uploads result to Snyk. - name: Snyk Open Source monitor From da0f98d1f99bf04ded515bea8336547266d49f20 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 15 Apr 2025 14:40:43 -0500 Subject: [PATCH 10/15] suggested changes Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 15 +++++++++++---- js/generateFormComponents.js | 6 +++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index 471d529..7cc0f10 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -159,6 +159,7 @@ async function createBranchOnProject(projectURL, token) else { console.error('Error creating new branch: ', newBranchData); + alert("Failed to create branch on project! Error code: ", newBranchResponse.status, ". Please check API Key permissions and try again.") return false; } } @@ -190,7 +191,7 @@ async function addFileToBranch(projectURL, token, codeJSONObj) body: JSON.stringify({ message: "Add codejson to project", committer: { - name: "CodeJSON formsite", + name: "codejson-generator form site", email: "opensource@cms.hhs.gov" }, content: encodedContent, @@ -209,6 +210,7 @@ async function addFileToBranch(projectURL, token, codeJSONObj) else { console.error('Error adding file: ', data); + alert("Failed to add file on project! Error code: ", response.status, ". Please check API Key permissions and try again.") return false; } } @@ -227,7 +229,7 @@ async function createPR(projectURL, token) }, body: JSON.stringify({ title: "Add code.json to Project", - body: "Add generated code.json file to project. Code.json was generated via a form.io form site.", + body: "Add generated code.json file to project. Code.json was generated via codejson-generator form site.", head: NEW_BRANCH, base: 'main', @@ -245,6 +247,7 @@ async function createPR(projectURL, token) else { console.error("Error creating PR!: ", data); + alert("Failed to create PR on project! Error code: ", response.status, ". Please check API Key permissions and try again.") return false; } } @@ -279,18 +282,22 @@ async function createProjectPR(event){ } } } + else + { + console.error("Could not create branch on requested repository with the requested API key!") + } } else { console.error("No URL found!"); - alert("No URL given for project!"); + alert("No URL given for project! Please provide project URL in repositoryURL text box"); } } else { console.error("No API key found!"); - alert("No Api Key in submitted data!"); + alert("No API Key in submitted data! Please provide an API key"); } //console.log(codeJSONObj) } diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index 2bb34f5..6c809b3 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -303,7 +303,11 @@ async function createFormComponents() { "tableView": true, "key": "gh_api_key", "type": "textfield", - "input": true + "input": true, + "description": "Generate a Github API Key from here: https://github.com/settings/tokens/new .\n\ + The token should have these permissions: \n\ + - Contents: read &write \n- Workflows: read & write\ + - Pull requests: read & write" }); // Add submit button to form From 8b336891d3aeb6c984e695a31db031b4d5ce4f2f Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 15 Apr 2025 14:42:41 -0500 Subject: [PATCH 11/15] add createProjectPr to window properties --- js/formDataToJson.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index 7cc0f10..fe915ae 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -323,3 +323,4 @@ async function downloadFile(event) { window.createCodeJson = createCodeJson; window.copyToClipboard = copyToClipboard; window.downloadFile = downloadFile; +window.createProjectPR = createProjectPR; From 6d04de83f141d6dd021a533258222af6290748e1 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Tue, 15 Apr 2025 14:46:10 -0500 Subject: [PATCH 12/15] add password type to api key field Signed-off-by: Isaac Milarsky --- js/generateFormComponents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index 6c809b3..4bad13a 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -302,7 +302,7 @@ async function createFormComponents() { "disableSortingAndFiltering": false, "tableView": true, "key": "gh_api_key", - "type": "textfield", + "type": "password", "input": true, "description": "Generate a Github API Key from here: https://github.com/settings/tokens/new .\n\ The token should have these permissions: \n\ From f8099c375177825735cef5b648067d3095b16f5d Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Thu, 24 Apr 2025 13:15:55 -0500 Subject: [PATCH 13/15] review response Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 6 +++--- js/generateFormComponents.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index fe915ae..eae0b18 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -159,7 +159,7 @@ async function createBranchOnProject(projectURL, token) else { console.error('Error creating new branch: ', newBranchData); - alert("Failed to create branch on project! Error code: ", newBranchResponse.status, ". Please check API Key permissions and try again.") + alert("Failed to create branch on project! Error code: " + newBranchResponse.status + ". Please check API Key permissions and try again.") return false; } } @@ -210,7 +210,7 @@ async function addFileToBranch(projectURL, token, codeJSONObj) else { console.error('Error adding file: ', data); - alert("Failed to add file on project! Error code: ", response.status, ". Please check API Key permissions and try again.") + alert("Failed to add file on project! Error code: " + response.status + ". Please check API Key permissions and try again.") return false; } } @@ -247,7 +247,7 @@ async function createPR(projectURL, token) else { console.error("Error creating PR!: ", data); - alert("Failed to create PR on project! Error code: ", response.status, ". Please check API Key permissions and try again.") + alert("Failed to create PR on project! Error code: " + response.status + ". Please check API Key permissions and try again.") return false; } } diff --git a/js/generateFormComponents.js b/js/generateFormComponents.js index 4bad13a..d623518 100644 --- a/js/generateFormComponents.js +++ b/js/generateFormComponents.js @@ -306,7 +306,7 @@ async function createFormComponents() { "input": true, "description": "Generate a Github API Key from here: https://github.com/settings/tokens/new .\n\ The token should have these permissions: \n\ - - Contents: read &write \n- Workflows: read & write\ + - Contents: read & write \n- Workflows: read & write\ - Pull requests: read & write" }); From b867a9e7d47607f07182db1bb42ff7584645a9c3 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Thu, 24 Apr 2025 13:18:09 -0500 Subject: [PATCH 14/15] dup Signed-off-by: Isaac Milarsky --- index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/index.html b/index.html index 1b819d8..5f9e7de 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,6 @@ - From 3f585914042451a576a3fc4a660ea89a6cb1dac6 Mon Sep 17 00:00:00 2001 From: Isaac Milarsky Date: Fri, 2 May 2025 12:40:11 -0500 Subject: [PATCH 15/15] requested changes Signed-off-by: Isaac Milarsky --- js/formDataToJson.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/formDataToJson.js b/js/formDataToJson.js index eae0b18..157aeae 100644 --- a/js/formDataToJson.js +++ b/js/formDataToJson.js @@ -166,6 +166,7 @@ async function createBranchOnProject(projectURL, token) else { console.error('Error fetching base branch info:', data); + alert('Error fetching base branch info:', data); return false; } } @@ -284,7 +285,8 @@ async function createProjectPR(event){ } else { - console.error("Could not create branch on requested repository with the requested API key!") + console.error("Could not create branch on requested repository with the requested API key!"); + alert("Could not create branch on requested repository with the requested API key!"); } } else