diff --git a/_data/links/Children/Main/links.json b/_data/links/Children/Main/links.json index f5b33bf5..f67e6db1 100644 --- a/_data/links/Children/Main/links.json +++ b/_data/links/Children/Main/links.json @@ -57,23 +57,16 @@ "website": "https://il.brainpop.com/" }, { - "displayName": "מערך בייביסיטר ארצי", + "displayName": "נסיון עריכה", "name": "NewDealBabysitter", - "shortDescription": "מערך בייביסיטר ארצי", - "description": "זקוקים/ות לבייביסיטר בזמן המלחמה? 'חוזה חדש' פה בשבילכם! משפחות רבות מוצאות עצמן במצב קשה בו אחד או יותר מהורי המשפחה אינו בבית, והמשפחה זקוקה לעזרה עם הילדים. לצורך כך הקמנו מערך ארצי של שמרטפים ושמרטפיות (הצטרפות מגיל 18). מוזמנים להצטרף לאחת מהקבוצות האזוריות, בה יבוצע חיבור בין משפחות הזקוקת לעזרה לבין המתנדבים שלנו.", - "initiativeValidationDetails": "Known organization from before the war", - "url": "https://www.new-deal.org.il/babysitter", - "website": "https://www.new-deal.org.il/babysitter", - "whatsapp": "https://chat.whatsapp.com/E7POYA8pBlu1C1EZy1fDLq", - "docs": "https://www.hopp.bio/new-deal", - "initiativeImage": "https://scontent.ftlv6-1.fna.fbcdn.net/v/t39.30808-6/307851307_420511490189366_1794830304047005228_n.png?_nc_cat=109&ccb=1-7&_nc_sid=5f2048&_nc_ohc=wuiPNY9ShrMAX8tE1tR&_nc_ht=scontent.ftlv6-1.fna&oh=00_AfBe0c3Ywgl9gSTeoSmWSjtCyX51nr97EMMExVLbo_z28Q&oe=65547942", + "shortDescription": "EditableFoo test2", + "description": "EditableFoo full test", + "initiativeValidationDetails": "source: trust me bro", + "url": "https://exampl.ecom", "tags": [ - "חוזה חדש", - "בייביסיטר", - "שמרטף", - "מלחמה", - "משפחה", - "ילדים" + "נסיון", + "עריכה", + "ביביסיטר" ] } ] diff --git a/scripts/generatePullRequestForNewInitiative.js b/scripts/generatePullRequestForNewInitiative.js index c4b8dd3f..c95503cb 100644 --- a/scripts/generatePullRequestForNewInitiative.js +++ b/scripts/generatePullRequestForNewInitiative.js @@ -66,7 +66,9 @@ module.exports = async ({github, context}) => { await createCommentAsync(`**WARNING**: ${warning} Automatic PR will NOT be generated -${json} +\`\`\`json +${JSON.stringify(json, null, 2)} +\`\`\` See GitHub Action logs for more details: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`); } @@ -164,9 +166,10 @@ The value of property \`${prop}\` (\`${value}\`) is already present in \`${linkJ \`\`\`json ${linksJsonString} \`\`\` -**If this is a mistake and it doesn't already exist:** edit the issue's title so that it starts with **\`[NEW-INITIATIVE-FORCE-PR]:\`**`, +**If this is a mistake and it doesn't already exist:** edit the issue's title so that it starts with **\`[FORCE-PR-NEW-INITIATIVE]:\`** +**If you wish to update an existing initiative:** edit the issue's title so that it starts with **\`[UPDATE-INITIATIVE]:\`**`, "Suspected existing initiative", - markdownNewInitiativeJson) + newInitiativeJson) return true; } } @@ -175,6 +178,26 @@ ${linksJsonString} return false; } + async function updateExistingInitiativeAsync(categoryJson, newInitiativeJson) { + const initiativeName = newInitiativeJson.name; + + if (!(initiativeName?.trim())) { + await warnAndCommentAsync("For update, you must provide a name that matches the name of an existing initiative", "no initiative name provided", newInitiativeJson); + return false; + } + + const existingCategoryIndex = categoryJson.links.findIndex((link => + link.name?.localeCompare(initiativeName, undefined, { sensitivity: 'accent' }) === 0 + )) + if (existingCategoryIndex === -1) { + await warnAndCommentAsync(`Could not find existing initiative '${initiativeName}' in category '${category}'`, "initiative not found", newInitiativeJson); + return false; + } + + categoryJson.links[existingCategoryIndex] = newInitiativeJson; + return true; + } + const tempFolder = process.env.TEMP || "/tmp"; const gptResponse = await fs.readFile(tempFolder + "/gpt-auto-comment.output", "utf8"); @@ -199,30 +222,43 @@ ${linksJsonString} return await warnAndCommentAsync("Could not process GPT response as JSON", e, jsonString); } - const markdownNewInitiativeJson = "```json\n" + JSON.stringify(newInitiativeJson, null, 2) + "\n```"; + // saving the category before we delete it from the object + category = newInitiativeJson.category + removeRedundantInitiativeJsonProperties(newInitiativeJson); + + const issueTitleUpper = process.env.ISSUE_TITLE.toLocaleUpperCase("en-us"); + const forceNewInitiative = issueTitleUpper.startsWith("[FORCE-PR-NEW-INITIATIVE]:"); + const updateInitiative = issueTitleUpper.startsWith("[UPDATE-INITIATIVE]:"); + + if (forceNewInitiative) { + console.warn("FORCE-PR requested: skipping existing initiative validation"); + } + else if (!updateInitiative && await detectExistingInitiativeAsync(newInitiativeJson)) { + return; + } let categoryLinksJsonFile; try { - categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${newInitiativeJson.category}/links.json`; + categoryLinksJsonFile = `${process.env.GITHUB_WORKSPACE}/_data/links/${category}/links.json`; console.log("resolved category links file: " + categoryLinksJsonFile); const categoryJsonString = await fs.readFile(categoryLinksJsonFile, "utf8"); categoryJson = JSON.parse(categoryJsonString); } catch (e) { - return await warnAndCommentAsync("Could not process category links JSON", e, markdownNewInitiativeJson); + return await warnAndCommentAsync("Could not process category links JSON", e, newInitiativeJson); } - removeRedundantInitiativeJsonProperties(newInitiativeJson); - - if (process.env.ISSUE_TITLE.toLocaleUpperCase("en-us").startsWith("[NEW-INITIATIVE-FORCE-PR]:")) { - console.warn("FORCE-PR requested: skipping existing initiative validation"); + if (updateInitiative) { + const edited = await updateExistingInitiativeAsync(categoryJson, newInitiativeJson, newInitiativeJson) + if (!edited) { + return; + } } - else if (await detectExistingInitiativeAsync(newInitiativeJson)) { - return; + else { + categoryJson.links.push(newInitiativeJson); } - categoryJson.links.push(newInitiativeJson); await fs.writeFile(categoryLinksJsonFile, JSON.stringify(categoryJson, null, 2), "utf8"); const branch = `auto-pr-${context.issue.number}`; @@ -230,7 +266,7 @@ ${linksJsonString} pushPrBranch(branch, categoryLinksJsonFile, newInitiativeJson.name); } catch (e) { - return await warnAndCommentAsync("encountered error during git execution", e, markdownNewInitiativeJson); + return await warnAndCommentAsync("encountered error during git execution", e, newInitiativeJson); } let pr; @@ -238,7 +274,7 @@ ${linksJsonString} pr = await createOrUpdatePullRequestAsync(branch, newInitiativeJson.name || "???"); } catch (e) { - return await warnAndCommentAsync("Could not create pull request", e, markdownNewInitiativeJson); + return await warnAndCommentAsync("Could not create pull request", e, newInitiativeJson); } console.log("resolved PR: " + JSON.stringify(pr)) diff --git a/scripts/gptGenerateJsonFromIssue.py b/scripts/gptGenerateJsonFromIssue.py index d99d8d0b..8e489616 100644 --- a/scripts/gptGenerateJsonFromIssue.py +++ b/scripts/gptGenerateJsonFromIssue.py @@ -1,5 +1,6 @@ import logging import os +import re import openai import yaml @@ -107,10 +108,12 @@ def ask_gpt_for_initiative_json(self, issue_body: str) -> str: logging.warn("GPT did not infer function calling, best-effort answer parsing will be performed") return response_message["content"] -def get_new_initiative_details() -> str: +def get_new_initiative_details() -> str: + prefixPattern = r'^\[.*-INITIATIVE\]:\s*' + initiative_details = f""" ### Initiative Display Name - {os.environ["ISSUE_TITLE"].replace("[NEW-INITIATIVE]:", "").replace("[NEW-INITIATIVE-FORCE-PR]:", "")} + {re.sub(prefixPattern, "", os.environ["ISSUE_TITLE"], flags=re.IGNORECASE)} {os.environ["ISSUE_BODY"]} """ diff --git a/scripts/test_generatePullRequestForNewInitiative.js b/scripts/test_generatePullRequestForNewInitiative.js index e41f8f97..2df01656 100644 --- a/scripts/test_generatePullRequestForNewInitiative.js +++ b/scripts/test_generatePullRequestForNewInitiative.js @@ -1,12 +1,12 @@ const context = { serverUrl: "https://github.com", - runId: 6762019754, + runId: process.env.GITHUB_RUN_ID, repo: { - owner: "ohadschn", - repo: "ConnectPortal" + owner: process.env.GITHUB_OWNER, + repo: process.env.GITHHUB_REPO }, issue: { - number: 10 + number: process.env.GITHUB_ISSUE_NUMBER } }