mikepenz/release-changelog-builder-action

How to use this - set labels/use commits messages

mStirner opened this issue · 14 comments

I want to use this in my automatic release workflow to generate a changelog.
But no matter what i do i see always "no changes" in my playground release.

How/what do i have to put in my git commits to appear in the release changelog?

Playground repo: https://github.com/mStirner/playground-test-auto-release
Workflow:

name: Release Workflow

on:
  pull_request:
    branches:
      - main
    types:
      - closed

jobs:
  release:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    permissions: write-all

    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '16'
      - run: npm ci
      - run: npm run release

      - name: "Read package.json"
        run: echo "PACKAGE_JSON=$(jq -c . < package.json)" >> $GITHUB_ENV

      - name: "Build Changelog"
        id: build_changelog
        uses: mikepenz/release-changelog-builder-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: "Create GitHub release"    
        uses: ncipollo/release-action@v1        
        with:
          artifacts: "dist/*"
          tag: "v${{ fromJson(env.PACKAGE_JSON).version }}"
          generateReleaseNotes: false
          skipIfReleaseExists: true
          body: ${{steps.build_changelog.outputs.changelog}}

No matter what, and how i format it in the git commit message, im unable to see it in the release output. Does not work:

  • [fix]: foo
  • `fix`: foo
  • fix: foo

How should "labels" be define to be recognized by this action?
I did not found anything about that in the documentation/readme.

In the action output (https://github.com/mStirner/playground-test-auto-release/actions/runs/7929554235/job/21650025772#step:7:36) it prints: "No pull requests found"

The action by default works with pull requests only. It appears you are trying to use it without pull requests but instead with commits?

Screenshot 2024-02-16 at 14 16 08

Please configure the action to run in the commit based mode. However remember that commits have less information than pull requests, so you will need to provide additional configuration to tell the action how to categorize your commits.

There are some test cases around that which can probably give you some pointers on how to configure it:
https://github.com/mikepenz/release-changelog-builder-action/blob/develop/__tests__/releaseNotesBuilder.test.ts#L257-L286

Thanks for the hint, dont know how i over read that.
But i encountered a other problem while setting commitMode to true:

grafik

The fromatted output looks a bit strange, and for every commit message "PR: #0" is shown: https://github.com/mStirner/playground-test-auto-release/releases/tag/v1.1.6

Also should, a commit message with "fix" or "`fix`" not be under the "Fix" Category instead of "Uncategorized"?

@mStirner I found myself in the same situation and this worked nicely for me:

      - name: "Build Changelog"
        id: changelog
        uses: mikepenz/release-changelog-builder-action@v4.1.1
        with:
          commitMode: true
          configurationJson: |
            {
              "categories": [
                {
                  "title": "## What's Changed since #{{FROM_TAG}}",
                  "labels": []
                }
              ],
              "template": "#{{CHANGELOG}}",
              "pr_template": "- #{{TITLE}}\n",
              "empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}",
              "max_pull_requests": 1000,
              "max_back_track_time_days": 1000
            }
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

The key solution to the problem is pr_template,
where the default is something like "pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}"

Here's a screenshot of my result:

image

@mikepenz Thanks for your work! It's a great tool in my workflow.

Thank you so much @skaramicke for the kind work and chiming in on this issue providing help :)

@mStirner please have a look on the information related the template per PR (or in your case commit)

to the second question regarding categorisation.

As noted in my first message, the action by default uses pull requests (and on these labels) to categorize the information, however none of this exists for commit messages. For commit messages you will be required to provide your own logic to extract the categories.

