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

fix: Limit number of labels added to 100 #497

Merged
merged 23 commits into from
Jun 21, 2023

Conversation

markmssd
Copy link
Contributor

@markmssd markmssd commented Feb 2, 2023

Description:
Github Issues can have at most 100 labels assigned to them. This PR limits the labels being added to 100, and logs the rest as a warning.

Closes #561
Closes #562

TODO: Unit tests, will add them if the PR makes sense!

Related issue:
Add link to the related issue.

Check list:

  • Mark if documentation changes are required.
  • Mark if tests were added or updated to cover the changes.

@markmssd markmssd requested a review from a team as a code owner February 2, 2023 21:37
@markmssd markmssd changed the title Limit number of labels added to 100 fix: Limit number of labels added to 100 Feb 2, 2023
dist/index.js Outdated
for (const [label, globs] of labelGlobs.entries()) {
core.debug(`processing ${label}`);
if (checkGlobs(changedFiles, globs)) {
labels.push(label);
if (labels.length >= GITHUB_MAX_LABELS) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this neglects the number of labels that are already present. Say the PR has 50 labels, and we come up with 100 that we want to apply, but only 25 of those are already present. The correct result would be to add 50 new ones, 25 remain the same, and 25 would be excess. But the current code reports 100 labels with no excess.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've moved the addLabels to happen AFTER the removeLabels (which happens with syncLabels enabled only) to mitigate this issue. But maybe there's a better way still, I'll check again. Thanks!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, an easy solution seems to be first getting the labels already on the issue with listLabelsOnIssue. Then, you have all the information needed to ensure the total count remains less than 100 while tracking accurately all additions/removals that you want to do.

kodiakhq bot pushed a commit to cloudquery/cloudquery that referenced this pull request Mar 8, 2023

#### Summary

GitHub does not support more than 100 labels per PR, so the PR labeler action fails when that happens. There's ongoing work to fix it, see actions/labeler#497, but I think we can ignore the action failures for now.

<!--
@markmssd
Copy link
Contributor Author

@macksal Alright so I ended up simply using pullRequest.labels, which already holds all the PR's labels. Then:

  • I hydrate the labels array with those current labels only if syncLabels=false
  • Push all matching labels into the labels array (making sure there is no duplicates)
  • Splice the array at 100 (the maximum number of labels allowed on a PR). This splits the original labels array to a length of 100, and all the rest is returned into excessLabels array.
  • If syncLabels=true, I use setLabels, otherwise I addLabels. Either way, it's guaranteed to never set/add more than 100 labels
  • If there was an excess in excessLabels array, simply log them

If that makes sense I'll add unit tests!

@markmssd
Copy link
Contributor Author

@macksal I've rebased my branch to resolve conflicts. Kindly let me know if it needs any more changes (other than unit tests)!

@dusan-trickovic
Copy link
Contributor

Hello, @markmssd ! Thanks for creating the PR - we love and endorse customer contributions! Overall, your PR looks good, it definitely deals well with the scenario of trying to add more than 100 labels and with what to do with the excess.

However, we would also like you to take a look at this PR and its changes. Maybe it can help you see if anything could be added and/or refactored. Furthermore, those two together could solve this issue, as the latter deals with reducing the array by filtering duplicates, but not limiting the number of labels to 100, which former takes into account.

In addition to that, there's another finding that could prove to be beneficial to the solution as well and which we strongly recommend incorporating into the final application. Namely, upon some inspection on our end, we have discovered that the Action will likely keep throwing HttpError: Server Error unless we split the total number of labels in the array past the certain index and send them in parts instead. That 'golden number', as far as our tests go, turns out to be 48.

What that means is that if there are less than 48 labels present in the array, those can be sent all at once without any problems. As soon as that number is exceeded, the array should be split. We suggest splitting it in half, as this seems to be the most efficient way.

However, keep in mind that, as the number of labels keep increasing (e.g. 100 labels), splitting it in half could also give us more than 48 labels to work with. As a solution to this, you could put some kind of a loop in place that could perform the action above for as long as needed (e.g. 100 gets split into 2x50, which then split to 2x25).

Example of this part of the logic:

const LABELS_LIMIT_TO_ADD_AT_ONCE = 48;

while (labelsToBeAdded.length > 0) {
    let splicedLabelsList: string[] = [];
    splicedLabelsList = labelsToBeAdded.splice(0, LABELS_LIMIT_TO_ADD_AT_ONCE / 2);
    await sendLabels(client, prNumber, splicedLabelsList);
}

I hope I explained this clearly :) For any further clarifications, questions and suggestions, please feel free to reach out to us again and we will try to answer them as best as we can. And, of course, feel free to also add some unit tests :)

Thank you for your time and contribution to our software :)

@dusan-trickovic
Copy link
Contributor

Hello, @markmssd ! I just wanted to give you a little ping to see if there are any new updates on your end? Maybe some thoughts about my previous suggestion? Thank you in advance :)

@markmssd
Copy link
Contributor Author

markmssd commented Jun 7, 2023

Hey @dusan-trickovic , thanks for the thorough explanation!

I just got back from vacation and I'll need a few days before getting back to this PR.

So if I understand correctly, this HTTP Server Error happens only when using the "addLabels" method, or also when using "setLabels"? If that's the case, I could also change the PR to ONLY use setLabels, and it would fix all issues.

The logic would be:

  • if syncLabels=true, use setLabels with new labels only.
  • if syncLabels=false, use setLabels with current PR's labels + new ones

(In both cases it would dedupe labels and trim to 100 max)

However if the HTTP Server Error happens with setLabels too, then I'll go with your suggestion with the golden number 48, what do you think?

src/labeler.ts Show resolved Hide resolved
@markmssd
Copy link
Contributor Author

markmssd commented Jun 8, 2023

@dusan-trickovic everything is done and tested, let me know what you think and if it requires some changes!

Copy link
Contributor

@dusan-trickovic dusan-trickovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @markmssd ! Thank you again for creating this PR! I have written a few initial review points that should be addressed before continuing on. Please let us know if you have any additional questions about them, any additional suggestions or concerns :)

src/labeler.ts Outdated Show resolved Hide resolved
src/labeler.ts Show resolved Hide resolved
src/labeler.ts Outdated Show resolved Hide resolved
src/labeler.ts Show resolved Hide resolved
Copy link
Contributor

@MaksimZhukov MaksimZhukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @markmssd! Thank you for the contribution!
Looks good to me! I left a minor comment

src/labeler.ts Outdated Show resolved Hide resolved
@MaksimZhukov
Copy link
Contributor

@markmssd could you please resolve conflicts?

.gitignore Outdated
lib/
.vscode/
.idea/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Till the moment the IDE settings were avoided to be added to the repo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I can remove them haha, it was just getting annoying locally

src/labeler.ts Outdated
@@ -39,23 +43,33 @@ export async function run() {
configPath
);

const labels: string[] = [];
const labelsToRemove: string[] = [];
const labels: string[] = pullRequest.labels.map(label => label.name);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be it worth to create Set object at this point and avoid !labels.includes(label) check further

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially tried with a Set but the code was getting really ugly, I'll try that again 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I pushed changes that use Sets instead, let me know what you think

@markmssd
Copy link
Contributor Author

Conflicts have been served ✅ I also added an additional check to only call setLabels if there was actually a change, to avoid unnecessary API calls, and fixed the tests accordingly.

@dusan-trickovic
Copy link
Contributor

Hello @markmssd ! The PR looks good, we will be merging it now. Thank you very much for your contribution! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HttpError: Server Error when using labeler with over 50 labels
9 participants