Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions .github/scripts/update_renovate_changelogs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env python3
import argparse
import re
import subprocess
import sys
import tomllib
from pathlib import Path

KEY_MAPPING = {
("versions", "jackson"): "jackson",
("versions", "ktlint"): "ktlint",
("versions", "javaparser"): "javaparser",
("libraries", "palantir-java-format-default"): "palantir-java-format",
("libraries", "adocfmt"): "adocfmt",
("libraries", "antlr4-formatter"): "antlr4-formatter",
("libraries", "cleanthat-java"): "cleanthat",
("libraries", "cool-rdf-formatter"): "cool-rdf-formatter",
("libraries", "diktat-runner"): "diktat",
("libraries", "flexmark-all"): "flexmark",
("libraries", "freshmark"): "freshmark",
("libraries", "gherkin-utils"): "gherkin-utils",
("libraries", "google-java-format"): "google-java-format",
("libraries", "gson"): "gson",
("libraries", "json-simple"): "json-simple",
("libraries", "ktfmt"): "ktfmt",
("libraries", "prince-of-space-core"): "prince-of-space",
("libraries", "scalafmt-core"): "scalafmt",
("libraries", "sortpom-sorter"): "sortpom",
("libraries", "tabletest-formatter-core"): "tabletest-formatter",
("libraries", "zjsonpatch"): "zjsonpatch",
}

CHANGELOG_FILES = [
Path("CHANGES.md"),
Path("plugin-gradle/CHANGES.md"),
Path("plugin-maven/CHANGES.md"),
]


def extract_formatter_versions(toml_str: str) -> dict[str, str]:
data = tomllib.loads(toml_str)
versions = data.get("versions", {})
libraries = data.get("libraries", {})
result = {}
for (sec, key), tool_name in KEY_MAPPING.items():
if sec == "versions":
if key in versions:
result[tool_name] = str(versions[key])
elif sec == "libraries":
if key in libraries:
val = libraries[key]
if isinstance(val, str):
parts = val.split(":")
if len(parts) >= 3:
result[tool_name] = parts[-1]
elif isinstance(val, dict):
if "version" in val:
result[tool_name] = str(val["version"])
elif "version.ref" in val and val["version.ref"] in versions:
result[tool_name] = str(versions[val["version.ref"]])
return result


def insert_changelog_entries(content: str, entries: list[str]) -> str:
unreleased_match = re.search(r"(##\s*\[Unreleased\]\s*\n+)", content)
if not unreleased_match:
return content

unreleased_start = unreleased_match.end()
next_release_match = re.search(r"\n##\s*\[", content[unreleased_start:])
if next_release_match:
unreleased_end = unreleased_start + next_release_match.start()
unreleased_block = content[unreleased_start:unreleased_end]
after_block = content[unreleased_end:]
else:
unreleased_block = content[unreleased_start:]
after_block = ""

new_entries = [e for e in entries if e not in unreleased_block]
if not new_entries:
return content

entries_text = "\n".join(new_entries)

changes_match = re.search(r"(###\s*Changes\s*\n)", unreleased_block)
if changes_match:
changes_header_end = changes_match.end()
# Find the end of ### Changes section (either next ### or next ## or end of block)
next_section_match = re.search(r"\n(###\s+\w+|##\s*\[)", unreleased_block[changes_header_end:])
if next_section_match:
changes_end = changes_header_end + next_section_match.start()
changes_content = unreleased_block[changes_header_end:changes_end].rstrip()
rest = unreleased_block[changes_end:].lstrip("\n")
unreleased_block = (
unreleased_block[:changes_header_end]
+ (changes_content + "\n" if changes_content else "")
+ entries_text
+ "\n\n"
+ rest
)
else:
changes_content = unreleased_block[changes_header_end:].rstrip()
unreleased_block = (
unreleased_block[:changes_header_end]
+ (changes_content + "\n" if changes_content else "")
+ entries_text
+ "\n\n"
)
else:
if unreleased_block.strip():
unreleased_block = "### Changes\n" + entries_text + "\n\n" + unreleased_block.lstrip()
else:
unreleased_block = "### Changes\n" + entries_text + "\n\n"

return content[:unreleased_start] + unreleased_block + after_block


def main() -> None:
parser = argparse.ArgumentParser(description="Update changelog files for Renovate version bumps.")
parser.add_argument("--base-ref", default="origin/main", help="Base ref or branch name to compare against")
parser.add_argument("--pr-number", required=True, help="Pull Request number")
parser.add_argument("--pr-url", required=True, help="Pull Request URL")
args = parser.parse_args()

toml_path = Path("gradle/libs.versions.toml")
if not toml_path.exists():
print(f"Error: {toml_path} does not exist.")
sys.exit(1)

head_content = toml_path.read_text(encoding="utf-8")

# Find the merge base commit between base_ref and HEAD so that only changes in this PR are considered
merge_base_proc = subprocess.run(
["git", "merge-base", args.base_ref, "HEAD"],
capture_output=True,
text=True,
)
if merge_base_proc.returncode == 0 and merge_base_proc.stdout.strip():
compare_ref = merge_base_proc.stdout.strip()
else:
compare_ref = args.base_ref

