Skip to content

Commit

Permalink
Added short type of release notes for git tag message
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Stepin committed Jun 13, 2024
1 parent fdbcf32 commit e9242a2
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 31 deletions.
56 changes: 44 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
# Git Parse Commits
[![GitHub release](https://img.shields.io/github/release/stepin/git-parse-commits.svg)](https://github.com/stepin/git-parse-commits/releases) [![github license badge](https://img.shields.io/github/license/stepin/git-parse-commits)](https://github.com/stepin/git-parse-commits)

## Intro

When we create release in Gitea / Gitlab / Github we need to fill 3 fields:
- Release name
- Tag name
- Release description
- Tag commit message

Yes, it's not that hard to fill it every time automatically but it anyway takes time,
and it's error-prone process.

So, this script is introduced to automate this process. Some key points:
- Human decides what will be in release note but decision point is moved to MR merge time (when
we specify MR commit message)
- Human decides when release should happen (start manual job)
- If something is not working it's still possible to create release from UI without these CI job


## Details

This script is to be used in CICD pipelines to provide new version number
(bases on commit messages) and releses notes (also bases on commit messages).
(bases on commit messages) and releases notes (also bases on commit messages).

Docker image: [stepin/git-parse-commits:latest](https://hub.docker.com/r/stepin/git-parse-commits)

Example how to use with Docker:

```shell
docker run --rm -it -v "$(PWD):/git" -w /git --user "$(id -u)" stepin/git-parse-commits:2.0.0 releaseVersion
docker run --rm -it -v "$(PWD):/git" -w /git --user "$(id -u)" stepin/git-parse-commits:2.0.0 releaseNotes
docker run --rm -it -v "$(PWD):/git" -w /git --user "$(id -u)" stepin/git-parse-commits:2.1.0 releaseVersion
docker run --rm -it -v "$(PWD):/git" -w /git --user "$(id -u)" stepin/git-parse-commits:2.1.0 releaseNotes
docker run --rm -it -v "$(PWD):/git" -w /git --user "$(id -u)" stepin/git-parse-commits:2.1.0 releaseNotes --short
```

Example usage for Gitlab:
Expand All @@ -19,7 +40,7 @@ Example usage for Gitlab:
create_changelog:
stage: "build"
image:
name: "stepin/git-parse-commits:2.0.0"
name: "stepin/git-parse-commits:2.1.0"
entrypoint: [""]
variables:
GIT_DEPTH: "0"
Expand All @@ -31,11 +52,13 @@ create_changelog:
- echo "CURRENT_VERSION=$CURRENT_VERSION" >> relNotes.env
- cat relNotes.env
- git-parse-commits releaseNotes > releaseNotes.md
- git-parse-commits releaseNotes --short > gitTagCommitMessage.txt
artifacts:
reports:
dotenv: relNotes.env
paths:
- releaseNotes.md
- gitTagCommitMessage.txt
expire_in: 1 day
rules:
- if: $CI_MERGE_REQUEST_IID
Expand All @@ -51,7 +74,7 @@ release:
- echo "Release $RELEASE_VERSION"
release:
tag_name: "$RELEASE_VERSION"
tag_message: "Release $RELEASE_VERSION"
tag_message: "gitTagCommitMessage.txt"
description: "releaseNotes.md"
assets:
links:
Expand All @@ -73,19 +96,19 @@ release:
## Help
```
docker run --rm -it stepin/git-parse-commits --help
$ docker run --rm -it stepin/git-parse-commits --help

Usage: git-parse-commits [<options>] <command> [<args>]...

Provides next release version and release notes from git commit messages.

Options:
-j, --json output in json format
-t, --tag-prefix=<text> prefix for tags (optional)
--tag add tag prefix to versions (only if tag prefix is defined)
-s, --scope=<text> scope to filter release note items
-i, --initial-revision=<text> start range from next revision
-l, --last-revision=<text> stop on this revision
-j, --json Output in json format
-t, --tag-prefix=<text> Prefix for tags (optional)
--tag Add tag prefix to versions (only if tag prefix is defined)
-s, --scope=<text> Scope to filter release note items
-i, --initial-revision=<text> Start range from next revision
-l, --last-revision=<text> Stop on this revision
-h, --help Show this message and exit

Commands:
Expand All @@ -94,6 +117,15 @@ Commands:
lastReleaseVersion Prints version of last release
releaseVersion Prints version of next release from git commit messages
releaseNotes Prints release notes from git commit messages

$ docker run --rm -it stepin/git-parse-commits releaseNotes -h
Usage: git-parse-commits releaseNotes [<options>]

Prints release notes from git commit messages

Options:
-s, --short Switch output to short format to be used as description of git tag
-h, --help Show this message and exit
```


Expand Down
66 changes: 53 additions & 13 deletions git-parse-commits.main.kts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ class GitCommitsParser {
if (!scope.isNullOrEmpty()) {
parsedCommits =
parsedCommits.filter { commit ->
commit.headers = commit.headers.filter { it.scope.isNullOrEmpty() || it.scope == scope }
commit.headers =
commit.headers.filter { it.scope.isNullOrEmpty() || it.scope == scope }
commit.headers.isNotEmpty()
}
}
Expand Down Expand Up @@ -416,29 +417,29 @@ class GitParseCommits :
printHelpOnEmptyArgs = true,
help = "Provides next release version and release notes from git commit messages.",
) {
private val json by option("-j", "--json", help = "output in json format").flag()
private val json by option("-j", "--json", help = "Output in json format").flag()
private val tagPrefix by option(
"-t",
"--tag-prefix",
help = "prefix for tags (optional)",
help = "Prefix for tags (optional)",
).default("")
private val tag by option(
help = "add tag prefix to versions (only if tag prefix is defined)",
help = "Add tag prefix to versions (only if tag prefix is defined)",
).flag()
private val scope by option(
"-s",
"--scope",
help = "scope to filter release note items",
help = "Scope to filter release note items",
).default("")
private val initialRevision by option(
"-i",
"--initial-revision",
help = "start range from next revision",
help = "Start range from next revision",
).default("")
private val lastRevision by option(
"-l",
"--last-revision",
help = "stop on this revision",
help = "Stop on this revision",
).default("HEAD")

override fun run() {
Expand Down Expand Up @@ -562,6 +563,11 @@ class ReleaseNotes(
name = "releaseNotes",
help = "Prints release notes from git commit messages",
) {
private val asShort by option(
"-s",
"--short",
help = "Switch output to short format to be used as description of git tag",
).flag()
private val config by requireObject<CliConfig>()

override fun run() {
Expand All @@ -577,17 +583,21 @@ class ReleaseNotes(
if (config.asJson) {
Json.encodeToString<GitCommitsParser.ParsedInfo>(parsedInfo)
} else {
formatReleaseNotes(parsedInfo)
formatReleaseNotes(parsedInfo, asShort)
}
println(result)
}

private fun formatReleaseNotes(parsedInfo: GitCommitsParser.ParsedInfo): String {
private fun formatReleaseNotes(
parsedInfo: GitCommitsParser.ParsedInfo,
asShort: Boolean,
): String {
val linesPerGroup = getReleaseLinesPerGroup(parsedInfo)
val features = groupToText("Features", linesPerGroup["Features"])
val fixes = groupToText("Fixes", linesPerGroup["Fixes"])
val other = groupToText("Other", linesPerGroup["Other"])
return listOfNotNull(features, fixes, other).joinToString("\n\n")
val features = groupToText("Features", linesPerGroup["Features"], asShort)
val fixes = groupToText("Fixes", linesPerGroup["Fixes"], asShort)
val other = groupToText("Other", linesPerGroup["Other"], asShort)
val separator = if (asShort) "\n" else "\n\n"
return listOfNotNull(features, fixes, other).joinToString(separator)
}

data class ReleaseLine(
Expand Down Expand Up @@ -626,6 +636,36 @@ class ReleaseNotes(
private fun groupToText(
header: String,
lines: Set<ReleaseLine>?,
asShort: Boolean,
): String? {
if (asShort) {
return groupToTextShort(lines)
}
return groupToTextFull(header, lines)
}

private fun groupToTextShort(lines: Set<ReleaseLine>?): String? {
if (lines.isNullOrEmpty()) return null
val result = mutableListOf<String>()
lines.forEach { line ->
val scope = if (line.scope != "*" && line.scope != null) line.scope else ""
var type =
if (scope.isNotEmpty()) {
"${line.type}($scope)"
} else {
line.type
}
if (type.isNotEmpty()) {
type += ": "
}
result.add("- (${line.sha}) ${type}${line.description}")
}
return result.joinToString("\n")
}

private fun groupToTextFull(
header: String,
lines: Set<ReleaseLine>?,
): String? {
if (lines.isNullOrEmpty()) return null
val result = mutableListOf("### $header\n")
Expand Down
12 changes: 6 additions & 6 deletions tests/results/X-help
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ Usage: git-parse-commits [<options>] <command> [<args>]...
Provides next release version and release notes from git commit messages.

Options:
-j, --json output in json format
-t, --tag-prefix=<text> prefix for tags (optional)
--tag add tag prefix to versions (only if tag prefix is defined)
-s, --scope=<text> scope to filter release note items
-i, --initial-revision=<text> start range from next revision
-l, --last-revision=<text> stop on this revision
-j, --json Output in json format
-t, --tag-prefix=<text> Prefix for tags (optional)
--tag Add tag prefix to versions (only if tag prefix is defined)
-s, --scope=<text> Scope to filter release note items
-i, --initial-revision=<text> Start range from next revision
-l, --last-revision=<text> Stop on this revision
-h, --help Show this message and exit

Commands:
Expand Down
1 change: 1 addition & 0 deletions tests/results/X-releaseNotes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- (3285c7b) feat: something commited
5 changes: 5 additions & 0 deletions tests/results/mono1-releaseNotes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- (6aef24f) feat(component1): something commited
- (a43c63f) feat: Merge branch 'dev/0.4.0-branch'
- (d6720e8) feat(component1): best feature ever
- (871fce1) fix: now it's better for sure
- (28bd0fe) chore(component1): even better
1 change: 1 addition & 0 deletions tests/results/mono2-releaseNotes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions tests/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cd repo
../../git-parse-commits releaseVersion > ../results/X-releaseVersion
../../git-parse-commits -j releaseVersion | jq . > ../results/X-releaseVersion.json
../../git-parse-commits releaseNotes > ../results/X-releaseNotes.md
../../git-parse-commits releaseNotes -s > ../results/X-releaseNotes.txt
../../git-parse-commits -j releaseNotes | jq . > ../results/X-releaseNotes.json

# additional
Expand Down Expand Up @@ -82,10 +83,12 @@ cd ../repo2
../../git-parse-commits -s component1 --tag-prefix component1- lastReleaseVersion > ../results/mono1-lastReleaseVersion
../../git-parse-commits -s component1 --tag-prefix component1- releaseVersion > ../results/mono1-releaseVersion
../../git-parse-commits -s component1 --tag-prefix component1- releaseNotes > ../results/mono1-releaseNotes.md
../../git-parse-commits -s component1 --tag-prefix component1- releaseNotes -s > ../results/mono1-releaseNotes.txt
../../git-parse-commits -s component2 --tag-prefix component2- --tag currentVersion > ../results/mono2-currentVersion
../../git-parse-commits -s component2 --tag-prefix component2- --tag lastReleaseVersion > ../results/mono2-lastReleaseVersion
../../git-parse-commits -s component2 --tag-prefix component2- --tag releaseVersion > ../results/mono2-releaseVersion
../../git-parse-commits -s component2 --tag-prefix component2- --tag releaseNotes > ../results/mono2-releaseNotes.md
../../git-parse-commits -s component2 --tag-prefix component2- --tag releaseNotes -s > ../results/mono2-releaseNotes.txt

# no tags case
cd ../repo4
Expand Down

0 comments on commit e9242a2

Please sign in to comment.