feat: Filter copr_build jobs based on paths and files changed#2780
feat: Filter copr_build jobs based on paths and files changed#2780LecrisUT wants to merge 4 commits intopackit:mainfrom
copr_build jobs based on paths and files changed#2780Conversation
|
Build failed. ❌ pre-commit FAILURE in 1m 48s |
|
Build failed. ✔️ pre-commit SUCCESS in 1m 52s |
|
This change depends on a change that failed to merge. Change packit/ogr#921 is needed. |
| for changed_file in self.get_files_changed(): | ||
| # Check if any of the files changed are under the paths that are being tracked | ||
| if any(changed_file.is_relative_to(p) for p in paths): | ||
| return True | ||
| return False |
There was a problem hiding this comment.
Actually, what do we do if we have an empty commit, like the Fedora rebuild commits? Should it be a special case to skip this check?
There was a problem hiding this comment.
like the Fedora rebuild commits?
those wouldn't be happening in upstream, so I don't think we have to think about that, or am I missing something?
There was a problem hiding this comment.
I mean if they want to have that behaviour. I occasionally do that 1, but if it's documented that it is or it is not supported, than that's fine as well.
Footnotes
|
Build failed. ✔️ pre-commit SUCCESS in 1m 54s |
|
I briefly looked into the code and I am thinking if it wouldn't be more fitting to have the logic for checking this in this method, which would mean it would work generally, not just for Copr build jobs. |
Probably, but it's not as extendable as with the Checker, needing another place to be aware of that check are being done. I see that there already are checks like |
|
@LecrisUT can you elaborate more on what you are suggesting? I agree the code I linked could be refactored, but it is something different than the Checker's logic, as that is tight to the handlers, while the checks I linked are meant for actually getting the relevant job configurations to the particular event. |
Indeed, not using the same def get_jobs_matching_event(self) -> list[JobConfig]:
jobs_matching_trigger = []
checkers = JobChecker.get_all_checkers()
for job in self.event.packages_config.get_job_views():
if all(c.check(job) for c in checkers):
jobs_matching_trigger.append(job)The class JobChecker:
all_checkers: Final[ClassVar[list[type[JobChecker]]]] = []
def __init_subclass__(cls):
# Register all checkers when the class is created
cls.all_checkers.append(cls)
@classmethod
def get_all_checkers(cls) -> list[JobChecker]:
return [checker_cls() for checker_cls in cls.all_checkers]
def check(job: JobView) -> bool: ...(Of course with a better interface, constructor, etc.) |
|
@LecrisUT understood, thanks for the explanation! Yes, that sounds like it could improve the readability and extensibility. |
|
Hi @LecrisUT , thanks for all the work so far. Do you think it's real to finish this? (Asking for the Copr team that would hugely benefit from this..) Anything we can help with? |
|
I can try to make some progress this week. One question to be answered is #2780 (comment). There are a few ways to approach this:
I am inclined to go with the 3rd option, just because it will come in handy for the future. Footnotes |
|
Nice, thanks @LecrisUT ! I don't have a strong opinion but using webhook might avoid extra API calls (compared to OGR approach). But on the other hand, not sure if this would be same for other git forges. (With OGR, we might be able to find a way more easily.) |
|
My suggestion would be to try to use webhooks directly as it seems the most straightforward (we have also already been having issues with API rate limits). |
|
Where do I get the push event? Otherwise, it seems we still need the ogr changes for the pull-request trigger, the webhook does not have equivalent data. |
|
Build failed. ✔️ pre-commit SUCCESS in 1m 56s |
betulependule
left a comment
There was a problem hiding this comment.
Nice work. It looks good to me so far. Do you think you'll be able to make progress with this soon?
Could you please elaborate what you mean? |
Yes, it's just one blocker to figure out and adding the relevant tests
Sure, when I was looking at this, I couldn't find the appropriate mixin that can be used with |
Yes, you're right that there are no equivalents for upstream PRs (as far as I can tell). I suppose we'll need a new Mixin class for this, then? @lbarcziova, what do you think? I'm still rather new to this project so I don't understand this part too much just yet 😅. |
| if self.job_config.trigger == JobConfigTriggerType.pull_request: | ||
| changes = self.copr_build_helper.pull_request_object.changes |
There was a problem hiding this comment.
I double checked the definitions of GitHub and GitLab definitions of the MR / PR webhook events and you are definitely right that the information related to what files were changed is not present.
Do I understand correctly that your current approach is the following?
- In
parser.py, once a PR / MR webhook event is received, useogrto get a list of commits (cast asCommitInfo) contained in this PR / MR. - Inside the
AreFilesChangedclass, take the list of commits and aggregate the three lists of filesadded,modifiedandremoved.
There was a problem hiding this comment.
In the current implementation, it does not go through the ogr and with the changes in the parser.py (parse_github_push_event) it would be materializing the webhook data to a more complete python object with the included files changed (but I did not properly test it, the failing CI should give us some reference for where this is connected).
2. Inside the
AreFilesChangedclass, take the list of commits and aggregate the three lists of filesadded,modifiedandremoved.
That is what it is supposed to happen (replacing self.copr_build_helper.pull_request_object.changes, that is still from the ogr required change, I will drop it to make it clearer). As soon as we can get the output of parse_github_push_event in this checker class using a mixin, then that would unlock everything that we were missing here.
|
Build failed. ✔️ pre-commit SUCCESS in 1m 45s |
| if not isinstance(pr_event, (github.pr.Action, gitlab.mr.Action)): | ||
| # TODO: What about comments? | ||
| raise NotImplementedError() | ||
| # TODO: How to handle PRs? |
There was a problem hiding this comment.
How about we create another Mixin class, which will use the existing get_pr_files_diff function in ogr to retrieve the files diff? It should return a dictionary, so we would need to process it into a list of files changed.
// dictionary representing files diff
files_changed = project.get_pr_files_diff(pr_id=id_from_pr_event)
There was a problem hiding this comment.
It does not seem to be available for github and gitlab? https://github.com/search?q=repo%3Apackit%2Fogr%20get_pr_files_diff&type=code And I think the internal API would not make it efficient to query that format. Maybe we go through packit/ogr#921?
There was a problem hiding this comment.
Oh, you're right. In that case using packit/ogr#921 sounds good to me.
There was a problem hiding this comment.
Suggestion: Shall we just try-except this part and make it behave as previously until packit/ogr#921 lands? Or we wait for that first?
Thing is I don't know how raise is handled and if it is safe to use.
There was a problem hiding this comment.
Oh neat, the depends-on should actually work according to zuul below 🤔. I guess we can test it with that cross-dependency
Signed-off-by: Cristian Le <git@lecris.dev>
Signed-off-by: Cristian Le <git@lecris.dev>
|
Merge Failed. This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset. |
copr_build jobs based on paths and files changedcopr_build jobs based on paths and files changed
Signed-off-by: Cristian Le <git@lecris.dev>
|
✔️ pre-commit SUCCESS in 1m 50s |
TODO:
/packitcommand is usedpackit/packit.dev.Depends-on: packit/ogr#921
Fixes packit/packit#1997
Fixes #2006
RELEASE NOTES BEGIN
copr_buildjobs are triggered only if there are changed files under thepathsfieldRELEASE NOTES END