Skip to content

Add github logger to be able to use Annotations on GitHub Actions#1368

Merged
maks-rafalko merged 21 commits intoinfection:masterfrom
maks-rafalko:feature/checkstyle-report
Oct 31, 2020
Merged

Add github logger to be able to use Annotations on GitHub Actions#1368
maks-rafalko merged 21 commits intoinfection:masterfrom
maks-rafalko:feature/checkstyle-report

Conversation

@maks-rafalko
Copy link
Member

@maks-rafalko maks-rafalko commented Oct 22, 2020

This PR:

Fixes #1322

Description

This feature allows adding errors/warnings for particular commits/PRs - GitHub Annotations

Basically, this feature adds escaped mutants information (diff) to particular lines where modified source code wasn't detected by tests:

checkstyle

Things to note

  • Unfortunately, GitHub Annotations does not allow using syntax highlighting inside annotations, so we can't display a pretty diff, as well as using <details> tag to be able to show/hide huge text.
  • Currently, I've added a separate GH Action to run Infection just for the added files in order to display warnings.
  • Displayed warnings does not fail the build

Goal

This will greatly improve review process as it will be immediately clear what parts of the code are not covered by tests properly (thus escaped mutants)

Suggestions are appreciated.

@maks-rafalko maks-rafalko added this to the 0.19 milestone Oct 22, 2020
@maks-rafalko maks-rafalko requested review from sanmai and sidz October 22, 2020 21:54
@maks-rafalko maks-rafalko marked this pull request as draft October 22, 2020 22:06
@sanmai
Copy link
Member

sanmai commented Oct 22, 2020

Just a quick note that there’s hardly any reason why Infection can’t output GitHub compatible annotations straight away.

@sanmai
Copy link
Member

sanmai commented Oct 22, 2020

I mean we can skip this XML and cs2pr altogether by outputting the annotations right from Infection. This will also solve the problem I’ll mention in the review comments in a moment.

Copy link
Member

Choose a reason for hiding this comment

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

Just like it so it could be:

"github": "/dev/stdout" // or /dev/stderr, whichever works best

And the it could output the annotations directly:
https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message

Copy link
Member

Choose a reason for hiding this comment

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

If you look in the source of cs2pr, these annotations are pretty damn simple:

https://github.com/staabm/annotate-pull-request-from-checkstyle/blob/79e8cb48fb729d31684d02fe856dbf2282b65d6f/cs2pr#L108-L137

It is not to say we should scrap this new checkstyle report, but it won't exactly work here.

Copy link
Member

Choose a reason for hiding this comment

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

I think it can be even better with "github" progress reporter.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it can be even better with "github" progress reporter.

what is it?

Copy link
Member

Choose a reason for hiding this comment

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

Like ProgressFormatter or DotFormatter. Set with --formatter option.

@sanmai
Copy link
Member

sanmai commented Oct 22, 2020

If I understood correctly, PHPStan enables this reporter automatically (?) on GitHub CI.

Their implementation: https://github.com/phpstan/phpstan-src/blob/c99b7f8c09fe6e319624ef3b0b66f43d30056fe4/src/Command/ErrorFormatter/GithubErrorFormatter.php

@maks-rafalko
Copy link
Member Author

maks-rafalko commented Oct 22, 2020

If I understood correctly, PHPStan enables this reporter automatically (?) on GitHub CI.

seems so, but I'm not sure it's a good choice TBH for Infection. Without proper filtering (as we do it right now), this will overload the diff with thousands of warnings by default (which MT can produce with even not very big projects)

@maks-rafalko maks-rafalko marked this pull request as ready for review October 22, 2020 23:51
@maks-rafalko maks-rafalko requested a review from sanmai October 22, 2020 23:55
@sanmai
Copy link
Member

sanmai commented Oct 23, 2020

Without proper filtering (as we do it right now), this will overload the diff with thousands of warnings by default

If Infection can detect it is running on GitHub (provided it was asked to do that), then it can fetch and run against changed files just as well.

@sanmai
Copy link
Member

sanmai commented Oct 23, 2020

For example, specifying --formatter=github might trigger all this new machinery with changed files etc.

I agree it's not the best idea to enable this behavior by default.

@maks-rafalko
Copy link
Member Author

maks-rafalko commented Oct 23, 2020

For example, specifying --formatter=github might trigger all this new machinery with changed files etc.

my opinion:

  1. formatter and logger - two different concepts. Formatter is for displaying the MT process, during the run (on each step). Logger - doing smth with the calculated results after MT is done. So here we are dealing with logger. We don't want to display GH Annotation on each step.

  2. I don't like an idea of making Infection too opionated here. Why should it decide for developer what files to filter? Why only Added files but not Modified? Why not both? Why both? And so on.

So, the current state of PR IMO is ideal - we give a developer new logger that can display GH Annotations to a file / stdout. Developer decides what files to mutate in order to use it - all the files in the project, just added new files, just modified or a combination.

