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

Demo the use of CHANGELOG.md for managing library and tool versions #2095

Merged
merged 11 commits into from
Feb 18, 2022

Conversation

baronfel
Copy link
Contributor

@baronfel baronfel commented Feb 14, 2022

This PR demonstrates the use of Ionide.KeepAChangelog.Tasks along with a KeepAChangelog-formatted CHANGELOG.md file to manage versions for the Fantomas libraries and tool.

Generally, the MSBuild tasks and targets in this package hook into the build/pack/etc flow wherever versioning information is needed, then parse the Changelog file that the ChangelogFile MSBuild property points to for version information, including

  • number
  • release date
  • release notes

Then, this information is used to set the assembly version, NuGet package version, build date metadata, and package release notes data. The intent is that this encourages proper care and feeding of your project's Changelog.

In addition, this PR uses Directory.Build.props to set many common packaging properties, which allows for removal of much of the build logic in build.fsx. This is good, because mismatch between MSBuild from the CLI and FAKE calls can result in unnecessary re-builds.

Finally, with this package it becomes easy to have separate Changelog files for different components of the project. Note here that I was able to create a dedicated Changelog for the Fantomas.Client library, since it is much newer, with one MSbuild property.

If this is accepted, it would become possible to document a new contributor flow:

  • create an issue
  • create a PR for the work on that issue
  • in the PR, add a changelog item under the Unreleased changelog version section, so that maintainers have an up-to-date list of changes since the last release

In the near future, Ionide.KeepAChangelog will use the unreleased section's content to auto-generate and suggest prerelease versions for packages, so that you don't have to keep track yourself.

I'm happy to talk about the changes overall or in detail. I suggest reviewing this commit-by-commit, as I tried to keep each one contained as a logical step of the transition.

@nojaf
Copy link
Contributor

nojaf commented Feb 14, 2022

Hello Chet, this looks great! I went over the diff commit by commit and I have an understanding of the changes you've made.
This will be an improvement and we should totally have this.

One thing I still can't really grasp is when do I do what exactly. So, part of the magic runs when our Pack target is invoked?
When exactly do I manually run GenerateChangelog? What steps are still manually here?
If I want to do the next release, how do I start with this?

Apologies if I'm asking obvious questions.

@baronfel
Copy link
Contributor Author

These are all good questions, exactly the kinds of things I hoped to surface with this PR!

So, part of the magic runs when our Pack target is invoked?

Yeah! The .NET SDK has conventions for discovering and running MSBuild tasks, targets, and props from PackageReferences (this can be turned off with various combinations of PrivateAssets and ExcludeAssets). The library packages up props and targets that then become dependencies of the Build and/or Pack targets of your build, so MSBuild executes them. You can see this if you build with dotnet build -bl and open the generated msbuild.binlog with the MSBuild Structured Log Viewer tool. Search for GetChangelogVersion or SetVersionFromChangelog to see the calls.

When exactly do I manually run GenerateChangelog?

That whole target and supporting function can be deleted as part of this, actually. I kept it to illustrate the process of migrating from RELEASE_NOTES to CHANGELOG, and to answer any questions about that process. If this is accepted, I'd send one more commit that removes that FAKE target, the supporting functions, and the RELEASE_NOTES.md file.

What steps are still manually here?

As far as tracking changes - instead of writing to RELEASE_NOTES, you'd add new sections/lines to CHANGELOG based on the patterns found at https://keepachangelog.com/en/1.0.0/#how. There are VSCode extensions with snippets for creating a new version block, a new section, etc if you want some tooling support.

As far as creating a release - nothing! Keep using your FAKE targets if you are happy with them :)

If I want to do the next release, how do I start with this?

To make a release, generally you'd have some changes accruing in the Unreleased section of the changelog. To make a release, change this section to the release version you want, add a date (YYYY-mm-dd), and that's it! The next time someone makes a commit, create a new ## Unreleased section and start adding items. If you mess up the formatting, the MSBuild targets will give you an error you can use to correct it.

Hope this helps!

@baronfel
Copy link
Contributor Author

Rebased to include the recent net6.0 reversion on the 4.7 branch.

@nojaf
Copy link
Contributor

nojaf commented Feb 15, 2022

Hey Chet, this is slowly making sense to me. Although I must say, I feel like a Medieval farmer at the start of the Renaissance. This stuff is overwhelming.
As we are no longer using the release notes, could you remove them as well in this PR? And remove the FAKE target that we won't use anyway. I think I'll just release 4.7 with this as it is such a step forwards.

