fix(remove-label): do not encode the label to make sure to remove it (#220)
* test: add two more tests relating the label syntax issues both are failing * chore: add more logs and fix the tests on error meaning that I did not find a reproduction... * chore: minor improvements with the types and logs * fix(remove-label): do not encode the label to make sure to remove it could lead to an issue since based on the comment it was here on purpose
This commit is contained in:
parent
107018c400
commit
ddc7648635
|
@ -1,11 +1,8 @@
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as github from '@actions/github';
|
import * as github from '@actions/github';
|
||||||
import {Octokit} from '@octokit/rest';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IssueProcessor,
|
IssueProcessor,
|
||||||
Issue,
|
Issue,
|
||||||
Label,
|
|
||||||
IssueProcessorOptions
|
IssueProcessorOptions
|
||||||
} from '../src/IssueProcessor';
|
} from '../src/IssueProcessor';
|
||||||
|
|
||||||
|
@ -189,6 +186,66 @@ test('processing a stale issue will close it', async () => {
|
||||||
expect(processor.closedIssues.length).toEqual(1);
|
expect(processor.closedIssues.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('processing a stale issue containing a space in the label will close it', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
1,
|
||||||
|
'A stale issue that should be closed',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
['state: stale']
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts: IssueProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
staleIssueLabel: 'state: stale'
|
||||||
|
};
|
||||||
|
|
||||||
|
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 issue containing a slash in the label will close it', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
1,
|
||||||
|
'A stale issue that should be closed',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
['lifecycle/stale']
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts: IssueProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
staleIssueLabel: 'lifecycle/stale'
|
||||||
|
};
|
||||||
|
|
||||||
|
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', async () => {
|
test('processing a stale PR will close it', async () => {
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
generateIssue(
|
generateIssue(
|
||||||
|
@ -650,6 +707,38 @@ test('stale label should not be removed if a comment was added by the bot (and t
|
||||||
expect(processor.removedLabelIssues.length).toEqual(0);
|
expect(processor.removedLabelIssues.length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('stale label containing a space should be removed if a comment was added to a stale issue', async () => {
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
1,
|
||||||
|
'An issue that should un-stale',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
['stat: stale']
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
const opts: IssueProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
removeStaleWhenUpdated: true,
|
||||||
|
staleIssueLabel: 'stat: stale'
|
||||||
|
};
|
||||||
|
|
||||||
|
const processor = new IssueProcessor(
|
||||||
|
opts,
|
||||||
|
async p => (p == 1 ? TestIssueList : []),
|
||||||
|
async (num, dt) => [{user: {login: 'notme', type: 'User'}}], // return a fake comment to indicate there was an update
|
||||||
|
async (issue, label) => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.closedIssues.length).toEqual(0);
|
||||||
|
expect(processor.staleIssues.length).toEqual(0);
|
||||||
|
expect(processor.removedLabelIssues.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
test('stale issues should not be closed until after the closed number of days', async () => {
|
test('stale issues should not be closed until after the closed number of days', async () => {
|
||||||
let lastUpdate = new Date();
|
let lastUpdate = new Date();
|
||||||
lastUpdate.setDate(lastUpdate.getDate() - 5);
|
lastUpdate.setDate(lastUpdate.getDate() - 5);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import {context, getOctokit} from '@actions/github';
|
import {context, getOctokit} from '@actions/github';
|
||||||
|
import {GitHub} from '@actions/github/lib/utils';
|
||||||
import {GetResponseTypeFromEndpointMethod} from '@octokit/types';
|
import {GetResponseTypeFromEndpointMethod} from '@octokit/types';
|
||||||
import {isLabeled} from './functions/is-labeled';
|
import {isLabeled} from './functions/is-labeled';
|
||||||
import {labelsToList} from './functions/labels-to-list';
|
import {labelsToList} from './functions/labels-to-list';
|
||||||
|
@ -68,7 +69,7 @@ export interface IssueProcessorOptions {
|
||||||
* Handle processing of issues for staleness/closure.
|
* Handle processing of issues for staleness/closure.
|
||||||
*/
|
*/
|
||||||
export class IssueProcessor {
|
export class IssueProcessor {
|
||||||
readonly client: any; // need to make this the correct type
|
readonly client: InstanceType<typeof GitHub>;
|
||||||
readonly options: IssueProcessorOptions;
|
readonly options: IssueProcessorOptions;
|
||||||
private operationsLeft = 0;
|
private operationsLeft = 0;
|
||||||
|
|
||||||
|
@ -176,7 +177,13 @@ export class IssueProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// does this issue have a stale label?
|
// does this issue have a stale label?
|
||||||
let isStale = isLabeled(issue, staleLabel);
|
let isStale: boolean = isLabeled(issue, staleLabel);
|
||||||
|
|
||||||
|
if (isStale) {
|
||||||
|
core.info(`This issue has a stale label`);
|
||||||
|
} else {
|
||||||
|
core.info(`This issue hasn't a stale label`);
|
||||||
|
}
|
||||||
|
|
||||||
// should this issue be marked stale?
|
// should this issue be marked stale?
|
||||||
const shouldBeStale = !IssueProcessor.updatedSince(
|
const shouldBeStale = !IssueProcessor.updatedSince(
|
||||||
|
@ -506,12 +513,13 @@ export class IssueProcessor {
|
||||||
|
|
||||||
// Remove a label from an issue
|
// Remove a label from an issue
|
||||||
private async removeLabel(issue: Issue, label: string): Promise<void> {
|
private async removeLabel(issue: Issue, label: string): Promise<void> {
|
||||||
core.info(`Removing label from issue #${issue.number}`);
|
core.info(`Removing label "${label}" from issue #${issue.number}`);
|
||||||
|
|
||||||
this.removedLabelIssues.push(issue);
|
this.removedLabelIssues.push(issue);
|
||||||
|
|
||||||
this.operationsLeft -= 1;
|
this.operationsLeft -= 1;
|
||||||
|
|
||||||
|
// @todo remove the debug only to be able to test the code below
|
||||||
if (this.options.debugOnly) {
|
if (this.options.debugOnly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +529,7 @@ export class IssueProcessor {
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
issue_number: issue.number,
|
issue_number: issue.number,
|
||||||
name: encodeURIComponent(label) // A label can have a "?" in the name
|
name: label
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.error(`Error removing a label: ${error.message}`);
|
core.error(`Error removing a label: ${error.message}`);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import deburr from 'lodash.deburr';
|
import deburr from 'lodash.deburr';
|
||||||
import {Issue, Label} from '../IssueProcessor';
|
import {Issue, Label} from '../IssueProcessor';
|
||||||
|
|
||||||
|
type CleanLabel = string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
* Check if the label is listed as a label of the issue
|
* Check if the label is listed as a label of the issue
|
||||||
|
@ -19,6 +21,6 @@ export function isLabeled(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanLabel(label: Readonly<string>): string {
|
function cleanLabel(label: Readonly<string>): CleanLabel {
|
||||||
return deburr(label.toLowerCase());
|
return deburr(label.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue