Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enhancements to Workflow Flexibility and Documentation #4

Merged
merged 5 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 64 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
## Handle Multiple Issues

> ℹ️ This GitHub workflow is designed for open source projects where users are allowed to create only one issue at a time.
> ℹ️ This GitHub workflow is designed for open source projects where users are allowed to work on only one issue at a time.

With this GitHub workflow, you can automate tasks whenever an author creates multiple open issues.

### Use cases

- The workflow can comment the issues that are already created by the author which are currently in the open state.
- You can also filter the issues that are assigned to you
- You can add your own comment message (even multiline) in the issue.
- Add a custom label on the issue.
- You can add label or labels based on your preferences.
- Optionally, you can also close the issue (previous issues won't be affected), and only the current issue will be closed.

---

### 🚀 Getting Started

- For custom configuration in-depth, you can check [examples](#examples).
- Create a file in the repository at the following path: `.github/workflows/handle-multiple-issues.yml` and paste the following code into it.

```yml
name: Handle Multiple Issues

on:
issues:
types:
Expand All @@ -32,8 +36,7 @@ jobs:
with:
label: "multiple issues" #default
close: false #default
issueNumber: true #default is false
gh-token: ${{ secrets.GITHUB_TOKEN }} # this is mandatory
issueNumber: true #default is true
```

---
Expand All @@ -44,26 +47,30 @@ Various inputs are defined to let you configure the action:

| Name | Description | Default |
| ---- | ----------- | ------- |
| `gh-token` | The GitHub token for authentication | N/A |
| `label` | A label to add if the conditions are fulfilled | `'multiple issues'` |
| `gh-token` | The GitHub token for authentication | `'${{ github.token }}'` |
| `label` | Add a label to the current issue. Use commas to separate if there are multiple labels. | `'multiple issues'` |
| `comment` | A message to comment on the issue | `''` |
| `close` | This will close the issue if set to true | `'false'` |
| `issueNumber` | This will comment all the previous issues that are created by the author | `'potential-duplicate'` |
| `issueNumber` | This will comment all the previous issues that are created by the author | `'true'` |
| `assign` | This will filter the issues that are assigned to the author (works only if `issueNumber` is `true`) | `'false'` |

<br>

The four Combinations that you can use with comment and issueNumber:
The Combinations that you can use with `comment`, `assign` and `issueNumber`:

> Suppose, a user has created `#1`, `#2` which are currently open and we have now included this workflow. Now suppose he creates the `#3` issue.
> Suppose, a user has created `#1`, `#2` which are currently open, only `#2` is assigned to author and we have now included this workflow. Now suppose he creates the `#3` issue.

> You can see the [examples](#examples) for better clarity.

| issueNumber | comment | Purpose | Message by Bot |
| ----------- | ------- | ------- | -------------- |
| `true` | | To mention issue number with the default message | `#2, #1 is already opened by you` |
| `true` | `custom_message` | To mention issue number with a custom message | `#2, #1 custom_message` |
| `false` | `custom_message` | Custom message without mentioning issue | `custom_message` |
| `false` | | Nothing is mentioned; only the label is added as per the workflow | |
| issueNumber | comment | assign | Purpose | Message by Bot |
| ----------- | ------- | ------ | ------- | -------------- |
| `true` | | `false` | To mention issue number with the default message | `#2, #1 is already opened by you` |
| `true` | `custom_message` | `false` | To mention issue number with a custom message | `#2, #1 custom_message` |
| `false` | `custom_message` | `false` | Custom message without mentioning issue | `custom_message` |
| `false` | | `false` | Nothing is mentioned; only the label is added as per the workflow | |
| `true` | | `true` | To filter issues that are created by the author and assigned to the same author | `#2 has been opened by you and is also assigned to you.` |

> Only the default message is modified when `assign` is set to `true`; the concept of a custom message remains unchanged.


---
Expand All @@ -78,8 +85,7 @@ uses: Anmol-Baranwal/handle-multiple-issues@v1
with:
label: "up for grabs" #default is 'multiple issues'
close: false #default
issueNumber: true #default is false
gh-token: ${{ secrets.GITHUB_TOKEN }}
issueNumber: true #default is true
```

</details>
Expand All @@ -94,8 +100,7 @@ uses: Anmol-Baranwal/handle-multiple-issues@v1
with:
# label 'multiple issues' will be added
comment: 'custom message'
issueNumber: true
gh-token: ${{ secrets.GITHUB_TOKEN }} # this is mandatory
issueNumber: true #default is true
```

</details>
Expand All @@ -110,7 +115,7 @@ uses: Anmol-Baranwal/handle-multiple-issues@v1
with:
label: "multiple issues" #default
comment: 'custom message'
gh-token: ${{ secrets.GITHUB_TOKEN }} # this is mandatory
issueNumber: false #default is true
```

</details>
Expand All @@ -127,8 +132,7 @@ with:
comment: |
custom message1
custom message2
issueNumber: true #default is false
gh-token: ${{ secrets.GITHUB_TOKEN }} # this is mandatory
issueNumber: true #default is true

# Suppose #1 is already created by the author.
# Output
Expand All @@ -138,6 +142,44 @@ with:

</details>

<br>

<details>
<summary>Add multiple labels</summary>

```yml
uses: Anmol-Baranwal/handle-multiple-issues@v1
with:
label: 'label1, label2' # separate using comma
issueNumber: true #default is true
```

</details>

<br>

<details>
<summary>To filter issues that are assigned to the author</summary>

<br>

- The same rules for message applies to this condition
- This will not work unless `issueNumber` is `true`.


```yml
uses: Anmol-Baranwal/handle-multiple-issues@v1
with:
issueNumber: true # default is true
assign: true # this will not work, unless 'issueNumber' is true

# Suppose #1, #2 is already created by the author. But only #2 is assigned to the author.
# Output
# #2 has been opened by you and is also assigned to you.
```

</details>

---

### 🤝 How to Contribute?
Expand Down
14 changes: 12 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ description: 'Handle the current issue if the author has existing open issues'
author: 'Anmol Baranwal <[email protected]>'
inputs:
label:
description: 'Label to add to the current issue.'
description: 'Add a label to the current issue. Use commas to separate if there are multiple labels.'
default: 'multiple issues'
required: false
issueNumber:
description: 'Include the previous issue number created by the author in the comment.'
default: 'true'
required: false
comment:
description: 'Custom text to add with or without the issue number in the comment.'
default: ''
required: false
close:
description: 'Close the current issue if set to true.'
required: false
gh-token:
description: 'The GitHub token for authentication.'
required: true
default: ${{ github.token }}
required: false
assign:
description: 'To filter the issues that are assigned to the author'
default: 'false'
required: false
runs:
using: 'node16'
main: 'dist/index.js'
Expand Down
27 changes: 16 additions & 11 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const core = __importStar(__nccwpck_require__(2186));
const github = __importStar(__nccwpck_require__(5438));
async function HandleMultipleIssues() {
var _a;
console.log("Hello World!");
try {
const token = core.getInput("gh-token");
if (!token)
Expand All @@ -49,9 +48,9 @@ async function HandleMultipleIssues() {
const context = github.context;
core.notice("step 1.");
// Retrieve custom inputs
const label = core.getInput("label") || "multiple issues"; // Set default label
const labelInput = core.getInput("label");
const issueNumber = core.getInput("issueNumber") === "true" || false; // converts to boolean
const labels = core.getInput("label").split(",").map(label => label.trim());
const assign = core.getInput("assign") === "true" || false;
const issueNumber = core.getInput("issueNumber") === "true";
const comment = core.getInput("comment");
const close = core.getInput("close") === "true" || false;
const checkComment = comment.trim() !== "";
Expand All @@ -64,12 +63,15 @@ async function HandleMultipleIssues() {
creator: author,
state: "open",
});
if (authorIssues.length === 0) {
core.notice("No existing open issues for this author.");
const filteredIssues = assign
? authorIssues.filter((issue) => issue.assignees.some((assignee) => assignee.login === author))
: authorIssues;
if (filteredIssues.length === 0) {
core.notice(`No existing ${assign === true ? "issues created by and assigned to" : "open issues for"} this author.`);
return; // No need to continue.
}
core.notice("step 3.");
const previousIssueNumbers = authorIssues
const previousIssueNumbers = filteredIssues
.filter((issue) => issue.number !== context.issue.number) // Exclude the current issue
.map((issue) => issue.number);
if (previousIssueNumbers.length > 0) {
Expand All @@ -78,8 +80,8 @@ async function HandleMultipleIssues() {
.map((issueNumber) => `#${issueNumber}`)
.join(", ");
// Check if label is an array and add multiple labels if needed
if (Array.isArray(label)) {
for (const lbl of label) {
if (Array.isArray(labels)) {
for (const lbl of labels) {
await octokit.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
Expand All @@ -94,7 +96,7 @@ async function HandleMultipleIssues() {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumberToLabel,
labels: [label],
labels: [labels],
});
}
core.notice("Labels added to issue #" + issueNumberToLabel);
Expand All @@ -104,7 +106,10 @@ async function HandleMultipleIssues() {
let commentText = "";
if (!checkComment) {
// Condition 1: issueNumber is true, comment is false
commentText = `${issueLinks} is already opened by you.`;
if (assign)
commentText = `${issueLinks} has been opened by you and is also assigned to you.`;
else
commentText = `${issueLinks} is already opened by you.`;
}
else if (checkComment) {
// Condition 2: issueNumber is true, comment is true
Expand Down
40 changes: 25 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import * as core from "@actions/core";
import * as github from "@actions/github";

async function HandleMultipleIssues() {
console.log("Hello World!");

try {
const token = core.getInput("gh-token");

Expand All @@ -23,9 +21,9 @@ async function HandleMultipleIssues() {
core.notice("step 1.");

// Retrieve custom inputs
const label = core.getInput("label") || "multiple issues"; // Set default label
const labelInput = core.getInput("label");
const issueNumber = core.getInput("issueNumber") === "true" || false; // converts to boolean
const labels = core.getInput("label").split(",").map(label => label.trim());
const assign = core.getInput("assign") === "true" || false;
const issueNumber = core.getInput("issueNumber") === "true";
const comment = core.getInput("comment");
const close = core.getInput("close") === "true" || false;

Expand All @@ -43,14 +41,24 @@ async function HandleMultipleIssues() {
state: "open",
});

if (authorIssues.length === 0) {
core.notice("No existing open issues for this author.");
return; // No need to continue.
}
const filteredIssues = assign
? authorIssues.filter((issue: any) =>
issue.assignees.some((assignee: any) => assignee.login === author)
)
: authorIssues

if (filteredIssues.length === 0) {
core.notice(
`No existing ${
assign === true ? "issues created by and assigned to" : "open issues for"
} this author.`
)
return // No need to continue.
}

core.notice("step 3.");

const previousIssueNumbers = authorIssues
const previousIssueNumbers = filteredIssues
.filter((issue: { number: any }) => issue.number !== context.issue.number) // Exclude the current issue
.map((issue: { number: any }) => issue.number);

Expand All @@ -62,8 +70,8 @@ async function HandleMultipleIssues() {
.join(", ");

// Check if label is an array and add multiple labels if needed
if (Array.isArray(label)) {
for (const lbl of label) {
if (Array.isArray(labels)) {
for (const lbl of labels) {
await octokit.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
Expand All @@ -77,7 +85,7 @@ async function HandleMultipleIssues() {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumberToLabel,
labels: [label],
labels: [labels],
});
}

Expand All @@ -90,7 +98,9 @@ async function HandleMultipleIssues() {

if (!checkComment) {
// Condition 1: issueNumber is true, comment is false
commentText = `${issueLinks} is already opened by you.`;

if(assign) commentText = `${issueLinks} has been opened by you and is also assigned to you.`;
else commentText = `${issueLinks} is already opened by you.`;
} else if (checkComment) {
// Condition 2: issueNumber is true, comment is true
commentText = `${issueLinks} ${comment}`;
Expand Down Expand Up @@ -135,4 +145,4 @@ async function HandleMultipleIssues() {
}
}

HandleMultipleIssues();
HandleMultipleIssues();
Loading