-
Notifications
You must be signed in to change notification settings - Fork 421
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
Add support for exclusions #22
Conversation
@damccorm Just a friendly ping on this PR. |
Can we add unit tests? |
I originally intended to, but there are no unit tests as far as I could tell. It didn't seem like this PR was the appropriate place to bootstrap unit tests for the project. |
Yeah, you're correct. I glanced at the test folder but it has a todo ;) . https://github.com/actions/labeler/blob/master/__tests__/main.test.ts |
Yup, same thing I saw. I could still give it a shot though, but fair warning, I'm fairly new to TS and have never used Jest. |
@jalaziz I wrote tests for a similar Action which might give you some inspiration: https://github.com/TimonVS/pr-labeler-action/pull/16/files#diff-74e406fb3eb7c98388edeb1b1c5dcf08. |
Can this be merged? 😄 |
@dakale to have a look after the new year. |
Im not sure the logic for short circuiting exclusion matches makes sense. With this, they are only useful if you list them first, eg, if I have simply have:
Imo, I expect a PR that changes files in src/ but also changes src/some_file, to not match this label. I would read this as "any changes to src/ but not to src/some_file" Previously, returning I do think we can continue short circuiting when an exclusion is met, because the logic for matching a label is at least one positive AND no exclusions, so no positive matches for globs after the exclusion would ever need to be considered. The only difference would be instead of returning true as soon as a file matches a glob, we would defer returning true until after all globs for that file have been considered and no exclusions were met which matches my above example |
Please see the discussion in #9. I had concerns about order being significant, but @damccorm suggested it should be fine. |
Im still not convinced that order should matter, given that no specific example was brought up in that conversation that actually requires ordering Its not described, but I think what this follow example:
is expressing, is "None of the files in example2//*, except example2/foo//*", (which is the opposite of how I originally described the logic: any files in... except). This to me, isnt useful because its equivalent to just listing the match with no exclusions, because if you know what file you want to match, you can express that directly, instead of indirectly/inversely by subtracting all non-matches from the set of all possible files In fact, I think the above example could be rewritten as:
without any loss of meaning (assuming the app logic is updated to not care about order), without impacting the actual logic of what is happening. You could put them in any order you want actually, it expresses the same thing, which is that there is at least one file in the PR that matches the label and isnt excluded. If you start with '**/*` and then start removing files via exclusions, you arrive at the same result (note this requires an implementation change to not short circuit at the first positive match) Hopefully that makes sense and is actually correct. Basically what Im trying to boil it down to is a simpler system that can have its logic expressed simply: If a file matches any globs in a label, and is not excluded, the label is applied. This doesnt change any existing behavior, because "any match" is indistinguishable from "first match" when you dont have exclusions, only the implementation changes Id be happy to merge this if its implemented as described above, or to continue this discussion |
@chabou sorry, been a bit busy, but looking at fixing this soon.
@dakale I'm trying to recall all the context around ordering, but I believe the reason why I was suggested order would matter was because of the statement from #9 (comment) of "Probably, we'd want to evaluate sequentially until we find a pattern that matches. So that way we could even do something like:" As for the example from #9, I think precedence matters. Also, your interpretation missed something:
Should translate to "match all files, except
Unfortunately, that's not true, because of the I would love if order didn't matter, but I don't see how that is accomplished with a single flat list without having to parse the patters to understand at which level the wildcard is being applied. How do you feel about the map syntax I proposed? I think it would be more explicit and allow for additional use-cases such as #9 (comment). The idea with supporting a map would be that we can represent the boolean expression simply as: Thinking about it a bit more, if we keep a single flat list and define it as
|
Hey @jalaziz I think you bring up a great point, and the map syntax you propose does seem to seem solve it, and other usecases, like: Branch name: #54
Change type: #47
Having a rich object here, where the match path(s) are specified as a Have you thought through whether it might make sense to allow both the match/exclude properties to be Regardless, I think what you have proposed in #9 (comment) looks promising as a starting point and should be extensible. Since a Either way Im happy to help get a simple form of these changes in. Do you want to work on a new PR or iterate on this one (to change to map syntax)? |
Funny you mention that. When I was looking at #9 again, I was thinking the same thing. I would definitely add support for a list of strings. Might as well make it as robust as could be.
I'll iterate on this one. Will work on this today. |
Just an update. I was working on the new richer syntax and then got distracted. However, I'm back to looking at this and trying to get it ready for review. It turns out that supporting #9 (comment) is not quite the same as the exclusions we've been talking about. Specifically, the use case I originally brought up would match if at least one file does not match the excluded paths. However, the exclusion @fluzzi wants is more of a "reject if path matches". Since I think there's value in both, I've been working on a change that supports both types of exclusion. I need to get some sleep, but hope to have it ready for review tomorrow. |
Paths can be negated to stop searching through the remaining patterns in a the glob list. All changed files tested and at least one matching file will result in a label being added. Fixes actions#9
@dakale Still need to update the documentation, but I think what I ended up with is far more flexible than my original idea. Each "matcher" now accepts two possible fields:
Exclusions can now be represented as:
However, you can also reject a label if a file exists with:
One thing I did not do is add support for single elements without array or list syntax. I didn't want to complicate type checking, but I can add support if you think it's necessary. I'll work on documentation once I get some indication that this approach works for everyone. |
@jalaziz Great job! Hopefully I can get rid of our fork soon https://datadoghq.dev/integrations-core/meta/ci/#fork |
A new "rich" matcher object can be provided instead of a normal glob. The matcher object has two fields that accept an array of globs: * Globs in "all" must all match every changed file. * Globs in "some" must all match at least one changed file. Combined with negated globs, this allows for a precise control of when labels are applied.
This looks pretty good so far. I see that the there are still README changes that are now outdated and might be misleading. Ideally, outside of full, up to date documentation, it would be best to at least avoid checking in outdated docs Beyond that my only nit is: How do you feel about "any" instead of "some"? To me, "some" usually means > 1 whereas "any" means > 0? |
Yeah, I'll be updating the docs, just wanted to make sure you're ok with the approach before adding docs and examples. I'm definitely ok with any. I just chose some because of the JavaScript Array method name, but I much prefer any/all. Will update the name and docs. |
@dakale everything should be updated. I can squash once everything I get the final approval. |
Regarding the docs, I would expect the "Basic Examples" to come first, before the "Match Object" documentation, as the latter is more advanced. |
@ericcornelissen I chose to place it before "Basic Examples" because it describes the "theory" of the examples. Happy to move it after the examples though. |
@jalaziz Im fine with merging this now unless you want to add anything else. No need to squash since I can just do squash+merge anyways. Ultimately, I think Ill need to go back and reorganize the docs anyways so they dont need to perfect here. I dont think the README is the best place to have extensive docs beyond a few small examples so ill need to measure the right amount to include here, and add some details around which version of labeler this will even be available in. Since the version of the README containing these samples is on the master branch, and that corresponds to the version of the action that has the described functionality, it should be fine. Although it would be ideal to describe it in terms of versions too. Ill need to create a tag and release for this (will probably be v3), until then to be able to consume these changes users will need to use labeler@master, or using the sha of this merge commit (or newer). |
Yay! 🎉 |
@dakale I have nothing to add if it all looks good to you. |
Mentioned in vmware-tanzu/vm-operator#50 (review) (this was not added automatically for some reason) |
Paths can be negated to stop searching through the remaining patterns in
a the glob list. All changed files tested and at least one matching file
will result in a label being added.
Fixes #9