updated changelog.

This commit is contained in:
Abdul.Mohsen B. A. A. 2026-04-27 21:01:10 +00:00
parent b88f821093
commit f6e1fac0c1
2 changed files with 62 additions and 61 deletions

View file

@ -1,6 +1,6 @@
[ [
{ {
"tag": "Unmerged (dev branch)", "tag": "Untagged",
"full_sha": "084f5082ad174e6a6d725db03a8da9d9afbaef7e", "full_sha": "084f5082ad174e6a6d725db03a8da9d9afbaef7e",
"date": "2026-04-27T17:58:00+00:00", "date": "2026-04-27T17:58:00+00:00",
"commits": [ "commits": [

View file

@ -38,6 +38,48 @@ def sanitize_commit_message(message):
return "\n".join(lines).strip() return "\n".join(lines).strip()
def get_preferred_ref(repo, *names):
"""Return the first matching ref by name."""
refs_by_name = {ref.name: ref for ref in repo.refs}
for name in names:
ref = refs_by_name.get(name)
if ref is not None:
return ref
return None
def add_commits_by_sha(target, commits):
"""Store commits by SHA so overlapping refs only appear once."""
for commit in commits:
target[commit.hexsha] = commit
def build_untagged_entry(commits_by_sha):
"""Create one entry for commits that are not part of a tag yet."""
if not commits_by_sha:
return None
commits = sorted(
commits_by_sha.values(), key=lambda c: c.committed_datetime, reverse=True
)
latest_commit = commits[0]
return {
"tag": "Untagged",
"full_sha": latest_commit.hexsha,
"date": latest_commit.committed_datetime.astimezone(UTC).isoformat(),
"commits": [
{
"sha": c.hexsha[:8],
"full_sha": c.hexsha,
"message": sanitize_commit_message(c.message),
"author": c.author.name,
"date": c.committed_datetime.astimezone(UTC).isoformat(),
}
for c in commits
],
}
def generate_changelog(repo_path, changelog_path): def generate_changelog(repo_path, changelog_path):
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
tags = get_sorted_tags(repo) tags = get_sorted_tags(repo)
@ -45,46 +87,27 @@ def generate_changelog(repo_path, changelog_path):
head_commit = repo.head.commit head_commit = repo.head.commit
head_branch = None head_branch = None
untagged_commits = {}
try: try:
head_branch = repo.active_branch.name head_branch = repo.active_branch.name
except TypeError: except TypeError:
pass # Detached HEAD pass # Detached HEAD
# 🔼 If HEAD is not on 'dev', include unmerged commits from dev # Collect dev commits not yet in main so they share one untagged bucket.
if "dev" in repo.heads and head_branch != "dev": if head_branch != "dev":
try: try:
dev_branch = repo.heads["dev"] dev_branch = get_preferred_ref(repo, "origin/dev", "dev")
main_branch_name = "main" if "main" in repo.heads else "master" main_branch = get_preferred_ref(
main_branch = repo.heads[main_branch_name] repo, "origin/main", "origin/master", "main", "master"
unmerged_commits = list(
repo.iter_commits(
f"{main_branch.name}..{dev_branch.name}", no_merges=True
)
) )
if unmerged_commits:
changelog.insert( if dev_branch is not None and main_branch is not None:
0, unmerged_commits = list(
{ repo.iter_commits(
"tag": f"Unmerged ({dev_branch.name} branch)", f"{main_branch.name}..{dev_branch.name}", no_merges=True
"full_sha": dev_branch.commit.hexsha, )
"date": dev_branch.commit.committed_datetime.astimezone(
UTC
).isoformat(),
"commits": [
{
"sha": c.hexsha[:8],
"full_sha": c.hexsha,
"message": sanitize_commit_message(c.message),
"author": c.author.name,
"date": c.committed_datetime.astimezone(
UTC
).isoformat(),
}
for c in unmerged_commits
],
},
) )
add_commits_by_sha(untagged_commits, unmerged_commits)
except Exception as e: except Exception as e:
print(f"[WARN] Could not get unmerged dev commits: {e}", file=sys.stderr) print(f"[WARN] Could not get unmerged dev commits: {e}", file=sys.stderr)
@ -134,39 +157,17 @@ def generate_changelog(repo_path, changelog_path):
} }
) )
# Unreleased changes after latest tag # Collect commits after the latest tag into the same untagged bucket.
if head_commit.hexsha != tags[0].commit.hexsha: if head_commit.hexsha != tags[0].commit.hexsha:
commits = get_commits_between( commits = get_commits_between(
repo, tags[0].commit.hexsha, head_commit.hexsha repo, tags[0].commit.hexsha, head_commit.hexsha
) )
if commits: if commits:
unreleased_label = ( add_commits_by_sha(untagged_commits, commits)
f"Unreleased ({head_branch})"
if head_branch untagged_entry = build_untagged_entry(untagged_commits)
else f"Unreleased ({head_commit.hexsha[:8]})" if untagged_entry:
) changelog.insert(0, untagged_entry)
changelog.insert(
0,
{
"tag": unreleased_label,
"full_sha": head_commit.hexsha,
"date": head_commit.committed_datetime.astimezone(
UTC
).isoformat(),
"commits": [
{
"sha": c.hexsha[:8],
"full_sha": c.hexsha,
"message": sanitize_commit_message(c.message),
"author": c.author.name,
"date": c.committed_datetime.astimezone(
UTC
).isoformat(),
}
for c in commits
],
},
)
with open(changelog_path, "w", encoding="utf-8") as f: with open(changelog_path, "w", encoding="utf-8") as f:
json.dump(changelog, f, indent=2) json.dump(changelog, f, indent=2)