Compare commits

...

4 Commits
v1.1 ... v1.2

Author SHA1 Message Date
xrkffgg
c5ab529e59 docs: fix typo 2020-12-25 02:22:50 +08:00
xrkffgg
1e0cecdcea docs: update changelog & pref doc 2020-12-25 02:21:14 +08:00
xrkffgg
13ffb8b717 perf: remove console 2020-12-25 02:10:26 +08:00
xrkffgg
b5274335c3 feat: add check-issue & remove labels (#12) 2020-12-25 01:33:27 +08:00
12 changed files with 473 additions and 13 deletions

1
.env
View File

@@ -1 +0,0 @@
GH_TOKEN=

1
.gitignore vendored
View File

@@ -11,6 +11,7 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# Private # Private
.env
# misc # misc
.DS_Store .DS_Store

View File

@@ -6,6 +6,8 @@ English | [简体中文](./README.zh-CN.md)
A GitHub Action to help you manage issues A GitHub Action to help you manage issues
Online documentation | [Changelog](./changelog.md)
## 😎 Why use GitHub Action? ## 😎 Why use GitHub Action?
1. Complete free. 1. Complete free.
@@ -26,12 +28,14 @@ A GitHub Action to help you manage issues
- [`lock-issue`](#lock-issue) - [`lock-issue`](#lock-issue)
- [`open-issue`](#open-issue) - [`open-issue`](#open-issue)
- [`remove-assignees`](#remove-assignees) - [`remove-assignees`](#remove-assignees)
- [`remove-labels`](#remove-labels)
- [`set-labels`](#set-labels) - [`set-labels`](#set-labels)
- [`unlock-issue`](#unlock-issue) - [`unlock-issue`](#unlock-issue)
- [`update-comment`](#update-comment) - [`update-comment`](#update-comment)
- [`update-issue`](#update-issue) - [`update-issue`](#update-issue)
- ⭐ Advanced - ⭐ Advanced
- [`check-inactive`](#check-inactive) - [`check-inactive`](#check-inactive)
- [`check-issue`](#check-issue)
- [`close-issues`](#close-issues) - [`close-issues`](#close-issues)
- [`find-comments`](#find-comments) - [`find-comments`](#find-comments)
- [`lock-issues`](#lock-issues) - [`lock-issues`](#lock-issues)
@@ -325,6 +329,31 @@ Remove the person designated by issue.
⏫ [Back to list](#List) ⏫ [Back to list](#List)
#### `remove-labels`
Remove the specified labels.
```yml
- name: Remove labels
uses: actions-cool/issues-helper@v1.2
with:
actions: 'remove-labels'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
labels: 'xx'
```
| Param | Desc | Type | Required | Version |
| -- | -- | -- | -- | -- |
| actions | Action type | string | ✔ | v1.2 |
| token | [Token explain](#token) | string | ✔ | v1.2 |
| issue-number | The number of issue | number | ✔ | v1.2 |
| labels | The removed labels. When it is a blank character, do not remove | string | ✔ | v1.2 |
- `labels` supports multiple, such as `x1,x2,x3`, only the labels added by the issue will be removed
⏫ [Back to list](#List)
#### `set-labels` #### `set-labels`
Replace the labels of issue. Replace the labels of issue.
@@ -449,7 +478,7 @@ Update the specified issue according to the `issue-number`.
### ⭐ Advanced ### ⭐ Advanced
It is not recommended to use multiple actions for advanced usage. Advanced usage is not recommended to use multiple actions at the same time.
#### `check-inactive` #### `check-inactive`
@@ -495,6 +524,61 @@ jobs:
- `inactive-day`: When entering, it will filter the issue update time earlier than the current time minus the number of inactive days. If not entered, all - `inactive-day`: When entering, it will filter the issue update time earlier than the current time minus the number of inactive days. If not entered, all
- `inactive-label`: The default is `inactive`, others can be customized. When the project does not contain the label, it will be created automatically - `inactive-label`: The default is `inactive`, others can be customized. When the project does not contain the label, it will be created automatically
⏫ [Back to list](#List)
#### `check-issue`
Check whether the issue meets the conditions according to the passed parameters and `issue-number`, and return a boolean value.
The effect of the following example is: when an issue is newly opened, verify whether the current issue designator contains `x1` or `x2`. If one designated person is satisfied, the verification will pass, and at the same time, verify whether the title meets the conditions. The conditions are as follows:
```js
x1 + y1
x2 + y1
x1 + y2
x2 + y2
"x1y3y2" true
"1x2y" false
"y2 x1" true
"x1" false
```
```yml
name: Check Issue
on:
issues:
types: [edited]
jobs:
check-issue:
runs-on: ubuntu-latest
steps:
- name: check-issue
uses: actions-cool/issues-helper@v1
with:
actions: 'check-issue'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
assignee-includes: 'x1,x2'
title-includes: 'x1,x2/y1,y2'
```
| Param | Desc | Type | Required | Version |
| -- | -- | -- | -- | -- |
| actions | Action type | string | ✔ | v1.2 |
| token | [Token explain](#token) | string | ✔ | v1.2 |
| issue-number | The number of issue | number | ✔ | v1.2 |
| assignee-includes | Assignees contains check | string | ✖ | v1.2 |
| title-includes | Title contains check | string | ✖ | v1.2 |
| body-includes | Body contains check | string | ✖ | v1.2 |
- `title-includes` `body-includes` supports the format `x1,x2` or `x1,x2/y1,y2`. Only supports two levels
- Return `check-result`
⏫ [Back to list](#List)
#### `close-issues` #### `close-issues`
Every 7 days at UTC 0, close the issues that have been filled with the `need info` label and have not been active for more than 7 days. Every 7 days at UTC 0, close the issues that have been filled with the `need info` label and have not been active for more than 7 days.
@@ -733,11 +817,15 @@ Click the `···` icon in the upper right corner of a comment, select `Copy lin
## Actions Template ## Actions Template
You can directly use this [GitHub Actions workflow template](https://github.com/actions-cool/.github) repositorie template. - You can directly use this [GitHub Actions workflow template](https://github.com/actions-cool/.github) repositorie template
- Personal exercises and tests [Actions](https://github.com/xrkffgg/test-ci) repository
## 💖 Who is using? ## 💖 Who is using?
You can come to the following repositories for reference. Please leave a message at [**here** ](https://github.com/actions-cool/issues-helper/issues/6). You can come to the following repositories for reference. Please leave a message at [**here**](https://github.com/actions-cool/issues-helper/issues/6).
At the same time, if you have any questions during use, you can also ask and inquire in the issue or discussion.
<table> <table>
<tr> <tr>

View File

@@ -6,6 +6,8 @@
一个帮你管理 issues 的 GitHub Action 一个帮你管理 issues 的 GitHub Action
在线文档 | [更新日志](./changelog.zh-CN.md)
## 😎 为什么用 GitHub Action ## 😎 为什么用 GitHub Action
1. 完全免费。 1. 完全免费。
@@ -26,12 +28,14 @@
- [`lock-issue`](#lock-issue) - [`lock-issue`](#lock-issue)
- [`open-issue`](#open-issue) - [`open-issue`](#open-issue)
- [`remove-assignees`](#remove-assignees) - [`remove-assignees`](#remove-assignees)
- [`remove-labels`](#remove-labels)
- [`set-labels`](#set-labels) - [`set-labels`](#set-labels)
- [`unlock-issue`](#unlock-issue) - [`unlock-issue`](#unlock-issue)
- [`update-comment`](#update-comment) - [`update-comment`](#update-comment)
- [`update-issue`](#update-issue) - [`update-issue`](#update-issue)
- ⭐ 进 阶 - ⭐ 进 阶
- [`check-inactive`](#check-inactive) - [`check-inactive`](#check-inactive)
- [`check-issue`](#check-issue)
- [`close-issues`](#close-issues) - [`close-issues`](#close-issues)
- [`find-comments`](#find-comments) - [`find-comments`](#find-comments)
- [`lock-issues`](#lock-issues) - [`lock-issues`](#lock-issues)
@@ -325,6 +329,31 @@ jobs:
⏫ [返回列表](#列-表) ⏫ [返回列表](#列-表)
#### `remove-labels`
移除指定 labels。
```yml
- name: Remove labels
uses: actions-cool/issues-helper@v1.2
with:
actions: 'remove-labels'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
labels: 'xx'
```
| 参数 | 描述 | 类型 | 必填 | 版本 |
| -- | -- | -- | -- | -- |
| actions | 操作类型 | string | ✔ | v1.2 |
| token | [token 说明](#token) | string | ✔ | v1.2 |
| issue-number | 指定的 issue | number | ✔ | v1.2 |
| labels | 移除的 labels。当为空字符时不进行移除 | string | ✔ | v1.2 |
- `labels` 支持多个,如 `x1,x2,x3`,只会移除 issue 已添加的 labels
⏫ [返回列表](#列-表)
#### `set-labels` #### `set-labels`
替换 issue 的 labels。 替换 issue 的 labels。
@@ -449,7 +478,7 @@ jobs:
### ⭐ 进 阶 ### ⭐ 进 阶
进阶用法不建议 actions 多使用。 进阶用法不建议 actions 多个一次同时使用。
#### `check-inactive` #### `check-inactive`
@@ -495,6 +524,61 @@ jobs:
- `inactive-day`:当输入时,会筛选 issue 更新时间早于当前时间减去非活跃天数。不填时,会查询所有 - `inactive-day`:当输入时,会筛选 issue 更新时间早于当前时间减去非活跃天数。不填时,会查询所有
- `inactive-label`:默认为 `inactive`,可自定义其他。当项目未包含该 label 时,会自动新建 - `inactive-label`:默认为 `inactive`,可自定义其他。当项目未包含该 label 时,会自动新建
⏫ [返回列表](#列-表)
#### `check-issue`
根据传入的参数和 `issue-number` 来检查该 issue 是否满足条件,返回一个布尔值。
下面的例子效果是:当 issue 新开时,校验当前 issue 指定人是否包含 `x1` 或者 `x2`,满足一个指定人即可校验通过,同时校验标题是否满足条件。条件如下:
```js
x1 + y1
x2 + y1
x1 + y2
x2 + y2
"x1y3y2" true
"1x2y" false
"y2 x1" true
"x1" false
```
```yml
name: Check Issue
on:
issues:
types: [edited]
jobs:
check-issue:
runs-on: ubuntu-latest
steps:
- name: check-issue
uses: actions-cool/issues-helper@v1
with:
actions: 'check-issue'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
assignee-includes: 'x1,x2'
title-includes: 'x1,x2/y1,y2'
```
| 参数 | 描述 | 类型 | 必填 | 版本 |
| -- | -- | -- | -- | -- |
| actions | 操作类型 | string | ✔ | v1.2 |
| token | [token 说明](#token) | string | ✔ | v1.2 |
| issue-number | 指定的 issue | number | ✔ | v1.2 |
| assignee-includes | 是否包含指定人 | string | ✖ | v1.2 |
| title-includes | 标题包含校验 | string | ✖ | v1.2 |
| body-includes | 内容包含校验 | string | ✖ | v1.2 |
- `title-includes` `body-includes` 支持格式 `x1,x2` 或者 `x1,x2/y1,y2`。只支持两个层级
- 返回 `check-result`
⏫ [返回列表](#列-表)
#### `close-issues` #### `close-issues`
每 7 天 UTC 0 时,关闭已填加 `need info` label 且 7 天以上未活跃的 issues。 每 7 天 UTC 0 时,关闭已填加 `need info` label 且 7 天以上未活跃的 issues。
@@ -733,11 +817,15 @@ jobs:
## Actions 模板 ## Actions 模板
可直接使用这个 [GitHub Actions workflow template](https://github.com/actions-cool/.github) 仓库的模板 - 可直接使用这个 [GitHub Actions workflow template](https://github.com/actions-cool/.github) 仓库的模板
- 个人练习和测试 [Actions](https://github.com/xrkffgg/test-ci) 的仓库
## 💖 谁在使用? ## 💖 谁在使用?
你可以来以下项目进行参考。欢迎在[ **这里** ](https://github.com/actions-cool/issues-helper/issues/6)留言。 你可以来以下项目进行参考。欢迎在 [**这里**](https://github.com/actions-cool/issues-helper/issues/6) 留言。
同时,如果你在使用过程中有什么疑问,也可以在 issue 或者 discussion 中进行提问和查询。
<table> <table>
<tr> <tr>

View File

@@ -1,9 +1,9 @@
name: 'Issues Helper' name: 'Issues Helper'
description: 'Some operations on issue' description: 'A GitHub Action to help you manage issues'
author: 'xrkffgg' author: 'xrkffgg'
branding: branding:
icon: 'message-square' icon: 'message-square'
color: 'blue' color: 'black'
inputs: inputs:
actions: actions:
description: 'Action name' description: 'Action name'
@@ -32,6 +32,8 @@ inputs:
description: 'Find comments direction' description: 'Find comments direction'
comment-auth: comment-auth:
description: 'Find comments query auth' description: 'Find comments query auth'
assignee-includes:
description: 'Check use'
body-includes: body-includes:
description: 'Query use' description: 'Query use'
title-includes: title-includes:
@@ -55,6 +57,8 @@ outputs:
description: 'Create comment ID' description: 'Create comment ID'
comments: comments:
description: 'Find comments' description: 'Find comments'
check-result:
description: 'Check issue'
runs: runs:
using: node12 using: node12
main: 'dist/index.js' main: 'dist/index.js'

41
changelog.md Normal file
View File

@@ -0,0 +1,41 @@
# ✨ Changelog
## Version rules
- Use two-level semantic version, such as v1, v1.1, v2, v2.1
- v1 represents the initial version
- The fixes and additions to the v1 version will be released to the v1.1 version
- When the released v1.x runs stable for a certain period of time, release the advanced v2 version
## Version selection
- It is recommended to use the latest releases version. It can be seen in [releases](https://github.com/actions-cool/issues-helper/releases)
- You can also refer to the update log below to select the version
- It also supports the direct use of branch versions. Such as:
```yml
- name: Issues Helper
uses: actions-cool/issues-helper@main
```
## Change Log
### 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.

41
changelog.zh-CN.md Normal file
View File

@@ -0,0 +1,41 @@
# ✨ 更新日志
## 版本规则
- 采用两级语义化版本如v1、v1.1、v2、v2.1
- v1 表示初始版本
- 对 v1 版本的修复和新增会发布到 v1.1 版本
- 当发布的 v1.x 运行一定时间稳定后,发布进阶 v2 版本
## 版本选择
- 建议采用最新 releases 版本。可在 [releases](https://github.com/actions-cool/issues-helper/releases) 看到
- 同时也可参照下面的更新日志来选择版本
- 也支持直接使用分支版本。如:
```yml
- name: Issues Helper
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.

103
dist/index.js vendored
View File

@@ -5996,6 +5996,8 @@ const {
doLockIssue doLockIssue
} = __webpack_require__(9932); } = __webpack_require__(9932);
const { dealInput, matchKeyword } = __webpack_require__(6254);
const token = core.getInput('token'); const token = core.getInput('token');
const octokit = new Octokit({ auth: `token ${token}` }); const octokit = new Octokit({ auth: `token ${token}` });
@@ -6005,6 +6007,7 @@ direction = direction === 'desc' ? 'desc' : 'asc';
const commentAuth = core.getInput("comment-auth"); const commentAuth = core.getInput("comment-auth");
const bodyIncludes = core.getInput('body-includes'); const bodyIncludes = core.getInput('body-includes');
const titleIncludes = core.getInput('title-includes'); const titleIncludes = core.getInput('title-includes');
const assigneeIncludes = core.getInput('assignee-includes');
const issueCreator = core.getInput("issue-creator"); const issueCreator = core.getInput("issue-creator");
const issueAssignee = core.getInput('issue-assignee'); const issueAssignee = core.getInput('issue-assignee');
@@ -6038,6 +6041,54 @@ async function doCheckInactive (owner, repo, labels) {
} }
}; };
/**
* 检查 issue 是否满足条件,满足返回 true
* 当前 issue 的指定人是否有一个满足 assigneeIncludes 里的某个
* 关键字匹配,是否包含前一个某个+后一个某个 '官网,网站/挂了,无法访问'
*/
async function doCheckIssue (owner, repo, issueNumber) {
var checkResult = true;
const issue = await octokit.issues.get({
owner,
repo,
issue_number: issueNumber
});
if (!!checkResult && assigneeIncludes) {
let assigneesCheck = dealInput(assigneeIncludes);
let checkAssignee = false;
issue.data.assignees.forEach(it => {
if (checkResult && !checkAssignee && assigneesCheck.includes(it.login)) {
checkResult = true;
checkAssignee = true;
}
})
!checkAssignee ? checkResult = false : null;
}
if (!!checkResult && titleIncludes) {
const titleArr = titleIncludes.split('/');
const keyword1 = dealInput(titleArr[0]);
const keyword2 = dealInput(titleArr[1]);
checkResult =
keyword2.length ?
matchKeyword(issue.data.title, keyword1) && matchKeyword(issue.data.title, keyword2) :
matchKeyword(issue.data.title, keyword1);
}
if (!!checkResult && bodyIncludes) {
const bodyArr = bodyIncludes.split('/');
const keyword1 = dealInput(bodyArr[0]);
const keyword2 = dealInput(bodyArr[1]);
checkResult =
keyword2.length ?
matchKeyword(issue.data.body, keyword1) && matchKeyword(issue.data.body, keyword2) :
matchKeyword(issue.data.body, keyword1);
}
core.info(`Actions: [check-issue][${!!checkResult}] success!`);
core.setOutput("check-result", !!checkResult);
};
async function doCloseIssues (owner, repo, labels) { async function doCloseIssues (owner, repo, labels) {
const issues = await doQueryIssues(owner, repo, labels, 'open'); const issues = await doQueryIssues(owner, repo, labels, 'open');
@@ -6115,7 +6166,12 @@ async function doQueryIssues (owner, repo, labels, state) {
res.data.forEach(iss => { res.data.forEach(iss => {
const a = bodyIncludes ? iss.body.includes(bodyIncludes) : true; const a = bodyIncludes ? iss.body.includes(bodyIncludes) : true;
const b = titleIncludes ? iss.title.includes(titleIncludes) : true; const b = titleIncludes ? iss.title.includes(titleIncludes) : true;
if (a && b) { /**
* Note: GitHub's REST API v3 considers every pull request an issue, but not every issue is a pull request.
* For this reason, "Issues" endpoints may return both issues and pull requests in the response.
* You can identify pull requests by the pull_request key.
*/
if (a && b && iss.pull_request === undefined) {
if (inactiveDay && typeof(inactiveDay) === 'number') { if (inactiveDay && typeof(inactiveDay) === 'number') {
let lastTime = dayjs.utc().subtract(inactiveDay, 'day'); let lastTime = dayjs.utc().subtract(inactiveDay, 'day');
let updateTime = dayjs.utc(iss.updated_at); let updateTime = dayjs.utc(iss.updated_at);
@@ -6133,6 +6189,7 @@ async function doQueryIssues (owner, repo, labels, state) {
module.exports = { module.exports = {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,
@@ -6300,6 +6357,28 @@ async function doRemoveAssignees (owner, repo, issueNumber, assignees) {
core.info(`Actions: [remove-assignees][${assignees}] success!`); core.info(`Actions: [remove-assignees][${assignees}] success!`);
}; };
async function doRemoveLabels (owner, repo, issueNumber, labels) {
const issue = await octokit.issues.get({
owner,
repo,
issue_number: issueNumber
});
const dealLabels = dealInput(labels);
let addLables = [];
if (dealLabels.length) {
issue.data.labels.forEach(item => {
!dealLabels.includes(item.name) ? addLables.push(item.name) : '';
})
await octokit.issues.setLabels({
owner,
repo,
issue_number: issueNumber,
labels: addLables
});
core.info(`Actions: [remove-labels][${labels}] success!`);
}
};
async function doSetLabels (owner, repo, issueNumber, labels) { async function doSetLabels (owner, repo, issueNumber, labels) {
await octokit.issues.setLabels({ await octokit.issues.setLabels({
owner, owner,
@@ -6348,7 +6427,7 @@ async function doUpdateComment (
await octokit.issues.updateComment(params); await octokit.issues.updateComment(params);
core.info(`Actions: [update-comment][${commentId}] success!`); core.info(`Actions: [update-comment][${commentId}] success!`);
} }
if (contents) { if (contents) {
await doCreateCommentContent(owner, repo, commentId, dealInput(contents)); await doCreateCommentContent(owner, repo, commentId, dealInput(contents));
@@ -6443,6 +6522,7 @@ module.exports = {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,
@@ -6470,6 +6550,7 @@ const {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,
@@ -6478,6 +6559,7 @@ const {
const { const {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,
@@ -6494,6 +6576,7 @@ const ALLACTIONS = [
'lock-issue', 'lock-issue',
'open-issue', 'open-issue',
'remove-assignees', 'remove-assignees',
'remove-labels',
'set-labels', 'set-labels',
'unlock-issue', 'unlock-issue',
'update-comment', 'update-comment',
@@ -6501,6 +6584,7 @@ const ALLACTIONS = [
// advanced // advanced
'check-inactive', 'check-inactive',
'check-issue',
'close-issues', 'close-issues',
'find-comments', 'find-comments',
'lock-issues', 'lock-issues',
@@ -6574,6 +6658,9 @@ async function main() {
case 'remove-assignees': case 'remove-assignees':
await doRemoveAssignees(owner, repo, issueNumber, assignees); await doRemoveAssignees(owner, repo, issueNumber, assignees);
break; break;
case 'remove-labels':
await doRemoveLabels(owner, repo, issueNumber, labels);
break;
case 'set-labels': case 'set-labels':
await doSetLabels(owner, repo, issueNumber, labels); await doSetLabels(owner, repo, issueNumber, labels);
break; break;
@@ -6611,6 +6698,13 @@ async function main() {
labels labels
) )
break; break;
case 'check-issue':
await doCheckIssue(
owner,
repo,
issueNumber
);
break;
case 'close-issues': case 'close-issues':
await doCloseIssues( await doCloseIssues(
owner, owner,
@@ -6664,8 +6758,13 @@ function dealInput (para) {
return arr; return arr;
}; };
function matchKeyword(content, keywords) {
return keywords.find(item => content.toLowerCase().includes(item));
};
module.exports = { module.exports = {
dealInput, dealInput,
matchKeyword,
}; };

View File

@@ -15,6 +15,8 @@ const {
doLockIssue doLockIssue
} = require('./base.js'); } = require('./base.js');
const { dealInput, matchKeyword } = require('./util.js');
const token = core.getInput('token'); const token = core.getInput('token');
const octokit = new Octokit({ auth: `token ${token}` }); const octokit = new Octokit({ auth: `token ${token}` });
@@ -24,6 +26,7 @@ direction = direction === 'desc' ? 'desc' : 'asc';
const commentAuth = core.getInput("comment-auth"); const commentAuth = core.getInput("comment-auth");
const bodyIncludes = core.getInput('body-includes'); const bodyIncludes = core.getInput('body-includes');
const titleIncludes = core.getInput('title-includes'); const titleIncludes = core.getInput('title-includes');
const assigneeIncludes = core.getInput('assignee-includes');
const issueCreator = core.getInput("issue-creator"); const issueCreator = core.getInput("issue-creator");
const issueAssignee = core.getInput('issue-assignee'); const issueAssignee = core.getInput('issue-assignee');
@@ -57,6 +60,54 @@ async function doCheckInactive (owner, repo, labels) {
} }
}; };
/**
* 检查 issue 是否满足条件,满足返回 true
* 当前 issue 的指定人是否有一个满足 assigneeIncludes 里的某个
* 关键字匹配,是否包含前一个某个+后一个某个 '官网,网站/挂了,无法访问'
*/
async function doCheckIssue (owner, repo, issueNumber) {
var checkResult = true;
const issue = await octokit.issues.get({
owner,
repo,
issue_number: issueNumber
});
if (!!checkResult && assigneeIncludes) {
let assigneesCheck = dealInput(assigneeIncludes);
let checkAssignee = false;
issue.data.assignees.forEach(it => {
if (checkResult && !checkAssignee && assigneesCheck.includes(it.login)) {
checkResult = true;
checkAssignee = true;
}
})
!checkAssignee ? checkResult = false : null;
}
if (!!checkResult && titleIncludes) {
const titleArr = titleIncludes.split('/');
const keyword1 = dealInput(titleArr[0]);
const keyword2 = dealInput(titleArr[1]);
checkResult =
keyword2.length ?
matchKeyword(issue.data.title, keyword1) && matchKeyword(issue.data.title, keyword2) :
matchKeyword(issue.data.title, keyword1);
}
if (!!checkResult && bodyIncludes) {
const bodyArr = bodyIncludes.split('/');
const keyword1 = dealInput(bodyArr[0]);
const keyword2 = dealInput(bodyArr[1]);
checkResult =
keyword2.length ?
matchKeyword(issue.data.body, keyword1) && matchKeyword(issue.data.body, keyword2) :
matchKeyword(issue.data.body, keyword1);
}
core.info(`Actions: [check-issue][${!!checkResult}] success!`);
core.setOutput("check-result", !!checkResult);
};
async function doCloseIssues (owner, repo, labels) { async function doCloseIssues (owner, repo, labels) {
const issues = await doQueryIssues(owner, repo, labels, 'open'); const issues = await doQueryIssues(owner, repo, labels, 'open');
@@ -134,7 +185,12 @@ async function doQueryIssues (owner, repo, labels, state) {
res.data.forEach(iss => { res.data.forEach(iss => {
const a = bodyIncludes ? iss.body.includes(bodyIncludes) : true; const a = bodyIncludes ? iss.body.includes(bodyIncludes) : true;
const b = titleIncludes ? iss.title.includes(titleIncludes) : true; const b = titleIncludes ? iss.title.includes(titleIncludes) : true;
if (a && b) { /**
* Note: GitHub's REST API v3 considers every pull request an issue, but not every issue is a pull request.
* For this reason, "Issues" endpoints may return both issues and pull requests in the response.
* You can identify pull requests by the pull_request key.
*/
if (a && b && iss.pull_request === undefined) {
if (inactiveDay && typeof(inactiveDay) === 'number') { if (inactiveDay && typeof(inactiveDay) === 'number') {
let lastTime = dayjs.utc().subtract(inactiveDay, 'day'); let lastTime = dayjs.utc().subtract(inactiveDay, 'day');
let updateTime = dayjs.utc(iss.updated_at); let updateTime = dayjs.utc(iss.updated_at);
@@ -152,6 +208,7 @@ async function doQueryIssues (owner, repo, labels, state) {
module.exports = { module.exports = {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,

View File

@@ -154,6 +154,28 @@ async function doRemoveAssignees (owner, repo, issueNumber, assignees) {
core.info(`Actions: [remove-assignees][${assignees}] success!`); core.info(`Actions: [remove-assignees][${assignees}] success!`);
}; };
async function doRemoveLabels (owner, repo, issueNumber, labels) {
const issue = await octokit.issues.get({
owner,
repo,
issue_number: issueNumber
});
const dealLabels = dealInput(labels);
let addLables = [];
if (dealLabels.length) {
issue.data.labels.forEach(item => {
!dealLabels.includes(item.name) ? addLables.push(item.name) : '';
})
await octokit.issues.setLabels({
owner,
repo,
issue_number: issueNumber,
labels: addLables
});
core.info(`Actions: [remove-labels][${labels}] success!`);
}
};
async function doSetLabels (owner, repo, issueNumber, labels) { async function doSetLabels (owner, repo, issueNumber, labels) {
await octokit.issues.setLabels({ await octokit.issues.setLabels({
owner, owner,
@@ -202,7 +224,7 @@ async function doUpdateComment (
await octokit.issues.updateComment(params); await octokit.issues.updateComment(params);
core.info(`Actions: [update-comment][${commentId}] success!`); core.info(`Actions: [update-comment][${commentId}] success!`);
} }
if (contents) { if (contents) {
await doCreateCommentContent(owner, repo, commentId, dealInput(contents)); await doCreateCommentContent(owner, repo, commentId, dealInput(contents));
@@ -297,6 +319,7 @@ module.exports = {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,

View File

@@ -13,6 +13,7 @@ const {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,
@@ -21,6 +22,7 @@ const {
const { const {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,
@@ -37,6 +39,7 @@ const ALLACTIONS = [
'lock-issue', 'lock-issue',
'open-issue', 'open-issue',
'remove-assignees', 'remove-assignees',
'remove-labels',
'set-labels', 'set-labels',
'unlock-issue', 'unlock-issue',
'update-comment', 'update-comment',
@@ -44,6 +47,7 @@ const ALLACTIONS = [
// advanced // advanced
'check-inactive', 'check-inactive',
'check-issue',
'close-issues', 'close-issues',
'find-comments', 'find-comments',
'lock-issues', 'lock-issues',
@@ -117,6 +121,9 @@ async function main() {
case 'remove-assignees': case 'remove-assignees':
await doRemoveAssignees(owner, repo, issueNumber, assignees); await doRemoveAssignees(owner, repo, issueNumber, assignees);
break; break;
case 'remove-labels':
await doRemoveLabels(owner, repo, issueNumber, labels);
break;
case 'set-labels': case 'set-labels':
await doSetLabels(owner, repo, issueNumber, labels); await doSetLabels(owner, repo, issueNumber, labels);
break; break;
@@ -154,6 +161,13 @@ async function main() {
labels labels
) )
break; break;
case 'check-issue':
await doCheckIssue(
owner,
repo,
issueNumber
);
break;
case 'close-issues': case 'close-issues':
await doCloseIssues( await doCloseIssues(
owner, owner,

View File

@@ -11,6 +11,11 @@ function dealInput (para) {
return arr; return arr;
}; };
function matchKeyword(content, keywords) {
return keywords.find(item => content.toLowerCase().includes(item));
};
module.exports = { module.exports = {
dealInput, dealInput,
matchKeyword,
}; };