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

Merged
merged 2 commits into from
Feb 20, 2025

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.

@Jericho
Copy link
Contributor Author

Jericho commented Mar 10, 2024

Rebased to pull in yesterday's commits.

@gep13
Copy link
Member

gep13 commented May 24, 2024

@Jericho is there something "special" that has to be done to get the generated release notes to contain the contributors?

The reason that I ask is that we have an upcoming release of Chocolatey CLI, and I thought I would take this for a spin to see it in action, however, I am not seeing anything other than the normal output in the generated release notes. I can see that in code, the contributors for the issues are populated in the GetContributors call, but the template changes don't seem to be taking effect.

@Jericho
Copy link
Contributor Author

Jericho commented May 24, 2024

If you are referencing my beta package #tool nuget:https://f.feedz.io/jericho/jericho/nuget/?package=GitReleaseManager&version=0.17.0-collaborators0003, nothing special that you need to do. The result will be release notes similar to the notes on this project: https://github.com/Jericho/StrongGrid/releases (please note, I started using my beta package in late December 2023 if I remember correctly, so only consider releases since January 2024).

If you are running GRM from source in Visual Studio, make sure you "rebuild" the whole project. It seems that changes to templates are not effective until you rebuild. This issue has caused me grief on several occasions where I modified the template but my changes were no reflected in the resulting release notes. My guess is that this problem is due to Visual Studio not automatically detecting changes to .sbn files. Anyway, long story short: make sure you rebuild the project and you should be good to go.

@gep13
Copy link
Member

gep13 commented May 24, 2024

Thank you for the hint, although that doesn't seem to have helped.

I am trying this out of Visual Studio.

I went as far as closing Visual Studio, manually deleting the bin and obj folders in each project folder, then re-opening the solution, and running the GitReleaseManager.Tool project.

The contributors are still not being added into the generated release notes.

@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.

@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.

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

Jericho and others added 2 commits February 20, 2025 14:58
This commit adds the ability to query for, and add, information about
the contributors for linked issues and PR's into the generated release
notes.

This is made possible via a new `include-contributors` option in the
create section of the GitReleaseManager.yaml file.  This is false by
default.

In addition, a new scriban template has been created, so allow complete
segregation between release notes that have contributors, and those that
don't. This was done mainly to allow better maintainability going
forward, and to reduce the complexity of the default template.

This has been implemented for both GitHug and GitLab.  For GitHub, it
was necessary to use GraphQL to get the necessary information, where as
with GitLab, the required information could be returned via the REST API.
During testing, it was found that release notes containing contributors
could not be created, since there was an exception thrown when trying
to map models.  Digging into the problem, there were some missing
mappings, and also some required translations between properties with
different names.

Once these addition mappings were in place, it was possible to create
release notes, with contributors, in both GitHub and GitLab.
@gep13
Copy link
Member

gep13 commented Feb 20, 2025

@Jericho I have just taken this for a spin, on both GitHub and GitLab, and from what I can see, this is working really well (I did have to add some additional mappings into the GitLabProfile in order to get it to function).

I am going to get this merged in, and shipped in the next release of GitReleaseManager! Apologies on it taking so long to get this in, appreciate you being patient!

Copy link
Member

@gep13 gep13 left a comment

Choose a reason for hiding this comment

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

LGTM!

@gep13 gep13 merged commit 819bf76 into GitTools:develop Feb 20, 2025
2 checks passed
gep13 pushed a commit to Jericho/GitReleaseManager that referenced this pull request Feb 20, 2025
This new config option will be available in GRM 0.19.0 (when PR GitTools#541  is merged).
gep13 pushed a commit to Jericho/GitReleaseManager that referenced this pull request Feb 20, 2025
This new config option will be available in GRM 0.19.0 (when PR GitTools#541  is merged).
@Jericho Jericho deleted the collaborators branch February 20, 2025 16:37
@gep13
Copy link
Member

gep13 commented Feb 20, 2025

@Jericho I think I would class this as a success! 😄

image

@Jericho
Copy link
Contributor Author

Jericho commented Feb 20, 2025

Glad you like it!

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