first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Convert changelog-draft.json to the release-pipeline-compatible changelog-release.json.
|
||||
|
||||
Reads the audit artifact produced by the changelog-draft skill and emits the
|
||||
flat JSON structure consumed by the create_release workflow (Slack payload
|
||||
builder + in-app changelog.json step).
|
||||
|
||||
Usage:
|
||||
python3 convert_to_release_json.py --input <changelog-draft.json> --output <changelog-release.json>
|
||||
|
||||
The output schema:
|
||||
{
|
||||
"newFeatures": ["..."],
|
||||
"improvements": ["..."],
|
||||
"bugFixes": ["..."],
|
||||
"images": ["..."],
|
||||
"oz_updates": ["..."]
|
||||
}
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
|
||||
# Map from changelog-draft.json category names to release JSON keys.
|
||||
CATEGORY_MAP = {
|
||||
"NEW-FEATURE": "newFeatures",
|
||||
"IMPROVEMENT": "improvements",
|
||||
"BUG-FIX": "bugFixes",
|
||||
"OZ": "oz_updates",
|
||||
"IMAGE": "images",
|
||||
}
|
||||
|
||||
|
||||
def github_profile_link(username: str) -> str:
|
||||
"""Format a GitHub username as a markdown profile link."""
|
||||
return f"[@{username}](https://github.com/{username})"
|
||||
|
||||
|
||||
def format_entry(entry: dict) -> str:
|
||||
"""Format a single changelog entry as a text line with a PR link.
|
||||
|
||||
Includes external contributor attribution when applicable.
|
||||
"""
|
||||
text = entry["text"]
|
||||
pr_number = entry.get("pr_number") or entry.get("number")
|
||||
url = entry.get("url") or entry.get("pr_url")
|
||||
|
||||
link = ""
|
||||
if url and pr_number:
|
||||
link = f" ([#{pr_number}]({url}))"
|
||||
|
||||
attribution = ""
|
||||
if entry.get("is_external") and entry.get("author"):
|
||||
attribution = f" — {github_profile_link(entry['author'])} ✨"
|
||||
return f"{text}{link}{attribution}"
|
||||
|
||||
|
||||
def convert(draft: dict) -> dict:
|
||||
"""Convert a changelog-draft.json dict to changelog-release.json dict."""
|
||||
release: dict[str, list[str]] = {
|
||||
"newFeatures": [],
|
||||
"improvements": [],
|
||||
"bugFixes": [],
|
||||
"images": [],
|
||||
"oz_updates": [],
|
||||
}
|
||||
|
||||
for entry in draft.get("entries", []):
|
||||
category = entry.get("category", "")
|
||||
release_key = CATEGORY_MAP.get(category)
|
||||
if release_key is None:
|
||||
continue
|
||||
|
||||
if category == "IMAGE":
|
||||
# IMAGE entries store a URL in "text" — pass through directly.
|
||||
release["images"].append(entry["text"])
|
||||
else:
|
||||
release[release_key].append(format_entry(entry))
|
||||
|
||||
return release
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Convert changelog-draft.json to changelog-release.json"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input",
|
||||
required=True,
|
||||
help="Path to changelog-draft.json",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
required=True,
|
||||
help="Path to write changelog-release.json",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.input) as f:
|
||||
draft = json.load(f)
|
||||
|
||||
release = convert(draft)
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(release, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
# Summary to stdout for CI logs
|
||||
for key, items in release.items():
|
||||
print(f" {key}: {len(items)} entries")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user