Skip to content

Commit fe4d872

Browse files
author
pepicrft
committed
fix(ci): only release on feat / fix / perf / refactor commits
The decide job was returning release=true for a chore: commit because cliff.toml had no commit_parsers and filter_commits was false, so git-cliff treated every conventional commit (chore, ci, docs, test, style) as bump-worthy. Add explicit parsers that: - Group feat / fix / perf / refactor under release sections. - Skip chore / ci / docs / test / style / build entirely. - Skip anything else as a catch-all. Set filter_commits = true so skipped commits do not contribute to either the changelog or git-cliff's bump calculation. Also harden the workflow's decide step against three failure modes of git-cliff --bumped-version observed locally: (a) git-cliff prints "There is nothing to bump" on stderr but still emits the previous tag on stdout. Detect that signal directly. (b) The proposed version equals the latest tag. (c) The proposed version is <= the latest tag (sort -V), which can happen when git-cliff's notion of "latest" excludes our own chore(release): bump commits. Any of these means "skip release", with explicit log lines so it is obvious from the run summary why nothing shipped.
1 parent 4973a3b commit fe4d872

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

.github/workflows/release.yml

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,48 @@ jobs:
4949
exit 0
5050
fi
5151
52-
NEXT="$(git-cliff --config cliff.toml --bumped-version 2>/dev/null || true)"
52+
# Capture both stdout (the version string) and stderr (where
53+
# git-cliff says "There is nothing to bump") in one go.
54+
GC_OUT="$(git-cliff --config cliff.toml --bumped-version 2>&1 || true)"
55+
NEXT="$(printf '%s\n' "$GC_OUT" | tail -n1)"
5356
LATEST="$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || true)"
5457
55-
echo "Latest tag: ${LATEST:-(none)}"
58+
echo "Latest tag: ${LATEST:-(none)}"
5659
echo "git-cliff bumped-version: ${NEXT:-(none)}"
5760
61+
# Three reasons to skip:
62+
# (a) git-cliff explicitly said nothing bumps;
63+
# (b) git-cliff returned the same string as the latest tag;
64+
# (c) git-cliff returned a version <= the latest tag (it
65+
# can do this when the "latest" tag points at a commit
66+
# whose only contents are filtered, e.g. our own
67+
# chore(release): bump commit).
68+
if printf '%s\n' "$GC_OUT" | grep -q "nothing to bump"; then
69+
echo "git-cliff: nothing to bump; skipping release."
70+
echo "release=false" >> "$GITHUB_OUTPUT"
71+
exit 0
72+
fi
73+
5874
if [[ -z "$NEXT" || "$NEXT" == "$LATEST" ]]; then
59-
echo "No releasable commits since last tag; skipping."
75+
echo "No new version proposed; skipping release."
6076
echo "release=false" >> "$GITHUB_OUTPUT"
61-
else
62-
VERSION="${NEXT#v}"
63-
echo "Will release ${NEXT}"
64-
echo "release=true" >> "$GITHUB_OUTPUT"
65-
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
77+
exit 0
78+
fi
79+
80+
if [[ -n "$LATEST" ]]; then
81+
HIGHEST="$(printf '%s\n%s\n' "$LATEST" "$NEXT" | sort -V | tail -n1)"
82+
if [[ "$HIGHEST" == "$LATEST" ]]; then
83+
echo "Proposed ${NEXT} is not greater than ${LATEST}; skipping release."
84+
echo "release=false" >> "$GITHUB_OUTPUT"
85+
exit 0
86+
fi
6687
fi
6788
89+
VERSION="${NEXT#v}"
90+
echo "Will release ${NEXT}"
91+
echo "release=true" >> "$GITHUB_OUTPUT"
92+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
93+
6894
build_nif:
6995
name: NIF ${{ matrix.job.target }}
7096
needs: decide

cliff.toml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,26 @@ split_commits = false
7575
commit_preprocessors = [
7676
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" },
7777
]
78+
# Only feat / fix / perf / refactor commits are release-worthy. Anything
79+
# else (chore, ci, docs, test, style, build) is filtered out so that
80+
# git-cliff's --bumped-version returns the current version when nothing
81+
# user-visible changed, and the workflow's decide job correctly skips
82+
# the release.
83+
commit_parsers = [
84+
{ message = "^feat", group = "Features" },
85+
{ message = "^fix", group = "Bug Fixes" },
86+
{ message = "^perf", group = "Performance" },
87+
{ message = "^refactor", group = "Refactor" },
88+
{ message = "^chore", skip = true },
89+
{ message = "^ci", skip = true },
90+
{ message = "^docs?", skip = true },
91+
{ message = "^test", skip = true },
92+
{ message = "^style", skip = true },
93+
{ message = "^build", skip = true },
94+
{ message = ".*", skip = true },
95+
]
7896
protect_breaking_commits = false
79-
filter_commits = false
97+
filter_commits = true
8098
tag_pattern = "v[0-9].*"
8199
skip_tags = "beta|alpha"
82100
ignore_tags = "rc"

0 commit comments

Comments
 (0)