Compare commits

..

13 Commits
v1 ... 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
xrkffgg
62ec5c7335 Delete compressed-size.yml 2020-12-24 16:40:51 +08:00
xrkffgg
822d3a57be fix: yml not support array (#11)
* fix: yml not support array

* add
2020-12-24 16:40:07 +08:00
xrkffgg
1d0bb25b58 Create compressed-size.yml 2020-12-24 15:16:54 +08:00
John60676
e92345f030 docs: add ref user (#9)
* refactor: add ref template user

* refactor: update README
2020-12-24 14:02:04 +08:00
xrkffgg
4f43f584a7 docs: update description 2020-12-24 13:07:49 +08:00
xrkffgg
597b0b36ce docs: add user (#8)
* docs: add user

* fix

* add

* add
2020-12-24 13:00:12 +08:00
xrkffgg
87d4e59578 docs: update text 2020-12-24 10:06:43 +08:00
xrkffgg
90971f72b3 docs: update badge 2020-12-24 10:05:48 +08:00
xrkffgg
4db267691c docs: update badge 2020-12-23 22:29:01 +08:00
13 changed files with 633 additions and 135 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

168
README.md
View File

@@ -2,9 +2,11 @@
English | [简体中文](./README.zh-CN.md) English | [简体中文](./README.zh-CN.md)
[![](https://img.shields.io/github/workflow/status/actions-cool/issues-helper/ci?style=flat-square)](https://github.com/actions-cool/issues-helper/actions) [![](https://img.shields.io/github/stars/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/stargazers) [![](https://img.shields.io/github/v/release/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/releases) [![](https://img.shields.io/github/license/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/blob/main/LICENSE) [![](https://img.shields.io/github/workflow/status/actions-cool/issues-helper/ci?style=flat-square)](https://github.com/actions-cool/issues-helper/actions) [![](https://img.shields.io/badge/marketplace-issues--helper-red?style=flat-square)](https://github.com/marketplace/actions/issues-helper) [![](https://img.shields.io/github/stars/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/stargazers) [![](https://img.shields.io/github/v/release/actions-cool/issues-helper?style=flat-square&color=orange)](https://github.com/actions-cool/issues-helper/releases) [![](https://img.shields.io/badge/discussions-on%20github-blue?style=flat-square&color=%2308979c)](https://github.com/actions-cool/issues-helper/discussions) [![](https://img.shields.io/github/license/actions-cool/issues-helper?style=flat-square)](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? ## 😎 Why use GitHub Action?
@@ -12,7 +14,7 @@ A GitHub Action to help you deal with issues
2. Fully automatic. 2. Fully automatic.
3. Hosted on the GitHub server, as long as GitHub is not down, it will keep running. 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 ## List
@@ -26,12 +28,14 @@ A GitHub Action to help you deal with 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)
@@ -65,7 +69,7 @@ jobs:
actions: 'add-assignees' actions: 'add-assignees'
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }} issue-number: ${{ github.event.issue.number }}
assignees: 'xxx' or ['xxx'] or ['xx1', 'xx2'] assignees: 'xxx' or 'xx1,xx2'
``` ```
| Param | Desc | Type | Required | Version | | Param | Desc | Type | Required | Version |
@@ -73,12 +77,13 @@ jobs:
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| issue-number | The number of issue | number | ✔ | 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` - `actions` support multiple and separated by comma. Like: `add-assignees,add-labels`
- The `name` can be modified according to the actual situation - The `name` can be modified according to the actual situation
- [on reference](#github-docs) - [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) - `${{ 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) ⏫ [Back to list](#List)
@@ -104,7 +109,7 @@ jobs:
actions: 'add-labels' actions: 'add-labels'
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }} issue-number: ${{ github.event.issue.number }}
labels: 'bug' or ['bug'] or ['bug1', 'bug2'] labels: 'bug' or 'xx1,xx2'
``` ```
| Param | Desc | Type | Required | Version | | Param | Desc | Type | Required | Version |
@@ -112,7 +117,9 @@ jobs:
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| issue-number | The number of issue | number | ✔ | 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) ⏫ [Back to list](#List)
@@ -164,7 +171,7 @@ jobs:
Hello @${{ github.event.issue.user.login }}. Add some comments. Hello @${{ github.event.issue.user.login }}. Add some comments.
你好 @${{ github.event.issue.user.login }}。巴拉巴拉。 你好 @${{ github.event.issue.user.login }}。巴拉巴拉。
contents: '+1' or ['+1', 'heart'] contents: '+1' or '+1,heart'
``` ```
| Param | Desc | Type | Required | Version | | Param | Desc | Type | Required | Version |
@@ -173,12 +180,13 @@ jobs:
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| issue-number | The number of issue | number | ✔ | v1 | | issue-number | The number of issue | number | ✔ | v1 |
| body | Add comment content | string | ✖ | 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.` - `body` default is `Currently at ${owner}/${repo}. And this is default comment.`
- Where `${owner}/${repo}` means the current repo - Where `${owner}/${repo}` means the current repo
- Return `comment-id`, which can be used for subsequent operations. [Usage reference](#outputs-use) - 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 - `${{ 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) ⏫ [Back to list](#List)
@@ -215,9 +223,9 @@ jobs:
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| title | The title of the new issue | string | ✖ | v1 | | title | The title of the new issue | string | ✖ | v1 |
| body | The body 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 | | labels | The labels for the new issue | string | ✖ | v1 |
| assignees | The assignees for the new issue | string \| string\[] | ✖ | v1 | | assignees | The assignees for the new issue | string | ✖ | v1 |
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 | | contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
- `title` default is `Default Title` - `title` default is `Default Title`
- Return `issue-number`. [Usage reference](#outputs-use) - Return `issue-number`. [Usage reference](#outputs-use)
@@ -317,7 +325,32 @@ Remove the person designated by issue.
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| issue-number | The number of issue | number | ✔ | 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) ⏫ [Back to list](#List)
@@ -340,7 +373,7 @@ Replace the labels of issue.
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| issue-number | The number of issue | number | ✔ | 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) ⏫ [Back to list](#List)
@@ -398,7 +431,7 @@ jobs:
| comment-id | The comment ID | number | ✔ | v1 | | comment-id | The comment ID | number | ✔ | v1 |
| body | Update the content of comment | string | ✖ | v1 | | body | Update the content of comment | string | ✖ | v1 |
| update-mode | Update mode. Default `replace`, another `append` | 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 `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` - 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 | | title | Modify the title of the issue | string | ✖ | v1 |
| body | Modify the content of issue | string | ✖ | v1 | | body | Modify the content of issue | string | ✖ | v1 |
| update-mode | Update mode. Default `replace`, another `append` | string | ✖ | v1 | | update-mode | Update mode. Default `replace`, another `append` | string | ✖ | v1 |
| labels | Replace the labels of issue | string \| string\[] | ✖ | v1 | | labels | Replace the labels of issue | string | ✖ | v1 |
| assignees | Replace the assignees of issue | string \| string\[] | ✖ | v1 | | assignees | Replace the assignees of issue | string | ✖ | v1 |
| contents | Add [reaction](#reactions-types) | string \| string\[] | ✖ | v1 | | contents | Add [reaction](#reactions-types) | string | ✖ | v1 |
- `state` defaults to `open` - `state` defaults to `open`
- When the option is not filled, it will keep the original - 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 ### ⭐ 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`
@@ -475,7 +508,7 @@ jobs:
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| body | When operating an issue, you can comment. Do not comment when not typing | 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-state | State filtering | string | ✖ | v1 |
| issue-assignee | Assignee filtering | string | ✖ | v1 | | issue-assignee | Assignee filtering | string | ✖ | v1 |
| issue-creator | Creator 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-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.
@@ -520,7 +608,7 @@ jobs:
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| body | When operating an issue, you can comment. Do not comment when not typing | 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-assignee | Assignee filtering | string | ✖ | v1 |
| issue-creator | Creator filtering | string | ✖ | v1 | | issue-creator | Creator filtering | string | ✖ | v1 |
| issue-mentioned | Mentioned filtering | string | ✖ | v1 | | issue-mentioned | Mentioned filtering | string | ✖ | v1 |
@@ -601,7 +689,7 @@ jobs:
| actions | Action type | string | ✔ | v1 | | actions | Action type | string | ✔ | v1 |
| token | [Token explain](#token) | string | ✔ | v1 | | token | [Token explain](#token) | string | ✔ | v1 |
| body | When operating an issue, you can comment. Do not comment when not typing | 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-state | State filtering | string | ✖ | v1 |
| issue-assignee | Assignee filtering | string | ✖ | v1 | | issue-assignee | Assignee filtering | string | ✖ | v1 |
| issue-creator | Creator 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 ## 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 ## LICENSE

View File

@@ -1,10 +1,12 @@
# 🤖 Issues Helper # 🤖 Issues 助手
[English](./README.md) | 简体中文 [English](./README.md) | 简体中文
[![](https://img.shields.io/github/workflow/status/actions-cool/issues-helper/ci?style=flat-square)](https://github.com/actions-cool/issues-helper/actions) [![](https://img.shields.io/github/stars/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/stargazers) [![](https://img.shields.io/github/v/release/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/releases) [![](https://img.shields.io/github/license/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/blob/main/LICENSE) [![](https://img.shields.io/github/workflow/status/actions-cool/issues-helper/ci?style=flat-square)](https://github.com/actions-cool/issues-helper/actions) [![](https://img.shields.io/badge/marketplace-issues--helper-red?style=flat-square)](https://github.com/marketplace/actions/issues-helper) [![](https://img.shields.io/github/stars/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/stargazers) [![](https://img.shields.io/github/v/release/actions-cool/issues-helper?style=flat-square&color=orange)](https://github.com/actions-cool/issues-helper/releases) [![](https://img.shields.io/badge/discussions-on%20github-blue?style=flat-square&color=%2308979c)](https://github.com/actions-cool/issues-helper/discussions) [![](https://img.shields.io/github/license/actions-cool/issues-helper?style=flat-square)](https://github.com/actions-cool/issues-helper/blob/main/LICENSE)
一个帮你理 issues 的 GitHub Action 一个帮你理 issues 的 GitHub Action
在线文档 | [更新日志](./changelog.zh-CN.md)
## 😎 为什么用 GitHub Action ## 😎 为什么用 GitHub Action
@@ -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)
@@ -65,7 +69,7 @@ jobs:
actions: 'add-assignees' actions: 'add-assignees'
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }} 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 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| issue-number | 指定的 issue | number | ✔ | v1 | | issue-number | 指定的 issue | number | ✔ | v1 |
| assignees | 指定人。当不填或者为空字符、空数组时,不操作 | string \| string\[] | ✖ | v1 | | assignees | 指定人。当不填或者为空字符时,不操作 | string | ✖ | v1 |
- `actions` 支持多个,需用逗号隔开。如:`add-assignees,add-labels` - `actions` 支持多个,需用逗号隔开。如:`add-assignees,add-labels`
- 其中的 `name` 可根据自行根据实际情况修改 - 其中的 `name` 可根据自行根据实际情况修改
- [on 参考](#github-docs) - [on 参考](#github-docs)
- `${{ github.event.issue.number }}` 表示当前 issue[更多参考](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events) - `${{ 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' actions: 'add-labels'
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }} 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 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| issue-number | 指定的 issue | number | ✔ | 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. Hello ${{ github.event.issue.user.login }}. Add some comments.
你好 ${{ github.event.issue.user.login }}。巴拉巴拉。 你好 ${{ 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 | | token | [token 说明](#token) | string | ✔ | v1 |
| issue-number | 指定的 issue | number | ✔ | v1 | | issue-number | 指定的 issue | number | ✔ | v1 |
| body | 新增评论的内容 | string | ✖ | 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.` - `body` 默认为:`Currently at ${owner}/${repo}. And this is default comment.`
- 其中 `${owner}/${repo}` 表示当前仓库 - 其中 `${owner}/${repo}` 表示当前仓库
- 返回 `comment-id`,可用于之后操作。[用法参考](#outputs-使用) - 返回 `comment-id`,可用于之后操作。[用法参考](#outputs-使用)
- `${{ github.event.issue.user.login }}` 表示该 issue 的创建者 - `${{ github.event.issue.user.login }}` 表示该 issue 的创建者
- `contents` 支持多个需用逗号隔开。注意设置多个需使用v1.1以上版本
⏫ [返回列表](#列-表) ⏫ [返回列表](#列-表)
@@ -215,9 +223,9 @@ jobs:
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| title | 新增 issue 的标题 | string | ✖ | v1 | | title | 新增 issue 的标题 | string | ✖ | v1 |
| body | 新增 issue 的内容 | string | ✖ | v1 | | body | 新增 issue 的内容 | string | ✖ | v1 |
| labels | 为新增 issue 添加 labels | string \| string\[] | ✖ | v1 | | labels | 为新增 issue 添加 labels | string | ✖ | v1 |
| assignees | 为新增 issue 添加 assignees | string \| string\[] | ✖ | v1 | | assignees | 为新增 issue 添加 assignees | string | ✖ | v1 |
| contents | 为新增 issue 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 | | contents | 为新增 issue 增加 [reaction](#reactions-types) | string | ✖ | v1 |
- `title` 默认为:`Default Title` - `title` 默认为:`Default Title`
- 返回 `issue-number`[用法参考](#outputs-使用) - 返回 `issue-number`[用法参考](#outputs-使用)
@@ -317,7 +325,32 @@ jobs:
| actions | 操作类型 | string | ✔ | v1 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| issue-number | 指定的 issue | number | ✔ | 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 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| issue-number | 指定的 issue | number | ✔ | 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 | | comment-id | 指定的 comment | number | ✔ | v1 |
| body | 更新 comment 的内容 | string | ✖ | v1 | | body | 更新 comment 的内容 | string | ✖ | v1 |
| update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 | | update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 |
| contents | 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 | | contents | 增加 [reaction](#reactions-types) | string | ✖ | v1 |
- `body` 不填时,会保持原有 - `body` 不填时,会保持原有
- `update-mode``append` 时,会进行附加操作。非 `append` 都会进行替换。仅对 `body` 生效 - `update-mode``append` 时,会进行附加操作。非 `append` 都会进行替换。仅对 `body` 生效
@@ -434,9 +467,9 @@ jobs:
| title | 修改 issue 的标题 | string | ✖ | v1 | | title | 修改 issue 的标题 | string | ✖ | v1 |
| body | 修改 issue 的内容 | string | ✖ | v1 | | body | 修改 issue 的内容 | string | ✖ | v1 |
| update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 | | update-mode | 更新模式。默认 `replace` 替换,`append` 附加 | string | ✖ | v1 |
| labels | 替换 issue 的 labels | string \| string\[] | ✖ | v1 | | labels | 替换 issue 的 labels | string | ✖ | v1 |
| assignees | 替换 issue 的 assignees | string \| string\[] | ✖ | v1 | | assignees | 替换 issue 的 assignees | string | ✖ | v1 |
| contents | 增加 [reaction](#reactions-types) | string \| string\[] | ✖ | v1 | | contents | 增加 [reaction](#reactions-types) | string | ✖ | v1 |
- `state` 默认为 `open` - `state` 默认为 `open`
- 当可选项不填时,会保持原有 - 当可选项不填时,会保持原有
@@ -445,7 +478,7 @@ jobs:
### ⭐ 进 阶 ### ⭐ 进 阶
进阶用法不建议 actions 多使用。 进阶用法不建议 actions 多个一次同时使用。
#### `check-inactive` #### `check-inactive`
@@ -475,7 +508,7 @@ jobs:
| actions | 操作类型 | string | ✔ | v1 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 | | body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
| labels | 标签筛选 | string \| string\[] | ✖ | v1 | | labels | 标签筛选 | string | ✖ | v1 |
| issue-state | 状态筛选 | string | ✖ | v1 | | issue-state | 状态筛选 | string | ✖ | v1 |
| issue-assignee | 指定人筛选 | string | ✖ | v1 | | issue-assignee | 指定人筛选 | string | ✖ | v1 |
| issue-creator | 创建人筛选 | string | ✖ | v1 | | issue-creator | 创建人筛选 | string | ✖ | v1 |
@@ -491,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。
@@ -520,7 +608,7 @@ jobs:
| actions | 操作类型 | string | ✔ | v1 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 | | body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
| labels | 标签筛选 | string \| string\[] | ✖ | v1 | | labels | 标签筛选 | string | ✖ | v1 |
| issue-assignee | 指定人筛选 | string | ✖ | v1 | | issue-assignee | 指定人筛选 | string | ✖ | v1 |
| issue-creator | 创建人筛选 | string | ✖ | v1 | | issue-creator | 创建人筛选 | string | ✖ | v1 |
| issue-mentioned | 提及人筛选 | string | ✖ | v1 | | issue-mentioned | 提及人筛选 | string | ✖ | v1 |
@@ -601,7 +689,7 @@ jobs:
| actions | 操作类型 | string | ✔ | v1 | | actions | 操作类型 | string | ✔ | v1 |
| token | [token 说明](#token) | string | ✔ | v1 | | token | [token 说明](#token) | string | ✔ | v1 |
| body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 | | body | 操作 issue 时,可进行评论。不填时,不评论 | string | ✖ | v1 |
| labels | 标签筛选 | string \| string\[] | ✖ | v1 | | labels | 标签筛选 | string | ✖ | v1 |
| issue-state | 状态筛选 | string | ✖ | v1 | | issue-state | 状态筛选 | string | ✖ | v1 |
| issue-assignee | 指定人筛选 | string | ✖ | v1 | | issue-assignee | 指定人筛选 | string | ✖ | v1 |
| issue-creator | 创建人筛选 | string | ✖ | v1 | | issue-creator | 创建人筛选 | string | ✖ | v1 |
@@ -729,11 +817,41 @@ jobs:
## Actions 模板 ## 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 ## LICENSE

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.

168
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');
@@ -6107,15 +6158,7 @@ async function doQueryIssues (owner, repo, labels, state) {
issueMentioned ? params.mentioned = issueMentioned : null; issueMentioned ? params.mentioned = issueMentioned : null;
if (labels) { if (labels) {
if (typeof(labels) === 'string') { params.labels = labels;
params.labels = labels;
} else {
let temp = '';
labels.forEach((it,index) => {
index == labels.length - 1 ? temp += `${it}` : temp += `${it},`;
});
params.labels = temp;
}
} }
const res = await octokit.issues.listForRepo(params); const res = await octokit.issues.listForRepo(params);
@@ -6123,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);
@@ -6141,6 +6189,7 @@ async function doQueryIssues (owner, repo, labels, state) {
module.exports = { module.exports = {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,
@@ -6215,12 +6264,12 @@ async function doCreateComment (owner, repo, issueNumber, body) {
core.setOutput("comment-id", data.id); core.setOutput("comment-id", data.id);
if (contents) { if (contents) {
await doCreateCommentContent(owner, repo, data.id, contents); await doCreateCommentContent(owner, repo, data.id, dealInput(contents));
} }
}; };
async function doCreateCommentContent(owner, repo, commentId) { async function doCreateCommentContent(owner, repo, commentId, contents) {
if (typeof(contents) === 'object') { if (contents.length) {
contents.forEach(async item => { contents.forEach(async item => {
if (testContent(item)) { if (testContent(item)) {
await octokit.reactions.createForIssueComment({ await octokit.reactions.createForIssueComment({
@@ -6232,14 +6281,6 @@ async function doCreateCommentContent(owner, repo, commentId) {
core.info(`Actions: [create-reactions][${item}] success!`); 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); core.setOutput("issue-number", data.number);
if (contents) { if (contents) {
await doCreateIssueContent(owner, repo, data.number, contents); await doCreateIssueContent(owner, repo, data.number, dealInput(contents));
} }
}; };
async function doCreateIssueContent(owner, repo, issueNumber) { async function doCreateIssueContent(owner, repo, issueNumber, contents) {
if (typeof(contents) === 'object') { if (contents.length) {
contents.forEach(async item => { contents.forEach(async item => {
if (testContent(item)) { if (testContent(item)) {
await octokit.reactions.createForIssue({ await octokit.reactions.createForIssue({
@@ -6275,14 +6316,6 @@ async function doCreateIssueContent(owner, repo, issueNumber) {
core.info(`Actions: [create-reactions][${item}] success!`); 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!`); 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,
@@ -6375,7 +6430,7 @@ async function doUpdateComment (
} }
if (contents) { 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_body = issue.data.body;
const issue_title = issue.data.title; 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 = { let params = {
owner, owner,
@@ -6455,6 +6522,7 @@ module.exports = {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,
@@ -6482,6 +6550,7 @@ const {
doLockIssue, doLockIssue,
doOpenIssue, doOpenIssue,
doRemoveAssignees, doRemoveAssignees,
doRemoveLabels,
doSetLabels, doSetLabels,
doUnlockIssue, doUnlockIssue,
doUpdateComment, doUpdateComment,
@@ -6490,6 +6559,7 @@ const {
const { const {
doCheckInactive, doCheckInactive,
doCheckIssue,
doCloseIssues, doCloseIssues,
doFindComments, doFindComments,
doLockIssues, doLockIssues,
@@ -6506,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',
@@ -6513,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',
@@ -6586,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;
@@ -6623,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,
@@ -6666,17 +6748,23 @@ main();
function dealInput (para) { function dealInput (para) {
let arr = []; let arr = [];
if (para) { if (para) {
if (typeof(para) === 'string') { const paraArr = para.split(',');
arr.push(para); paraArr.forEach(it => {
} else { if(it.trim()){
arr = para; arr.push(it.trim())
} }
})
} }
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

@@ -1,6 +1,6 @@
{ {
"name": "issue-helper", "name": "issue-helper",
"version": "1.0.0", "version": "1.0",
"private": true, "private": true,
"description": "Some operations on issue.", "description": "Some operations on issue.",
"main": "src/main.js", "main": "src/main.js",

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');
@@ -126,15 +177,7 @@ async function doQueryIssues (owner, repo, labels, state) {
issueMentioned ? params.mentioned = issueMentioned : null; issueMentioned ? params.mentioned = issueMentioned : null;
if (labels) { if (labels) {
if (typeof(labels) === 'string') { params.labels = labels;
params.labels = labels;
} else {
let temp = '';
labels.forEach((it,index) => {
index == labels.length - 1 ? temp += `${it}` : temp += `${it},`;
});
params.labels = temp;
}
} }
const res = await octokit.issues.listForRepo(params); const res = await octokit.issues.listForRepo(params);
@@ -142,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);
@@ -160,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

@@ -61,12 +61,12 @@ async function doCreateComment (owner, repo, issueNumber, body) {
core.setOutput("comment-id", data.id); core.setOutput("comment-id", data.id);
if (contents) { if (contents) {
await doCreateCommentContent(owner, repo, data.id, contents); await doCreateCommentContent(owner, repo, data.id, dealInput(contents));
} }
}; };
async function doCreateCommentContent(owner, repo, commentId) { async function doCreateCommentContent(owner, repo, commentId, contents) {
if (typeof(contents) === 'object') { if (contents.length) {
contents.forEach(async item => { contents.forEach(async item => {
if (testContent(item)) { if (testContent(item)) {
await octokit.reactions.createForIssueComment({ await octokit.reactions.createForIssueComment({
@@ -78,14 +78,6 @@ async function doCreateCommentContent(owner, repo, commentId) {
core.info(`Actions: [create-reactions][${item}] success!`); 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); core.setOutput("issue-number", data.number);
if (contents) { if (contents) {
await doCreateIssueContent(owner, repo, data.number, contents); await doCreateIssueContent(owner, repo, data.number, dealInput(contents));
} }
}; };
async function doCreateIssueContent(owner, repo, issueNumber) { async function doCreateIssueContent(owner, repo, issueNumber, contents) {
if (typeof(contents) === 'object') { if (contents.length) {
contents.forEach(async item => { contents.forEach(async item => {
if (testContent(item)) { if (testContent(item)) {
await octokit.reactions.createForIssue({ await octokit.reactions.createForIssue({
@@ -121,14 +113,6 @@ async function doCreateIssueContent(owner, repo, issueNumber) {
core.info(`Actions: [create-reactions][${item}] success!`); 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!`); 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,
@@ -221,7 +227,7 @@ async function doUpdateComment (
} }
if (contents) { 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_body = issue.data.body;
const issue_title = issue.data.title; 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 = { let params = {
owner, owner,
@@ -301,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

@@ -1,15 +1,21 @@
function dealInput (para) { function dealInput (para) {
let arr = []; let arr = [];
if (para) { if (para) {
if (typeof(para) === 'string') { const paraArr = para.split(',');
arr.push(para); paraArr.forEach(it => {
} else { if(it.trim()){
arr = para; arr.push(it.trim())
} }
})
} }
return arr; return arr;
}; };
function matchKeyword(content, keywords) {
return keywords.find(item => content.toLowerCase().includes(item));
};
module.exports = { module.exports = {
dealInput, dealInput,
matchKeyword,
}; };