From 00f1064e280cbb7d11543ad050fda9e80a5022bc Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Thu, 1 May 2025 18:11:46 +0200 Subject: [PATCH 1/6] wip --- .github/workflows/manage-issue-header.yml | 48 +++++++++++++ scripts/manage-issue-header.js | 82 +++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 .github/workflows/manage-issue-header.yml create mode 100644 scripts/manage-issue-header.js diff --git a/.github/workflows/manage-issue-header.yml b/.github/workflows/manage-issue-header.yml new file mode 100644 index 0000000..6f47a17 --- /dev/null +++ b/.github/workflows/manage-issue-header.yml @@ -0,0 +1,48 @@ +name: Manage issue header + +on: + workflow_call: + secrets: + LE_BOT_APP_ID: + description: "GitHub App ID for authentication" + required: true + LE_BOT_PRIVATE_KEY: + description: "GitHub App Private Key for authentication" + required: true +jobs: + manage-issue-header: + runs-on: ubuntu-latest + if: | + (github.event.action == 'labeled' && github.event.label.name == 'help wanted') || + (github.event.action == 'unlabeled' && github.event.label.name == 'help wanted') + steps: + - name: Generate App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.LE_BOT_APP_ID }} + private_key: ${{ secrets.LE_BOT_PRIVATE_KEY }} + + - name: Checkout called repository + uses: actions/checkout@v3 + with: + repository: learningequality/.github + ref: main + token: ${{ steps.generate-token.outputs.token }} + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '16' + + - name: Install dependencies + run: npm install + + - name: Run script + id: run-script + uses: actions/github-script@v6 + with: + github-token: ${{ steps.generate-token.outputs.token }} + script: | + const script = require('./scripts/manage-issue-header.js'); + return await script({github, context, core}); diff --git a/scripts/manage-issue-header.js b/scripts/manage-issue-header.js new file mode 100644 index 0000000..6603911 --- /dev/null +++ b/scripts/manage-issue-header.js @@ -0,0 +1,82 @@ +/** + * Adds/removes issue contributing header when 'help wanted' label is added / removed. + */ + +module.exports = async ({ github, context, core }) => { + try { + const HELP_WANTED_LABEL = "help wanted"; + + const repoOwner = context.repo.owner; + const repoName = context.repo.repo; + const issueNumber = context.payload.issue.number; + const actionType = context.payload.action; + const labelName = context.payload.label.name; + + if (labelName !== HELP_WANTED_LABEL) { + console.log(`This event does not involve the '${HELP_WANTED_LABEL}' label. Exiting.`); + return; + } + + const isAddingHeader = actionType === "labeled"; + const isRemovingHeader = actionType === "unlabeled"; + + if (!isAddingHeader && !isRemovingHeader) { + console.log(`Unsupported action type: ${actionType}. Exiting.`); + return; + } + + const issue = await github.rest.issues.get({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber + }); + + const currentBody = issue.data.body || ""; + console.log('Current body:', currentBody) + + const helpWantedHeader = "## Help wanted\n\n"; + + if (isAddingHeader) { + await updateIssueWithHeader(github, repoOwner, repoName, issueNumber, currentBody, helpWantedHeader); + } else if (isRemovingHeader) { + await removeHeaderFromIssue(github, repoOwner, repoName, issueNumber, currentBody, helpWantedHeader); + } + + } catch (error) { + core.setFailed(`Error in managing help wanted header: ${error.message}`); + } +}; + +async function updateIssueWithHeader(github, owner, repo, issueNumber, currentBody, header) { + if (currentBody.includes(header)) { + console.log("Help wanted header already exists in the issue. No changes needed."); + return; + } + + const newBody = header + currentBody; + await github.rest.issues.update({ + owner, + repo, + issue_number: issueNumber, + body: newBody + }); + + console.log(`Successfully added 'Help wanted' header to issue #${issueNumber}`); +} + +async function removeHeaderFromIssue(github, owner, repo, issueNumber, currentBody, header) { + if (!currentBody.includes(header)) { + console.log("Help wanted header does not exist in the issue. No changes needed."); + return; + } + const newBody = currentBody.replace(header, ""); + await github.rest.issues.update({ + owner, + repo, + issue_number: issueNumber, + body: newBody + }); + + console.log(`Successfully removed 'Help wanted' header from issue #${issueNumber}`); +} + From e8b9083887a1f1c7c0d13d96aa8104ab9bfeca46 Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Thu, 1 May 2025 18:32:39 +0200 Subject: [PATCH 2/6] Temporarily remove le org --- .github/workflows/manage-issue-header.yml | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/.github/workflows/manage-issue-header.yml b/.github/workflows/manage-issue-header.yml index 6f47a17..60092f1 100644 --- a/.github/workflows/manage-issue-header.yml +++ b/.github/workflows/manage-issue-header.yml @@ -2,13 +2,7 @@ name: Manage issue header on: workflow_call: - secrets: - LE_BOT_APP_ID: - description: "GitHub App ID for authentication" - required: true - LE_BOT_PRIVATE_KEY: - description: "GitHub App Private Key for authentication" - required: true + jobs: manage-issue-header: runs-on: ubuntu-latest @@ -16,19 +10,12 @@ jobs: (github.event.action == 'labeled' && github.event.label.name == 'help wanted') || (github.event.action == 'unlabeled' && github.event.label.name == 'help wanted') steps: - - name: Generate App Token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.LE_BOT_APP_ID }} - private_key: ${{ secrets.LE_BOT_PRIVATE_KEY }} - - name: Checkout called repository uses: actions/checkout@v3 with: - repository: learningequality/.github - ref: main - token: ${{ steps.generate-token.outputs.token }} + repository: MisRob/.github + ref: manage-issue-header + token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v3 @@ -42,7 +29,7 @@ jobs: id: run-script uses: actions/github-script@v6 with: - github-token: ${{ steps.generate-token.outputs.token }} + github-token: ${{ secrets.GITHUB_TOKEN }} script: | const script = require('./scripts/manage-issue-header.js'); return await script({github, context, core}); From e84f58db21356f15b43277f4f46a5fe66513dc73 Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Fri, 2 May 2025 17:48:33 +0200 Subject: [PATCH 3/6] Add message --- scripts/manage-issue-header.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/manage-issue-header.js b/scripts/manage-issue-header.js index 6603911..d676096 100644 --- a/scripts/manage-issue-header.js +++ b/scripts/manage-issue-header.js @@ -34,8 +34,8 @@ module.exports = async ({ github, context, core }) => { const currentBody = issue.data.body || ""; console.log('Current body:', currentBody) - const helpWantedHeader = "## Help wanted\n\n"; - + const helpWantedHeader = '\n\n\n\n🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:\n\n- **Read [the contributing guidelines](https://learningequality.org/contributing-to-our-open-code-base/)** carefully. **Pay extra attention to the [Using generative AI](https://learningequality.org/contributing-to-our-open-code-base/#using-generative-ai)**. **Pull requests and comments that don’t follow the guidelines won’t be answered.**\n- **Confirm that you’ve read the guidelines** in your comment.\n\n\n\n' + if (isAddingHeader) { await updateIssueWithHeader(github, repoOwner, repoName, issueNumber, currentBody, helpWantedHeader); } else if (isRemovingHeader) { From 0e484c89a29b9c9b26544b2a35f4d1feed88ddbe Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Thu, 8 May 2025 15:32:48 +0200 Subject: [PATCH 4/6] WIP --- scripts/manage-issue-header.js | 91 +++++++++++++++------------------- 1 file changed, 39 insertions(+), 52 deletions(-) diff --git a/scripts/manage-issue-header.js b/scripts/manage-issue-header.js index d676096..7a04c7d 100644 --- a/scripts/manage-issue-header.js +++ b/scripts/manage-issue-header.js @@ -1,27 +1,43 @@ /** - * Adds/removes issue contributing header when 'help wanted' label is added / removed. + * Updates issue contributing header according to the presence of the 'help wanted' label. */ +const HELP_WANTED_LABEL = 'help wanted'; + +const HEADER_START_MARKER = ''; +const HEADER_END_MARKER = ''; + +const HELP_WANTED_HEADER = '\n\n\n\n🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:\n\n- **Read the Contributing guidelines** carefully. **Pay extra attention to the [Using generative AI](https://learningequality.org/contributing-to-our-open-code-base/#using-generative-ai)**. **Pull requests and comments that don’t follow the guidelines won’t be answered.**\n- **Confirm that you’ve read the guidelines** in your comment.\n\n\n\n\n\n'; + +const NON_HELP_WANTED_HEADER = '\n\n\n\n❌ **This issue is not open for contribution. Please read the Contributing guidelines** carefully to learn about the contributing process and how to find suitable issues.\n\n\n\n\n\n'; + +function clearHeader(issueBody) { + const startIndex = issueBody.indexOf(HEADER_START_MARKER); + const endIndex = issueBody.indexOf(HEADER_END_MARKER); + + if (startIndex === -1 || endIndex === -1) { + return issueBody; + } + + return issueBody.substring(0, startIndex) + issueBody.substring(endIndex + HEADER_END_MARKER.length).trimStart(); +} + module.exports = async ({ github, context, core }) => { try { - const HELP_WANTED_LABEL = "help wanted"; - const repoOwner = context.repo.owner; const repoName = context.repo.repo; const issueNumber = context.payload.issue.number; const actionType = context.payload.action; const labelName = context.payload.label.name; - if (labelName !== HELP_WANTED_LABEL) { - console.log(`This event does not involve the '${HELP_WANTED_LABEL}' label. Exiting.`); + const labelAdded = actionType === "labeled"; + const labelRemoved = actionType === "unlabeled"; + + if (!labelAdded && !labelRemoved) { return; } - const isAddingHeader = actionType === "labeled"; - const isRemovingHeader = actionType === "unlabeled"; - - if (!isAddingHeader && !isRemovingHeader) { - console.log(`Unsupported action type: ${actionType}. Exiting.`); + if (labelName !== HELP_WANTED_LABEL) { return; } @@ -32,51 +48,22 @@ module.exports = async ({ github, context, core }) => { }); const currentBody = issue.data.body || ""; - console.log('Current body:', currentBody) - - const helpWantedHeader = '\n\n\n\n🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:\n\n- **Read [the contributing guidelines](https://learningequality.org/contributing-to-our-open-code-base/)** carefully. **Pay extra attention to the [Using generative AI](https://learningequality.org/contributing-to-our-open-code-base/#using-generative-ai)**. **Pull requests and comments that don’t follow the guidelines won’t be answered.**\n- **Confirm that you’ve read the guidelines** in your comment.\n\n\n\n' - if (isAddingHeader) { - await updateIssueWithHeader(github, repoOwner, repoName, issueNumber, currentBody, helpWantedHeader); - } else if (isRemovingHeader) { - await removeHeaderFromIssue(github, repoOwner, repoName, issueNumber, currentBody, helpWantedHeader); + let newBody = clearHeader(currentBody); + if (labelAdded) { + newBody = HELP_WANTED_HEADER + newBody; + } else if (labelRemoved) { + newBody = NON_HELP_WANTED_HEADER + newBody; } + + await github.rest.issues.update({ + owner: repoOwner, + repo: repoName, + issue_number: issueNumber, + body: newBody + }); } catch (error) { - core.setFailed(`Error in managing help wanted header: ${error.message}`); + core.setFailed(`Error: ${error.message}`); } }; - -async function updateIssueWithHeader(github, owner, repo, issueNumber, currentBody, header) { - if (currentBody.includes(header)) { - console.log("Help wanted header already exists in the issue. No changes needed."); - return; - } - - const newBody = header + currentBody; - await github.rest.issues.update({ - owner, - repo, - issue_number: issueNumber, - body: newBody - }); - - console.log(`Successfully added 'Help wanted' header to issue #${issueNumber}`); -} - -async function removeHeaderFromIssue(github, owner, repo, issueNumber, currentBody, header) { - if (!currentBody.includes(header)) { - console.log("Help wanted header does not exist in the issue. No changes needed."); - return; - } - const newBody = currentBody.replace(header, ""); - await github.rest.issues.update({ - owner, - repo, - issue_number: issueNumber, - body: newBody - }); - - console.log(`Successfully removed 'Help wanted' header from issue #${issueNumber}`); -} - From 247aa98bb04aa4f47e9b5418ea148ba2a1e347c0 Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Thu, 22 May 2025 14:12:51 +0200 Subject: [PATCH 5/6] Update bar color --- scripts/manage-issue-header.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/manage-issue-header.js b/scripts/manage-issue-header.js index 7a04c7d..02d9b9d 100644 --- a/scripts/manage-issue-header.js +++ b/scripts/manage-issue-header.js @@ -7,7 +7,7 @@ const HELP_WANTED_LABEL = 'help wanted'; const HEADER_START_MARKER = ''; const HEADER_END_MARKER = ''; -const HELP_WANTED_HEADER = '\n\n\n\n🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:\n\n- **Read the Contributing guidelines** carefully. **Pay extra attention to the [Using generative AI](https://learningequality.org/contributing-to-our-open-code-base/#using-generative-ai)**. **Pull requests and comments that don’t follow the guidelines won’t be answered.**\n- **Confirm that you’ve read the guidelines** in your comment.\n\n\n\n\n\n'; +const HELP_WANTED_HEADER = '\n\n\n\n🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:\n\n- **Read the Contributing guidelines** carefully. **Pay extra attention to the [Using generative AI](https://learningequality.org/contributing-to-our-open-code-base/#using-generative-ai)**. **Pull requests and comments that don’t follow the guidelines won’t be answered.**\n- **Confirm that you’ve read the guidelines** in your comment.\n\n\n\n\n\n'; const NON_HELP_WANTED_HEADER = '\n\n\n\n❌ **This issue is not open for contribution. Please read the Contributing guidelines** carefully to learn about the contributing process and how to find suitable issues.\n\n\n\n\n\n'; From 51489ab33e3e701a2a06dcc423c59fac50595d1b Mon Sep 17 00:00:00 2001 From: Michaela Robosova Date: Thu, 22 May 2025 14:13:35 +0200 Subject: [PATCH 6/6] Revert "Temporarily remove le org" This reverts commit e8b9083887a1f1c7c0d13d96aa8104ab9bfeca46. --- .github/workflows/manage-issue-header.yml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/manage-issue-header.yml b/.github/workflows/manage-issue-header.yml index 60092f1..6f47a17 100644 --- a/.github/workflows/manage-issue-header.yml +++ b/.github/workflows/manage-issue-header.yml @@ -2,7 +2,13 @@ name: Manage issue header on: workflow_call: - + secrets: + LE_BOT_APP_ID: + description: "GitHub App ID for authentication" + required: true + LE_BOT_PRIVATE_KEY: + description: "GitHub App Private Key for authentication" + required: true jobs: manage-issue-header: runs-on: ubuntu-latest @@ -10,12 +16,19 @@ jobs: (github.event.action == 'labeled' && github.event.label.name == 'help wanted') || (github.event.action == 'unlabeled' && github.event.label.name == 'help wanted') steps: + - name: Generate App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.LE_BOT_APP_ID }} + private_key: ${{ secrets.LE_BOT_PRIVATE_KEY }} + - name: Checkout called repository uses: actions/checkout@v3 with: - repository: MisRob/.github - ref: manage-issue-header - token: ${{ secrets.GITHUB_TOKEN }} + repository: learningequality/.github + ref: main + token: ${{ steps.generate-token.outputs.token }} - name: Setup Node.js uses: actions/setup-node@v3 @@ -29,7 +42,7 @@ jobs: id: run-script uses: actions/github-script@v6 with: - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ steps.generate-token.outputs.token }} script: | const script = require('./scripts/manage-issue-header.js'); return await script({github, context, core});