Please see the example I referenced before, it uses the label_extractor and transformers to get the "labels" you want for your case to cateogrize (this example is based on the test which uses emojis, but is transformable to any other pattern you anyone may use - https://github.com/mikepenz/release-changelog-builder-action/blob/develop/configs_test/configuration_commits_emoji.json#L24-L36)

Thank you very much @skaramicke. Your reply helped me a lot.
But there is one thing that i find "confusing".

My latest release is v1.1.9, the previous one is v1.1.8.
But in the changelog is written "What's Changed since v1.1.7".
Why does it skip v1.1.8?

Same for release v1.1.8, it says in release notes "What's Changed since v1.1.6".
Why does it skip the release v1.1.7?

Seems like its working correctly in your screenshot.
Where is my mistake?

grafik

https://github.com/mStirner/playground-test-auto-release/releases

That seems weird. Are you using #{{FROM_TAG}}?

Mine seems perfectly sequential

image

I copy & pasted your json config.
Thats the current workflow file:

name: Release Workflow

on:
  pull_request:
    branches:
      - main
    types:
      - closed

jobs:
  release:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    permissions: write-all

    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '16'
      - run: npm ci
      - run: npm run release

      - name: "Read package.json"
        run: echo "PACKAGE_JSON=$(jq -c . < package.json)" >> $GITHUB_ENV

      - name: "Build Changelog"
        id: build_changelog
        uses: mikepenz/release-changelog-builder-action@v4
        with:
          commitMode: true
          configurationJson: |
            {
              "categories": [
                {
                  "title": "## What's Changed since #{{FROM_TAG}}",
                  "labels": []
                }
              ],
              "template": "#{{CHANGELOG}}",
              "pr_template": "- #{{TITLE}}\n",
              "empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}",
              "max_pull_requests": 1000,
              "max_back_track_time_days": 1000
            }          
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: "Create GitHub release"    
        uses: ncipollo/release-action@v1        
        with:
          artifacts: "dist/*"
          tag: "v${{ fromJson(env.PACKAGE_JSON).version }}"
          generateReleaseNotes: false
          skipIfReleaseExists: true
          body: ${{steps.build_changelog.outputs.changelog}}

Yes, i use #{{FROM_TAG}}

The only difference is that I don’t run my workflow in pull requests at all, only on tag pushes.

My tag exists when the workflow starts and yours is created as part of the create release action. So when you’re building the change log, it’s considering the current tag before the latest one is created as the “to” tag, and the previous one as “from”, and then you create a fresh one and the text you put on it is already generated.

I’d try and create the new tag before generating the change log, and then put that in the create release action.

Thanks @skaramicke for chiming in and helping again.

@mStirner as @skaramicke correctly noted the problem is that you run the action as part of the merge to main as part of closing it.

At this time the toTag you want does not yet exist, and the release-action you use will create the tag&release for you: https://github.com/mStirner/playground-test-auto-release/actions/runs/7943737909/workflow#L56

The release-changelog-builder-actions sole purpose is to build the release notes, however it won't tag for you.

Screenshot 2024-02-18 at 16 57 49 Looking at the logs you can see that it retrieves the tags from the API from GitHub which can only find the latest 2 tags existing. This is highlighted in the README: https://github.com/mikepenz/release-changelog-builder-action?tab=readme-ov-file#note Screenshot 2024-02-18 at 16 59 58

If you want to adjust this behavior I'd advice that you pass in the toTag as configuration to the action, which you can do like so:
Screenshot 2024-02-18 at 17 00 16

Given you want to get all commits but don't have the tag, you can pass in the SHA of that commit for it to build the diff from
So it should work if you do:

      - name: "Build Changelog"
        id: build_changelog
        uses: mikepenz/release-changelog-builder-action@v4
        with:
          toTag: "${{ github.sha }}"
          commitMode: true
          configurationJson: |
            {
              "categories": [
                {
                  "title": "## What's Changed since #{{FROM_TAG}}",
                  "labels": []
                }
              ],
              "template": "#{{CHANGELOG}}",
              "pr_template": "- #{{TITLE}}\n",
              "empty_template": "#{{OWNER}}\n#{{REPO}}\n#{{FROM_TAG}}\n#{{TO_TAG}}",
              "max_pull_requests": 1000,
              "max_back_track_time_days": 1000
            }          
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

In this case it will take the merge hash you provided and then find the last release from the API. which should match your needs

Thanks @mikepenz it work well, but now i have another issue ^^
In every release note, there are all merges listed, please see screenshot below:

grafik

Can i ignore all merges? (Or at least show only the newest)
I tried it with:

"exclude_merge_branches": [
  "*"
]

Do not work.

You solve one issue, and got a new one :D
But i if the merge messages are ignored, that should it be.

It seems you do work with pull requests 🤔 so why not use those to construct your release notes? :D

Usually (when using the commit mode) people would define rules to get the categorisation from the commit messages (often via conventions in their messages or so) - which would allow them to only include commit messages categorised in their changelogs.

practically speaking the action doesn't necessarily assume that something was a merge commit.

So to the exclude_merge_branches please see how it is implemented below:

Screenshot 2024-02-20 at 10 05 23

So you very likely wanna define something like: mStirner/dev in that array

Here's how i thought about using this action:

  • Create for changes a PR into the dev branch
  • Review these PR/run tests
  • If everything is fine, merge
  • When enough changes are made/issues fixed, create a PR from dev to main
  • Bump the version in the package.json
  • Review the PR from dev -> main
  • Merge and create after the merge a release with the new version define in the package.json

The downside with define a exclude merge filter like mStirner/dev is when the projects get larger, i have to do that for every contributor, which is not possible. So i thought a wildcard selector would be nice/work.

Perhaps i should said that earlier to clarify things.

But nerveless, why does it create for every release a complete log of all ever made merges?
Should it not be only the ones back till the old release?

@mStirner thanks for the description.

It still seems like PR based release notes could work. but either is fine for the action in the end.

You have a good point. the action itself does only make a diff between the 2 refs: https://github.com/mikepenz/release-changelog-builder-action/blob/f10242a33e9e2b28447260eb5d8024826e1b34d4/src/pr-collector/commits.ts#L80C34-L80C35

could it be your release action tags on the branch of the PR you merge into main? (and not actually on main)
given github.sha we use now for the release notes generation is the hash of the merge. (the release tag should probably be on the same hash for that matter)

If you want the hash of the last commit github.event.pull_request.head.sha may be the way to go instead. (there also exists base.sha for reference)

Screenshot 2024-02-20 at 13 26 10

Thank you very much @mikepenz and @skaramicke for your help.
I came up with a solution that meet my needs.

Currently it works like described above:

Here's how i thought about using this action:

* Create for changes a PR into the dev branch

* Review these PR/run tests

* If everything is fine, merge

* When enough changes are made/issues fixed, create a PR from dev to main

* Bump the version in the package.json

* Review the PR from dev -> main

* Merge and create after the merge a release with the new version define in the package.json

But instead of creating the release tag in the action, i use now a Grunt script, that handels the tagging and publishing:

    grunt.registerTask("publish", () => {
        [
            `git tag v${pkg.version}`,
            "git add package.json",
            `git commit -m "Bumped version to v${pkg.version}"`,
            `git push origin v${pkg.version}`,
            "git push"
        ].forEach((cmd) => {
            cp.execSync(cmd, {
                env: process.env,
                stdio: "inherit"
            });
        });
    });

So after doing some work, change the version in package.json, run npm run publish and create a PR from dev to main.
After merging, a new release is created with the version specified in the package.json and release notes back to the latest release.

Thank you very much guys!

I close this issue.