diff --git a/README.en-US.md b/README.en-US.md index b1ac89b..54a87ec 100644 --- a/README.en-US.md +++ b/README.en-US.md @@ -41,6 +41,7 @@ When the following list does not have the features you want, you can submit it i - [`unlock-issue`](#unlock-issue) - [`update-comment`](#update-comment) - [`update-issue`](#update-issue) + - [`welcome`](#welcome) - ⭐ Advanced - [`check-inactive`](#check-inactive) - [`check-issue`](#check-issue) @@ -484,6 +485,47 @@ Update the specified issue according to the `issue-number`. ⏫ [Back to list](#List) +#### `welcome` + +When an issue is created, the user who created the issue for the first time is welcome. + +If the user is not creating for the first time, there is no operation. + +```yml +name: Issue Welcome + +on: + issues: + types: [opened] + +jobs: + issue-welcome: + runs-on: ubuntu-latest + steps: + - name: welcome + uses: actions-cool/issues-helper@v1.3 + with: + actions: 'welcome' + token: ${{ secrets.GITHUB_TOKEN }} + body: hi @${{ github.event.issue.user.login }}, welcome! + labels: 'welcome1, welcome2' + assignees: 'xx1' + issue-contents: '+1, -1, eyes' +``` + +| Param | Desc | Type | Required | Version | +| -- | -- | -- | -- | -- | +| actions | Action type | string | ✔ | v1.3 | +| token | [Token explain](#token) | string | ✔ | v1.3 | +| body | Comment on the welcome content, no comment if you leave it blank | string | ✖ | v1.3 | +| labels | Add labels to this issue | string | ✖ | v1.3 | +| assignees | Add assignees to this issue | string | ✖ | v1.3 | +| issue-contents | Add [reaction](#reactions-types) to this issue| string | ✖ | v1.3 | + +- If these 4 options are not filled, no operation + +⏫ [Back to list](#List) + ### 🌟 Advanced Advanced usage is not recommended to use multiple actions at the same time. diff --git a/README.md b/README.md index bce410e..5762b6c 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ - [`unlock-issue`](#unlock-issue) - [`update-comment`](#update-comment) - [`update-issue`](#update-issue) + - [`welcome`](#welcome) - ⭐ 进 阶 - [`check-inactive`](#check-inactive) - [`check-issue`](#check-issue) @@ -484,6 +485,45 @@ jobs: ⏫ [返回列表](#列-表) +#### `welcome` + +当一个 issue 新建时,对首次新建 issue 的用户进行欢迎。若用户非首次新建,则无操作。 + +```yml +name: Issue Welcome + +on: + issues: + types: [opened] + +jobs: + issue-welcome: + runs-on: ubuntu-latest + steps: + - name: welcome + uses: actions-cool/issues-helper@v1.3 + with: + actions: 'welcome' + token: ${{ secrets.GITHUB_TOKEN }} + body: hi @${{ github.event.issue.user.login }}, welcome! + labels: 'welcome1, welcome2' + assignees: 'xx1' + issue-contents: '+1, -1, eyes' +``` + +| 参数 | 描述 | 类型 | 必填 | 版本 | +| -- | -- | -- | -- | -- | +| actions | 操作类型 | string | ✔ | v1.3 | +| token | [token 说明](#token) | string | ✔ | v1.3 | +| body | 评论欢迎的内容,不填则不评论 | string | ✖ | v1.3 | +| labels | 为该 issue 增加 labels | string | ✖ | v1.3 | +| assignees | 为该 issue 增加 assignees | string | ✖ | v1.3 | +| issue-contents | 为该 issue 增加 [reaction](#reactions-types) | string | ✖ | v1.3 | + +- 若这 4 个可选项都不填,则无操作 + +⏫ [返回列表](#列-表) + ### 🌟 进 阶 进阶用法不建议 actions 多个一次同时使用。 diff --git a/action.yml b/action.yml index 3dec888..43804d3 100644 --- a/action.yml +++ b/action.yml @@ -44,6 +44,8 @@ inputs: description: 'Query use' issue-mentioned: description: 'Query use' + issue-contents: + description: 'For welcome' issue-state: description: 'Query use' inactive-day: diff --git a/dist/index.js b/dist/index.js index dfc6624..e5e52e6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1461,7 +1461,7 @@ exports.Octokit = Octokit; Object.defineProperty(exports, "__esModule", ({ value: true })); -var isPlainObject = __webpack_require__(3287); +var isPlainObject = __webpack_require__(558); var universalUserAgent = __webpack_require__(5030); function lowercaseKeys(object) { @@ -1849,6 +1849,52 @@ exports.endpoint = endpoint; //# sourceMappingURL=index.js.map +/***/ }), + +/***/ 558: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +function isPlainObject(o) { + var ctor,prot; + + if (isObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; + + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +} + +exports.isPlainObject = isPlainObject; + + /***/ }), /***/ 8467: @@ -3361,7 +3407,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var endpoint = __webpack_require__(9440); var universalUserAgent = __webpack_require__(5030); -var isPlainObject = __webpack_require__(3287); +var isPlainObject = __webpack_require__(9062); var nodeFetch = _interopDefault(__webpack_require__(467)); var requestError = __webpack_require__(537); @@ -3503,6 +3549,52 @@ exports.request = request; //# sourceMappingURL=index.js.map +/***/ }), + +/***/ 9062: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +function isPlainObject(o) { + var ctor,prot; + + if (isObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; + + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +} + +exports.isPlainObject = isPlainObject; + + /***/ }), /***/ 5375: @@ -3876,52 +3968,6 @@ module.exports.config = config module.exports.parse = parse -/***/ }), - -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} - -function isPlainObject(o) { - var ctor,prot; - - if (isObject(o) === false) return false; - - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; - - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } - - // Most likely a plain Object - return true; -} - -exports.isPlainObject = isPlainObject; - - /***/ }), /***/ 467: @@ -6146,7 +6192,7 @@ async function doLockIssues (owner, repo, labels) { } }; -async function doQueryIssues (owner, repo, labels, state) { +async function doQueryIssues (owner, repo, labels, state, creator) { let params = { owner, repo, @@ -6161,6 +6207,10 @@ async function doQueryIssues (owner, repo, labels, state) { params.labels = labels; } + if (creator) { + params.creator = creator; + } + const res = await octokit.issues.listForRepo(params); let issues = []; res.data.forEach(iss => { @@ -6193,6 +6243,9 @@ module.exports = { doCloseIssues, doFindComments, doLockIssues, + + // tool + doQueryIssues, }; @@ -6203,8 +6256,11 @@ module.exports = { __webpack_require__(2437).config(); const core = __webpack_require__(2186); +const github = __webpack_require__(5438); const { Octokit } = __webpack_require__(5375); +const { doQueryIssues } = __webpack_require__(9319); + const ALLREACTIONS = [ "+1", "-1", @@ -6222,6 +6278,7 @@ const token = core.getInput('token'); const octokit = new Octokit({ auth: `token ${token}` }); const contents = core.getInput("contents"); +const issueContents = core.getInput("issue-contents"); async function doAddAssignees (owner, repo, issueNumber, assignees) { await octokit.issues.addAssignees({ @@ -6499,6 +6556,41 @@ async function doUpdateIssue ( } }; +async function doWelcome (owner, repo, assignees, labels, body) { + const context = github.context; + const isIssue = !!context.payload.issue; + if (!isIssue) { + core.setFailed("The event that triggered this action must be a issue. Error!"); + } else { + const auth = context.payload.sender.login; + core.info(`Actions: [welcome: auth=][${auth}]`); + const issueNumber = context.issue.number; + const creator = 'zoo-js-bot'; + const issues = await doQueryIssues(owner, repo, false, 'all', creator); + if (issues.length == 0 || (issues.length == 1 && issues[0].number == issueNumber)) { + if (core.getInput("body")) { + await doCreateComment(owner, repo, issueNumber, body); + } else { + core.info(`Actions: [welcome] no body!`); + } + + if (assignees) { + await doAddAssignees(owner, repo, issueNumber, assignees); + } + + if (labels) { + await doAddLabels(owner, repo, issueNumber, labels); + } + + if (issueContents) { + await doCreateIssueContent(owner, repo, issueNumber, dealInput(issueContents)); + } + } else { + core.info(`Actions: [welcome][${auth}] is not first time!`); + } + } +}; + // tool function testContent(con) { if (ALLREACTIONS.includes(con)) { @@ -6527,6 +6619,7 @@ module.exports = { doUnlockIssue, doUpdateComment, doUpdateIssue, + doWelcome, }; @@ -6555,6 +6648,7 @@ const { doUnlockIssue, doUpdateComment, doUpdateIssue, + doWelcome, } = __webpack_require__(9932); const { @@ -6581,6 +6675,7 @@ const ALLACTIONS = [ 'unlock-issue', 'update-comment', 'update-issue', + 'welcome', // advanced 'check-inactive', @@ -6689,6 +6784,15 @@ async function main() { labels ); break; + case 'welcome': + await doWelcome( + owner, + repo, + assignees, + labels, + body + ); + break; // advanced case 'check-inactive': diff --git a/docs/base.en-US.md b/docs/base.en-US.md index 356ec47..917c6cc 100644 --- a/docs/base.en-US.md +++ b/docs/base.en-US.md @@ -405,3 +405,42 @@ Update the specified issue according to the `issue-number`. - `state` defaults to `open` - When the option is not filled, it will keep the original + +## `welcome` + +When an issue is created, the user who created the issue for the first time is welcome. + +If the user is not creating for the first time, there is no operation. + +```yml +name: Issue Welcome + +on: + issues: + types: [opened] + +jobs: + issue-welcome: + runs-on: ubuntu-latest + steps: + - name: welcome + uses: actions-cool/issues-helper@v1.3 + with: + actions: 'welcome' + token: ${{ secrets.GITHUB_TOKEN }} + body: hi @${{ github.event.issue.user.login }}, welcome! + labels: 'welcome1, welcome2' + assignees: 'xx1' + issue-contents: '+1, -1, eyes' +``` + +| Param | Desc | Type | Required | Version | +| -- | -- | -- | -- | -- | +| actions | Action type | string | ✔ | v1.3 | +| token | [Token explain](/en-US/guide/ref#-token) | string | ✔ | v1.3 | +| body | Comment on the welcome content, no comment if you leave it blank | string | ✖ | v1.3 | +| labels | Add labels to this issue | string | ✖ | v1.3 | +| assignees | Add assignees to this issue | string | ✖ | v1.3 | +| issue-contents | Add [reaction](/en-US/guide/ref#-reactions-type) to this issue| string | ✖ | v1.3 | + +- If these 4 options are not filled, no operation \ No newline at end of file diff --git a/docs/base.md b/docs/base.md index 48df3c5..b79f3fc 100644 --- a/docs/base.md +++ b/docs/base.md @@ -405,3 +405,41 @@ jobs: - `state` 默认为 `open` - 当可选项不填时,会保持原有 + + +## `welcome` + +当一个 issue 新建时,对首次新建 issue 的用户进行欢迎。若用户非首次新建,则无操作。 + +```yml +name: Issue Welcome + +on: + issues: + types: [opened] + +jobs: + issue-welcome: + runs-on: ubuntu-latest + steps: + - name: welcome + uses: actions-cool/issues-helper@v1.3 + with: + actions: 'welcome' + token: ${{ secrets.GITHUB_TOKEN }} + body: hi @${{ github.event.issue.user.login }}, welcome! + labels: 'welcome1, welcome2' + assignees: 'xx1' + issue-contents: '+1, -1, eyes' +``` + +| 参数 | 描述 | 类型 | 必填 | 版本 | +| -- | -- | -- | -- | -- | +| actions | 操作类型 | string | ✔ | v1.3 | +| token | [token 说明](/guide/ref#-token-说明) | string | ✔ | v1.3 | +| body | 评论欢迎的内容,不填则不评论 | string | ✖ | v1.3 | +| labels | 为该 issue 增加 labels | string | ✖ | v1.3 | +| assignees | 为该 issue 增加 assignees | string | ✖ | v1.3 | +| issue-contents | 为该 issue 增加 [reaction](/guide/ref#-reactions-类型) | string | ✖ | v1.3 | + +- 若这 4 个可选项都不填,则无操作 \ No newline at end of file diff --git a/docs/changelog.en-US.md b/docs/changelog.en-US.md index f3e2fda..ea78f8d 100644 --- a/docs/changelog.en-US.md +++ b/docs/changelog.en-US.md @@ -21,20 +21,4 @@ toc: menu uses: actions-cool/issues-helper@main ``` -## v1.2 - -`2020.12.25` - -- feat: add check-issue & remove labels. [#12](https://github.com/actions-cool/issues-helper/pull/12) - -## v1.1 - -`2020.12.24` - -- fix: yml not support array. [#11](https://github.com/actions-cool/issues-helper/pull/11) - -## v1 - -`2020.12.23` - -🎉 First release. + diff --git a/docs/changelog.md b/docs/changelog.md index 6bd7134..ded8e76 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -21,20 +21,4 @@ toc: menu uses: actions-cool/issues-helper@main ``` -## v1.2 - -`2020.12.25` - -- feat: add check-issue & remove labels. [#12](https://github.com/actions-cool/issues-helper/pull/12) - -## v1.1 - -`2020.12.24` - -- fix: yml not support array. [#11](https://github.com/actions-cool/issues-helper/pull/11) - -## v1 - -`2020.12.23` - -🎉 First release. + diff --git a/docs/log.md b/docs/log.md new file mode 100644 index 0000000..cfd0b64 --- /dev/null +++ b/docs/log.md @@ -0,0 +1,23 @@ +## v1.3 + +`2020.12.28` + +- feat: add welcome. [#19](https://github.com/actions-cool/issues-helper/pull/19) + +## v1.2 + +`2020.12.25` + +- feat: add check-issue & remove labels. [#12](https://github.com/actions-cool/issues-helper/pull/12) + +## v1.1 + +`2020.12.24` + +- fix: yml not support array. [#11](https://github.com/actions-cool/issues-helper/pull/11) + +## v1 + +`2020.12.23` + +🎉 First release. diff --git a/src/advanced.js b/src/advanced.js index f84034a..28ec2e2 100644 --- a/src/advanced.js +++ b/src/advanced.js @@ -165,7 +165,7 @@ async function doLockIssues (owner, repo, labels) { } }; -async function doQueryIssues (owner, repo, labels, state) { +async function doQueryIssues (owner, repo, labels, state, creator) { let params = { owner, repo, @@ -180,6 +180,10 @@ async function doQueryIssues (owner, repo, labels, state) { params.labels = labels; } + if (creator) { + params.creator = creator; + } + const res = await octokit.issues.listForRepo(params); let issues = []; res.data.forEach(iss => { @@ -212,4 +216,7 @@ module.exports = { doCloseIssues, doFindComments, doLockIssues, + + // tool + doQueryIssues, }; diff --git a/src/base.js b/src/base.js index 2517e17..1df0276 100644 --- a/src/base.js +++ b/src/base.js @@ -1,7 +1,10 @@ require('dotenv').config(); const core = require("@actions/core"); +const github = require("@actions/github"); const { Octokit } = require('@octokit/rest'); +const { doQueryIssues } = require('./advanced.js'); + const ALLREACTIONS = [ "+1", "-1", @@ -19,6 +22,7 @@ const token = core.getInput('token'); const octokit = new Octokit({ auth: `token ${token}` }); const contents = core.getInput("contents"); +const issueContents = core.getInput("issue-contents"); async function doAddAssignees (owner, repo, issueNumber, assignees) { await octokit.issues.addAssignees({ @@ -296,6 +300,41 @@ async function doUpdateIssue ( } }; +async function doWelcome (owner, repo, assignees, labels, body) { + const context = github.context; + const isIssue = !!context.payload.issue; + if (!isIssue) { + core.setFailed("The event that triggered this action must be a issue. Error!"); + } else { + const auth = context.payload.sender.login; + core.info(`Actions: [welcome: auth=][${auth}]`); + const issueNumber = context.issue.number; + const creator = 'zoo-js-bot'; + const issues = await doQueryIssues(owner, repo, false, 'all', creator); + if (issues.length == 0 || (issues.length == 1 && issues[0].number == issueNumber)) { + if (core.getInput("body")) { + await doCreateComment(owner, repo, issueNumber, body); + } else { + core.info(`Actions: [welcome] no body!`); + } + + if (assignees) { + await doAddAssignees(owner, repo, issueNumber, assignees); + } + + if (labels) { + await doAddLabels(owner, repo, issueNumber, labels); + } + + if (issueContents) { + await doCreateIssueContent(owner, repo, issueNumber, dealInput(issueContents)); + } + } else { + core.info(`Actions: [welcome][${auth}] is not first time!`); + } + } +}; + // tool function testContent(con) { if (ALLREACTIONS.includes(con)) { @@ -324,4 +363,5 @@ module.exports = { doUnlockIssue, doUpdateComment, doUpdateIssue, + doWelcome, }; diff --git a/src/main.js b/src/main.js index 0336c36..9d8ed18 100644 --- a/src/main.js +++ b/src/main.js @@ -18,6 +18,7 @@ const { doUnlockIssue, doUpdateComment, doUpdateIssue, + doWelcome, } = require('./base.js'); const { @@ -44,6 +45,7 @@ const ALLACTIONS = [ 'unlock-issue', 'update-comment', 'update-issue', + 'welcome', // advanced 'check-inactive', @@ -152,6 +154,15 @@ async function main() { labels ); break; + case 'welcome': + await doWelcome( + owner, + repo, + assignees, + labels, + body + ); + break; // advanced case 'check-inactive':