This is a library that can:
- Generate a changelog, or releasenotes, from a GIT repository.
- Determine next version, based on format of commits since last release.
It is fully configurable with a Mustache (Handlebars) template filled with a context of placeholders and helpers.
The changelog can:
- Be stored to file, like
CHANGELOG.md. There are some templates used for testing available here. - Or, just rendered to a
String.
It can integrate with Jira, Redmine, GitLab and/or GitHub to retrieve the title of issues.
| Version | Java Version |
|---|---|
| version < 2.0.0 | 8 |
| 2.0.0 <= version < 2.2.0 | 11 |
| 2.2.0 <= version | 17 |
This software can be used with:
- A Gradle plugin.
- A Maven plugin.
- A Jenkins plugin.
- A command line tool.
- A Docker image.
- A GitHub Action
- A library.
There are examples of different templates in the code that are used for testing.
Here is an example template.
If you are using conventional commits:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]You can use built in helpers to produce a nice changelog. You can add your own helpers (using Javascript or Java) as described here.
You can use partials in your templates.
changelog.hbs
commit.partial
This is configured like:
gitChangelogApi
.withTemplateBaseDir("...")
.withTemplateSuffix(".partial"); //Optional, defaults to ".partial"Some helpers are implemented in this library. And users can also add more helpers as described in Handlebars. If you add your own helpers, using Javascript, you will need to add a scriptengine like Nashorn to your classpath.
Loop each part of the URL.
Conditional, renders a block if given Tag matches release-tag.
Renders date of Tag on format YYYY-MM-DD.
Returns the Tag chronologically before/after the given Tag (or nothing if there is none). Ordered by tag time, not by rendering order. Composes with other helpers, like building a compare link between a release and the one before it:
Same as previousTag/nextTag, but returns the tag's name directly (or an empty string if there is none), for when you just need the name.
Conditional, renders a block if given List<Issue> contains given type.
Conditional, renders a block if given List<Issue> contains issues that don't match the given type.
Conditional, renders a block if given List<Issue> contains given label.
Conditional, renders a block if given List<Issue> contains labels that don't match the given label.
Conditional, renders a block if given label matches the given value.
Conditional, renders a block if given List<Commits> contains given type.
Conditional, renders a block if given List<Commits> contains given scope.
Conditional, renders a block if given List<Commits> contains given type and scope.
Conditional, renders a block if given List<Commits> contains a commit with the given
type whose scope is not one of the given, comma-separated, scopes. Useful for a
catch-all section whose heading should stay hidden once every commit of that type has
already been claimed by a more specific section.
Conditional, renders a block if given List<Commits> contains commits that don't match the given type.
Conditional, renders a block if given List<Commits> contains breaking changes.
Renders date of Commit on format YYYY-MM-DD.
Renders description of Commit.
Renders reverted commit refered to by Commit.
Conditional, renders a block if given Issue is of type.
Conditional, renders a block if given Issue is of type.
Conditional, renders a block if given Commit is of type.
Conditional, renders a block if given Commit is of type.
Conditional, renders a block if given Commit is breaking.
Conditional, renders a block if given Commit has scope.
Conditional, renders a block if given Commit has footers.
Conditional, renders a block if given Commit has paragraphs.
Renders block for each scope in Commit.
Renders block for each refs in Commit.
Renders block for each fixes in Commit.
Renders block for each paragraph in Commit.
Renders block for each footer in Commit.
Optional tokenMatching regex parameter filters footer tokens.
Conditional, renders a block if given Footer has value.
Conditional, renders a block if a equals b.
Conditional, renders a block if a matches regexp b.
Works just like Java substring.
A negative <b> or <c> counts from the end of the string, like Python/JavaScript
slicing. This is useful when you want to trim relative to the end without knowing the
length up front, e.g. {{subString . 0 -1}} drops the last character.
The template is supplied with this context of prepopulated mustache/handlebars variables:
Click here to show context
(ownerName, repoName, urlParts - derived from the clone URL, git remote origin MUST BE SET)
- ownerName (for this repo it would be "tomasbjerre")
- repoName (for this repo it would be "git-changelog-lib")
- urlParts (for this repo it would be [git-changelog-lib, tomasbjerre, git@github.com])
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* tags
- name
- annotation
- tagTime
- hasTagTime
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* authors
- authorName
- authorEmail
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* issueTypes
- name (Like GitHub, GitLab, Jira, ...)
* issues
- name
- hasIssue
- issue
- hasLink
- link
- hasTitle
- title
- hasDescription
- description
- hasType
- type
- isJira
- isGitHub
- isGitLab
- isCustom
- isNoIssue
- hasLabels
- labels
- hasLinkedIssues
- linkedIssues
- hasAdditionalFields
- additionalFields
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* authors
- authorName
- authorEmail
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* issues
- name
- hasIssue
- issue
- hasLink
- link
- hasTitle
- title
- hasDescription
- description
- hasType
- type
- isJira
- isGitHub
- isGitLab
- isCustom
- isNoIssue
- hasLabels
- labels
- hasLinkedIssues
- linkedIssues
- hasAdditionalFields
- additionalFields
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* authors
- authorName
- authorEmail
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* authors
- authorName
- authorEmail
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* issues
- name
- hasIssue
- issue
- hasLink
- link
- hasTitle
- title
- hasDescription
- description
- hasType
- type
- isJira
- isGitHub
- isGitLab
- isCustom
- isNoIssue
- hasLabels
- labels
- hasLinkedIssues
- linkedIssues
- hasAdditionalFields
- additionalFields
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
* authors
- authorName
- authorEmail
* commits
- authorName
- authorEmailAddress
- commitTime
- hash
- hashFull
- commitCount (Only present if withCommitCount(true) was used)
- merge (True if this is a merge-commit)
* files (List of strings, the files changed in this commit. Empty unless withCommitFiles(true) was used)
- message (The full message)
- messageNotes (Notes attached to the commit, see 'git notes')
- messageTitle (Only the first line of the message)
- messageBody (Everything, except the title)
* messageBodyItems (List of strings, the lines after the title)
It has a builder for creating the changelog.
gitChangelogApiBuilder()
.withFromCommit(ZERO_COMMIT)
.withToRef("refs/heads/master")
.withTemplatePath("changelog.hbs")
.render();It can be used to calculate next version number, based on commits:
def nextVersion = gitChangelogApiBuilder()
.withSemanticMajorVersionPattern("^[Bb]reaking")
.withSemanticMinorVersionPattern("[Ff]eature")
.getNextSemanticVersion();
println "Next version:" + nextVersion.toString();
println " Major:" + nextVersion.getMajor();
println " Minor:" + nextVersion.getMinor();
println " Patch:" + nextVersion.getPatch();Settings can be supplied with the build or from a JSON config (documented here).