git_show_cmd = ["git", "show", f"{compare_ref}:gradle/libs.versions.toml"]
proc = subprocess.run(git_show_cmd, capture_output=True, text=True)
if proc.returncode != 0:
print(f"Warning: Failed to fetch base toml from {compare_ref}: {proc.stderr}")
sys.exit(0)

base_content = proc.stdout

base_versions = extract_formatter_versions(base_content)
head_versions = extract_formatter_versions(head_content)

entries = []
for tool_name, new_ver in head_versions.items():
old_ver = base_versions.get(tool_name)
if old_ver and old_ver != new_ver:
entry = f"- Bump default `{tool_name}` version `{old_ver}` -> `{new_ver}`. ([#{args.pr_number}]({args.pr_url}))"
entries.append(entry)

if not entries:
print("No formatter default versions changed in this branch.")
return

print(f"Detected {len(entries)} formatter version update(s):")
for entry in entries:
print(f" {entry}")

for changelog_file in CHANGELOG_FILES:
if not changelog_file.exists():
continue
original = changelog_file.read_text(encoding="utf-8")
updated = insert_changelog_entries(original, entries)
if updated != original:
changelog_file.write_text(updated, encoding="utf-8")
print(f"Updated {changelog_file}")
else:
print(f"No changes needed for {changelog_file}")


if __name__ == "__main__":
main()
41 changes: 41 additions & 0 deletions .github/workflows/renovate-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Renovate Changelog Updater

on:
pull_request:
types: [ opened, synchronize, reopened ]
paths:
- 'gradle/libs.versions.toml'

jobs:
update-changelog:
name: Update Changelog
if: github.actor == 'renovate[bot]' || startsWith(github.head_ref, 'renovate/')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Update Changelogs
run: |
python3 .github/scripts/update_renovate_changelogs.py \
--base-ref "origin/${{ github.base_ref }}" \
--pr-number "${{ github.event.pull_request.number }}" \
--pr-url "${{ github.event.pull_request.html_url }}"
- name: Commit and push changes
run: |
if [ -n "$(git status --porcelain CHANGES.md plugin-gradle/CHANGES.md plugin-maven/CHANGES.md)" ]; then
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add CHANGES.md plugin-gradle/CHANGES.md plugin-maven/CHANGES.md
git commit -m "Update changelogs for default formatter version bump (#${{ github.event.pull_request.number }})"
git push origin HEAD:${{ github.head_ref }}
else
echo "No changelog updates needed."
fi
21 changes: 21 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
jdk-release = "17"
durian = "1.2.0"
selfie = "3.1.1"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
jackson = "2.20.1"
maven-api = "3.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
ktlint = "1.8.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
javaparser = "3.27.1"

[libraries]
Expand All @@ -31,6 +34,7 @@ ktlint-ruleset-standard = { module = "com.pinterest.ktlint:ktlint-ruleset-standa
javaparser-core = { module = "com.github.javaparser:javaparser-core", version.ref = "javaparser" }
javaparser-symbol-solver-core = { module = "com.github.javaparser:javaparser-symbol-solver-core", version.ref = "javaparser" }

# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
palantir-java-format-default = "com.palantir.javaformat:palantir-java-format:2.80.0"

jgit = "org.eclipse.jgit:org.eclipse.jgit:7.7.1.202607240634-r"
Expand All @@ -49,24 +53,41 @@ plexus-build-api = "org.sonatype.plexus:plexus-build-api:0.0.7"
concurrent-trees = "com.googlecode.concurrent-trees:concurrent-trees:2.6.1"
owasp-encoder = "org.owasp.encoder:encoder:1.4.0"
mustache-compiler = "com.github.spullara.mustache.java:compiler:0.9.14"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
adocfmt = "org.drjekyll:adocfmt:0.3.1"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
antlr4-formatter = "com.khubla.antlr4formatter:antlr4-formatter:1.2.1"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
cleanthat-java = "io.github.solven-eu.cleanthat:java:2.25"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
cool-rdf-formatter = "cool.rdf:cool-rdf-formatter:2.0.1"
diktat-rules = "org.cqfn.diktat:diktat-rules:1.2.5"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
diktat-runner = "com.saveourtool.diktat:diktat-runner:2.0.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
flexmark-all = "com.vladsch.flexmark:flexmark-all:0.64.8"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
freshmark = "com.diffplug.freshmark:freshmark:1.3.1"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
gherkin-utils = "io.cucumber:gherkin-utils:10.0.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
google-java-format = "com.google.googlejavaformat:google-java-format:1.30.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
gson = "com.google.code.gson:gson:2.14.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
json-simple = "org.json:json:20210307"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
ktfmt = "com.facebook:ktfmt:0.63"
palantir-java-format = "com.palantir.javaformat:palantir-java-format:1.1.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
prince-of-space-core = "io.github.agustafson.princeofspace:prince-of-space-core:2.2.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
scalafmt-core = "org.scalameta:scalafmt-core_2.13:3.8.1"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
sortpom-sorter = "com.github.ekryd.sortpom:sortpom-sorter:4.0.0"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
tabletest-formatter-core = "org.tabletest:tabletest-formatter-core:1.1.2"
# When updating this version, remember to update CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md.
zjsonpatch = "com.flipkart.zjsonpatch:zjsonpatch:0.4.16"

rewrite-recipe-migrate-java = "org.openrewrite.recipe:rewrite-migrate-java:3.36.0"
Expand Down