mirror of
https://github.com/actions/stale.git
synced 2025-12-26 18:28:18 +00:00
Compare commits
8 Commits
better_log
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f111c4f385 | ||
|
|
c2daa6ff62 | ||
|
|
32507178a3 | ||
|
|
e169e4e149 | ||
|
|
d7468118d7 | ||
|
|
c72e3d7ff2 | ||
|
|
db0a20585c | ||
|
|
b6f9559915 |
@@ -31,10 +31,12 @@ function generateIssue(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultProcessorOptions: IssueProcessorOptions = {
|
const DefaultProcessorOptions: IssueProcessorOptions = Object.freeze({
|
||||||
repoToken: 'none',
|
repoToken: 'none',
|
||||||
staleIssueMessage: 'This issue is stale',
|
staleIssueMessage: 'This issue is stale',
|
||||||
stalePrMessage: 'This PR is stale',
|
stalePrMessage: 'This PR is stale',
|
||||||
|
closeIssueMessage: 'This issue is being closed',
|
||||||
|
closePrMessage: 'This PR is being closed',
|
||||||
daysBeforeStale: 1,
|
daysBeforeStale: 1,
|
||||||
daysBeforeClose: 30,
|
daysBeforeClose: 30,
|
||||||
staleIssueLabel: 'Stale',
|
staleIssueLabel: 'Stale',
|
||||||
@@ -44,8 +46,9 @@ const DefaultProcessorOptions: IssueProcessorOptions = {
|
|||||||
onlyLabels: '',
|
onlyLabels: '',
|
||||||
operationsPerRun: 100,
|
operationsPerRun: 100,
|
||||||
debugOnly: true,
|
debugOnly: true,
|
||||||
removeStaleWhenUpdated: false
|
removeStaleWhenUpdated: false,
|
||||||
};
|
ascending: false
|
||||||
|
});
|
||||||
|
|
||||||
test('empty issue list results in 1 operation', async () => {
|
test('empty issue list results in 1 operation', async () => {
|
||||||
const processor = new IssueProcessor(
|
const processor = new IssueProcessor(
|
||||||
@@ -62,11 +65,36 @@ test('empty issue list results in 1 operation', async () => {
|
|||||||
expect(operationsLeft).toEqual(99);
|
expect(operationsLeft).toEqual(99);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('processing an issue with no label will make it stale and close it, if it is old enough', async () => {
|
test('processing an issue with no label will make it stale and close it, if it is old enough only if days-before-close is set to 0', async () => {
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z')
|
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const opts = {...DefaultProcessorOptions};
|
||||||
|
opts.daysBeforeClose = 0;
|
||||||
|
|
||||||
|
const processor = new IssueProcessor(
|
||||||
|
opts,
|
||||||
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
|
async (num, dt) => [],
|
||||||
|
async (issue, label) => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.staleIssues.length).toEqual(1);
|
||||||
|
expect(processor.closedIssues.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('processing an issue with no label will make it stale and not close it if days-before-close is set to > 0', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z')
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts = {...DefaultProcessorOptions};
|
||||||
|
opts.daysBeforeClose = 15;
|
||||||
|
|
||||||
const processor = new IssueProcessor(
|
const processor = new IssueProcessor(
|
||||||
DefaultProcessorOptions,
|
DefaultProcessorOptions,
|
||||||
async p => (p == 1 ? TestIssueList : []),
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
@@ -78,7 +106,32 @@ test('processing an issue with no label will make it stale and close it, if it i
|
|||||||
await processor.processIssues(1);
|
await processor.processIssues(1);
|
||||||
|
|
||||||
expect(processor.staleIssues.length).toEqual(1);
|
expect(processor.staleIssues.length).toEqual(1);
|
||||||
expect(processor.closedIssues.length).toEqual(1);
|
expect(processor.closedIssues.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('processing an issue with no label will not make it stale if days-before-stale is set to -1', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z')
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
staleIssueMessage: '',
|
||||||
|
daysBeforeStale: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
const processor = new IssueProcessor(
|
||||||
|
opts,
|
||||||
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
|
async (num, dt) => [],
|
||||||
|
async (issue, label) => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.staleIssues.length).toEqual(0);
|
||||||
|
expect(processor.closedIssues.length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('processing an issue with no label will make it stale but not close it', async () => {
|
test('processing an issue with no label will make it stale but not close it', async () => {
|
||||||
@@ -155,6 +208,60 @@ test('processing a stale PR will close it', async () => {
|
|||||||
expect(processor.closedIssues.length).toEqual(1);
|
expect(processor.closedIssues.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('processing a stale issue will close it even if configured not to mark as stale', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z', false, [
|
||||||
|
'Stale'
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
daysBeforeStale: -1,
|
||||||
|
staleIssueMessage: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const processor = new IssueProcessor(
|
||||||
|
opts,
|
||||||
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
|
async (num, dt) => [],
|
||||||
|
async (issue, label) => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.staleIssues.length).toEqual(0);
|
||||||
|
expect(processor.closedIssues.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('processing a stale PR will close it even if configured not to mark as stale', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(1, 'An issue with no label', '2020-01-01T17:00:00Z', true, [
|
||||||
|
'Stale'
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
daysBeforeStale: -1,
|
||||||
|
stalePrMessage: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const processor = new IssueProcessor(
|
||||||
|
opts,
|
||||||
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
|
async (num, dt) => [],
|
||||||
|
async (issue, label) => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.staleIssues.length).toEqual(0);
|
||||||
|
expect(processor.closedIssues.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
test('closed issues will not be marked stale', async () => {
|
test('closed issues will not be marked stale', async () => {
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
generateIssue(
|
generateIssue(
|
||||||
@@ -489,7 +596,7 @@ test('stale label should be removed if a comment was added to a stale issue', as
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
const opts = DefaultProcessorOptions;
|
const opts = {...DefaultProcessorOptions};
|
||||||
opts.removeStaleWhenUpdated = true;
|
opts.removeStaleWhenUpdated = true;
|
||||||
|
|
||||||
const processor = new IssueProcessor(
|
const processor = new IssueProcessor(
|
||||||
@@ -519,7 +626,7 @@ test('stale label should not be removed if a comment was added by the bot (and t
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
const opts = DefaultProcessorOptions;
|
const opts = {...DefaultProcessorOptions};
|
||||||
opts.removeStaleWhenUpdated = true;
|
opts.removeStaleWhenUpdated = true;
|
||||||
|
|
||||||
const processor = new IssueProcessor(
|
const processor = new IssueProcessor(
|
||||||
@@ -549,7 +656,7 @@ test('stale issues should not be closed until after the closed number of days',
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
const opts = DefaultProcessorOptions;
|
const opts = {...DefaultProcessorOptions};
|
||||||
opts.daysBeforeStale = 5; // stale after 5 days
|
opts.daysBeforeStale = 5; // stale after 5 days
|
||||||
opts.daysBeforeClose = 1; // closes after 6 days
|
opts.daysBeforeClose = 1; // closes after 6 days
|
||||||
|
|
||||||
@@ -581,7 +688,7 @@ test('stale issues should be closed if the closed nubmer of days (additive) is a
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
const opts = DefaultProcessorOptions;
|
const opts = {...DefaultProcessorOptions};
|
||||||
opts.daysBeforeStale = 5; // stale after 5 days
|
opts.daysBeforeStale = 5; // stale after 5 days
|
||||||
opts.daysBeforeClose = 1; // closes after 6 days
|
opts.daysBeforeClose = 1; // closes after 6 days
|
||||||
|
|
||||||
@@ -612,7 +719,7 @@ test('stale issues should not be closed until after the closed number of days (l
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
const opts = DefaultProcessorOptions;
|
const opts = {...DefaultProcessorOptions};
|
||||||
opts.daysBeforeStale = 5; // stale after 5 days
|
opts.daysBeforeStale = 5; // stale after 5 days
|
||||||
opts.daysBeforeClose = 20; // closes after 25 days
|
opts.daysBeforeClose = 20; // closes after 25 days
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,12 @@ inputs:
|
|||||||
description: 'The message to post on the issue when tagging it. If none provided, will not mark issues stale.'
|
description: 'The message to post on the issue when tagging it. If none provided, will not mark issues stale.'
|
||||||
stale-pr-message:
|
stale-pr-message:
|
||||||
description: 'The message to post on the pr when tagging it. If none provided, will not mark pull requests stale.'
|
description: 'The message to post on the pr when tagging it. If none provided, will not mark pull requests stale.'
|
||||||
|
close-issue-message:
|
||||||
|
description: 'The message to post on the issue when closing it. If none provided, will not comment when closing an issue.'
|
||||||
|
close-pr-message:
|
||||||
|
description: 'The message to post on the pr when closing it. If none provided, will not comment when closing a pull requests.'
|
||||||
days-before-stale:
|
days-before-stale:
|
||||||
description: 'The number of days old an issue can be before marking it stale.'
|
description: 'The number of days old an issue can be before marking it stale. Set to -1 to never mark issues or pull requests as stale automatically.'
|
||||||
default: 60
|
default: 60
|
||||||
days-before-close:
|
days-before-close:
|
||||||
description: 'The number of days to wait to close an issue or pull request after it being marked stale. Set to -1 to never close stale issues.'
|
description: 'The number of days to wait to close an issue or pull request after it being marked stale. Set to -1 to never close stale issues.'
|
||||||
@@ -39,6 +43,9 @@ inputs:
|
|||||||
debug-only:
|
debug-only:
|
||||||
description: 'Run the processor in debug mode without actually performing any operations on live issues.'
|
description: 'Run the processor in debug mode without actually performing any operations on live issues.'
|
||||||
default: false
|
default: false
|
||||||
|
ascending:
|
||||||
|
description: 'The order to get issues or pull requests. Defaults to false, which is descending'
|
||||||
|
default: false
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node12'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
|||||||
2218
dist/index.js
vendored
2218
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,8 @@ export interface IssueProcessorOptions {
|
|||||||
repoToken: string;
|
repoToken: string;
|
||||||
staleIssueMessage: string;
|
staleIssueMessage: string;
|
||||||
stalePrMessage: string;
|
stalePrMessage: string;
|
||||||
|
closeIssueMessage: string;
|
||||||
|
closePrMessage: string;
|
||||||
daysBeforeStale: number;
|
daysBeforeStale: number;
|
||||||
daysBeforeClose: number;
|
daysBeforeClose: number;
|
||||||
staleIssueLabel: string;
|
staleIssueLabel: string;
|
||||||
@@ -47,6 +49,7 @@ export interface IssueProcessorOptions {
|
|||||||
operationsPerRun: number;
|
operationsPerRun: number;
|
||||||
removeStaleWhenUpdated: boolean;
|
removeStaleWhenUpdated: boolean;
|
||||||
debugOnly: boolean;
|
debugOnly: boolean;
|
||||||
|
ascending: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -117,6 +120,9 @@ export class IssueProcessor {
|
|||||||
const staleMessage: string = isPr
|
const staleMessage: string = isPr
|
||||||
? this.options.stalePrMessage
|
? this.options.stalePrMessage
|
||||||
: this.options.staleIssueMessage;
|
: this.options.staleIssueMessage;
|
||||||
|
const closeMessage: string = isPr
|
||||||
|
? this.options.closePrMessage
|
||||||
|
: this.options.closeIssueMessage;
|
||||||
const staleLabel: string = isPr
|
const staleLabel: string = isPr
|
||||||
? this.options.stalePrLabel
|
? this.options.stalePrLabel
|
||||||
: this.options.staleIssueLabel;
|
: this.options.staleIssueLabel;
|
||||||
@@ -124,8 +130,9 @@ export class IssueProcessor {
|
|||||||
isPr ? this.options.exemptPrLabels : this.options.exemptIssueLabels
|
isPr ? this.options.exemptPrLabels : this.options.exemptIssueLabels
|
||||||
);
|
);
|
||||||
const issueType: string = isPr ? 'pr' : 'issue';
|
const issueType: string = isPr ? 'pr' : 'issue';
|
||||||
|
const shouldMarkWhenStale = this.options.daysBeforeStale > -1;
|
||||||
|
|
||||||
if (!staleMessage) {
|
if (!staleMessage && shouldMarkWhenStale) {
|
||||||
core.info(`Skipping ${issueType} due to empty stale message`);
|
core.info(`Skipping ${issueType} due to empty stale message`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -159,7 +166,7 @@ export class IssueProcessor {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// determine if this issue needs to be marked stale first
|
// determine if this issue needs to be marked stale first
|
||||||
if (!isStale && shouldBeStale) {
|
if (!isStale && shouldBeStale && shouldMarkWhenStale) {
|
||||||
core.info(
|
core.info(
|
||||||
`Marking ${issueType} stale because it was last updated on ${issue.updated_at} and it does not have a stale label`
|
`Marking ${issueType} stale because it was last updated on ${issue.updated_at} and it does not have a stale label`
|
||||||
);
|
);
|
||||||
@@ -170,7 +177,12 @@ export class IssueProcessor {
|
|||||||
// process the issue if it was marked stale
|
// process the issue if it was marked stale
|
||||||
if (isStale) {
|
if (isStale) {
|
||||||
core.info(`Found a stale ${issueType}`);
|
core.info(`Found a stale ${issueType}`);
|
||||||
await this.processStaleIssue(issue, issueType, staleLabel);
|
await this.processStaleIssue(
|
||||||
|
issue,
|
||||||
|
issueType,
|
||||||
|
staleLabel,
|
||||||
|
closeMessage
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +199,8 @@ export class IssueProcessor {
|
|||||||
private async processStaleIssue(
|
private async processStaleIssue(
|
||||||
issue: Issue,
|
issue: Issue,
|
||||||
issueType: string,
|
issueType: string,
|
||||||
staleLabel: string
|
staleLabel: string,
|
||||||
|
closeMessage?: string
|
||||||
) {
|
) {
|
||||||
const markedStaleOn: string =
|
const markedStaleOn: string =
|
||||||
(await this.getLabelCreationDate(issue, staleLabel)) || issue.updated_at;
|
(await this.getLabelCreationDate(issue, staleLabel)) || issue.updated_at;
|
||||||
@@ -203,7 +216,7 @@ export class IssueProcessor {
|
|||||||
|
|
||||||
const issueHasUpdate: boolean = IssueProcessor.updatedSince(
|
const issueHasUpdate: boolean = IssueProcessor.updatedSince(
|
||||||
issue.updated_at,
|
issue.updated_at,
|
||||||
this.options.daysBeforeClose + (this.options.daysBeforeStale ?? 0)
|
this.options.daysBeforeClose
|
||||||
);
|
);
|
||||||
core.info(`Issue #${issue.number} has been updated: ${issueHasUpdate}`);
|
core.info(`Issue #${issue.number} has been updated: ${issueHasUpdate}`);
|
||||||
|
|
||||||
@@ -224,7 +237,7 @@ export class IssueProcessor {
|
|||||||
core.info(
|
core.info(
|
||||||
`Closing ${issueType} because it was last updated on ${issue.updated_at}`
|
`Closing ${issueType} because it was last updated on ${issue.updated_at}`
|
||||||
);
|
);
|
||||||
await this.closeIssue(issue);
|
await this.closeIssue(issue, closeMessage);
|
||||||
} else {
|
} else {
|
||||||
core.info(
|
core.info(
|
||||||
`Stale ${issueType} is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate}`
|
`Stale ${issueType} is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate}`
|
||||||
@@ -268,28 +281,39 @@ export class IssueProcessor {
|
|||||||
sinceDate: string
|
sinceDate: string
|
||||||
): Promise<Comment[]> {
|
): Promise<Comment[]> {
|
||||||
// find any comments since date on the given issue
|
// find any comments since date on the given issue
|
||||||
const comments = await this.client.issues.listComments({
|
try {
|
||||||
owner: github.context.repo.owner,
|
const comments = await this.client.issues.listComments({
|
||||||
repo: github.context.repo.repo,
|
owner: github.context.repo.owner,
|
||||||
issue_number: issueNumber,
|
repo: github.context.repo.repo,
|
||||||
since: sinceDate
|
issue_number: issueNumber,
|
||||||
});
|
since: sinceDate
|
||||||
|
});
|
||||||
return comments.data;
|
return comments.data;
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`List issue comments error: ${error.message}`);
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab issues from github in baches of 100
|
// grab issues from github in baches of 100
|
||||||
private async getIssues(page: number): Promise<Issue[]> {
|
private async getIssues(page: number): Promise<Issue[]> {
|
||||||
const issueResult: OctoKitIssueList = await this.client.issues.listForRepo({
|
try {
|
||||||
owner: github.context.repo.owner,
|
const issueResult: OctoKitIssueList = await this.client.issues.listForRepo(
|
||||||
repo: github.context.repo.repo,
|
{
|
||||||
state: 'open',
|
owner: github.context.repo.owner,
|
||||||
labels: this.options.onlyLabels,
|
repo: github.context.repo.repo,
|
||||||
per_page: 100,
|
state: 'open',
|
||||||
page
|
labels: this.options.onlyLabels,
|
||||||
});
|
per_page: 100,
|
||||||
|
direction: this.options.ascending ? 'asc' : 'desc',
|
||||||
return issueResult.data;
|
page
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return issueResult.data;
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Get issues for repo error: ${error.message}`);
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark an issue as stale with a comment and a label
|
// Mark an issue as stale with a comment and a label
|
||||||
@@ -304,27 +328,40 @@ export class IssueProcessor {
|
|||||||
|
|
||||||
this.operationsLeft -= 2;
|
this.operationsLeft -= 2;
|
||||||
|
|
||||||
|
// if the issue is being marked stale, the updated date should be changed to right now
|
||||||
|
// so that close calculations work correctly
|
||||||
|
const newUpdatedAtDate: Date = new Date();
|
||||||
|
issue.updated_at = newUpdatedAtDate.toString();
|
||||||
|
|
||||||
if (this.options.debugOnly) {
|
if (this.options.debugOnly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.client.issues.createComment({
|
try {
|
||||||
owner: github.context.repo.owner,
|
await this.client.issues.createComment({
|
||||||
repo: github.context.repo.repo,
|
owner: github.context.repo.owner,
|
||||||
issue_number: issue.number,
|
repo: github.context.repo.repo,
|
||||||
body: staleMessage
|
issue_number: issue.number,
|
||||||
});
|
body: staleMessage
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Error creating a comment: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
await this.client.issues.addLabels({
|
try {
|
||||||
owner: github.context.repo.owner,
|
await this.client.issues.addLabels({
|
||||||
repo: github.context.repo.repo,
|
owner: github.context.repo.owner,
|
||||||
issue_number: issue.number,
|
repo: github.context.repo.repo,
|
||||||
labels: [staleLabel]
|
issue_number: issue.number,
|
||||||
});
|
labels: [staleLabel]
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Error adding a label: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close an issue based on staleness
|
// Close an issue based on staleness
|
||||||
private async closeIssue(issue: Issue): Promise<void> {
|
private async closeIssue(issue: Issue, closeMessage?: string): Promise<void> {
|
||||||
core.info(
|
core.info(
|
||||||
`Closing issue #${issue.number} - ${issue.title} for being stale`
|
`Closing issue #${issue.number} - ${issue.title} for being stale`
|
||||||
);
|
);
|
||||||
@@ -337,12 +374,29 @@ export class IssueProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.client.issues.update({
|
if (closeMessage) {
|
||||||
owner: github.context.repo.owner,
|
try {
|
||||||
repo: github.context.repo.repo,
|
await this.client.issues.createComment({
|
||||||
issue_number: issue.number,
|
owner: github.context.repo.owner,
|
||||||
state: 'closed'
|
repo: github.context.repo.repo,
|
||||||
});
|
issue_number: issue.number,
|
||||||
|
body: closeMessage
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Error creating a comment: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.client.issues.update({
|
||||||
|
owner: github.context.repo.owner,
|
||||||
|
repo: github.context.repo.repo,
|
||||||
|
issue_number: issue.number,
|
||||||
|
state: 'closed'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Error updating an issue: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a label from an issue
|
// Remove a label from an issue
|
||||||
@@ -359,12 +413,16 @@ export class IssueProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.client.issues.removeLabel({
|
try {
|
||||||
owner: github.context.repo.owner,
|
await this.client.issues.removeLabel({
|
||||||
repo: github.context.repo.repo,
|
owner: github.context.repo.owner,
|
||||||
issue_number: issue.number,
|
repo: github.context.repo.repo,
|
||||||
name: encodeURIComponent(label) // A label can have a "?" in the name
|
issue_number: issue.number,
|
||||||
});
|
name: encodeURIComponent(label) // A label can have a "?" in the name
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
core.error(`Error removing a label: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the creation date of a given label on an issue (or nothing if no label existed)
|
// returns the creation date of a given label on an issue (or nothing if no label existed)
|
||||||
@@ -410,7 +468,7 @@ export class IssueProcessor {
|
|||||||
const millisSinceLastUpdated =
|
const millisSinceLastUpdated =
|
||||||
new Date().getTime() - new Date(timestamp).getTime();
|
new Date().getTime() - new Date(timestamp).getTime();
|
||||||
|
|
||||||
return millisSinceLastUpdated < daysInMillis;
|
return millisSinceLastUpdated <= daysInMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static parseCommaSeparatedString(s: string): string[] {
|
private static parseCommaSeparatedString(s: string): string[] {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ function getAndValidateArgs(): IssueProcessorOptions {
|
|||||||
repoToken: core.getInput('repo-token', {required: true}),
|
repoToken: core.getInput('repo-token', {required: true}),
|
||||||
staleIssueMessage: core.getInput('stale-issue-message'),
|
staleIssueMessage: core.getInput('stale-issue-message'),
|
||||||
stalePrMessage: core.getInput('stale-pr-message'),
|
stalePrMessage: core.getInput('stale-pr-message'),
|
||||||
|
closeIssueMessage: core.getInput('close-issue-message'),
|
||||||
|
closePrMessage: core.getInput('close-pr-message'),
|
||||||
daysBeforeStale: parseInt(
|
daysBeforeStale: parseInt(
|
||||||
core.getInput('days-before-stale', {required: true})
|
core.getInput('days-before-stale', {required: true})
|
||||||
),
|
),
|
||||||
@@ -35,7 +37,8 @@ function getAndValidateArgs(): IssueProcessorOptions {
|
|||||||
removeStaleWhenUpdated: !(
|
removeStaleWhenUpdated: !(
|
||||||
core.getInput('remove-stale-when-updated') === 'false'
|
core.getInput('remove-stale-when-updated') === 'false'
|
||||||
),
|
),
|
||||||
debugOnly: core.getInput('debug-only') === 'true'
|
debugOnly: core.getInput('debug-only') === 'true',
|
||||||
|
ascending: core.getInput('ascending') === 'true'
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const numberInput of [
|
for (const numberInput of [
|
||||||
|
|||||||
Reference in New Issue
Block a user