First-class citizen support for changelog
Currently there is no standard support for changelog in cargo-release. In handlebars-rust I use pre-release-replacement to maintain the changelog during release. It works well for most case. But when we are going to add support for github release #230 , the issue that we don't have a structured changelog for current release is becoming a block one.
So I think it's time to consider a first-class citizen support for changelog in cargo-release.
There are some important principles when maintaining a changelog with cargo-release:
- The changelog should be maintained manually instead of being generated directly from commit logs
- For the structure of changelog, we should follow a best practice, for instance, keep a changelog
- Unreleased changelog is drafted simultaneously with the change
- Changelog for current release can be extracted easily
- it can be a file
UPCOMING.mdto prepend to theCHANGELOG.md. - or a markdown parser to extract
Unreleasedsection from keep-a-changelog compatible markdown file.
- it can be a file
Some corner case we might need to consider:
- Several major versions are maintained in dedicated branch, do we need to merge the changelog?
- Do we recommend to update
CHANGELOG.mdorUPCOMING.mdwith a feature pull request? - Workspace support
Could you clarify what the need is for #230? Is it when making the release, we want to extract text to put in it?
Some random thoughts
- Codifying our regex patterns for updating changelogs would be nice
- However, how well will that work to force a single changelog structure?
- We need to keep in mind workspaces and how that'll interact (I generally don't keep a changelog per crate but others might)
@epage Yes. Because Github releases has release notes included, for example: https://github.com/open-telemetry/opentelemetry-java/releases/tag/v0.9.1
We will have to upload release notes of a particular version, see -n and -F option in gh release doc
Codifying our regex patterns for updating changelogs would be nice
We will add internal support for adding release date and version/link
However, how well will that work to force a single changelog structure?
This is an opt-in feature if changelog option is not provided it will be skipped.
We need to keep in mind workspaces and how that'll interact (I generally don't keep a changelog per crate but others might)
A quick idea is to follow current config strategy that searching changelog in crate and then workspace.
For those interested, for now I've taken to creating the release, with notes, via Github Actions
See https://github.com/crate-ci/typos/commit/5c92dc6f8cc68b9d1c8cb1e8840b81e78cf7f65d
Some quick thoughts on "first class changelog" support
Something I've been considering lately is how changelogs are a source of merge conflicts. I've been considering moving away from "upcoming" being in a single file. I've seen some repos where each change is its own file and a tool merges them together. I need to do some exploration on this. This suggests though that there are different ways of doing changelogs and it might be good to leave this to a hook
Do we recommend to update CHANGELOG.md or UPCOMING.md with a feature pull request?
I've been tempted to add to committed (a commit/PR checker) a check that if the conventional commit type is from a specific list (e.g. feat, fix), then the commit or PR must modify a file that matches a glob. See https://github.com/crate-ci/committed/issues/44
I just realized there is a specification about conventional commit message: https://www.conventionalcommits.org/en/v1.0.0/ . It is designed to generate changelog from commit message. We can first provide commit message generation for those projects follows this spec.
Along that route, yet another generator was recently release, https://github.com/orhun/git-cliff, which iirc leverages the parser I maintain, https://github.com/crate-ci/git-conventional. For people using it, they probably want to enforce the commit style which https://github.com/crate-ci/committed helps with.
Great! Sounds like we can provide an option, say changelog=conventional, to generate changelog from conventional commit messages. The changeset can also be hold in our context for replacement and hooks.
Something I've been considering lately is how changelogs are a source of merge conflicts. I've been considering moving away from "upcoming" being in a single file. I've seen some repos where each change is its own file and a tool merges them together. I need to do some exploration on this. This suggests though that there are different ways of doing changelogs and it might be good to leave this to a hook
I'd like to add something to this. In rust-libp2p, we have a workspace with 33 crates which is quite the effort in regards to doing releases. One problem we have is that we want to ensure at pull-request creation time, that we make the correct semver bump. Whilst reviewing a PR, you have the best context to make the decision whether a change is breaking or not. Currently, we do this by bumping the version in the PR directly. We do this semi manually at the moment and it is a source of merge conflicts among other things.
I've been thinking how to solve this problem and would like to propose something: https://github.com/libp2p/rust-libp2p/issues/2902#issuecomment-1445280193
This ties in with the idea I quoted above: A structured format for a changelog entry that - in addition to the changelog text - also specifies that semver impact. If this were integrated into cargo release, it could automatically issue the correct bump for a crate by taking the biggest semver bump amongst all these changelog files since the last release.
We could even automatically generate a "Breaking changes" section from this based on the semver bump of a particular change. This also plays nicely with reverting of commits.
What do you think? Is this something that you see in scope for cargo release?
I'm hesitant to adopt a format without it first having wide adoption or enough promise for wide adoption as I could end up pulling support for it later. In some cases, removing something can be worse than not offering it at all.
However, any such tool to manage these files could have a mode like cargo release changes that gives suggestions on version bumps that you then carry out.
Since I last commented on this issue, I heard of https://crates.io/crates/cargo-changelog which is trying to solve this problem. It looks like there hasn't been too much new development on it. I haven't taken the time yet to look at it deeper to provide feedback.
I'm hesitant to adopt a format without it first having wide adoption or enough promise for wide adoption as I could end up pulling support for it later. In some cases, removing something can be worse than not offering it at all.
That's fair.
However, any such tool to manage these files could have a mode like
cargo release changesthat gives suggestions on version bumps that you then carry out.
Yes, I thought more about it since I commented and I think it can actually be standalone.
Since I last commented on this issue, I heard of https://crates.io/crates/cargo-changelog which is trying to solve this problem. It looks like there hasn't been too much new development on it. I haven't taken the time yet to look at it deeper to provide feedback.
Thanks for pointing me towards that, I'll look into it.
Been looking into the concept of generating a changelog from fragments. My thoughts are at https://github.com/epage/epage.github.io/issues/23#issuecomment-1750832190
While I'd like there to be solid buy-in on built-in changelog support, I see this also helping in several other areas
- #62
- #107
Which all of this would make #117 possible.
I am trying to use the gif-cliff hook in a workspace setup, but I only want to run it from the top level, not for each crate, any pointers on how this could be configured?
What do you mean "from the top level"? Could you expand on your workflow?
We don't support running a hook regardless of what packages are being released. From most use cases I've seen, that would cause its own problems. Instead, I'd recommend associating the hook with one specific package that is most representative.
I have a set of workspace crates that I am always releasing together, and a single changelog in the workspace root. When running git cliff I only want to run it once from the workspace root to update that changelog. But the current pre-release-hook will execute it inside the the crate folders.
Is there a reason it can't be made to work from one of the crate folders?
It totally can, sorry took me a moment to understand. For reference this works well
# some-crate/release.toml
pre-release-hook = ["git", "cliff", "--workdir", "../", "-o", "../CHANGELOG.md", "--tag", "{{version}}" ]