You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by wa...@apache.org on 2020/10/28 01:02:00 UTC

[incubator-echarts-bot] 05/32: feat: update for new issue template

This is an automated email from the ASF dual-hosted git repository.

wangzx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-echarts-bot.git

commit 1c1fd56a52728146cc01062e57c98df3c3f235fc
Author: Ovilia <zw...@gmail.com>
AuthorDate: Wed Feb 20 20:16:20 2019 +0800

    feat: update for new issue template
---
 index.js              | 103 +++++++++++++++++++++++-----------
 src/coreCommitters.js |   4 +-
 src/issue.js          | 150 ++++++++++----------------------------------------
 src/text.js           |  59 ++++++++++++++++++++
 4 files changed, 162 insertions(+), 154 deletions(-)

diff --git a/index.js b/index.js
index 338360d..847df80 100644
--- a/index.js
+++ b/index.js
@@ -1,55 +1,59 @@
 const Issue = require('./src/issue');
 const coreCommitters = require('./src/coreCommitters');
+const {PR_OPENED, PR_MERGED, PR_NOT_MERGED, LABEL_HOWTO, NOT_USING_TEMPLATE} = require('./src/text');
 
 module.exports = app => {
-    app.on(['issues.opened', 'issues.edited'], async context => {
+    app.on(['issues.opened', 'issues.edited', 'issues.reopened'], async context => {
         const issue = new Issue(context);
 
-        if (!issue.isUsingTemplate()) {
-            // Close issue
-            const comment = context.github.issues.createComment(context.issue({
-                body: issue.response
-            }));
+        // Ignore comment because it will commented when adding invalid label
+        const comment = issue.response === NOT_USING_TEMPLATE
+            ? Promise.resolve()
+            : commentIssue(context, issue.response);
 
-            const close = context.github.issues.edit(context.issue({
-                state: 'closed'
-            }));
+        const addLabels = issue.addLabels.length
+            ? context.github.issues.addLabels(context.issue({
+                labels: issue.addLabels
+            }))
+            : Promise.resolve();
 
-            return Promise.all([comment, close]);
+        const removeLabels = issue.removeLabels.length
+            ? context.github.issues.addLabels(context.issue({
+                labels: issue.removeLabels
+            }))
+            : Promise.resolve();
+
+        if (issue.isUsingTemplate()) {
+            return Promise.all([comment, addLabels, removeLabel]);
         }
         else {
-            const addLabels = issue.tags.length
-                ? context.github.issues.addLabels(context.issue({
-                    labels: issue.tags
-                }))
-                : Promise.resolve();
-
-            const removeLabel = getRemoveLabel(
-                context,
-                issue.isMeetAllRequires()
-                    ? 'waiting-for-author'
-                    : 'waiting-for-help'
-            );
+            return Promise.all([comment, addLabels, removeLabels]);
+        }
+    });
 
-            const comment = context.github.issues.createComment(context.issue({
-                body: issue.response
-            }));
+    app.on('issues.labeled', async context => {
+        switch (context.payload.label.name) {
+            case 'invalid':
+                return Promise.all([commentIssue(context, NOT_USING_TEMPLATE), closeIssue(context)]);
 
-            return Promise.all([addLabels, removeLabel, comment]);
+            case 'howto':
+                return Promise.all([commentIssue(context, LABEL_HOWTO), closeIssue(context)]);
         }
     });
 
     app.on('issue_comment.created', async context => {
         const commenter = context.payload.comment.user.login;
-        let removeLabel, addLabel;
-        if (coreCommitters.isCoreCommitter(commenter)) {
+        const isCommenterAuthor = commenter === context.payload.issue.user.login;
+        let removeLabel;
+        let addLabel;
+        if (coreCommitters.isCoreCommitter(commenter) && !isCommenterAuthor) {
             // New comment from core committers
             removeLabel = getRemoveLabel(context, 'waiting-for-help');
             addLabel = context.github.issues.addLabels(context.issue({
                 labels: ['waiting-for-author']
             }));
         }
-        else if (commenter === context.payload.issue.user.login) {
+        else if (isCommenterAuthor) {
             // New comment from issue author
             removeLabel = getRemoveLabel(context, 'waiting-for-author');
             addLabel = context.github.issues.addLabels(context.issue({
@@ -58,6 +62,27 @@ module.exports = app => {
         }
         return Promise.all([removeLabel, addLabel]);
     });
+
+    // Pull Requests Not Tested Yet
+    // app.on(['pull_request.opened', 'pull_request.reopened'], async context => {
+    //     console.log('pull request open');
+    //     const comment = context.github.issues.createComment(context.issue({
+    //         body: PR_OPENED
+    //     }));
+
+    //     return Promise.all([comment]);
+    // });
+
+    // app.on(['pull_request.closed'], async context => {
+    //     console.log('pull request close');
+    //     console.log(context.payload);
+    //     const isMerged = context.payload['pull_request'].merged;
+    //     const comment = context.github.issues.createComment(context.issue({
+    //         body: isMerged ? PR_MERGED : PR_NOT_MERGED
+    //     }));
+
+    //     return Promise.all([comment]);
+    // });
 }
 
 function getRemoveLabel(context, name) {
@@ -67,8 +92,22 @@ function getRemoveLabel(context, name) {
         })
     ).catch(err => {
         // Ignore error caused by not existing.
-        if (err.message !== 'Not Found') {
-            throw(err);
-        }
+        // if (err.message !== 'Not Found') {
+        //     throw(err);
+        // }
     });
 }
+
+function closeIssue(context) {
+    const closeIssue = context.github.issues.edit(context.issue({
+        state: 'closed'
+    }));
+    return closeIssue;
+}
+
+function commentIssue(context, commentText) {
+    const comment = context.github.issues.createComment(context.issue({
+        body: commentText
+    }));
+    return comment;
+}
diff --git a/src/coreCommitters.js b/src/coreCommitters.js
index 6d9cf9f..c13147e 100644
--- a/src/coreCommitters.js
+++ b/src/coreCommitters.js
@@ -14,6 +14,6 @@ function isCoreCommitter(user) {
 }
 
 module.exports = {
-    getCoreCommitters: getCoreCommitters,
-    isCoreCommitter: isCoreCommitter
+    getCoreCommitters,
+    isCoreCommitter
 };
diff --git a/src/issue.js b/src/issue.js
index 73077ff..1d1d770 100644
--- a/src/issue.js
+++ b/src/issue.js
@@ -1,156 +1,66 @@
+const {NOT_USING_TEMPLATE, ISSUE_CREATED, ISSUE_UPDATED} = require('./text');
+
 class Issue {
     constructor(context) {
         this.context = context;
         this.issue = context.payload.issue;
         this.body = this.issue.body;
+        this.issueType = null;
+        this.addLabels = [];
+        this.removeLabels = [];
 
         if (this.isUsingTemplate()) {
             this.init();
         }
         else {
-            this.response = `💔 Oops... Please follow the issue template to ask questions.
-                I'm going to close this issue, and please create a new issue and DO NOT DELETE ISSUE TEMPLATE.`;
+            this.response = NOT_USING_TEMPLATE;
+            this.addLabels.push('invalid');
         }
     }
 
     init() {
-        this.isInEnglish = this._matches('I am using English in this issue');
-
-        this.issueType = 'others';
-        if (this._matches('I have a question to ask about')) {
-            this.issueType = 'support';
-        }
-        else if (this._matches('I have a bug to report')) {
+        if (this._contain('Steps to reproduce')) {
             this.issueType = 'bug';
         }
-        else if (this._matches('I have a feature to request')) {
+        else if (this._contain('What problem does this feature solve')) {
             this.issueType = 'new-feature';
         }
-        else if (this._matches('I have a feature to enhance')) {
-            this.issueType = 'enhancement';
-        }
-        else if (this._matches('There\'s something wrong with the documents')) {
-            this.issueType = 'doc';
+        else {
+            this.response = NOT_USING_TEMPLATE;
+            return;
         }
 
-        this.requiredReadDoc = this._matches('I have read the document');
-        this.requiredSearch = this._matches('I have searched for similar issues');
-        this.requiredLatest = this._matches('I have tried with the latest version');
-        this.requiredIssueType = this._matches('issue type');
-        this.requiredDesc = this._matches('one sentence description in issue details');
-        this.requiredDemo = this._matches('demo if this is bug report')
-            || this.issueType !== 'bug' && this.issueType !== 'support';
-        this.requiredVersion = this._matches('ECharts version');
-
         this._computeResponse();
-        this._computeTags();
     }
 
     isUsingTemplate() {
-        return this.body.indexOf('I have read the document') > -1;
-    }
-
-    isMeetAllRequires() {
-        return this.requiredReadDoc && this.requiredSearch && this.requiredLatest
-            && this.requiredIssueType && this.requiredDesc
-            && this.requiredDemo && this.requiredVersion;
+        return this.body.indexOf('generated by echarts-issue-helper') > -1;
     }
 
     _computeResponse() {
-        let response = '';
-
-        if (this.isMeetAllRequires()) {
-            switch(this.context.payload.action) {
-                case 'opened':
-                    response = 'Hi! We\'ve received your issue and the expected respond time is within one day for weekdays. Have a nice day! 🍵';
-                    break;
-                case 'edited':
-                    response = 'Thanks for editing. Please wait for the community to reply. 🍻'
-            }
-        }
-        else {
-            response += 'Thanks for editing, but something doesn\'t seem to be right:\n❗️ **[Error]** Please ';
-
-            if (!this.requiredReadDoc) {
-                response += 'read the [doc](https://echarts.apache.org/option.html) and [examples](https://ecomfe.github.io/echarts-examples/public/index.html)';
-            }
-            else if (!this.requiredSearch) {
-                response += '**search issue list**';
-            }
-            else if (!this.requiredLatest) {
-                response += 'try with the **lastest version** of ECharts';
-            }
-            else if (!this.requiredIssueType) {
-                response += 'provide with **issue type**';
-            }
-            else if (!this.requiredDesc) {
-                response += 'provide with **issue description**';
-            }
-            else if (!this.requiredDemo) {
-                response += 'provide with a **demo** (place N/A for demo if your problem does not need one and check the tick of demo)';
-            }
-            else if (!this.requiredVersion) {
-                response += 'provide with ECharts **version**';
-            }
-
-            response += ' first, and make sure everything is checked in the `REQUIRED FIELDS`.\nYou may edit this issue and I will check it again. 😃';
-        }
-
-        this.response = response;
-    }
-
-    _computeTags() {
-        this.tags = [];
-
-        if (this.isMeetAllRequires()) {
-            this.tags.push('waiting-for-help');
-        }
-        else {
-            this.tags.push('waiting-for-author');
-        }
-
-        if (this.isInEnglish) {
-            this.tags.push('en');
+        switch(this.context.payload.action) {
+            case 'opened':
+            case 'reopened':
+                this.response = ISSUE_CREATED;
+                break;
+            case 'edited':
+                this.response = ISSUE_UPDATED;
+                this.removeLabels.push('waiting-for-help');
+                break;
         }
 
-        if (this.issueType !== 'others') {
-            this.tags.push(this.issueType);
-        }
-
-        const topics = this._getTopics();
-        for (let i = 0; i < topics.length; ++i) {
-            this.tags.push(topics[i]);
-        }
-    }
-
-    _getTopics() {
-        if (this.topics) {
-            return this.topics;
-        }
-        else {
-            this.topics = [];
-        }
+        this.addLabels.push('waiting-for-help');
+        this.addLabels.push('pending');
+        this.addLabels.push(this.issueType);
 
-        const labels = {
-            'Legend': 'legend',
-            'Tooltip': 'tooltip',
-            'Event': 'event',
-            'Performance': 'performance',
-            'SVG': 'SVG',
-            'Map': 'map',
-            'ECharts GL': 'gl',
-            'Third-party': 'third-party'
-        };
-        for (let label in labels) {
-            if (this._matches(label)) {
-                this.topics.push(labels[label]);
-            }
+        const isInEnglish = this._contain('This issue is in English');
+        if (isInEnglish) {
+            this.addLabels.push('en');
         }
-        return this.topics;
     }
 
-    _matches(text) {
-        return this.body.indexOf('- [x] Required: ' + text) > -1;
+    _contain(txt) {
+        return this.body.indexOf(txt) > -1;
     }
 }
 
diff --git a/src/text.js b/src/text.js
new file mode 100644
index 0000000..22df08d
--- /dev/null
+++ b/src/text.js
@@ -0,0 +1,59 @@
+const NOT_USING_TEMPLATE =
+    `This issue is not created using [issue template](https://ecomfe.github.io/echarts-issue-helper/) so I'm going to close it. 🙊
+Sorry for this, but it helps saving our maintainers' time so that more developers get helped.
+Feel free to create another issue using the issue template.
+
+这个 issue 未使用 [issue 模板](https://ecomfe.github.io/echarts-issue-helper/?lang=zh-cn) 创建,所以我将关闭此 issue。
+为此带来的麻烦我深表歉意,但是请理解这是为了节约社区维护者的时间,以更高效地服务社区的开发者群体。
+如果您愿意,可以请使用 issue 模板重新创建 issue。`;
+
+const ISSUE_CREATED =
+    `Hi! We\'ve received your issue and please be patient to get responded. 🎉
+The average response time is expected to be within one day for weekdays.
+
+In the meanwhile, please make sure that **you have posted enough image to demo your request**. You may also check out the [API](http://echarts.apache.org/api.html) and [chart option](http://echarts.apache.org/option.html) to get the answer.
+
+Have a nice day! 🍵`;
+
+const ISSUE_UPDATED =
+    `An update has been made to this issue. The maintainers are right on their way. 🚒`;
+
+const PR_OPENED =
+    `Thanks for your contribution!
+@Ovilia Please check out this PR.`;
+
+const PR_MERGED =
+    `Congratulations! Your PR has been merged. Thanks for your contribution! 👍
+
+Now you are one of the ECharts contributors. Since we joined the Apache group, you need to assign [ICLA](https://www.apache.org/licenses/icla.pdf) file if this is your first PR.
+Please fill in the PDF and print it, then sign on it and send the scanned file to secretary@apache.org and oviliazhang at gmail.com with the title \`ICLA for incubator-echarts project\`.
+This may be a little tricky, and sorry for the trouble. This is required for the first time your commit is merged in. If you refused, your commit will be backed off.
+
+You may send an email to dev-subscribe@echarts.apache.org to subscribe our developing discussion on mail list.
+`;
+
+const PR_NOT_MERGED = `I'm sorry your PR didn't get merged. Don't get frustrated. Maybe next time. 😛`
+
+const LABEL_HOWTO =
+    `Sorry, but please ask *how-to* questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/echarts). Here's why:
+
+Maintaining open source projects, especially popular ones, is [hard work](https://nolanlawson.com/2017/03/05/what-it-feels-like-to-be-an-open-source-maintainer/). As ECharts's user base has grown, we are getting more and more usage questions, bug reports, feature requests and pull requests every single day.
+
+As a free and open source project, ECharts also has limited maintainer bandwidth. That means the only way to ensure the project's sustainability is to:
+
+1. Prioritize more concrete work (bug fixes and new features);
+2. Improve issue triaging efficiency.
+
+For (1), we have decided to use the GitHub issue lists exclusively for work that has well-defined, actionable goals. Questions and open ended discussions should be posted to mediums that are better suited for them.
+
+For (2), we have found that issues that do not provide proper information upfront usually results in terribly inefficient back-and-forth communication just to extract the basic information needed for actual triaging. This is exactly why we have created this app: to ensure that every issue is created with the necessary information, and to save time on both sides.`
+
+module.exports = {
+    NOT_USING_TEMPLATE,
+    ISSUE_CREATED,
+    ISSUE_UPDATED,
+    PR_OPENED,
+    LABEL_HOWTO,
+    PR_MERGED,
+    PR_NOT_MERGED
+};


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org