forked from wrenn/wrenn
Compare commits
2 Commits
main
...
10148f5b06
| Author | SHA1 | Date | |
|---|---|---|---|
| 10148f5b06 | |||
| a5720d7673 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -55,3 +55,5 @@ internal/dashboard/static/*
|
||||
.dual-graph/
|
||||
# Added by code-review-graph
|
||||
.code-review-graph/
|
||||
|
||||
__pycache__
|
||||
|
||||
@ -21,7 +21,6 @@ steps:
|
||||
from_secret: wrenn_api_key
|
||||
commands:
|
||||
- pip install wrenn
|
||||
- export RUST_VERSION=$$(grep '^rust-version ' envd-rs/Cargo.toml | cut -d'"' -f2)
|
||||
- python .woodpecker/scripts/build_rust.py
|
||||
depends_on: []
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ def install_rust(capsule: Capsule) -> bool:
|
||||
def clone_repo(capsule: Capsule) -> bool:
|
||||
try:
|
||||
capsule.git.clone(REPO_URL, REPO_DIR)
|
||||
capsule.commands.run(f"cd {REPO_DIR} && git checkout fix/large-operations")
|
||||
print("OK [git clone]")
|
||||
return True
|
||||
except GitCommandError as e:
|
||||
@ -84,8 +85,19 @@ def build_rust(capsule: Capsule) -> bool:
|
||||
if run(capsule, f"mkdir -p {REPO_DIR}/builds") != 0:
|
||||
return False
|
||||
|
||||
# result = capsule.commands.run("file --version")
|
||||
# print(result.stdout)
|
||||
# result = capsule.commands.run(
|
||||
# 'git rev-parse --short HEAD 2>/dev/null || echo "unknown"'
|
||||
# )
|
||||
# commit = result.stdout
|
||||
|
||||
# run(capsule, f"mkdir -p {REPO_DIR}/builds")
|
||||
# result = capsule.commands.run("which musl-gcc")
|
||||
# print(result.stdout)
|
||||
|
||||
handle = capsule.commands.run(
|
||||
"make build-envd",
|
||||
"git checkout fix/large-operations && make build-envd",
|
||||
background=True,
|
||||
cwd=REPO_DIR,
|
||||
envs={"PATH": RUST_PATH},
|
||||
@ -106,6 +118,23 @@ def build_rust(capsule: Capsule) -> bool:
|
||||
return False
|
||||
|
||||
print("OK [rust build]")
|
||||
|
||||
# if (
|
||||
# run(
|
||||
# capsule,
|
||||
# f"cp {REPO_DIR}/envd-rs/target/x86_64-unknown-linux-musl/release/envd {REPO_DIR}/builds/envd",
|
||||
# envs={"BIN_DIR": REPO_DIR},
|
||||
# )
|
||||
# != 0
|
||||
# ):
|
||||
# return False
|
||||
|
||||
# result = capsule.commands.run(f"readelf -d {REPO_DIR}/builds/envd 2>&1")
|
||||
# print(result.stdout, end="")
|
||||
# if result.stderr:
|
||||
# print(result.stderr, end="", file=sys.stderr)
|
||||
# result = capsule.commands.run(f"file {REPO_DIR}/builds/envd 2>&1")
|
||||
# print(result.stdout)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@ -105,73 +105,32 @@ def get_git_context(
|
||||
|
||||
def generate_release_notes(
|
||||
capsule: Capsule,
|
||||
current_tag: str,
|
||||
git_log: str,
|
||||
git_diff: str,
|
||||
output_path: str,
|
||||
model: str,
|
||||
) -> None:
|
||||
prompt = f"""
|
||||
You are inside a cloned git repository at:
|
||||
|
||||
{REPO_DIR}
|
||||
|
||||
Generate release notes for the latest tagged version of this software project.
|
||||
|
||||
Before writing anything, inspect the repository yourself using git commands.
|
||||
|
||||
You MUST determine:
|
||||
1. The latest version tag.
|
||||
2. The previous version tag, if one exists.
|
||||
3. The commits between the previous tag and the latest tag.
|
||||
4. The files and areas changed between those tags.
|
||||
|
||||
Use commands like:
|
||||
|
||||
git tag --sort=-version:refname
|
||||
|
||||
If there are at least two tags, compare the newest tag against the previous tag:
|
||||
|
||||
git log PREVIOUS_TAG..LATEST_TAG --pretty=format:'%s (%h)'
|
||||
git diff PREVIOUS_TAG..LATEST_TAG --stat
|
||||
git diff PREVIOUS_TAG..LATEST_TAG --name-only
|
||||
|
||||
If there is only one tag, inspect the latest tag with:
|
||||
|
||||
git log LATEST_TAG --pretty=format:'%s (%h)' -n 50
|
||||
git show LATEST_TAG --stat
|
||||
git show LATEST_TAG --name-only
|
||||
|
||||
Do not rely on any pre-injected commit list or diff summary.
|
||||
You must inspect the git history yourself.
|
||||
|
||||
Write the release notes in plain, friendly language that any developer can understand
|
||||
without deep knowledge of the codebase.
|
||||
|
||||
Avoid jargon like "goroutine", "PTY", "envd", or internal function names.
|
||||
Describe what the change means for the user instead.
|
||||
|
||||
Group related changes under headings that reflect what actually changed.
|
||||
Only include sections that are relevant to the actual changes.
|
||||
Do not include CI/CD-only changes.
|
||||
|
||||
Start with:
|
||||
|
||||
## What's New
|
||||
|
||||
The very next line must be a single short summary sentence.
|
||||
|
||||
Keep each bullet point to one clear sentence.
|
||||
|
||||
Here is an example of the style to aim for — not a template to copy:
|
||||
|
||||
{RELEASE_NOTES_EXAMPLE}
|
||||
|
||||
Output only the final markdown.
|
||||
No intro.
|
||||
No explanation.
|
||||
No conversational filler.
|
||||
No acknowledgments.
|
||||
No "I checked the logs" text.
|
||||
No thoughts.
|
||||
""".strip()
|
||||
prompt = (
|
||||
f"You are writing release notes for version {current_tag} of a software project.\n\n"
|
||||
f"Here is what changed between the previous version and this one:\n\n"
|
||||
f"Commit messages:\n{git_log}\n\n"
|
||||
f"Files and areas that changed:\n{git_diff}\n\n"
|
||||
f"Write the release notes in plain, friendly language that any developer can understand "
|
||||
f"without deep knowledge of the codebase. Avoid jargon like 'goroutine', 'PTY', 'envd', "
|
||||
f"or internal function names — describe what the change means for the user instead. "
|
||||
f"Group related changes under headings that reflect what actually changed. "
|
||||
f"Only include sections that are relevant to these specific changes. "
|
||||
f"Start with a short one-line summary of what this release is about. "
|
||||
f"Keep each bullet point to one clear sentence.\n\n"
|
||||
f"Here is an example of the style to aim for — not a template to copy:\n\n"
|
||||
f"{RELEASE_NOTES_EXAMPLE}\n\n"
|
||||
f"You MUST start the document with `## What's New`\n"
|
||||
f"The very next line MUST be a single short summary sentence.\n"
|
||||
f"Output only the markdown. No intro, no explanation."
|
||||
f"CRITICAL: Do not output any conversational filler, acknowledgments, or thoughts "
|
||||
f"like 'Let me look at the changes'. Output absolutely nothing except the final markdown."
|
||||
)
|
||||
|
||||
prompt_b64 = base64.b64encode(prompt.encode("utf-8")).decode("utf-8")
|
||||
|
||||
@ -186,22 +145,23 @@ def generate_release_notes(
|
||||
print(f"FAIL [write prompt]: {result.stderr}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# FIX: Wrapper function to handle execution and authentication dynamically
|
||||
def run_opencode_with_model(target_model: str) -> int:
|
||||
env = ""
|
||||
if "zhipu" in target_model.lower():
|
||||
env = f"ZHIPU_API_KEY={os.environ.get('ZHIPU_API_KEY', '')}"
|
||||
|
||||
raw_output_path = "/tmp/opencode_raw.txt"
|
||||
cmd = (
|
||||
f"{env} "
|
||||
f"~/.opencode/bin/opencode run "
|
||||
f'"Read the attached file and generate the release notes. Output ONLY markdown." '
|
||||
f"--model {target_model} "
|
||||
f"--file /tmp/oc_prompt.txt "
|
||||
f"> {raw_output_path}"
|
||||
f"> {output_path}"
|
||||
)
|
||||
|
||||
cmd_result = capsule.commands.run(cmd, cwd=REPO_DIR, timeout=300)
|
||||
cmd_result = capsule.commands.run(cmd, cwd=REPO_DIR, timeout=120)
|
||||
|
||||
if cmd_result.exit_code != 0:
|
||||
print(
|
||||
f"FAIL [opencode via {target_model}]: exit={cmd_result.exit_code}",
|
||||
@ -210,30 +170,6 @@ def generate_release_notes(
|
||||
print(f"STDOUT:\n{cmd_result.stdout}", file=sys.stderr)
|
||||
print(f"STDERR:\n{cmd_result.stderr}", file=sys.stderr)
|
||||
|
||||
clean_cmd = (
|
||||
f"awk 'found || /^## What.s [Nn]ew/ {{ found=1; print }}' "
|
||||
f"{raw_output_path} > {output_path}"
|
||||
)
|
||||
|
||||
clean_result = capsule.commands.run(clean_cmd, cwd=REPO_DIR, timeout=10)
|
||||
if clean_result.exit_code != 0:
|
||||
print(f"FAIL [clean output]: {clean_result.stderr}", file=sys.stderr)
|
||||
return clean_result.exit_code
|
||||
|
||||
check_result = capsule.commands.run(
|
||||
f"grep -q '^## What.s New' {output_path}",
|
||||
cwd=REPO_DIR,
|
||||
timeout=10,
|
||||
)
|
||||
if check_result.exit_code != 0:
|
||||
print(
|
||||
"FAIL: Could not find release notes heading in opencode output",
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(cmd_result.stdout, file=sys.stderr)
|
||||
print(cmd_result.stderr, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return cmd_result.exit_code
|
||||
|
||||
# First attempt with the target model
|
||||
@ -284,13 +220,24 @@ def main() -> None:
|
||||
capsule.git.clone(
|
||||
REPO_URL,
|
||||
REPO_DIR,
|
||||
username="tksadik92",
|
||||
)
|
||||
print("OK [git clone]")
|
||||
|
||||
current_tag, previous_tag = get_tags(capsule)
|
||||
git_log, git_diff = get_git_context(capsule, current_tag, previous_tag)
|
||||
|
||||
# Note: This simply creates the directory string safely
|
||||
output_path = os.path.normpath(CAPSULE_OUTPUT)
|
||||
|
||||
generate_release_notes(capsule, output_path, model)
|
||||
generate_release_notes(
|
||||
capsule,
|
||||
current_tag,
|
||||
git_log,
|
||||
git_diff,
|
||||
output_path,
|
||||
model,
|
||||
)
|
||||
|
||||
download_release_notes(capsule)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user