Rush and changelog generation - update
Tags: conventionalcommits, node, rush, yeoman
Published: 2022-07-11 13:03:00

It's been fun to write the `rush changefiles` command, but I must admit I'm not using it much; the amount of change files generated during the commits, even if limited to major/minor/patch, is staggering.

Instead, I decided to go for another [approach](https://github.com/microsoft/rushstack/issues/1659#issuecomment-1173674008) that... may even have a chance to make it into the **rush**🤞

## The idea
- The general idea of creating change files, and change logs stays the same.
- When running rush change I can use additional parameter, let's say `--show-commits` that would show the commits.
- And if `--recommend-changetype` parameter is used, the commits are parsed and the change type is suggested based on [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)

## In the meantime...
Not sure when (if at all) this proposal will become reality, so I extended my [generator-rush-conventionalcommits](https://www.npmjs.com/package/generator-rush-conventionalcommits) with `rush whatchanged` command.
It does two things:
- **Display commits history:** For each project returned by `projectAnalyzer.getChangedProjectsAsync`, display commits history included in the revision range used by `rush change`, in a `shortlog` format
- **Suggest change type** For each project returned by `projectAnalyzer.getChangedProjectsAsync`, filter commits in the revision range used by `rush change`, using [conventional-commit-types](https://www.npmjs.com/package/conventional-commit-types) as a reference 

## The script
[rush-whatChanged.js](https://github.com/kkazala/generator-rush-conventionalcommits/blob/main/generators/app/templates/rushCommon/scripts/rush-whatChanged.js) uses `projectAnalyzer` to obtain the list of changed projects; it also mirrors `projectAnalyzer` functionality when obtaining the merge base, to make sure that the commits displayed/parsed are exactly the ones that triggered the need for the change file. 

### Display commit history
To **display commit history**, the script executes: 
```powershell
git shortlog ${mergeHash}... -- "${project.projectRelativeFolder}"
```
This may be a lot of commits, so perhaps saving the history to a file might be a better idea. 

### Recommend change type
Calculating the **change type** follows [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). The script invokes `git rev-list --count --grep` with a regular expression to filter and count commit messages.

To detect and count commits that may require **major** change: 
```powershell
git rev-list --count --extended-regexp --grep "(^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(.*?)?!:.*|^BREAKING CHANGE: )" -- "${projectFolder}"
```
If no commits causing **major** change are found, the script searches for **minor** change commits:
```powershell
git rev-list --count --extended-regexp --grep "^feat((.*?))?:" -- "${projectFolder}"
```
And finally, if there are no major or minor changes, it will see if there are any commits causing **patch** bump:
```powershell
git rev-list --count --extended-regexp --grep "^fix((.*?))?:" -- "${projectFolder}"
```

The results will be summarized as following:
![rush whatchanged result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ux1uyvwwauo0l3wvolw2.png)
 
You may download the latest version of the generator from [npm](https://www.npmjs.com/package/generator-rush-conventionalcommits). 
The code is on [GitHub](https://github.com/kkazala/generator-rush-conventionalcommits)