What I think we should add (but in a separate PR), is an ability to set logger by command line option, like --logger-checkstyle=php://stdout, or any other of supported loggers

Why? To be able to not use checkstyle report for all the Infection runs in all currently available GH Actions, but to specify it only for Infection / Mutation Testing Code Review Annotations one

@sanmai
Copy link
Member

sanmai commented Oct 23, 2020

Why? To be able to not use checkstyle report for all the Infection runs in all currently available GH Actions, but to specify it only for Infection / Mutation Testing Code Review Annotations one

That's what I was thinking when I proposed --formatter=github. This will probably work just as well.

@sanmai
Copy link
Member

sanmai commented Oct 23, 2020

2. I don't like an idea of making Infection too opionated here. Why should it decide for developer what files to filter? Why only Added files but not Modified? Why not both? Why both? And so on.

Infection is already very opinionated in a similar way. For example, by choosing to add a whitelist (or what's it called now) to phpunit.xml if there is none. Making Infection collect all the necessary details for a user if the run it with --formatter=github or --logger-github is a step in the same direction. A user does not need to know or care what's under the hood. Infection just works.

Imagine you're writing a blog post. What would be better to write, that Infection will now automatically mutate only changed files if run with --logger-github, or that Infection can do that only if you're brave enough to sprinkle it with a bunch of hardly readable git/paste magic?

(I'd take it if you say that Infection shouldn't add <whitelist> if there's none, that's a major blocker for our issue with PHPUnit 9.3.)

@maks-rafalko
Copy link
Member Author

maks-rafalko commented Oct 23, 2020

What would be better to write, that Infection will now automatically mutate only changed files if run with --logger-github

  1. how would we do it from PHP code? (filter out changed/added files only)
  2. I still don't like the idea to decide what files to leave after filtering: Added, Modified, both. How to decide? Here in Infection we removed Modified because of too many failed builds due to the low MSI in the old files. But why should we do the same for all the projects? Then, we need to add settings to enable / disable M files? Doesn't sound good

Imagine you're writing a blog post. What would be better to write, that Infection will now automatically mutate only changed files if run with --logger-github, or that Infection can do that only if you're brave enough to sprinkle it with a bunch of hardly readable git/paste magic?

I'm ok with a couple of lines to be added to CI config. This tool is for developers

@sanmai
Copy link
Member

sanmai commented Oct 23, 2020

  1. shell_exec('git diff origin/$GITHUB_BASE_REF --diff-filter=AM --name-only') and take it from there.
  2. It can be --logger-github=AM with a default set to A

If there's --logger-github and isn't GITHUB_BASE_REF, then it's an error (or a pass?).

@maks-rafalko
Copy link
Member Author

Sounds good. I will give it a try, thanks!

@maks-rafalko maks-rafalko marked this pull request as draft October 23, 2020 09:31
@maks-rafalko maks-rafalko force-pushed the feature/checkstyle-report branch from 464def3 to 9d38e0f Compare October 24, 2020 09:11
@maks-rafalko maks-rafalko force-pushed the feature/checkstyle-report branch from 9b066a3 to fb507b0 Compare October 31, 2020 16:59
@maks-rafalko maks-rafalko merged commit bef65fc into infection:master Oct 31, 2020
@maks-rafalko maks-rafalko deleted the feature/checkstyle-report branch October 31, 2020 17:10
@maks-rafalko
Copy link
Member Author

Thank you all for the great review and ideas!

@sanmai
Copy link
Member

sanmai commented Nov 27, 2020

{
return (string) shell_exec(
sprintf(
'git diff %s --diff-filter=%s --name-only | grep src/ | paste -sd ","',
Copy link
Contributor

Choose a reason for hiding this comment

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

Hardcoded src/ is likely to be wrong, it should be picked by config.
PR coming soon

theofidry added a commit that referenced this pull request Nov 30, 2025
## Context

The user may apply a git filter in two different ways:

- `--git-diff-filter=AD`
- `--git-diff-lines` which is an alias for `--git-diff-filter=AM`.

Now the issue is that since this is two distinct options, we need to
distinguish the two inputs and validate them accordingly as they are
mutually exclusive.

I think there was some confusions before. The code evolved a lot since
the filters were first introduced (#1368, #1632, #2394, #2542). Checking
that the right options are passed correctly is now clearly enforced in
`RunCommand` (see #2542) and `ConfigurationFactory` responsibility is to
pass that `$sourceFilesFilter: string` value and the git related values
when a git filter is applied.


## Problem

Right now `Configuration#isForGitDiff` is set only if the user passed
`--git-diff-lines`. This is incorrect as the goal of this value is to
convey that we are applying a git diff of sorts for:

- `IndexXmlCoverageParser` to throw a more understandable exception to
the user when no coverage is found.
- `FileMutationGenerator/NodeMutationGenerator` to only mutate the nodes
that are part of the diff.

In other words, it should not matter which option was used.


## Solution

This PR corrects the value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

checkstyle output log format

4 participants

Comments