miniscruff/changie

Yaml format changelogs

Closed this issue · 5 comments

Is your feature request related to a problem? Please describe.
changie is good when we have to make changelogs that are human readable, but lot of times we would want to automate things like generation of changelogs especially when we are following rebase and squash strategies.

In these cases each commit will technically represent a set of feature we would like to be displayed in a changelog. Parsing a md file and understanding the changelog history is not easier however if we have the changelogs output in a yaml format, we can have machine readable formats and do a lot of other operations.

For example in one our use-cases we have a 2 set of deployments of the same project, code-base is same but lets say one version is deployed in one fleet every week, while other is a more critical set of changes which we deploy once in a month. Hence what we thought of doing is having a common master and batching the releases for the first thing, but when we are deploying the changes in a month, we would like to combine all the other historical versions into 1.

If changie was storing the version information in form of yaml, we could have easily combined the versions to produce a combined changelog, but at present we are following a longer route combining the version files which doesn't properly categories commit messages.

Describe the solution you'd like
We can let the user choose if they would like to have their change log files in .md or .yaml format. This would also easliy allow users to query from their changelog files what changes went between lets say 2 different versions.

Describe alternatives you've considered
Currently we have 2 different branches of these 2 releases and we are combing the diff vX.Y.Z files to produce the changelogs between the deployable branch and the master.

hmm, I think there are a few solutions here based on how I understand your process. Feel free to correct any of my assumptions.

One thing you can do is treat the more frequent releases as prereleases and follow the alpha/beta pattern.
That would consist of using --keep and --move-dir as part of your batch runs ( https://changie.dev/cli/changie_batch/ ) to keep the change fragments for the final release.
Also using --prerelease of say alpha-1 or beta-1 until beta-n.
Then when you go to release your combined version you can use --remove-prerelease to remove the prereleases, or not up to you. Also use --include to add the directory you moved your files to.
Here is the sequence of commands.

changie new ...
# first prerelease
changie batch --keep --move-dir alpha --prerelease alpha.1 minor
changie merge
changie new ... more stuff
# second prerelease
changie batch --keep --move-dir alpha --prerelease alpha.1 minor
changie merge
# final release time
changie batch --include alpha --remove-prereleases minor

You can keep the prereleases if you want as well if you want the historical release data, but for other teams once the release is complete they just want a combined alpha release notes.

Now for the second option, you can configure changie to output yaml releases markdown is not required only the default provided by init to follow keep a changelog. To create yaml releases you would do something along the lines of:

# .changie.yaml
versionExt: yaml
headerFormat: |
	# All notable changes to this project will be documented here.
	# The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
	# adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
	# and is generated by [itself](https://github.com/miniscruff/changie).
	changelog:
versionFormat: |
	- version: {{.Version}}
      release_date: '{{.Time.Format "2006-01-02"}}'
	  changes:
kindFormat: '{{.Kind}}:'
changeFormat: |
        - body: '{{.Body}}'
        - pull_request: {{.Custom.PullRequest}}

Now, I have not tested this and my yaml knowledge isn't perfect. But depending on your needs / wants you should be able to use yaml just fine.

I would also mention that I believe you won't need to build a yaml file and parse it yourself as changie probably already has enough options and parameters to support your workflow as in my first suggestion.

@miniscruff thanks a lot for your help, I didn't realise this is possible and now it seems simple, I think an example for the same can be something one would benefit from.

I prepared one configuration which can help others

changesDir: .changes
unreleasedDir: unreleased
headerPath: header.tpl.yaml
changelogPath: CHANGELOG.yaml
versionExt: yaml
fragmentFileFormat: '{{now | unixEpoch}}'
versionFormat: |-
  - version: {{.Version}}
    release_date: '{{.Time.Format "2006-01-02"}}'
    changes:
kindFormat: '{{- .Kind | indent 4 }}:'
changeFormat: |2-
      - body: {{.Body}}
        author: {{.Custom.Author}}
kinds:
- label: Added
  auto: minor
- label: Changed
  auto: major
- label: Deprecated
  auto: minor
- label: Removed
  auto: major
- label: Upgraded
  auto: patch
- label: Fixed
  auto: patch
- label: Security
  auto: patch
newlines:
  afterChangelogHeader: 1
envPrefix: CHANGIE_
custom:
- key: Author
  type: string

Also from the above suggestion I don't think this will work in our case like it is not something like a pre-release or something. So basically we have one code base but 2 deployments. One deployment caters to our business and other deployment caters to another business which have out-sourced to us. So we can move fast and deploy almost every week in our release, but when we are dealing with external parties we need to be extra careful and may deploy in lets say once in 2-3 weeks.

Hence we will be maintaining 2 release branches and we would like to collate the changelogs which are getting deployed in either of the branches, so both share the same master but different release branches.

Since my unreleased changes are getting merged to the master branch, if I don't collate them then it will keep on growing, on the other hand adding a check to delete fragments only after both the release branches are synced upto a common version also seems like a dirty hack. Like think from this perspective that if I don't have changie and I am using squash and merge where each commit represents a single feature / bugfix, then I can just take the diff between the respective release branch and master and that would be my changelog, which is what I am trying to more or less achieve here with the help of changie and its features.

Hence the procedure I am trying to follow is as follows:

  • Each MR will have a unreleased changie file
  • At the time of release from either of the branches, in master we will batch the unrelesed changes and mark it as a version
  • We will then take a diff of all the fragments that were added since last version
  • Combine their yaml files and produce - here merge step is to be implemented but shouldn't be a big deal
  • Add the release notes in the releases, we won't actually be needing to merge these fragments because afterall a lot of times we are only concerned about release of a specific date / version rather than scrolling through a large changelog file.

Also I tried your suggestion above, I think move-dir and keep doesn't work together. Since keep to keep the files in unreleased folder and move-dir is to move them to a new folder which is conflicting and keep is given priority.

But the above solves my problem so will be closing the issue.

If you need to create two changie configs every command will read from an env var, I believe its CHANGIE_CONFIG_PATH for a dual changie setup. Just throwing that out there but sounds like you have a solution. Reach out again if anything else comes up, happy to help any time.

@miniscruff Yes that also seems like a possible solution, I might think of implementing this in some way, just there can be few changie files which can be generated automatically while there can be some which are generated manually. So a manual intervention might lead to missing the changes. I would have thought to instead also divide them as projects but it is already a mono repo so would create complexity. But would will give it a thought.