From fa1062b15cb9cff1b578de161741b13fe1f5a613 Mon Sep 17 00:00:00 2001 From: Ricardo Mancinas Date: Fri, 2 Oct 2026 23:14:52 -0700 Subject: [PATCH] fix: drop unparseable inline fallback from action.yml The heredoc Python sat at column 0 inside the run: block, so every consumer failed with "yaml: line 93: could not find expected ':'". scripts/generate_notes.py ships with the action and covers it. Co-Authored-By: Claude Opus 5.5 --- action.yml | 80 +----------------------------------------------------- 1 file changed, 1 insertion(+), 79 deletions(-) diff --git a/action.yml b/action.yml index c7f385d..e1765ce 100644 --- a/action.yml +++ b/action.yml @@ -85,82 +85,4 @@ runs: INPUT_SYSTEM_PROMPT: ${{ inputs.system_prompt }} INPUT_SAVE_TO_FILE: ${{ inputs.save_to_file }} run: | - SCRIPT_PATH="${{ github.action_path }}/scripts/generate_notes.py" - if [[ -f "$SCRIPT_PATH" ]]; then - python3 "$SCRIPT_PATH" - else - python3 - << 'PYEOF' -import os, sys, subprocess, json, urllib.request, re, uuid - -api_key = os.environ.get("INPUT_API_KEY", "") -base_url = os.environ.get("INPUT_BASE_URL", "https://omni.freakma.com/v1").rstrip("/") -model = os.environ.get("INPUT_MODEL", "auto/fast") -version = os.environ.get("INPUT_VERSION", "") -from_ref = os.environ.get("INPUT_FROM_REF", "") -to_ref = os.environ.get("INPUT_TO_REF", "HEAD") -tag_pattern = os.environ.get("INPUT_TAG_PATTERN", "v*") -max_commits = int(os.environ.get("INPUT_MAX_COMMITS", "50")) -fallback = os.environ.get("INPUT_FALLBACK_NOTES", "Maintenance updates and performance improvements.") -timeout = int(os.environ.get("INPUT_TIMEOUT", "25")) -temp = float(os.environ.get("INPUT_TEMPERATURE", "0.2")) -sys_prompt = os.environ.get("INPUT_SYSTEM_PROMPT", "") -save_file = os.environ.get("INPUT_SAVE_TO_FILE", "") - -subprocess.run(["git", "fetch", "--tags", "--prune"], capture_output=True) - -if not from_ref: - if version: - target_tag = version if version.startswith("v") else f"v{version}" - res = subprocess.run(["git", "describe", "--tags", f"--match={tag_pattern}", "--abbrev=0", f"{target_tag}^"], capture_output=True, text=True) - if res.returncode == 0 and res.stdout.strip(): - from_ref = res.stdout.strip() - if not from_ref: - code, out = subprocess.run(["git", "describe", "--tags", f"--match={tag_pattern}", "--exact-match", to_ref], capture_output=True, text=True).returncode, "" - if code == 0: - res = subprocess.run(["git", "describe", "--tags", f"--match={tag_pattern}", "--abbrev=0", f"{to_ref}^"], capture_output=True, text=True) - if res.returncode == 0 and res.stdout.strip(): - from_ref = res.stdout.strip() - if not from_ref: - res = subprocess.run(["git", "describe", "--tags", f"--match={tag_pattern}", "--abbrev=0", to_ref], capture_output=True, text=True) - if res.returncode == 0 and res.stdout.strip(): - from_ref = res.stdout.strip() - -commits = "" -if from_ref: - res = subprocess.run(["git", "log", f"{from_ref}..{to_ref}", "--pretty=format:- %s (%h)"], capture_output=True, text=True) - if res.returncode == 0: - commits = res.stdout.strip() -if not commits: - res = subprocess.run(["git", "log", f"-n{max_commits}", "--pretty=format:- %s (%h)", to_ref], capture_output=True, text=True) - if res.returncode == 0: - commits = res.stdout.strip() - -filtered = [l.strip() for l in commits.splitlines() if l.strip() and not re.search(r'chore(\(ci\))?:\s*(bump version|release)', l, re.I)] -commits_clean = "\n".join(filtered) if filtered else commits - -notes = fallback -if commits_clean and api_key: - default_sys = "You are an automated release notes generator. Group changes under '### Features', '### Bug Fixes', and '### Improvements'. Filter chores. Output ONLY valid Markdown release notes." - p = f"Generate concise release notes{' for v' + version if version else ''} based on commits:\n\n{commits_clean}" - payload = {"model": model, "messages": [{"role": "system", "content": sys_prompt or default_sys}, {"role": "user", "content": p}], "temperature": temp} - try: - req = urllib.request.Request(f"{base_url}/chat/completions", data=json.dumps(payload).encode("utf-8"), headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}) - with urllib.request.urlopen(req, timeout=timeout) as r: - c = json.loads(r.read().decode("utf-8"))["choices"][0]["message"]["content"] - c = re.sub(r'.*?', '', c, flags=re.DOTALL).strip() - notes = c if c else fallback - except Exception as e: - sys.stderr.write(f"LLM call failed: {e}\n") - -if save_file: - with open(save_file, "w", encoding="utf-8") as f: - f.write(notes + "\n") - -gh = os.environ.get("GITHUB_OUTPUT") -if gh and os.path.exists(os.path.dirname(gh) or "."): - d = f"EOF_{uuid.uuid4().hex}" - with open(gh, "a", encoding="utf-8") as f: - f.write(f"notes<<{d}\n{notes}\n{d}\nnotes_file={save_file}\n") -print(notes) -PYEOF - fi + python3 "${{ github.action_path }}/scripts/generate_notes.py"