1
0
forked from wrenn/wrenn

2 Commits

Author SHA1 Message Date
e503afbc0f CI Test 3
All checks were successful
ci/woodpecker/push/pipeline Pipeline was successful
2026-05-22 01:31:40 +06:00
2f167f406c v0.1.6 (#45)
## What's New?
Performance updates for large capsules, admin panel enhancement and bug fixes

### Envd
- Fixed bug with sandbox metrics calculation
- Page cache drop and balloon inflation to reduce memfile snapshot
- Updated rpc timeout logic for better control
- Added tests

### Admin Panel
- Add/Remove platform admin
- Updated template deletion logic for fine grained permission

### Others
- Minor frontend visual improvement
- Minor bugfixes
- Version bump

Co-authored-by: Tasnim Kabir Sadik <tksadik92@gmail.com>
Reviewed-on: wrenn/wrenn#45
Co-authored-by: pptx704 <rafeed@omukk.dev>
Co-committed-by: pptx704 <rafeed@omukk.dev>
2026-05-22 01:27:00 +06:00
4 changed files with 93 additions and 70 deletions

2
.gitignore vendored
View File

@ -55,5 +55,3 @@ internal/dashboard/static/*
.dual-graph/
# Added by code-review-graph
.code-review-graph/
__pycache__

View File

@ -21,6 +21,7 @@ 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: []

View File

@ -73,7 +73,6 @@ 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:
@ -85,17 +84,6 @@ 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",
background=True,
@ -118,23 +106,6 @@ 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

View File

@ -105,32 +105,73 @@ 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 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 = 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_b64 = base64.b64encode(prompt.encode("utf-8")).decode("utf-8")
@ -145,23 +186,22 @@ 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"> {output_path}"
f"> {raw_output_path}"
)
cmd_result = capsule.commands.run(cmd, cwd=REPO_DIR, timeout=120)
cmd_result = capsule.commands.run(cmd, cwd=REPO_DIR, timeout=300)
if cmd_result.exit_code != 0:
print(
f"FAIL [opencode via {target_model}]: exit={cmd_result.exit_code}",
@ -170,6 +210,30 @@ 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
@ -220,24 +284,13 @@ 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,
current_tag,
git_log,
git_diff,
output_path,
model,
)
generate_release_notes(capsule, output_path, model)
download_release_notes(capsule)