From b10830ab7a0584b07bb65383ba45fab691b95647 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 15:47:25 +0200 Subject: [PATCH 01/16] GPT script - use temp folder for GPT output Doesn't contaminate repo root --- scripts/commentUsingGptResponse.js | 7 ++++--- scripts/gptGenerateJsonFromIssue.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/commentUsingGptResponse.js b/scripts/commentUsingGptResponse.js index e706770b..751ff9cc 100644 --- a/scripts/commentUsingGptResponse.js +++ b/scripts/commentUsingGptResponse.js @@ -4,13 +4,13 @@ module.exports = ({github, context}) => { const indexOfJsonStart = text.indexOf(jsonStartMarker); if (indexOfJsonStart === -1) { - console.log("Could not find JSON start marter"); + console.log("Could not find JSON start marker"); return null; } const indexOfJsonEnd = text.indexOf(jsonEndMarker, indexOfJsonStart + 1); if (indexOfJsonEnd === -1) { - console.log("Could not find JSON end marter"); + console.log("Could not find JSON end marker"); return null; } @@ -38,7 +38,8 @@ module.exports = ({github, context}) => { } const fs = require('fs') - const gptResponse = fs.readFileSync(process.env.GITHUB_WORKSPACE + "/gpt-auto-comment.output", 'utf8') + const tempFolder = process.env.TEMP || "/tmp" + const gptResponse = fs.readFileSync(tempFolder + "/gpt-auto-comment.output", "utf8") // https://stackoverflow.com/a/51602415/67824 var sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, "") diff --git a/scripts/gptGenerateJsonFromIssue.py b/scripts/gptGenerateJsonFromIssue.py index a64674cd..743bb3af 100644 --- a/scripts/gptGenerateJsonFromIssue.py +++ b/scripts/gptGenerateJsonFromIssue.py @@ -110,7 +110,7 @@ def ask_gpt_for_initiative_json(self, issue_body: str) -> str: if __name__ == "__main__": gpt_response = GPTAssistant().ask_gpt_for_initiative_json(os.environ["ISSUE_BODY"]) - respose_output_file = os.environ["GITHUB_WORKSPACE"] + "/gpt-auto-comment.output" + respose_output_file = os.getenv("TEMP", "/tmp") + "/gpt-auto-comment.output" logging.info(f"Writing GPT Response to {respose_output_file}:\n{gpt_response}") with open(respose_output_file, "w", encoding="utf-8") as output: From f87a748bc73a790de68787ba77f6462a94dee36f Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 15:55:12 +0200 Subject: [PATCH 02/16] retry on GPT failure --- .github/workflows/initiative-auto-comment.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/initiative-auto-comment.yml b/.github/workflows/initiative-auto-comment.yml index 8925bde0..a05a9e71 100644 --- a/.github/workflows/initiative-auto-comment.yml +++ b/.github/workflows/initiative-auto-comment.yml @@ -27,11 +27,15 @@ jobs: pip install -r "$GITHUB_WORKSPACE/scripts/requirements.txt" - name: Run GPT script + uses: nick-fields/retry@v2 env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} ISSUE_BODY: ${{ github.event.issue.body }} - run: python $GITHUB_WORKSPACE/scripts/gptGenerateJsonFromIssue.py - + with: + timeout_minutes: 5 + max_attempts: 3 + command: python $GITHUB_WORKSPACE/scripts/gptGenerateJsonFromIssue.py + - name: Post comment uses: actions/github-script@v6 with: From 9eaef2ae7e2241ba6948b2fe58d7c2bd3624a9ba Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 17:16:33 +0200 Subject: [PATCH 03/16] new initative yaml - fix initiativeImage key renamed from `logo` --- .github/ISSUE_TEMPLATE/new_initiative.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_initiative.yml b/.github/ISSUE_TEMPLATE/new_initiative.yml index 6c0c13df..bf051026 100644 --- a/.github/ISSUE_TEMPLATE/new_initiative.yml +++ b/.github/ISSUE_TEMPLATE/new_initiative.yml @@ -151,7 +151,7 @@ body: placeholder: https://twitter.com/iron-widgets - type: input - id: logo + id: initiativeImage attributes: label: Initiative logo description: Link to an image of the initiative's logo (suitable for inclusion in an HTML `IMG` tag) From b944566f5c030016a905b7c9c88e2e9cf7c17952 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 17:17:02 +0200 Subject: [PATCH 04/16] locally test GPT comment script --- scripts/test_commentUsingGptResponse.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 scripts/test_commentUsingGptResponse.js diff --git a/scripts/test_commentUsingGptResponse.js b/scripts/test_commentUsingGptResponse.js new file mode 100644 index 00000000..6582e689 --- /dev/null +++ b/scripts/test_commentUsingGptResponse.js @@ -0,0 +1,24 @@ +const github = { + rest: { + issues: { + createComment: (cmt) => { + console.log("posting comment:") + console.log(cmt) + } + } + } +} + +const context = { + repo: { + owner: "ohadschn", + repo: "links4israel" + }, + issue: { + number: 42 + } +} + +const script = require('./commentUsingGptResponse.js') + +script({github, context}) \ No newline at end of file From c3ca0f1028ca4aae01b75602dba607da8254a4c7 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 19:41:47 +0200 Subject: [PATCH 05/16] Foo --- _data/links/Medical/Main/links.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/_data/links/Medical/Main/links.json b/_data/links/Medical/Main/links.json index bc81c098..810786e0 100644 --- a/_data/links/Medical/Main/links.json +++ b/_data/links/Medical/Main/links.json @@ -41,6 +41,23 @@ "description": "ניתן על ידי חברת ניתאי שירותי עזרה ראשונה", "url": "./docs/ezra-rishona", "portal": "./docs/ezra-rishona" + }, + { + "displayName": "נסיון", + "name": "Foo", + "shortDescription": "FooBar", + "description": "The quick brown fox jumps over the lazy dog", + "initiativeValidationDetails": "Trust me!", + "url": "https://example.com", + "website": "https://example.com", + "logo": "https://example.com/log.png", + "tags": [ + "רופאים", + "מתנדבים", + "תרומה", + "בריאות", + "ישראל" + ] } ] } \ No newline at end of file From c789e66a607de4011075051be3790d751fef2c8a Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:05:14 +0200 Subject: [PATCH 06/16] auto create PR --- scripts/commentUsingGptResponse.js | 115 ++++++++++++++++++------ scripts/test_commentUsingGptResponse.js | 11 ++- 2 files changed, 100 insertions(+), 26 deletions(-) diff --git a/scripts/commentUsingGptResponse.js b/scripts/commentUsingGptResponse.js index 751ff9cc..7f245f41 100644 --- a/scripts/commentUsingGptResponse.js +++ b/scripts/commentUsingGptResponse.js @@ -1,4 +1,8 @@ module.exports = ({github, context}) => { + + const fs = require('fs') + const cp = require('child_process') + function tryExtractJson(text, jsonStartMarker, jsonEndMarker) { console.log(`Attempting to extract JSON with start marker "${jsonStartMarker}" and end marker "${jsonEndMarker}"` ); @@ -15,51 +19,112 @@ module.exports = ({github, context}) => { } return text.substring(indexOfJsonStart + jsonStartMarker.length, indexOfJsonEnd); - } + } - function createComment(gptResponseJson) { - console.log("Extracted JSON: " + gptResponseJson); - - try { - humanReadableJson = JSON.stringify(JSON.parse(gptResponseJson), null, 2); - } - catch (e) { - console.warn("Could not process JSON: " + e); - humanReadableJson = "// WARNING: THIS IS MOST LIKELY INVALID JSON, PLEASE REVIEW MANUALLY \n" + gptResponseJson; - } + function createPullRequest(branch, name) { + return github.rest.pulls.create({ + title: 'New Initiative: ' + name, + owner: context.repo.owner, + repo: context.repo.repo, + head: branch, + base: 'main', + body: "*IMPORTANT: Only merge after validating the initiative and double checking the generated JSON*" + }); + } - console.log("Human readable JSON: " + humanReadableJson); + function createComment(body) { github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, - body: "```json\n" + humanReadableJson + "\n```" + body: body }); } - const fs = require('fs') + function warnAndComment(warning, exception, json) { + console.warn(`${warning}: ${exception}`); + createComment(`WARNING: ${warning} (see GitHub Action logs for more details)\n` + "Automatic PR will NOT be generated:\n" + json) + } + + function executeGitCommand(args) { + console.log(`Executing: git ${args}`); + cp.execFileSync("git", args) + } + const tempFolder = process.env.TEMP || "/tmp" const gptResponse = fs.readFileSync(tempFolder + "/gpt-auto-comment.output", "utf8") // https://stackoverflow.com/a/51602415/67824 var sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, "") + console.log("Sanitized GPT response: " + sanitizedGptResponse) + const jsonStartMarker = "```json" const jsonEndMarker = "```" + jsonString = tryExtractJson(sanitizedGptResponse, jsonStartMarker, jsonEndMarker) || tryExtractJson(sanitizedGptResponse, jsonEndMarker, jsonEndMarker) + if (jsonString == null) { + console.log("Could not find JSON markers in GPT output, assuming raw JSON"); + jsonString = sanitizedGptResponse + } + console.log("Extracted JSON: " + jsonString); - console.log("Sanitized GPT response: " + sanitizedGptResponse) + try { + json = JSON.parse(jsonString) + } + catch (e) { + return warnAndComment("Could not process GPT response as JSON", e, jsonString) + } + + humanReadableJson = "```json\n" + JSON.stringify(json, null, 2) + "\n```" - json = tryExtractJson(sanitizedGptResponse, jsonStartMarker, jsonEndMarker); - if (json !== null) { - createComment(json); - return; + try { + var categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${json.category}/links.json` + console.log("resolved category links file: " + categoryLinksJsonFile) + + var categoryJsonString = fs.readFileSync(categoryLinksJsonFile, "utf8") + categoryJson = JSON.parse(categoryJsonString) + } + catch (e) { + return warnAndComment("Could not process category links JSON", e, humanReadableJson) + } + + delete json.category //not in our schema, and worse - will interfere with the existing initiative detection below + console.log("Attempting to detect already existing initiative under this category") + + const upperCategoryJsonString = categoryJsonString.toLocaleUpperCase("en-us") + for (const prop in json) { + + const value = json[prop] + if (typeof value !== "string") { + continue + } + + const PropValueUpper = value.toLocaleUpperCase("en-us") + if (upperCategoryJsonString.indexOf(PropValueUpper) !== -1) { + return warnAndComment(`Initiative might already exist under this category, the value of property ${prop} is already present in the JSON: ${value}`, "suspected existing initiative", humanReadableJson) + } } - json = tryExtractJson(sanitizedGptResponse, jsonEndMarker, jsonEndMarker) // sometimes GPT will return the JSON in the form of ``` {} ``` - if (json !== null) { - createComment(json); - return; + categoryJson.links.push(json) + fs.writeFileSync(categoryLinksJsonFile, JSON.stringify(categoryJson, null, 2), "utf8") + + const branch = `auto-pr-${context.issue.number}` + try { + executeGitCommand(["checkout", "-b", branch]) + executeGitCommand(["add", categoryLinksJsonFile]) + executeGitCommand(["commit", "-m", json.name || "new initiative"]) + executeGitCommand(["push", "origin", branch]) + } + catch (e) { + return warnAndComment("encountered error during git execution", e, humanReadableJson) + } + + try { + // TODO check if PR already exists + var pr = createPullRequest(branch, json.name || "???") + } + catch (e) { + return warnAndComment("Could not create pull request", e, humanReadableJson) } - console.log("Could not find JSON markers in GPT output, assuming raw JSON"); - createComment(sanitizedGptResponse); + createComment("Created pull request: " + pr.url); } \ No newline at end of file diff --git a/scripts/test_commentUsingGptResponse.js b/scripts/test_commentUsingGptResponse.js index 6582e689..e5a93b93 100644 --- a/scripts/test_commentUsingGptResponse.js +++ b/scripts/test_commentUsingGptResponse.js @@ -5,6 +5,15 @@ const github = { console.log("posting comment:") console.log(cmt) } + }, + pulls: { + create: (pr) => { + console.log("creating PR:") + console.log(pr) + return { + url: "https://example.com" + } + } } } } @@ -12,7 +21,7 @@ const github = { const context = { repo: { owner: "ohadschn", - repo: "links4israel" + repo: "ohadschn/ConnectPortal" }, issue: { number: 42 From 9850400f2b17352fb86c56fd540ef271cc4b8a36 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:26:21 +0200 Subject: [PATCH 07/16] check existing PRs --- scripts/commentUsingGptResponse.js | 84 +++++++++++++++++------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/scripts/commentUsingGptResponse.js b/scripts/commentUsingGptResponse.js index 7f245f41..5f6147ed 100644 --- a/scripts/commentUsingGptResponse.js +++ b/scripts/commentUsingGptResponse.js @@ -1,7 +1,7 @@ module.exports = ({github, context}) => { - const fs = require('fs') - const cp = require('child_process') + const fs = require('fs'); + const cp = require('child_process'); function tryExtractJson(text, jsonStartMarker, jsonEndMarker) { console.log(`Attempting to extract JSON with start marker "${jsonStartMarker}" and end marker "${jsonEndMarker}"` ); @@ -21,7 +21,21 @@ module.exports = ({github, context}) => { return text.substring(indexOfJsonStart + jsonStartMarker.length, indexOfJsonEnd); } - function createPullRequest(branch, name) { + function createOrUpdatePullRequest(branch, name) { + + var prs = github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + head: branch, + base: 'main', + }) + + if (prs && prs.length > 0) { + console.log("At least one PR exists for this branch: " + JSON.stringify(prs)); + prs[0].existing = true; + return prs[0]; + } + return github.rest.pulls.create({ title: 'New Initiative: ' + name, owner: context.repo.owner, @@ -43,88 +57,88 @@ module.exports = ({github, context}) => { function warnAndComment(warning, exception, json) { console.warn(`${warning}: ${exception}`); - createComment(`WARNING: ${warning} (see GitHub Action logs for more details)\n` + "Automatic PR will NOT be generated:\n" + json) + createComment(`WARNING: ${warning} (see GitHub Action logs for more details)\n` + "Automatic PR will NOT be generated:\n" + json); } function executeGitCommand(args) { console.log(`Executing: git ${args}`); - cp.execFileSync("git", args) + cp.execFileSync("git", args); } - const tempFolder = process.env.TEMP || "/tmp" - const gptResponse = fs.readFileSync(tempFolder + "/gpt-auto-comment.output", "utf8") + const tempFolder = process.env.TEMP || "/tmp"; + const gptResponse = fs.readFileSync(tempFolder + "/gpt-auto-comment.output", "utf8"); // https://stackoverflow.com/a/51602415/67824 - var sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, "") - console.log("Sanitized GPT response: " + sanitizedGptResponse) + var sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, ""); + console.log("Sanitized GPT response: " + sanitizedGptResponse); - const jsonStartMarker = "```json" - const jsonEndMarker = "```" - jsonString = tryExtractJson(sanitizedGptResponse, jsonStartMarker, jsonEndMarker) || tryExtractJson(sanitizedGptResponse, jsonEndMarker, jsonEndMarker) + const jsonStartMarker = "```json"; + const jsonEndMarker = "```"; + jsonString = tryExtractJson(sanitizedGptResponse, jsonStartMarker, jsonEndMarker) || tryExtractJson(sanitizedGptResponse, jsonEndMarker, jsonEndMarker); if (jsonString == null) { console.log("Could not find JSON markers in GPT output, assuming raw JSON"); - jsonString = sanitizedGptResponse + jsonString = sanitizedGptResponse; } console.log("Extracted JSON: " + jsonString); try { - json = JSON.parse(jsonString) + json = JSON.parse(jsonString); } catch (e) { - return warnAndComment("Could not process GPT response as JSON", e, jsonString) + return warnAndComment("Could not process GPT response as JSON", e, jsonString); } - humanReadableJson = "```json\n" + JSON.stringify(json, null, 2) + "\n```" + humanReadableJson = "```json\n" + JSON.stringify(json, null, 2) + "\n```"; try { - var categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${json.category}/links.json` - console.log("resolved category links file: " + categoryLinksJsonFile) + var categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${json.category}/links.json`; + console.log("resolved category links file: " + categoryLinksJsonFile); - var categoryJsonString = fs.readFileSync(categoryLinksJsonFile, "utf8") - categoryJson = JSON.parse(categoryJsonString) + var categoryJsonString = fs.readFileSync(categoryLinksJsonFile, "utf8"); + categoryJson = JSON.parse(categoryJsonString); } catch (e) { - return warnAndComment("Could not process category links JSON", e, humanReadableJson) + return warnAndComment("Could not process category links JSON", e, humanReadableJson); } delete json.category //not in our schema, and worse - will interfere with the existing initiative detection below - console.log("Attempting to detect already existing initiative under this category") + console.log("Attempting to detect already existing initiative under this category"); - const upperCategoryJsonString = categoryJsonString.toLocaleUpperCase("en-us") + const upperCategoryJsonString = categoryJsonString.toLocaleUpperCase("en-us"); for (const prop in json) { - const value = json[prop] + const value = json[prop]; if (typeof value !== "string") { - continue + continue; } - const PropValueUpper = value.toLocaleUpperCase("en-us") + const PropValueUpper = value.toLocaleUpperCase("en-us"); if (upperCategoryJsonString.indexOf(PropValueUpper) !== -1) { - return warnAndComment(`Initiative might already exist under this category, the value of property ${prop} is already present in the JSON: ${value}`, "suspected existing initiative", humanReadableJson) + return warnAndComment(`Initiative might already exist under this category, the value of property ${prop} is already present in the JSON: ${value}`, "suspected existing initiative", humanReadableJson); } } - categoryJson.links.push(json) - fs.writeFileSync(categoryLinksJsonFile, JSON.stringify(categoryJson, null, 2), "utf8") + categoryJson.links.push(json); + fs.writeFileSync(categoryLinksJsonFile, JSON.stringify(categoryJson, null, 2), "utf8"); - const branch = `auto-pr-${context.issue.number}` + const branch = `auto-pr-${context.issue.number}`; try { executeGitCommand(["checkout", "-b", branch]) executeGitCommand(["add", categoryLinksJsonFile]) executeGitCommand(["commit", "-m", json.name || "new initiative"]) - executeGitCommand(["push", "origin", branch]) + executeGitCommand(["push", "origin", branch, "--force"]) } catch (e) { - return warnAndComment("encountered error during git execution", e, humanReadableJson) + return warnAndComment("encountered error during git execution", e, humanReadableJson); } try { // TODO check if PR already exists - var pr = createPullRequest(branch, json.name || "???") + var pr = createOrUpdatePullRequest(branch, json.name || "???"); } catch (e) { - return warnAndComment("Could not create pull request", e, humanReadableJson) + return warnAndComment("Could not create pull request", e, humanReadableJson); } - createComment("Created pull request: " + pr.url); + createComment((pr.existing ? "Updated" : "Created") + " PR: " + pr.url); } \ No newline at end of file From 8c4202535423546c18dc1e9e31281f498175f7df Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:28:02 +0200 Subject: [PATCH 08/16] Revert "Foo" This reverts commit c3ca0f1028ca4aae01b75602dba607da8254a4c7. --- _data/links/Medical/Main/links.json | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/_data/links/Medical/Main/links.json b/_data/links/Medical/Main/links.json index 810786e0..bc81c098 100644 --- a/_data/links/Medical/Main/links.json +++ b/_data/links/Medical/Main/links.json @@ -41,23 +41,6 @@ "description": "ניתן על ידי חברת ניתאי שירותי עזרה ראשונה", "url": "./docs/ezra-rishona", "portal": "./docs/ezra-rishona" - }, - { - "displayName": "נסיון", - "name": "Foo", - "shortDescription": "FooBar", - "description": "The quick brown fox jumps over the lazy dog", - "initiativeValidationDetails": "Trust me!", - "url": "https://example.com", - "website": "https://example.com", - "logo": "https://example.com/log.png", - "tags": [ - "רופאים", - "מתנדבים", - "תרומה", - "בריאות", - "ישראל" - ] } ] } \ No newline at end of file From 50ae9b040d1a95578283a2c904f0b44a7f2da506 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:43:11 +0200 Subject: [PATCH 09/16] new initiative yaml - normalize categories --- .github/ISSUE_TEMPLATE/new_initiative.yml | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_initiative.yml b/.github/ISSUE_TEMPLATE/new_initiative.yml index bf051026..c7775d48 100644 --- a/.github/ISSUE_TEMPLATE/new_initiative.yml +++ b/.github/ISSUE_TEMPLATE/new_initiative.yml @@ -48,28 +48,33 @@ body: attributes: label: Initiative Category options: - - Agriculture - - Children + - Agriculture/Main + - Children/Main - Defense/Evacuation - Defense/Shelters - Defense/Weapons - - Donations - - FamilyHosting + - Donations/Agriculture + - Donations/Main + - FamilyHosting/Main - GeneralAssistance - - Initiatives - - Medical - - MemorialRemembrance - - MentalSupport + - Initiatives/Main + - Medical/Main + - MemorialRemembrance/Main + - MentalSupport/Main - MissingPersons/Main - - Reserves - - SocialNetworks - - StrategicCommunication - - Supplies + - Reserves/Main + - StrategicCommunication/Funding + - StrategicCommunication/Info + - StrategicCommunication/Main + - StrategicCommunication/SocialNetworks + - StrategicCommunication/Tools + - Supplies/Donation + - Supplies/Main - TechInitiatives/Main - TechInitiatives/Support - TechInitiatives/Volunteers - - Transportation - - Volunteering + - Transportation/Main + - Volunteering/Main default: 0 validations: required: true From 1952f7d6e02870ab2c92e396e275f10f6733856c Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:43:43 +0200 Subject: [PATCH 10/16] minor renames --- .../{initiative-auto-comment.yml => initiative-auto-pr.yml} | 4 ++-- ...gGptResponse.js => generatePullRequestForNewInitiative.js} | 0 ...esponse.js => test_generatePullRequestForNewInitiative.js} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename .github/workflows/{initiative-auto-comment.yml => initiative-auto-pr.yml} (93%) rename scripts/{commentUsingGptResponse.js => generatePullRequestForNewInitiative.js} (100%) rename scripts/{test_commentUsingGptResponse.js => test_generatePullRequestForNewInitiative.js} (90%) diff --git a/.github/workflows/initiative-auto-comment.yml b/.github/workflows/initiative-auto-pr.yml similarity index 93% rename from .github/workflows/initiative-auto-comment.yml rename to .github/workflows/initiative-auto-pr.yml index a05a9e71..e56c9a2a 100644 --- a/.github/workflows/initiative-auto-comment.yml +++ b/.github/workflows/initiative-auto-pr.yml @@ -36,9 +36,9 @@ jobs: max_attempts: 3 command: python $GITHUB_WORKSPACE/scripts/gptGenerateJsonFromIssue.py - - name: Post comment + - name: Generate PR uses: actions/github-script@v6 with: script: | - const script = require(process.env.GITHUB_WORKSPACE + '/scripts/commentUsingGptResponse.js') + const script = require(process.env.GITHUB_WORKSPACE + '/scripts/generatePullRequestForNewInitiative.js') script({github, context}) diff --git a/scripts/commentUsingGptResponse.js b/scripts/generatePullRequestForNewInitiative.js similarity index 100% rename from scripts/commentUsingGptResponse.js rename to scripts/generatePullRequestForNewInitiative.js diff --git a/scripts/test_commentUsingGptResponse.js b/scripts/test_generatePullRequestForNewInitiative.js similarity index 90% rename from scripts/test_commentUsingGptResponse.js rename to scripts/test_generatePullRequestForNewInitiative.js index e5a93b93..72597375 100644 --- a/scripts/test_commentUsingGptResponse.js +++ b/scripts/test_generatePullRequestForNewInitiative.js @@ -28,6 +28,6 @@ const context = { } } -const script = require('./commentUsingGptResponse.js') +const script = require('./generatePullRequestForNewInitiative.js') script({github, context}) \ No newline at end of file From 15b6ed520e600e0323d566fd902c712901f74895 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:45:52 +0200 Subject: [PATCH 11/16] minor yml renames --- .github/workflows/initiative-auto-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/initiative-auto-pr.yml b/.github/workflows/initiative-auto-pr.yml index e56c9a2a..2a4cb49e 100644 --- a/.github/workflows/initiative-auto-pr.yml +++ b/.github/workflows/initiative-auto-pr.yml @@ -1,11 +1,11 @@ -name: Initiative Request - Auto Comment +name: Initiative Request - Automatic PR on: issues: types: [opened, edited] jobs: - add-comment: + create-pr: if: contains(github.event.issue.labels.*.name, 'new-initiative-request') runs-on: ubuntu-latest permissions: From 847c02213a72aa08dc5450bf8ed215431d007eae Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:53:27 +0200 Subject: [PATCH 12/16] set git user details --- scripts/generatePullRequestForNewInitiative.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/generatePullRequestForNewInitiative.js b/scripts/generatePullRequestForNewInitiative.js index 5f6147ed..fc01f77e 100644 --- a/scripts/generatePullRequestForNewInitiative.js +++ b/scripts/generatePullRequestForNewInitiative.js @@ -123,6 +123,8 @@ module.exports = ({github, context}) => { const branch = `auto-pr-${context.issue.number}`; try { + executeGitCommand(["config", "user.name", "github-actions"]) + executeGitCommand(["config", "user.email", "41898282+github-actions[bot]@users.noreply.github.com"]) //https://github.com/orgs/community/discussions/26560 executeGitCommand(["checkout", "-b", branch]) executeGitCommand(["add", categoryLinksJsonFile]) executeGitCommand(["commit", "-m", json.name || "new initiative"]) From a5943cd5a88bbe6ff01c964611b1033b5cf35a6d Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 20:58:37 +0200 Subject: [PATCH 13/16] fix action permissions --- .github/workflows/initiative-auto-pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/initiative-auto-pr.yml b/.github/workflows/initiative-auto-pr.yml index 2a4cb49e..6d3312a2 100644 --- a/.github/workflows/initiative-auto-pr.yml +++ b/.github/workflows/initiative-auto-pr.yml @@ -9,8 +9,9 @@ jobs: if: contains(github.event.issue.labels.*.name, 'new-initiative-request') runs-on: ubuntu-latest permissions: - contents: read + contents: write issues: write + pull-requests: write steps: - name: Checkout code From d348f609c5a01a4cdcfcc0a4b87a96394d95d254 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 21:12:44 +0200 Subject: [PATCH 14/16] fix github API response handling --- scripts/generatePullRequestForNewInitiative.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/generatePullRequestForNewInitiative.js b/scripts/generatePullRequestForNewInitiative.js index fc01f77e..c7574c44 100644 --- a/scripts/generatePullRequestForNewInitiative.js +++ b/scripts/generatePullRequestForNewInitiative.js @@ -23,20 +23,22 @@ module.exports = ({github, context}) => { function createOrUpdatePullRequest(branch, name) { - var prs = github.rest.pulls.list({ + var response = github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, head: branch, base: 'main', }) + console.log("existing PRs: " + JSON.stringify(response)); - if (prs && prs.length > 0) { - console.log("At least one PR exists for this branch: " + JSON.stringify(prs)); - prs[0].existing = true; - return prs[0]; + existingPrs = response.data + if (existingPrs && existingPrs.length > 0) { + console.log("At least one PR exists for this branch"); + existingPrs[0].existing = true; + return existingPrs[0]; } - return github.rest.pulls.create({ + response = github.rest.pulls.create({ title: 'New Initiative: ' + name, owner: context.repo.owner, repo: context.repo.repo, @@ -44,6 +46,9 @@ module.exports = ({github, context}) => { base: 'main', body: "*IMPORTANT: Only merge after validating the initiative and double checking the generated JSON*" }); + console.log("Created new PR: " + JSON.stringify(response)); + + return response.data } function createComment(body) { @@ -135,7 +140,6 @@ module.exports = ({github, context}) => { } try { - // TODO check if PR already exists var pr = createOrUpdatePullRequest(branch, json.name || "???"); } catch (e) { From b9c1053c88441c26633c6299b8e272a9ee369e41 Mon Sep 17 00:00:00 2001 From: Ohad Schneider Date: Thu, 2 Nov 2023 21:22:14 +0200 Subject: [PATCH 15/16] fix variable scopes --- .../generatePullRequestForNewInitiative.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/generatePullRequestForNewInitiative.js b/scripts/generatePullRequestForNewInitiative.js index c7574c44..a507c0b0 100644 --- a/scripts/generatePullRequestForNewInitiative.js +++ b/scripts/generatePullRequestForNewInitiative.js @@ -23,22 +23,22 @@ module.exports = ({github, context}) => { function createOrUpdatePullRequest(branch, name) { - var response = github.rest.pulls.list({ + const existingResponse = github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, head: branch, base: 'main', }) - console.log("existing PRs: " + JSON.stringify(response)); + console.log("existing PRs: " + JSON.stringify(existingResponse)); - existingPrs = response.data + existingPrs = existingResponse.data if (existingPrs && existingPrs.length > 0) { console.log("At least one PR exists for this branch"); existingPrs[0].existing = true; return existingPrs[0]; } - response = github.rest.pulls.create({ + const newResponse = github.rest.pulls.create({ title: 'New Initiative: ' + name, owner: context.repo.owner, repo: context.repo.repo, @@ -46,9 +46,9 @@ module.exports = ({github, context}) => { base: 'main', body: "*IMPORTANT: Only merge after validating the initiative and double checking the generated JSON*" }); - console.log("Created new PR: " + JSON.stringify(response)); + console.log("Created new PR: " + JSON.stringify(newResponse)); - return response.data + return newResponse.data } function createComment(body) { @@ -74,7 +74,7 @@ module.exports = ({github, context}) => { const gptResponse = fs.readFileSync(tempFolder + "/gpt-auto-comment.output", "utf8"); // https://stackoverflow.com/a/51602415/67824 - var sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, ""); + const sanitizedGptResponse = gptResponse.replace(/[\u0000-\u001F\u007F-\u009F]/g, ""); console.log("Sanitized GPT response: " + sanitizedGptResponse); const jsonStartMarker = "```json"; @@ -95,11 +95,12 @@ module.exports = ({github, context}) => { humanReadableJson = "```json\n" + JSON.stringify(json, null, 2) + "\n```"; + let categoryLinksJsonFile, categoryJsonString; try { - var categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${json.category}/links.json`; + categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${json.category}/links.json`; console.log("resolved category links file: " + categoryLinksJsonFile); - var categoryJsonString = fs.readFileSync(categoryLinksJsonFile, "utf8"); + categoryJsonString = fs.readFileSync(categoryLinksJsonFile, "utf8"); categoryJson = JSON.parse(categoryJsonString); } catch (e) { @@ -139,8 +140,9 @@ module.exports = ({github, context}) => { return warnAndComment("encountered error during git execution", e, humanReadableJson); } + let pr; try { - var pr = createOrUpdatePullRequest(branch, json.name || "???"); + pr = createOrUpdatePullRequest(branch, json.name || "???"); } catch (e) { return warnAndComment("Could not create pull request", e, humanReadableJson); From b3077fd4c43c4096a0cda0a44007b459fa886a97 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:07:37 +0200 Subject: [PATCH 16/16] Bar21 --- _data/links/Children/Main/links.json | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/_data/links/Children/Main/links.json b/_data/links/Children/Main/links.json index 4d0e2bf2..23475ba1 100644 --- a/_data/links/Children/Main/links.json +++ b/_data/links/Children/Main/links.json @@ -55,6 +55,31 @@ "description": "קוד: בריינפופ23", "url": "https://il.brainpop.com/", "website": "https://il.brainpop.com/" + }, + { + "displayName": "Bar21", + "name": "Bar21", + "shortDescription": "FooBaz", + "description": "hello world", + "initiativeValidationDetails": "Source: Are you the developer? If not, how did you hear about it?\nLink to reputable source(s) promoting the initiative: [e.g. https://www.israelhayom.co.il/tech/tech-news/iron-swords]\nContact details for members of the initiative's team (so we can contact them directly for validation): [e.g. info@iron-widgets.com]", + "url": "N/A", + "website": "N/A", + "whatsapp": "N/A", + "telegram": "N/A", + "drive": "N/A", + "form": "N/A", + "docs": "N/A", + "discord": "N/A", + "facebook": "N/A", + "instagram": "N/A", + "tiktok": "N/A", + "twitter": "N/A", + "initiativeImage": "N/A", + "tags": [ + "Bar21", + "FooBaz", + "hello world" + ] } ] } \ No newline at end of file