7 Tips to Write Flawless Issue Reports on Github

This post was updated at November 2020 with fresh know-how.
What is new?

Switch from deprecated --set option to rector.php config. Updated Rector YAML to PHP configuration, as current standard.


Reporting issue is important for both you and the maintainer of the project. It can be a private issue in your local Gitlab repository, but open-source issues on Github have a much higher volume (obviously).

Do you want to be clear to the maintainer, be understood and resolve your issue quickly? Here is how to write.

Issue report is like any other text - it can be a piece of text you read and take nothing from or it can fun and rich for the information you really need, for e.g. a job advertisement. You can see:

Why Do You Need to Write Better Issues?

Do you think better issues is extra work on your side just to make maintainer happier? No! You profit from it.

What Do You Gain by Flawless Issue Report?

Where Should You Apply it?

Writing issue like this takes extra attention, thought and energy. It takes a few weeks to get used to it. So should you write flawless issues in every Github repository you work with? It would probably drain your energy and burn-out into falling back to just poor issue reports.

Personally, I'd focus only on few repositories that matter to me and that I plan to use in the future. The top 3 from top of my head right now would be Symfony, PHP Parser and EasyAdminBundle.

That way you won't burn out writing 10 issues mind-full issues to 10 different projects in a week and projects you love and use daily will grow in time - win-win.


Now you know why and where. I think you're ready for creating the very first flawless issue™:

(The examples will be related to Rector, as I work with it the most lately).

1. Add Project Version

The version of the used project is very important. Maybe you use LTS version, maybe it's legacy already, maybe it's experimental version and it's expected to break. You don't care about this, but it will give maintainer the context of your issue.

"I use Rector v0.5.7"

How do you find this information quickly?

composer show rector/rector | grep version
> versions : * v0.5.7

Even Better

This one is nice to have if you're into bleeding edge technologies:

"I use Rector v0.5.7, and it's still broken on dev-master"

Test dev-master as well. Maybe this issue was reported before 2 days and is already fixed on master? You don't have to read all the past issues - it's a waste of time (maybe there was just PR, or maybe just commit right to the master), just try it:

 {
     "require": {
-        "rector/rector": "^0.5.7"
+        "rector/rector": "dev-master"
     },
+    "minimum-stability": "dev",
+    "prefer-stable": true
 }
composer update
// retry your command

2. What Happened - Clear, Exact and Right To the Point

These reports have exactly 0 added information. By creating an "issue", you've already told the maintainer it's broken.

What should you go for instead? Remove the ambiguous:

In an issue:

"I run Rector on [this-code] and I got [this-exception] with [this-exception-message]"

3. Code over Text

These reports could be replaced by black-box style "...on something unknown". 0-value.

<?php

use Guzzle\Client;

final class GuzzleFactory
{
     public function create()
     {
         return new Client([
             'key' => 'some_key'
         ]);
     }
}

4. Highlight What You Can

Why do we use IDE? Why do traffic lights have colors? What does red in PHPUnit mean?

Colors gives us meta-information, that is processed by other parts of the brain then reading is. That way we understand element with colors faster and easier:

echo "1" . 5 + 0x15;

vs.

echo "1" . 5 + 0x15;

I'm not a dog so I fancy the 1st one.


In the most of Github issues you'll use php and diff syntax highligh:

```php echo "Hi"; ``` ```diff -expected +reality ```

4. The Smaller the Better

"What? I thought the more information you'll have, the easier is to fix it." This tip is counter-intuitive. The information is not about quantity, but quality.

The issue report should contain:

At first, it might be hard to figure out what's relevant for the maintainer of that particular project, but based on their feedback you can see it.

Let's look at the code of the previous example - this one has all the relevant information:

<?php

use Guzzle\Client;

final class GuzzleFactory
{
     public function create()
     {
         return new Client([
             'key' => 'some_key'
         ]);
     }
}

This one has duplicated of irrelevant information:

<?php

use Guzzle\Client;

final class GuzzleFactory
{
     public function create()
     {
         return new Client([
             'key' => 'some_key',
             'another_key' => 'some_key',
         ]);
     }
}

final class FacebookFactory
{
     public function create()
     {
         return new FacebookClient([
             'key' => 'some_key',
             'another_key' => 'some_key',
         ]);
     }
}

final class TwitterFactory
{
   public function create()
   {
       return new TwitterClient([
           'key' => 'some_key',
           'another_key' => 'some_key',
       ]);
   }
}

If all the code snippets produce the "Factory return type cannot be resolved" error, use just the first one.

(Hi Honza :D)

5. What Did you Do?

Now the maintainer knows:

✅ Great job! If all the issues were reported like this, the productivity in open-source will sky-rocket (and I mean "Elon Musk" sky-rocket).

The 1st questions that will pop-up in the maintainer's head are "How did you do that?"

Again, think of 4. The smaller the better tip while copy-pasting the config.

"I installed Rector as dev dependency to composer and run:"

vendor/bin/rector process src/SomeFile.php --dry-run

With rector.php config:

use Rector\Symfony\Set\SymfonySetList;
use Rector\Config\RectorConfig;

return function (RectorConfig $rectorConfig): void {
    $rectorConfig->import(SymfonySetList::SYMFONY_43);
};

Perfect!

6. What do You Want?

Now the maintainer has all the information about your code, your steps that lead to it and the configuration that caused it.

But what do you want?

Here is the diff syntax becomes very useful:

<?php

-echo 1 + 5; // real
+echo 6; // expected

Having comments is really great. Why?

<?php

-echo $value + $value2;
+echo $value+$value2;

Which one is preferred?

7. 1 Issue = 1 Issue

Last but not least, 1 issue report should talk about 1 issue. Imagine you go for a trip and you talk to your friend how to get there:

New issue - * traveling*:

issue is closed


Do you have 3 different (see tip #4 again) problems with your code? Create 3 different issues. Don't be afraid, you're not complaining too much.

It's better to have 3 separated issue, that one is easy-pick, 2nd is a question and 3rd need a test case, that all these at once.


Now go out, try, fail and learn :)


Happy coding!




Do you learn from my contents or use open-souce packages like Rector every day?
Consider supporting it on GitHub Sponsors. I'd really appreciate it!