mirror of
https://gitea.com/Lydanne/issues-helper.git
synced 2025-08-20 18:55:47 +08:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c5ab529e59 | ||
![]() |
1e0cecdcea | ||
![]() |
13ffb8b717 | ||
![]() |
b5274335c3 | ||
![]() |
62ec5c7335 | ||
![]() |
822d3a57be | ||
![]() |
1d0bb25b58 | ||
![]() |
e92345f030 | ||
![]() |
4f43f584a7 | ||
![]() |
597b0b36ce | ||
![]() |
87d4e59578 | ||
![]() |
90971f72b3 | ||
![]() |
4db267691c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,6 +11,7 @@ yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Private
|
||||
.env
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
168
README.md
168
README.md
@@ -2,9 +2,11 @@
|
||||
|
||||
English | [简体中文](./README.zh-CN.md)
|
||||
|
||||
[](https://github.com/actions-cool/issues-helper/actions) [](https://github.com/actions-cool/issues-helper/stargazers) [](https://github.com/actions-cool/issues-helper/releases) [](https://github.com/actions-cool/issues-helper/blob/main/LICENSE)
|
||||
[](https://github.com/actions-cool/issues-helper/actions) [](https://github.com/marketplace/actions/issues-helper) [](https://github.com/actions-cool/issues-helper/stargazers) [](https://github.com/actions-cool/issues-helper/releases) [](https://github.com/actions-cool/issues-helper/discussions) [](https://github.com/actions-cool/issues-helper/blob/main/LICENSE)
|
||||
|
||||
A GitHub Action to help you deal with issues
|
||||
A GitHub Action to help you manage issues
|
||||
|
||||
Online documentation | [Changelog](./changelog.md)
|
||||
|
||||
## 😎 Why use GitHub Action?
|
||||
|
||||
@@ -12,7 +14,7 @@ A GitHub Action to help you deal with issues
|
||||
2. Fully automatic.
|
||||
3. Hosted on the GitHub server, as long as GitHub is not down, it will keep running.
|
||||
|
||||
> Private projects have a limit of 2000 times per month, [Specific view](https://github.com/settings/billing). Public are unlimited.
|
||||
> Private projects have a limit of 2000 times per month. [Specific view](https://github.com/settings/billing). Public are unlimited.
|
||||
|
||||
## List
|
||||
|
||||
@@ -26,12 +28,14 @@ A GitHub Action to help you deal with issues
|
||||
- [`lock-issue`](#lock-issue)
|
||||
- [`open-issue`](#open-issue)
|
||||
- [`remove-assignees`](#remove-assignees)
|
||||
- [`remove-labels`](#remove-labels)
|
||||
- [`set-labels`](#set-labels)
|
||||
- [`unlock-issue`](#unlock-issue)
|
||||
- [`update-comment`](#update-comment)
|
||||
- [`update-issue`](#update-issue)
|
||||
- ⭐ Advanced
|
||||
- [`check-inactive`](#check-inactive)
|
||||
- [`check-issue`](#check-issue)
|
||||
- [`close-issues`](#close-issues)
|
||||
- [`find-comments`](#find-comments)
|
||||
- [`lock-issues`](#lock-issues)
|
||||
@@ -65,7 +69,7 @@ jobs:
|
||||
actions: 'add-assignees'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
assignees: 'xxx' or ['xxx'] or ['xx1', 'xx2']
|
||||
assignees: 'xxx' or 'xx1,xx2'
|
||||
```
|
||||
|
||||
| Param | Desc | Type | Required | Version |
|
||||
@@ -73,12 +77,13 @@ jobs:
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| issue-number | The number of issue | number | ✔ | v1 |
|
||||
| assignees | Designated person. No operation when no input or empty character or empty array | string \| string\[] | ✖ | v1 |
|
||||
| assignees | Designated person. No operation when no input or empty character | string | ✖ | v1 |
|
||||
|
||||
- `actions` support multiple and separated by comma. Like: `add-assignees,add-labels`
|
||||
- The `name` can be modified according to the actual situation
|
||||
- [on reference](#github-docs)
|
||||
- `${{ github.event.issue.number }}` is the current issue. [More references](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events)
|
||||
- `assignees` support multiple and separated by comma. Pay attention to multiple settings, you need to use the version above v1.1
|
||||
|
||||
⏫ [Back to list](#List)
|
||||
|
||||
@@ -104,7 +109,7 @@ jobs:
|
||||
actions: 'add-labels'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: 'bug' or ['bug'] or ['bug1', 'bug2']
|
||||
labels: 'bug' or 'xx1,xx2'
|
||||
```
|
||||
|
||||
| Param | Desc | Type | Required | Version |
|
||||
@@ -112,7 +117,9 @@ jobs:
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| issue-number | The number of issue | number | ✔ | v1 |
|
||||
| labels | New labels. When it is not filled in or is empty character, empty array, do not add | string \| string\[] | ✖ | v1 |
|
||||
| labels | New labels. When it is not filled in or is empty character, do not add | string | ✖ | v1 |
|
||||
|
||||
- `labels` support multiple and separated by comma. Pay attention to multiple settings, you need to use the version above v1.1
|
||||
|
||||
⏫ [Back to list](#List)
|
||||
|
||||
@@ -164,7 +171,7 @@ jobs:
|
||||
Hello @${{ github.event.issue.user.login }}. Add some comments.
|
||||
|
||||
你好 @${{ github.event.issue.user.login }}。巴拉巴拉。
|
||||
contents: '+1' or ['+1', 'heart']
|
||||
contents: '+1' or '+1,heart'
|
||||
```
|
||||
|
||||
| Param | Desc | Type | Required | Version |
|
||||
@@ -173,12 +180,13 @@ jobs:
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| issue-number | The number of issue | number | ✔ | v1 |
|
||||
| body | Add comment content | string | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `body` default is `Currently at ${owner}/${repo}. And this is default comment.`
|
||||
- Where `${owner}/${repo}` means the current repo
|
||||
- Return `comment-id`, which can be used for subsequent operations. [Usage reference](#outputs-use)
|
||||
- `${{ github.event.issue.user.login }}` indicates the creator of the issue
|
||||
- `contents` support multiple and separated by comma. Pay attention to multiple settings, you need to use the version above v1.1
|
||||
|
||||
⏫ [Back to list](#List)
|
||||
|
||||
@@ -215,9 +223,9 @@ jobs:
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| title | The title of the new issue | string | ✖ | v1 |
|
||||
| body | The body of the new issue | string | ✖ | v1 |
|
||||
| labels | The labels for the new issue | string \| string\[] | ✖ | v1 |
|
||||
| assignees | The assignees for the new issue | string \| string\[] | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| labels | The labels for the new issue | string | ✖ | v1 |
|
||||
| assignees | The assignees for the new issue | string | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `title` default is `Default Title`
|
||||
- Return `issue-number`. [Usage reference](#outputs-use)
|
||||
@@ -317,7 +325,32 @@ Remove the person designated by issue.
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| issue-number | The number of issue | number | ✔ | v1 |
|
||||
| assignees | Designated person removed. When it is an empty character, empty array, do not remove | string \| string\[] | ✔ | v1 |
|
||||
| assignees | Designated person removed. When it is an empty character, do not remove | string | ✔ | v1 |
|
||||
|
||||
⏫ [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)
|
||||
|
||||
@@ -340,7 +373,7 @@ Replace the labels of issue.
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| issue-number | The number of issue | number | ✔ | v1 |
|
||||
| labels | labels set. When empty characters, empty array, will remove all | string \| string\[] | ✔ | v1 |
|
||||
| labels | labels set. When empty characters, will remove all | string | ✔ | v1 |
|
||||
|
||||
⏫ [Back to list](#List)
|
||||
|
||||
@@ -398,7 +431,7 @@ jobs:
|
||||
| comment-id | The comment ID | number | ✔ | v1 |
|
||||
| body | Update the content of comment | string | ✖ | v1 |
|
||||
| update-mode | Update mode. Default `replace`, another `append` | string | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- When `body` is not entered, it will remain as it is
|
||||
- When `update-mode` is `append`, additional operations will be performed. Anything other than `append` will be replaced. Only effective for `body`
|
||||
@@ -434,9 +467,9 @@ Update the specified issue according to the `issue-number`.
|
||||
| title | Modify the title of the issue | string | ✖ | v1 |
|
||||
| body | Modify the content of issue | string | ✖ | v1 |
|
||||
| update-mode | Update mode. Default `replace`, another `append` | string | ✖ | v1 |
|
||||
| labels | Replace the labels of issue | string \| string\[] | ✖ | v1 |
|
||||
| assignees | Replace the assignees of issue | string \| string\[] | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| labels | Replace the labels of issue | string | ✖ | v1 |
|
||||
| assignees | Replace the assignees of issue | string | ✖ | v1 |
|
||||
| contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `state` defaults to `open`
|
||||
- When the option is not filled, it will keep the original
|
||||
@@ -445,7 +478,7 @@ Update the specified issue according to the `issue-number`.
|
||||
|
||||
### ⭐ 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`
|
||||
|
||||
@@ -475,7 +508,7 @@ jobs:
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| body | When operating an issue, you can comment. Do not comment when not typing | string | ✖ | v1 |
|
||||
| labels | Labels filtering | string \| string\[] | ✖ | v1 |
|
||||
| labels | Labels filtering | string | ✖ | v1 |
|
||||
| issue-state | State filtering | string | ✖ | v1 |
|
||||
| issue-assignee | Assignee filtering | string | ✖ | v1 |
|
||||
| issue-creator | Creator filtering | string | ✖ | v1 |
|
||||
@@ -491,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-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`
|
||||
|
||||
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.
|
||||
@@ -520,7 +608,7 @@ jobs:
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| body | When operating an issue, you can comment. Do not comment when not typing | string | ✖ | v1 |
|
||||
| labels | Labels filtering | string \| string\[] | ✖ | v1 |
|
||||
| labels | Labels filtering | string | ✖ | v1 |
|
||||
| issue-assignee | Assignee filtering | string | ✖ | v1 |
|
||||
| issue-creator | Creator filtering | string | ✖ | v1 |
|
||||
| issue-mentioned | Mentioned filtering | string | ✖ | v1 |
|
||||
@@ -601,7 +689,7 @@ jobs:
|
||||
| actions | Action type | string | ✔ | v1 |
|
||||
| token | [Token explain](#token) | string | ✔ | v1 |
|
||||
| body | When operating an issue, you can comment. Do not comment when not typing | string | ✖ | v1 |
|
||||
| labels | Labels filtering | string \| string\[] | ✖ | v1 |
|
||||
| labels | Labels filtering | string | ✖ | v1 |
|
||||
| issue-state | State filtering | string | ✖ | v1 |
|
||||
| issue-assignee | Assignee filtering | string | ✖ | v1 |
|
||||
| issue-creator | Creator filtering | string | ✖ | v1 |
|
||||
@@ -729,11 +817,41 @@ Click the `···` icon in the upper right corner of a comment, select `Copy lin
|
||||
|
||||
## Actions Template
|
||||
|
||||
[GitHub Actions workflow template](https://github.com/actions-cool/.github). After fork, you can use the template directly.
|
||||
- You can directly use this [GitHub Actions workflow template](https://github.com/actions-cool/.github) repositorie template
|
||||
|
||||
## 💖 Who are using?
|
||||
- Personal exercises and tests [Actions](https://github.com/xrkffgg/test-ci) repository
|
||||
|
||||
You can come to the following reference template. Please leave a message at [**here** ](https://github.com/actions-cool/issues-helper/issues/6).
|
||||
## 💖 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).
|
||||
|
||||
At the same time, if you have any questions during use, you can also ask and inquire in the issue or discussion.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ant-design/ant-design">
|
||||
<img src="https://avatars1.githubusercontent.com/u/12101536?s=200&v=4" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>ant-design</strong>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vueComponent/ant-design-vue">
|
||||
<img src="https://avatars2.githubusercontent.com/u/32120805?s=200&v=4" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>ant-design-vue</strong>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AttoJS/vue-request">
|
||||
<img src="https://raw.githubusercontent.com/AttoJS/art/master/vue-request-logo.png" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>vue-request</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## LICENSE
|
||||
|
||||
|
166
README.zh-CN.md
166
README.zh-CN.md
@@ -1,10 +1,12 @@
|
||||
# 🤖 Issues Helper
|
||||
# 🤖 Issues 助手
|
||||
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
[](https://github.com/actions-cool/issues-helper/actions) [](https://github.com/actions-cool/issues-helper/stargazers) [](https://github.com/actions-cool/issues-helper/releases) [](https://github.com/actions-cool/issues-helper/blob/main/LICENSE)
|
||||
[](https://github.com/actions-cool/issues-helper/actions) [](https://github.com/marketplace/actions/issues-helper) [](https://github.com/actions-cool/issues-helper/stargazers) [](https://github.com/actions-cool/issues-helper/releases) [](https://github.com/actions-cool/issues-helper/discussions) [](https://github.com/actions-cool/issues-helper/blob/main/LICENSE)
|
||||
|
||||
一个帮你处理 issues 的 GitHub Action
|
||||
一个帮你管理 issues 的 GitHub Action
|
||||
|
||||
在线文档 | [更新日志](./changelog.zh-CN.md)
|
||||
|
||||
## 😎 为什么用 GitHub Action?
|
||||
|
||||
@@ -26,12 +28,14 @@
|
||||
- [`lock-issue`](#lock-issue)
|
||||
- [`open-issue`](#open-issue)
|
||||
- [`remove-assignees`](#remove-assignees)
|
||||
- [`remove-labels`](#remove-labels)
|
||||
- [`set-labels`](#set-labels)
|
||||
- [`unlock-issue`](#unlock-issue)
|
||||
- [`update-comment`](#update-comment)
|
||||
- [`update-issue`](#update-issue)
|
||||
- ⭐ 进 阶
|
||||
- [`check-inactive`](#check-inactive)
|
||||
- [`check-issue`](#check-issue)
|
||||
- [`close-issues`](#close-issues)
|
||||
- [`find-comments`](#find-comments)
|
||||
- [`lock-issues`](#lock-issues)
|
||||
@@ -65,7 +69,7 @@ jobs:
|
||||
actions: 'add-assignees'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
assignees: 'xxx' or ['xxx'] or ['xx1', 'xx2']
|
||||
assignees: 'xxx' or 'xx1,xx2'
|
||||
```
|
||||
|
||||
| 参数 | 描述 | 类型 | 必填 | 版本 |
|
||||
@@ -73,12 +77,13 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| issue-number | 指定的 issue | number | ✔ | v1 |
|
||||
| assignees | 指定人。当不填或者为空字符、空数组时,不操作 | string \| string\[] | ✖ | v1 |
|
||||
| assignees | 指定人。当不填或者为空字符时,不操作 | string | ✖ | v1 |
|
||||
|
||||
- `actions` 支持多个,需用逗号隔开。如:`add-assignees,add-labels`
|
||||
- 其中的 `name` 可根据自行根据实际情况修改
|
||||
- [on 参考](#github-docs)
|
||||
- `${{ github.event.issue.number }}` 表示当前 issue,[更多参考](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events)
|
||||
- `assignees` 支持多个,需用逗号隔开。注意设置多个,需使用v1.1以上版本
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
@@ -104,7 +109,7 @@ jobs:
|
||||
actions: 'add-labels'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: 'bug' or ['bug'] or ['bug1', 'bug2']
|
||||
labels: 'bug' or 'bug1,bug2'
|
||||
```
|
||||
|
||||
| 参数 | 描述 | 类型 | 必填 | 版本 |
|
||||
@@ -112,7 +117,9 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| issue-number | 指定的 issue | number | ✔ | v1 |
|
||||
| labels | 新增的 labels。当不填或者为空字符、空数组时,不新增 | string \| string\[] | ✖ | v1 |
|
||||
| labels | 新增的 labels。当不填或者为空字符时,不新增 | string | ✖ | v1 |
|
||||
|
||||
- `labels` 支持多个,需用逗号隔开。注意设置多个,需使用v1.1以上版本
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
@@ -164,7 +171,7 @@ jobs:
|
||||
Hello ${{ github.event.issue.user.login }}. Add some comments.
|
||||
|
||||
你好 ${{ github.event.issue.user.login }}。巴拉巴拉。
|
||||
contents: '+1' or ['+1', 'heart']
|
||||
contents: '+1' or '+1,heart'
|
||||
```
|
||||
|
||||
| 参数 | 描述 | 类型 | 必填 | 版本 |
|
||||
@@ -173,12 +180,13 @@ jobs:
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| issue-number | 指定的 issue | number | ✔ | v1 |
|
||||
| body | 新增评论的内容 | string | ✖ | v1 |
|
||||
| contents | 为新增评论的增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| contents | 为新增评论的增加 [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `body` 默认为:`Currently at ${owner}/${repo}. And this is default comment.`
|
||||
- 其中 `${owner}/${repo}` 表示当前仓库
|
||||
- 返回 `comment-id`,可用于之后操作。[用法参考](#outputs-使用)
|
||||
- `${{ github.event.issue.user.login }}` 表示该 issue 的创建者
|
||||
- `contents` 支持多个,需用逗号隔开。注意设置多个,需使用v1.1以上版本
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
@@ -215,9 +223,9 @@ jobs:
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| title | 新增 issue 的标题 | string | ✖ | v1 |
|
||||
| body | 新增 issue 的内容 | string | ✖ | v1 |
|
||||
| labels | 为新增 issue 添加 labels | string \| string\[] | ✖ | v1 |
|
||||
| assignees | 为新增 issue 添加 assignees | string \| string\[] | ✖ | v1 |
|
||||
| contents | 为新增 issue 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| labels | 为新增 issue 添加 labels | string | ✖ | v1 |
|
||||
| assignees | 为新增 issue 添加 assignees | string | ✖ | v1 |
|
||||
| contents | 为新增 issue 增加 [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `title` 默认为:`Default Title`
|
||||
- 返回 `issue-number`,[用法参考](#outputs-使用)
|
||||
@@ -317,7 +325,32 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| issue-number | 指定的 issue | number | ✔ | v1 |
|
||||
| assignees | 移除的指定人。当为空字符、空数组时,不进行移除 | string \| string\[] | ✔ | v1 |
|
||||
| assignees | 移除的指定人。当为空字符时,不进行移除 | string | ✔ | v1 |
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
#### `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
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
@@ -340,7 +373,7 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| issue-number | 指定的 issue | number | ✔ | v1 |
|
||||
| labels | labels 设置。当空字符、空数组时,会移除所有 | string \| string\[] | ✔ | v1 |
|
||||
| labels | labels 设置。当空字符时,会移除所有 | string | ✔ | v1 |
|
||||
|
||||
⏫ [返回列表](#列-表)
|
||||
|
||||
@@ -398,7 +431,7 @@ jobs:
|
||||
| comment-id | 指定的 comment | number | ✔ | v1 |
|
||||
| body | 更新 comment 的内容 | string | ✖ | v1 |
|
||||
| update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 |
|
||||
| contents | 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| contents | 增加 [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `body` 不填时,会保持原有
|
||||
- `update-mode` 为 `append` 时,会进行附加操作。非 `append` 都会进行替换。仅对 `body` 生效
|
||||
@@ -434,9 +467,9 @@ jobs:
|
||||
| title | 修改 issue 的标题 | string | ✖ | v1 |
|
||||
| body | 修改 issue 的内容 | string | ✖ | v1 |
|
||||
| update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 |
|
||||
| labels | 替换 issue 的 labels | string \| string\[] | ✖ | v1 |
|
||||
| assignees | 替换 issue 的 assignees | string \| string\[] | ✖ | v1 |
|
||||
| contents | 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 |
|
||||
| labels | 替换 issue 的 labels | string | ✖ | v1 |
|
||||
| assignees | 替换 issue 的 assignees | string | ✖ | v1 |
|
||||
| contents | 增加 [reaction](#reactions-types) | string | ✖ | v1 |
|
||||
|
||||
- `state` 默认为 `open`
|
||||
- 当可选项不填时,会保持原有
|
||||
@@ -445,7 +478,7 @@ jobs:
|
||||
|
||||
### ⭐ 进 阶
|
||||
|
||||
进阶用法不建议 actions 多重使用。
|
||||
进阶用法不建议 actions 多个一次同时使用。
|
||||
|
||||
#### `check-inactive`
|
||||
|
||||
@@ -475,7 +508,7 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
|
||||
| labels | 标签筛选 | string \| string\[] | ✖ | v1 |
|
||||
| labels | 标签筛选 | string | ✖ | v1 |
|
||||
| issue-state | 状态筛选 | string | ✖ | v1 |
|
||||
| issue-assignee | 指定人筛选 | string | ✖ | v1 |
|
||||
| issue-creator | 创建人筛选 | string | ✖ | v1 |
|
||||
@@ -491,6 +524,61 @@ jobs:
|
||||
- `inactive-day`:当输入时,会筛选 issue 更新时间早于当前时间减去非活跃天数。不填时,会查询所有
|
||||
- `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`
|
||||
|
||||
每 7 天 UTC 0 时,关闭已填加 `need info` label 且 7 天以上未活跃的 issues。
|
||||
@@ -520,7 +608,7 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
|
||||
| labels | 标签筛选 | string \| string\[] | ✖ | v1 |
|
||||
| labels | 标签筛选 | string | ✖ | v1 |
|
||||
| issue-assignee | 指定人筛选 | string | ✖ | v1 |
|
||||
| issue-creator | 创建人筛选 | string | ✖ | v1 |
|
||||
| issue-mentioned | 提及人筛选 | string | ✖ | v1 |
|
||||
@@ -601,7 +689,7 @@ jobs:
|
||||
| actions | 操作类型 | string | ✔ | v1 |
|
||||
| token | [token 说明](#token) | string | ✔ | v1 |
|
||||
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
|
||||
| labels | 标签筛选 | string \| string\[] | ✖ | v1 |
|
||||
| labels | 标签筛选 | string | ✖ | v1 |
|
||||
| issue-state | 状态筛选 | string | ✖ | v1 |
|
||||
| issue-assignee | 指定人筛选 | string | ✖ | v1 |
|
||||
| issue-creator | 创建人筛选 | string | ✖ | v1 |
|
||||
@@ -729,11 +817,41 @@ jobs:
|
||||
|
||||
## Actions 模板
|
||||
|
||||
[GitHub Actions workflow template](https://github.com/actions-cool/.github) Fork 后,可直接使用模板。
|
||||
- 可直接使用这个 [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>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ant-design/ant-design">
|
||||
<img src="https://avatars1.githubusercontent.com/u/12101536?s=200&v=4" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>ant-design</strong>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vueComponent/ant-design-vue">
|
||||
<img src="https://avatars2.githubusercontent.com/u/32120805?s=200&v=4" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>ant-design-vue</strong>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AttoJS/vue-request">
|
||||
<img src="https://raw.githubusercontent.com/AttoJS/art/master/vue-request-logo.png" width="46" />
|
||||
</a>
|
||||
<br/>
|
||||
<strong>vue-request</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## LICENSE
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
name: 'Issues Helper'
|
||||
description: 'Some operations on issue'
|
||||
description: 'A GitHub Action to help you manage issues'
|
||||
author: 'xrkffgg'
|
||||
branding:
|
||||
icon: 'message-square'
|
||||
color: 'blue'
|
||||
color: 'black'
|
||||
inputs:
|
||||
actions:
|
||||
description: 'Action name'
|
||||
@@ -32,6 +32,8 @@ inputs:
|
||||
description: 'Find comments direction'
|
||||
comment-auth:
|
||||
description: 'Find comments query auth'
|
||||
assignee-includes:
|
||||
description: 'Check use'
|
||||
body-includes:
|
||||
description: 'Query use'
|
||||
title-includes:
|
||||
@@ -55,6 +57,8 @@ outputs:
|
||||
description: 'Create comment ID'
|
||||
comments:
|
||||
description: 'Find comments'
|
||||
check-result:
|
||||
description: 'Check issue'
|
||||
runs:
|
||||
using: node12
|
||||
main: 'dist/index.js'
|
||||
|
41
changelog.md
Normal file
41
changelog.md
Normal 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
41
changelog.zh-CN.md
Normal 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.
|
170
dist/index.js
vendored
170
dist/index.js
vendored
@@ -5996,6 +5996,8 @@ const {
|
||||
doLockIssue
|
||||
} = __webpack_require__(9932);
|
||||
|
||||
const { dealInput, matchKeyword } = __webpack_require__(6254);
|
||||
|
||||
const token = core.getInput('token');
|
||||
const octokit = new Octokit({ auth: `token ${token}` });
|
||||
|
||||
@@ -6005,6 +6007,7 @@ direction = direction === 'desc' ? 'desc' : 'asc';
|
||||
const commentAuth = core.getInput("comment-auth");
|
||||
const bodyIncludes = core.getInput('body-includes');
|
||||
const titleIncludes = core.getInput('title-includes');
|
||||
const assigneeIncludes = core.getInput('assignee-includes');
|
||||
|
||||
const issueCreator = core.getInput("issue-creator");
|
||||
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) {
|
||||
const issues = await doQueryIssues(owner, repo, labels, 'open');
|
||||
|
||||
@@ -6107,15 +6158,7 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
issueMentioned ? params.mentioned = issueMentioned : null;
|
||||
|
||||
if (labels) {
|
||||
if (typeof(labels) === 'string') {
|
||||
params.labels = labels;
|
||||
} else {
|
||||
let temp = '';
|
||||
labels.forEach((it,index) => {
|
||||
index == labels.length - 1 ? temp += `${it}` : temp += `${it},`;
|
||||
});
|
||||
params.labels = temp;
|
||||
}
|
||||
params.labels = labels;
|
||||
}
|
||||
|
||||
const res = await octokit.issues.listForRepo(params);
|
||||
@@ -6123,7 +6166,12 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
res.data.forEach(iss => {
|
||||
const a = bodyIncludes ? iss.body.includes(bodyIncludes) : 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') {
|
||||
let lastTime = dayjs.utc().subtract(inactiveDay, 'day');
|
||||
let updateTime = dayjs.utc(iss.updated_at);
|
||||
@@ -6141,6 +6189,7 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
|
||||
module.exports = {
|
||||
doCheckInactive,
|
||||
doCheckIssue,
|
||||
doCloseIssues,
|
||||
doFindComments,
|
||||
doLockIssues,
|
||||
@@ -6215,12 +6264,12 @@ async function doCreateComment (owner, repo, issueNumber, body) {
|
||||
core.setOutput("comment-id", data.id);
|
||||
|
||||
if (contents) {
|
||||
await doCreateCommentContent(owner, repo, data.id, contents);
|
||||
await doCreateCommentContent(owner, repo, data.id, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
async function doCreateCommentContent(owner, repo, commentId) {
|
||||
if (typeof(contents) === 'object') {
|
||||
async function doCreateCommentContent(owner, repo, commentId, contents) {
|
||||
if (contents.length) {
|
||||
contents.forEach(async item => {
|
||||
if (testContent(item)) {
|
||||
await octokit.reactions.createForIssueComment({
|
||||
@@ -6232,14 +6281,6 @@ async function doCreateCommentContent(owner, repo, commentId) {
|
||||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||||
}
|
||||
})
|
||||
} else if (typeof(contents) === 'string' && testContent(contents)) {
|
||||
await octokit.reactions.createForIssueComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: commentId,
|
||||
content: contents
|
||||
});
|
||||
core.info(`Actions: [create-reactions][${contents}] success!`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6258,12 +6299,12 @@ async function doCreateIssue (owner, repo, title, body, labels, assignees) {
|
||||
core.setOutput("issue-number", data.number);
|
||||
|
||||
if (contents) {
|
||||
await doCreateIssueContent(owner, repo, data.number, contents);
|
||||
await doCreateIssueContent(owner, repo, data.number, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
async function doCreateIssueContent(owner, repo, issueNumber) {
|
||||
if (typeof(contents) === 'object') {
|
||||
async function doCreateIssueContent(owner, repo, issueNumber, contents) {
|
||||
if (contents.length) {
|
||||
contents.forEach(async item => {
|
||||
if (testContent(item)) {
|
||||
await octokit.reactions.createForIssue({
|
||||
@@ -6275,14 +6316,6 @@ async function doCreateIssueContent(owner, repo, issueNumber) {
|
||||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||||
}
|
||||
})
|
||||
} else if (typeof(contents) === 'string' && testContent(contents)) {
|
||||
await octokit.reactions.createForIssue({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: issueNumber,
|
||||
content: contents
|
||||
});
|
||||
core.info(`Actions: [create-reactions][${contents}] success!`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6324,6 +6357,28 @@ async function doRemoveAssignees (owner, repo, issueNumber, assignees) {
|
||||
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) {
|
||||
await octokit.issues.setLabels({
|
||||
owner,
|
||||
@@ -6372,10 +6427,10 @@ async function doUpdateComment (
|
||||
|
||||
await octokit.issues.updateComment(params);
|
||||
core.info(`Actions: [update-comment][${commentId}] success!`);
|
||||
}
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
await doCreateCommentContent(owner, repo, commentId, contents);
|
||||
await doCreateCommentContent(owner, repo, commentId, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6397,8 +6452,20 @@ async function doUpdateIssue (
|
||||
})
|
||||
const issue_body = issue.data.body;
|
||||
const issue_title = issue.data.title;
|
||||
const issue_labels = issue.data.labels;
|
||||
const issue_assignees = issue.data.assignees;
|
||||
|
||||
let issue_labels = [];
|
||||
if (issue.data.labels.length > 0) {
|
||||
issue.data.labels.forEach(it =>{
|
||||
issue_labels.push(it.name);
|
||||
});
|
||||
}
|
||||
|
||||
let issue_assignees = [];
|
||||
if (issue.data.assignees.length > 0) {
|
||||
issue.data.assignees.forEach(it =>{
|
||||
issue_assignees.push(it.login);
|
||||
});
|
||||
}
|
||||
|
||||
let params = {
|
||||
owner,
|
||||
@@ -6455,6 +6522,7 @@ module.exports = {
|
||||
doLockIssue,
|
||||
doOpenIssue,
|
||||
doRemoveAssignees,
|
||||
doRemoveLabels,
|
||||
doSetLabels,
|
||||
doUnlockIssue,
|
||||
doUpdateComment,
|
||||
@@ -6482,6 +6550,7 @@ const {
|
||||
doLockIssue,
|
||||
doOpenIssue,
|
||||
doRemoveAssignees,
|
||||
doRemoveLabels,
|
||||
doSetLabels,
|
||||
doUnlockIssue,
|
||||
doUpdateComment,
|
||||
@@ -6490,6 +6559,7 @@ const {
|
||||
|
||||
const {
|
||||
doCheckInactive,
|
||||
doCheckIssue,
|
||||
doCloseIssues,
|
||||
doFindComments,
|
||||
doLockIssues,
|
||||
@@ -6506,6 +6576,7 @@ const ALLACTIONS = [
|
||||
'lock-issue',
|
||||
'open-issue',
|
||||
'remove-assignees',
|
||||
'remove-labels',
|
||||
'set-labels',
|
||||
'unlock-issue',
|
||||
'update-comment',
|
||||
@@ -6513,6 +6584,7 @@ const ALLACTIONS = [
|
||||
|
||||
// advanced
|
||||
'check-inactive',
|
||||
'check-issue',
|
||||
'close-issues',
|
||||
'find-comments',
|
||||
'lock-issues',
|
||||
@@ -6586,6 +6658,9 @@ async function main() {
|
||||
case 'remove-assignees':
|
||||
await doRemoveAssignees(owner, repo, issueNumber, assignees);
|
||||
break;
|
||||
case 'remove-labels':
|
||||
await doRemoveLabels(owner, repo, issueNumber, labels);
|
||||
break;
|
||||
case 'set-labels':
|
||||
await doSetLabels(owner, repo, issueNumber, labels);
|
||||
break;
|
||||
@@ -6623,6 +6698,13 @@ async function main() {
|
||||
labels
|
||||
)
|
||||
break;
|
||||
case 'check-issue':
|
||||
await doCheckIssue(
|
||||
owner,
|
||||
repo,
|
||||
issueNumber
|
||||
);
|
||||
break;
|
||||
case 'close-issues':
|
||||
await doCloseIssues(
|
||||
owner,
|
||||
@@ -6666,17 +6748,23 @@ main();
|
||||
function dealInput (para) {
|
||||
let arr = [];
|
||||
if (para) {
|
||||
if (typeof(para) === 'string') {
|
||||
arr.push(para);
|
||||
} else {
|
||||
arr = para;
|
||||
}
|
||||
const paraArr = para.split(',');
|
||||
paraArr.forEach(it => {
|
||||
if(it.trim()){
|
||||
arr.push(it.trim())
|
||||
}
|
||||
})
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
function matchKeyword(content, keywords) {
|
||||
return keywords.find(item => content.toLowerCase().includes(item));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
dealInput,
|
||||
matchKeyword,
|
||||
};
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "issue-helper",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0",
|
||||
"private": true,
|
||||
"description": "Some operations on issue.",
|
||||
"main": "src/main.js",
|
||||
|
@@ -15,6 +15,8 @@ const {
|
||||
doLockIssue
|
||||
} = require('./base.js');
|
||||
|
||||
const { dealInput, matchKeyword } = require('./util.js');
|
||||
|
||||
const token = core.getInput('token');
|
||||
const octokit = new Octokit({ auth: `token ${token}` });
|
||||
|
||||
@@ -24,6 +26,7 @@ direction = direction === 'desc' ? 'desc' : 'asc';
|
||||
const commentAuth = core.getInput("comment-auth");
|
||||
const bodyIncludes = core.getInput('body-includes');
|
||||
const titleIncludes = core.getInput('title-includes');
|
||||
const assigneeIncludes = core.getInput('assignee-includes');
|
||||
|
||||
const issueCreator = core.getInput("issue-creator");
|
||||
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) {
|
||||
const issues = await doQueryIssues(owner, repo, labels, 'open');
|
||||
|
||||
@@ -126,15 +177,7 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
issueMentioned ? params.mentioned = issueMentioned : null;
|
||||
|
||||
if (labels) {
|
||||
if (typeof(labels) === 'string') {
|
||||
params.labels = labels;
|
||||
} else {
|
||||
let temp = '';
|
||||
labels.forEach((it,index) => {
|
||||
index == labels.length - 1 ? temp += `${it}` : temp += `${it},`;
|
||||
});
|
||||
params.labels = temp;
|
||||
}
|
||||
params.labels = labels;
|
||||
}
|
||||
|
||||
const res = await octokit.issues.listForRepo(params);
|
||||
@@ -142,7 +185,12 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
res.data.forEach(iss => {
|
||||
const a = bodyIncludes ? iss.body.includes(bodyIncludes) : 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') {
|
||||
let lastTime = dayjs.utc().subtract(inactiveDay, 'day');
|
||||
let updateTime = dayjs.utc(iss.updated_at);
|
||||
@@ -160,6 +208,7 @@ async function doQueryIssues (owner, repo, labels, state) {
|
||||
|
||||
module.exports = {
|
||||
doCheckInactive,
|
||||
doCheckIssue,
|
||||
doCloseIssues,
|
||||
doFindComments,
|
||||
doLockIssues,
|
||||
|
71
src/base.js
71
src/base.js
@@ -61,12 +61,12 @@ async function doCreateComment (owner, repo, issueNumber, body) {
|
||||
core.setOutput("comment-id", data.id);
|
||||
|
||||
if (contents) {
|
||||
await doCreateCommentContent(owner, repo, data.id, contents);
|
||||
await doCreateCommentContent(owner, repo, data.id, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
async function doCreateCommentContent(owner, repo, commentId) {
|
||||
if (typeof(contents) === 'object') {
|
||||
async function doCreateCommentContent(owner, repo, commentId, contents) {
|
||||
if (contents.length) {
|
||||
contents.forEach(async item => {
|
||||
if (testContent(item)) {
|
||||
await octokit.reactions.createForIssueComment({
|
||||
@@ -78,14 +78,6 @@ async function doCreateCommentContent(owner, repo, commentId) {
|
||||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||||
}
|
||||
})
|
||||
} else if (typeof(contents) === 'string' && testContent(contents)) {
|
||||
await octokit.reactions.createForIssueComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: commentId,
|
||||
content: contents
|
||||
});
|
||||
core.info(`Actions: [create-reactions][${contents}] success!`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -104,12 +96,12 @@ async function doCreateIssue (owner, repo, title, body, labels, assignees) {
|
||||
core.setOutput("issue-number", data.number);
|
||||
|
||||
if (contents) {
|
||||
await doCreateIssueContent(owner, repo, data.number, contents);
|
||||
await doCreateIssueContent(owner, repo, data.number, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
async function doCreateIssueContent(owner, repo, issueNumber) {
|
||||
if (typeof(contents) === 'object') {
|
||||
async function doCreateIssueContent(owner, repo, issueNumber, contents) {
|
||||
if (contents.length) {
|
||||
contents.forEach(async item => {
|
||||
if (testContent(item)) {
|
||||
await octokit.reactions.createForIssue({
|
||||
@@ -121,14 +113,6 @@ async function doCreateIssueContent(owner, repo, issueNumber) {
|
||||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||||
}
|
||||
})
|
||||
} else if (typeof(contents) === 'string' && testContent(contents)) {
|
||||
await octokit.reactions.createForIssue({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: issueNumber,
|
||||
content: contents
|
||||
});
|
||||
core.info(`Actions: [create-reactions][${contents}] success!`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -170,6 +154,28 @@ async function doRemoveAssignees (owner, repo, issueNumber, assignees) {
|
||||
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) {
|
||||
await octokit.issues.setLabels({
|
||||
owner,
|
||||
@@ -218,10 +224,10 @@ async function doUpdateComment (
|
||||
|
||||
await octokit.issues.updateComment(params);
|
||||
core.info(`Actions: [update-comment][${commentId}] success!`);
|
||||
}
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
await doCreateCommentContent(owner, repo, commentId, contents);
|
||||
await doCreateCommentContent(owner, repo, commentId, dealInput(contents));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -243,8 +249,20 @@ async function doUpdateIssue (
|
||||
})
|
||||
const issue_body = issue.data.body;
|
||||
const issue_title = issue.data.title;
|
||||
const issue_labels = issue.data.labels;
|
||||
const issue_assignees = issue.data.assignees;
|
||||
|
||||
let issue_labels = [];
|
||||
if (issue.data.labels.length > 0) {
|
||||
issue.data.labels.forEach(it =>{
|
||||
issue_labels.push(it.name);
|
||||
});
|
||||
}
|
||||
|
||||
let issue_assignees = [];
|
||||
if (issue.data.assignees.length > 0) {
|
||||
issue.data.assignees.forEach(it =>{
|
||||
issue_assignees.push(it.login);
|
||||
});
|
||||
}
|
||||
|
||||
let params = {
|
||||
owner,
|
||||
@@ -301,6 +319,7 @@ module.exports = {
|
||||
doLockIssue,
|
||||
doOpenIssue,
|
||||
doRemoveAssignees,
|
||||
doRemoveLabels,
|
||||
doSetLabels,
|
||||
doUnlockIssue,
|
||||
doUpdateComment,
|
||||
|
14
src/main.js
14
src/main.js
@@ -13,6 +13,7 @@ const {
|
||||
doLockIssue,
|
||||
doOpenIssue,
|
||||
doRemoveAssignees,
|
||||
doRemoveLabels,
|
||||
doSetLabels,
|
||||
doUnlockIssue,
|
||||
doUpdateComment,
|
||||
@@ -21,6 +22,7 @@ const {
|
||||
|
||||
const {
|
||||
doCheckInactive,
|
||||
doCheckIssue,
|
||||
doCloseIssues,
|
||||
doFindComments,
|
||||
doLockIssues,
|
||||
@@ -37,6 +39,7 @@ const ALLACTIONS = [
|
||||
'lock-issue',
|
||||
'open-issue',
|
||||
'remove-assignees',
|
||||
'remove-labels',
|
||||
'set-labels',
|
||||
'unlock-issue',
|
||||
'update-comment',
|
||||
@@ -44,6 +47,7 @@ const ALLACTIONS = [
|
||||
|
||||
// advanced
|
||||
'check-inactive',
|
||||
'check-issue',
|
||||
'close-issues',
|
||||
'find-comments',
|
||||
'lock-issues',
|
||||
@@ -117,6 +121,9 @@ async function main() {
|
||||
case 'remove-assignees':
|
||||
await doRemoveAssignees(owner, repo, issueNumber, assignees);
|
||||
break;
|
||||
case 'remove-labels':
|
||||
await doRemoveLabels(owner, repo, issueNumber, labels);
|
||||
break;
|
||||
case 'set-labels':
|
||||
await doSetLabels(owner, repo, issueNumber, labels);
|
||||
break;
|
||||
@@ -154,6 +161,13 @@ async function main() {
|
||||
labels
|
||||
)
|
||||
break;
|
||||
case 'check-issue':
|
||||
await doCheckIssue(
|
||||
owner,
|
||||
repo,
|
||||
issueNumber
|
||||
);
|
||||
break;
|
||||
case 'close-issues':
|
||||
await doCloseIssues(
|
||||
owner,
|
||||
|
16
src/util.js
16
src/util.js
@@ -1,15 +1,21 @@
|
||||
function dealInput (para) {
|
||||
let arr = [];
|
||||
if (para) {
|
||||
if (typeof(para) === 'string') {
|
||||
arr.push(para);
|
||||
} else {
|
||||
arr = para;
|
||||
}
|
||||
const paraArr = para.split(',');
|
||||
paraArr.forEach(it => {
|
||||
if(it.trim()){
|
||||
arr.push(it.trim())
|
||||
}
|
||||
})
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
function matchKeyword(content, keywords) {
|
||||
return keywords.find(item => content.toLowerCase().includes(item));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
dealInput,
|
||||
matchKeyword,
|
||||
};
|
||||
|
Reference in New Issue
Block a user