One thing I still don't truly grasp is when I would be committing the Changelog.md file. Will that happen close to a release or with each commit?

@baronfel
Copy link
Contributor Author

I pushed up a couple commits that remove the old RELEASE_NOTES and add to the CONTRIBUTING guide some examples of workflows.

One thing I still don't truly grasp is when I would be committing the Changelog.md file. Will that happen close to a release or with each commit?

Changelog entries should be added on each PR ideally, just to limit the amount of overhead spent collecting them. They should be added to the Unreleased section of the document (see the example I left in the CONTRIBUTING.md document just now).

When you're ready to release, you as the maintainer have two steps:

  • decide on what the next version number should be
  • change the line ## Unreleased to ## <version number> - <version release date>

then you're all set. In FsAutoComplete I made a target that does this 'promotion' for me, based on some analysis of the Changelog contents, but I don't think that's required at all. A future version of Ionide.KeepAChangelog might add this ability as an MSBuild target, so you could call it via dotnet msbuild -t:PromoteRelease or something and it would do this for you. Again, that's all just automating the very simple manual process.

@@ -180,6 +180,23 @@ For example, `git checkout -b fix-1404`.

- Code should be formatted to our standard style, using either `dotnet fake run build.fsx -t Format` which works on all files, or
`dotnet fake run build.fsx -t FormatChanged` to just change the files in git.
- If you forget, there's a git `pre-push` script that will run this for you, make sure to run `dotnet fake build -t EnsureRepoConfig` to set that hook up.

- Add an entry to the `CHANGELOG.md` in the `Unreleased` section based on what kind of change your change is. Follow the guidelines at [KeepAChangelog](https://keepachangelog.com/en/1.0.0/#how) to make your message relevant to future readers.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any way to enforce this via our main build pipeline?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not easily, I suppose you could do some custom check like 'the commits in this PR must have changed CHANGELOG.md', but that's a bit finicky to get correct. I might suggest making a pull request template that reminds users/provides a checklist for them to work though (this template could point to sections of the CONTRIBUTING.md for clarification, for example).

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, of course not everything needs to be in there as well.
For example, today I discovered there is an unused function in TokenParser. At some point, I'll submit a PR to remove it.
But such a thing should not really make the release notes.

Let me think about the proper guidance of this. If a bug was solved, we definitely need an entry there.

Sorry, this is taking me some time to merge this one in. I'd just want to go over this one slowly to make sure I grasp everything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No worries at all - I want you to be completely comfortable with the process at the end of this, and the tool is very young, so I completely understand wanting to have a firm grasp on the mechanics.

If you prefer, I can remove the guidance about changelogs from the CONTRIBUTING doc, and you can keep the writing of changelogs as a release-time activity, as you do now. In that case nothing about your workflow would change at all.

Copy link
Contributor

Choose a reason for hiding this comment

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

No, I need to give it some more thought but I like the idea that these things are captured sooner in the development cycle.
There is nothing complicated in mentioning you fixed a bug in the changelog.
I need to think about a set of practices when to add what message.
There really are upfront moments when you know it should be included in the release notes.
I welcome the idea that this becomes a joint effort.

@baronfel
Copy link
Contributor Author

Note after talking to @nojaf today:

  • rebase this work onto master

@baronfel baronfel changed the base branch from 4.7 to master February 18, 2022 05:45
@baronfel
Copy link
Contributor Author

ok, I think I did that rebase back onto master correctly. The packages seem to have the correct versions at least.

Copy link
Contributor

@nojaf nojaf left a comment

Choose a reason for hiding this comment

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

Many thanks @baronfel!

@nojaf nojaf merged commit f4ffa7e into fsprojects:master Feb 18, 2022
jindraivanek pushed a commit to jindraivanek/fantomas that referenced this pull request Mar 30, 2022
…sprojects#2095)

* swap out package references

* migrate from release notes to changelog file

* set version and package release notes from the CHANGELOG files

* fix build script formatting

* pack at the solution level for increased speed

remove customizations from build.fsx in favor of Directory.Build.props so that 'basic' command line builds are correct as well

* minimize duplication for packaging in projects - centralize in Directory.Build.props

* Remove Release Notes

* Add examples to CONTRIBUTING

* Add additional pointers for the changelog in CONTRIBUTING.md.

* Update CHANGELOG.md with KeepAChangelog.

* Add missing dates for older releases in CHANGELOG.md.

Co-authored-by: nojaf <florian.verdonck@outlook.com>
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.

None yet

2 participants