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

(#89) Add ability to populate release notes with information about contributors #541

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from

Conversation

Jericho
Copy link
Contributor

@Jericho Jericho commented Nov 5, 2023

Properly attribute each issue / PR which is part of a release.

Resolves #89

@Jericho Jericho marked this pull request as draft November 6, 2023 15:44
@Jericho Jericho marked this pull request as ready for review November 7, 2023 15:25
@Jericho
Copy link
Contributor Author

Jericho commented Nov 12, 2023

@gep13 please review at your convenience but do not merge yet. I just rebased your recent changes and I am now investigating how to implement my new feature in GitLat.

UPDATE: I converted to draft to make sure this PR is not merged.

@Jericho Jericho marked this pull request as draft November 12, 2023 16:44
@Jericho Jericho marked this pull request as ready for review November 16, 2023 03:20
@Jericho
Copy link
Contributor Author

Jericho commented Nov 16, 2023

I solved all the remaining issues. This logic is compatible with multiple issues/PRs being associated with a given issue/PRs and also the GetLinkedIssues method has been implemented for GitLab.

@Jericho
Copy link
Contributor Author

Jericho commented Dec 4, 2023

@gep13 in case I wasn't clear: this PR is ready for review.

@Jericho
Copy link
Contributor Author

Jericho commented Dec 8, 2023

In case anybody is interested to try this new feature, you can replace

#tool nuget:?package=GitReleaseManager&version=0.16.0
with
#tool nuget:https://f.feedz.io/jericho/jericho/nuget/?package=GitReleaseManager&version=0.17.0-collaborators0003

in your cake script and you'll be able to generate release notes similar to this: https://github.com/Jericho/ZoomNet/releases/tag/0.71.0

@gep13 gep13 changed the title Contributors (#89) Add ability to populate release notes with information about contributors Feb 12, 2024
@gep13
Copy link
Member

gep13 commented Feb 12, 2024

@Jericho please accept my apologies for the radio silence on this PR! Simply put, I haven't had any time to even think about looking at this. I am hoping to review this in the coming days, and will provide some feedback (if there is any).

Thanks again for your help with this!

@Jericho
Copy link
Contributor Author

Jericho commented Feb 13, 2024

No apologies necessary. I'm just glad to be contributing.

@gep13
Copy link
Member

gep13 commented Mar 9, 2024

@Jericho apologies again! I haven't had a chance to look at this yet, and looks like I am going to have to do an immediate release to fix the issue with creating releases as a result of a required change upstream to Octokit.

@gep13
Copy link
Member

gep13 commented May 24, 2024

Just tried using the GitReleaseManager.Cli as the startup project, and it is having the same result.

@Jericho
Copy link
Contributor Author

Jericho commented May 24, 2024

Please set a break point on line 66 in ReleaseNotesBuilderIntegrationTests.cs and run the SingleMilestone unit test. It will generate the notes for GRM version 0.12.0 which contains a good mix of issues, PRs, excluded labels and, more importantly for the case at hand, 10 different people contributed to this release. When Visual Studio hits your break point, hover your mouse over the result variable and click on View. You should get a popup window where you'll be able to eyeball the generated release notes. I just ran this unit test and here's what I get:

image

Do you get the same?

@gep13
Copy link
Member

gep13 commented May 24, 2024

No, I do not :-(

image

Although, I do get contributors back:

image

@Jericho
Copy link
Contributor Author

Jericho commented May 24, 2024

Is there a possibility that, somehow, you managed to override the built-in template with your own?

Also, can you verify that you have the expected index.sbn which should look like this:
image

@Jericho
Copy link
Contributor Author

Jericho commented May 24, 2024

And while we're on the topic of templates, double-check the presence of contributors.sbn and contributor-details.sbn in the src\GitReleaseManager.Core\Templates\default folder.

@gep13
Copy link
Member

gep13 commented May 24, 2024

While I do make use of custom templates on some projects, I can confirm that none are in play when testing this PR. I can confirm this here:

image

Where the default file path, i.e. the embedded resource, is being used.

Yes, I can confirm that the index.sbn is the same as your screenshot.

And yes, I can also confirm that the two contributor sbn files are in that folder.

@gep13
Copy link
Member

gep13 commented May 24, 2024

Doh! I have figured it out...

I suddenly remembered about the .tt file!

image

You have to right click on that, and then click Run Custom Tool to have it generate the .cs file, which is then embedded into the assembly.

I don't know exactly when this is run as part of the normal build process, but it might also explain why you found you had to clean the files in order to get things to work properly.

@AdmiringWorm might be able to provide some insight into when this part of the tooling works. Thinking about it, I "think" it runs as part of the Cake build, but I thought it ran inside Visual Studio as well.

Now that I have this working, I should be able to take this for a proper trial.

@AdmiringWorm
Copy link
Member

@AdmiringWorm might be able to provide some insight into when this part of the tooling works. Thinking about it, I "think" it runs as part of the Cake build, but I thought it ran inside Visual Studio as well.

It is indeed run as part of the Cake build, it is a separate task called Transform-TextTemplates. Do note that it is not the same as when running it through Visual Studio (not sure why, but the support in VS seems to become worse and worse for TT templates), but it should be close enough.

Jericho and others added 2 commits July 10, 2024 09:56
This is necessary because I merged the develop branch earlier today where the reference to NUnit's NuGet package was upgraded to version 4.x. If I understand the situation correctly, the 'legacy' assertion syntax was supported until version 3.x and was removed in 4.x. That's why my unit tests with the old syntax worked until I rebased my branch earlier today.
@gep13
Copy link
Member

gep13 commented Jul 10, 2024

@Jericho 👋 apologies again for not coming back to you sooner about this one! I would try to give an excuse, but I really don't have one, so, moving on...

A couple of questions/observations...

  1. What are your thoughts about adding an IncludeContributors property to the CreateConfig class, to allow control over whether or not to include Contributors within the release notes? As it stands, Contributors are always included, and a user would need to edit the default template if they didn't want to include that information. Having this be controllable via the configuration file would seem like a natural way to do things, and would be inline with other configuration options that already exists.
  2. When running the SingleMilestone test (without making any changes to the code) I noticed something interesting. In the rendered markdown, there is this Improvement
image

Issue 113 was indeed raised by Geoffrey, however, there is a linked Pull Request that was raised by me. Shouldn't the description for this issue include the information about the link to the PR?

  1. The default template is becoming quite "busy", with lots of different options and switches that can be pulled. Do you think it would make sense to include another template by default, which would specifically be used when including Contributors? That way, the Default template can remain slightly smaller, and less involved.
  2. Instantiating the GraphQLHttpClient here doesn't seem right. This client should probably be injected in the constructor or maybe, rather than mixing the REST GitHub client with the graph QL client in the same provider, there should be a separate provider specifically for graphQL operations.

I haven't really got a strong opinion either way. If we go down the route of using a Configuration value to include/exclude the Contributor information, then we could control when this is instantiated? Or, as you say, perhaps split this out into a separate provider. That might make things a little more complicated in the long run though.

  1. I haven't tested this yet against a GitLab repository, as I would need to set one up for testing this out. Things seem a little simpler to do via the GitLab client though, as it doesn't involve GraphQL.

Again.. I am loving this PR, and the functionality that this provides! Thank you so much for putting the work in so far to get this to where it is!

@gep13
Copy link
Member

gep13 commented Jul 10, 2024

Regarding GitLab, I have just tested it on a repository that has an issue with a linked MR, but the generated release notes doesn't mention the associated MR. The LinkedIssues property is empty on the issue. Did you have to do anything "special" within GitLab to make an issue link through to an MR?

@gep13
Copy link
Member

gep13 commented Jul 10, 2024

Related to the above, if I use this:

image

I can get the associated MR for the issue in question, so that makes me wonder if I haven't done something between the issue and the MR in GitLab to link them in the correct way.

@Jericho
Copy link
Contributor Author

Jericho commented Jul 11, 2024

  1. What are your thoughts about adding an IncludeContributors property to the CreateConfig class, to allow control over whether or not to include Contributors within the release notes?

Sure, no problem. I can add a Boolean property to the CreateConfig class to allow developers to indicate whether they want contributors to be included in the release notes or not.

  1. When running the SingleMilestone test (without making any changes to the code) I noticed something interesting. In the rendered markdown, there is this Improvement Issue 113 was indeed raised by Geoffrey, however, there is a linked Pull Request that was raised by me. Shouldn't the description for this issue include the information about the link to the PR?

Please make yourself comfortable, answering this seemingly simple question might take a while. Here goes my attempt to explain, based on my (potentially flawed) understanding.

GitHub's API does not have a way to retrieve the list of issues/PRs linked to a given issue. The only workaround I was able to find is to use GitHub's graphql API. But even this API does not allow you to easily retrieve the linked issues/PRs. You have to retrieve so called "timeline events" of specific types (in our case we want "connected" and "disconnected"), sort them in chronological order and then we can derive which issues and PRs have been "connected" to the desired issue without having been disconnected. Here's a fictitious example: let's say you link a PR with the issue, realize you made a mistake and unlink this PR and finally you correct your mistake by linking another PR. In this fictitious scenario, the graphQL API would return the following timeline items:

  • first item: issue 111 connected to PR 222
  • second item: issue 111 disconnected from PR 222
  • third item: issue 111 connected to PR 333

In this example, you can see that PR 222 is initially associated to the desired issue but subsequently unlinked. and finally, PR 333 is linked and it's not unlinked. Based on these timeline events we can conclude that PR 333 is the one PR associated to the desired issue. I hope you're following me so far. FYI: this logic is similar to what is described in this StackOverflow comment.

ok, so now that we have the theory out of the way, let's try to investigate specifically what is going on with issue 113 in the GitReleaseManager repo. Here's the tool I use to debug the graphql query and here's the query that you can copy and paste in this tool:

{
  repository(name: "GitReleaseManager", owner: "GitTools") {
    issue(number: 113) {
      timelineItems(first: 50, itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT]) {
        nodes {
          __typename
          ... on ConnectedEvent {
            createdAt
            id
            source {
              __typename
              ... on Issue {
                number
              }
              ... on PullRequest {
                number
              }
            }
            subject {
              __typename
              ... on Issue {
                number
              }
              ... on PullRequest {
                number
              }
            }
          }
          ... on DisconnectedEvent {
            createdAt
            id
            source {
              __typename
              ... on Issue {
                number
              }
              ... on PullRequest {
                number
                author {
                  avatarUrl
                  resourcePath
                }
              }
            }
            subject {
              __typename
              ... on Issue {
                number
              }
              ... on PullRequest {
                number
              }
            }
          }
        }
      }
    }
  }
}

After you click the "Run" button, you will see this result:
image

As you can see in the result, there are no timeline events!!!! Not a single one!!!! Allow me to repeat what I just said, for dramatic effect: not a single one! In other words: GitHub is telling us that this issue was never connected to any other issue or PR. This does not make sense. You and I know that the issue is indeed linked to a PR, therefore we expect at the very least one "connect" timeline event. But the reality is that the API returns zero records.

The ultimate question is: why is GitHub's graphQL Api returning data that seems incorrect or incomplete. I do not know with certainty the answer to this question but I have a theory (emphasis on "theory"): if you go back the the graphQL query that I presented earlier and that you copied/pasted into the GraphQL explorer, you'll notice that I added a "filter" when querying timeline items, like so: timelineItems(first: 50, itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT]) {. The filter indicated that I am interested in "connected" and "disconnected" events because, as previously explained, these are the types of events that signify that a given issue/PR was linked/unlinked to the desired issue. My theory is that the issue and PR were associated in a way to generated a different type of event. What type of event you might ask? I have no idea. But if my theory is correct, it would explain why our graphQL query returns zero timeline event.

Anyway, I'm sure I have bored you to death with all this information. The TL;DR is that I suspect there's another type of event that in some scenarios, such as the one for issue number 113, represents the association of two records. I have no clue what if this theory is true and if it is, what would be the type of event in question. I have been using a beta copy of GRM to generate my release notes for at least 6 months and never noticed this problem. So I'm wondering if this issue you found is an edge case or if it's common.

  1. The default template is becoming quite "busy", with lots of different options and switches that can be pulled. Do you think it would make sense to include another template by default, which would specifically be used when including Contributors? That way, the Default template can remain slightly smaller, and less involved.

In other words, leave index.sbn alone and create a new index-with-contributors.sbn? Sure, no problem.

  1. Or, as you say, perhaps split this out into a separate provider. That might make things a little more complicated in the long run though.

Separating it in a distinct provider would have been my preferred method but GitLab doesn't have this concept of a GraphQL client. So I was at a loss to design a way that works for both Git environments.

  1. I haven't tested this yet against a GitLab repository, as I would need to set one up for testing this out. Things seem a little simpler to do via the GitLab client though, as it doesn't involve GraphQL.

Yes indeed, much much much simpler.

@Jericho
Copy link
Contributor Author

Jericho commented Jul 11, 2024

Related to the above, if I use this:

image I can get the associated MR for the issue in question, so that makes me wonder if I haven't done something between the issue and the MR in GitLab to link them in the correct way.

My code for GitLab retrieves the issues/PRs that close a particular issue when merged. The line of code you added in your code snippet retrieves issues/PRs that are merely "related" and don't necessarily close the desired issue. That's a very subtle nuance but, as your scenario demonstrates, quite an important one. I will change my logic to match your code snippet.

@gep13
Copy link
Member

gep13 commented Jul 11, 2024

@Jericho said...
Sure, no problem. I can add a Boolean property to the CreateConfig class to allow developers to indicate whether they want contributors to be included in the release notes or not.

Woot! 😄

@Jericho said...
In other words, leave index.sbn alone and create a new index-with-contributors.sbn? Sure, no problem.

No, this wasn't exactly what I was referring to. Rather here at this location:

https://github.com/GitTools/GitReleaseManager/tree/develop/src/GitReleaseManager.Core/Templates

We create a new folder, perhaps named contributors or something similar, and we place all the required files to generate the release notes, including the contributors in there. That way, we keep things completely separate. Then, within the code, when the new configuration value is in play, we use this named template, rather than the default one.

Does that make sense? This idea came from @AdmiringWorm, so if I haven't made this clear, perhaps he can help to elaborate.

@Jericho said...
Separating it in a distinct provider would have been my preferred method but GitLab doesn't have this concept of a GraphQL client. So I was at a loss to design a way that works for both Git environments.

Hmm, that is a fair point.

What about adding an overload to the GitHubProvider, to pass in an instance of the GraphQL Client, and then in the Program.cs, based on when the contributors config value has been set, either call the new constructor with an instance of the client, or call the other one? That way, it is only created when needed. Just an idea, haven't dug into this too much, so I could be missing something here.

@Jericho said...
My code for GitLab retrieves the issues/PRs that close a particular issue when merged. The line of code you added in your code snippet retrieves issues/PRs that are merely "related" and don't necessarily close the desired issue. That's a very subtle nuance but, as your scenario demonstrates, quite an important one. I will change my logic to match your code snippet.

Just to level set here... Do you have an example of a GitLab issue/PR pair that works with the current code that you have in place? How exactly did you create the association between the two? The repository I was using for testing isn't public, so I can't share, but within the issue body, there is this section:

image

Do you have that in the issue that you have created? Or do you have another section? If so, I would be curious to know how you have associated the two together, as I could be doing something wrong.

…ct that we want contributors to be included in the release notes or not.
…orresponds to a certain path. If the node is not present in the doc, fallback to a second path. If this second path is not present, fallback to a third path and so on.
….IndexOf' where the result is used to check for the presence/absence of a substring can be replaced by 'string.Contains'
Jericho added a commit to Jericho/GitReleaseManager that referenced this pull request Jul 20, 2024
This new config option will be available in GRM 0.19.0 (when PR GitTools#541  is merged).
@Jericho
Copy link
Contributor Author

Jericho commented Jul 20, 2024

Changes since last review:

  • Added a configuration option so users can specify whether they want contributors to be included in the release notes
  • Created a separate template which is used when the config option is set to true
  • Enhanced the GraphQL query to reduce the number of queries to fetch all necessary info about all the linked issues/PRs
  • Injectable GraphQL client

Ready for another review

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.

Automatically crediting the author/contributor of the PR in the release notes
3 participants