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..02d9b9d
--- /dev/null
+++ b/scripts/manage-issue-header.js
@@ -0,0 +1,69 @@
+/**
+ * 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 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;
+
+ const labelAdded = actionType === "labeled";
+ const labelRemoved = actionType === "unlabeled";
+
+ if (!labelAdded && !labelRemoved) {
+ return;
+ }
+
+ if (labelName !== HELP_WANTED_LABEL) {
+ return;
+ }
+
+ const issue = await github.rest.issues.get({
+ owner: repoOwner,
+ repo: repoName,
+ issue_number: issueNumber
+ });
+
+ const currentBody = issue.data.body || "";
+
+ 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: ${error.message}`);
+ }
+};