fix: Limit number of labels added to 100 (#497)

* push to excess labels to avoid reaching the limit

* build dist

* never set more than 100 labels

* use splice instead of set

* ignore IDE folders

* install @octokit/plugin-retry

* always setLabels

* fix indentations

* fix specs

* add spec for excess labels

* prettier

* licensed cache

* revert to !!core.getInput('sync-labels')

* better warning for exceeded labels

* keep manually-added labels

* nest the dedupe logic

* rename `removeLabel` to `removeLabelFromList` to avoid confusion

* use Sets, and issue a call only if labels have actually changed

* remove IDE config folders from gitignore

* remove obsolete duplucation check

---------

Co-authored-by: Mark Massoud <mark@unrealcloud.io>
This commit is contained in:
Mark Massoud
2023-06-21 05:49:43 -04:00
committed by GitHub
parent b5ff161cf0
commit 7a202e6428
12 changed files with 1933 additions and 77 deletions

View File

@@ -8,11 +8,11 @@ jest.mock('@actions/core');
jest.mock('@actions/github');
const gh = github.getOctokit('_');
const addLabelsMock = jest.spyOn(gh.rest.issues, 'addLabels');
const removeLabelMock = jest.spyOn(gh.rest.issues, 'removeLabel');
const setLabelsMock = jest.spyOn(gh.rest.issues, 'setLabels');
const reposMock = jest.spyOn(gh.rest.repos, 'getContent');
const paginateMock = jest.spyOn(gh, 'paginate');
const getPullMock = jest.spyOn(gh.rest.pulls, 'get');
const coreWarningMock = jest.spyOn(core, 'warning');
const yamlFixtures = {
'only_pdfs.yml': fs.readFileSync('__tests__/fixtures/only_pdfs.yml')
@@ -41,12 +41,16 @@ describe('run', () => {
configureInput({});
usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles('foo.pdf');
getPullMock.mockResolvedValue(<any>{
data: {
labels: []
}
});
await run();
expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(1);
expect(addLabelsMock).toHaveBeenCalledWith({
expect(setLabelsMock).toHaveBeenCalledTimes(1);
expect(setLabelsMock).toHaveBeenCalledWith({
owner: 'monalisa',
repo: 'helloworld',
issue_number: 123,
@@ -58,12 +62,16 @@ describe('run', () => {
configureInput({dot: true});
usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles('.foo.pdf');
getPullMock.mockResolvedValue(<any>{
data: {
labels: []
}
});
await run();
expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(1);
expect(addLabelsMock).toHaveBeenCalledWith({
expect(setLabelsMock).toHaveBeenCalledTimes(1);
expect(setLabelsMock).toHaveBeenCalledWith({
owner: 'monalisa',
repo: 'helloworld',
issue_number: 123,
@@ -75,11 +83,15 @@ describe('run', () => {
configureInput({});
usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles('.foo.pdf');
getPullMock.mockResolvedValue(<any>{
data: {
labels: []
}
});
await run();
expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(0);
expect(setLabelsMock).toHaveBeenCalledTimes(0);
});
it('(with dot: true) does not add labels to PRs that do not match our glob patterns', async () => {
@@ -89,8 +101,7 @@ describe('run', () => {
await run();
expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(0);
expect(setLabelsMock).toHaveBeenCalledTimes(0);
});
it('(with sync-labels: true) it deletes preexisting PR labels that no longer match the glob pattern', async () => {
@@ -104,19 +115,18 @@ describe('run', () => {
mockGitHubResponseChangedFiles('foo.txt');
getPullMock.mockResolvedValue(<any>{
data: {
labels: [{name: 'touched-a-pdf-file'}]
labels: [{name: 'touched-a-pdf-file'}, {name: 'manually-added'}]
}
});
await run();
expect(addLabelsMock).toHaveBeenCalledTimes(0);
expect(removeLabelMock).toHaveBeenCalledTimes(1);
expect(removeLabelMock).toHaveBeenCalledWith({
expect(setLabelsMock).toHaveBeenCalledTimes(1);
expect(setLabelsMock).toHaveBeenCalledWith({
owner: 'monalisa',
repo: 'helloworld',
issue_number: 123,
name: 'touched-a-pdf-file'
labels: ['manually-added']
});
});
@@ -131,14 +141,43 @@ describe('run', () => {
mockGitHubResponseChangedFiles('foo.txt');
getPullMock.mockResolvedValue(<any>{
data: {
labels: [{name: 'touched-a-pdf-file'}]
labels: [{name: 'touched-a-pdf-file'}, {name: 'manually-added'}]
}
});
await run();
expect(addLabelsMock).toHaveBeenCalledTimes(0);
expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(setLabelsMock).toHaveBeenCalledTimes(0);
});
it('(with sync-labels: false) it only logs the excess labels', async () => {
configureInput({
'repo-token': 'foo',
'configuration-path': 'bar',
'sync-labels': false
});
usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles('foo.pdf');
const existingLabels = Array.from({length: 100}).map((_, idx) => ({
name: `existing-label-${idx}`
}));
getPullMock.mockResolvedValue(<any>{
data: {
labels: existingLabels
}
});
await run();
expect(setLabelsMock).toHaveBeenCalledTimes(0);
expect(coreWarningMock).toHaveBeenCalledTimes(1);
expect(coreWarningMock).toHaveBeenCalledWith(
'Maximum of 100 labels allowed. Excess labels: touched-a-pdf-file',
{title: 'Label limit for a PR exceeded'}
);
});
});