ci(release): publish curated release notes, never an empty body (#48)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Alice <alice@prismshadow.com>
This commit is contained in:
Yaowei Zheng
2026-07-23 22:41:50 +08:00
committed by GitHub
parent 001056f97c
commit cc1be054de
4 changed files with 72 additions and 1 deletions
+26
View File
@@ -159,11 +159,37 @@ jobs:
sha256sum "$f" > "$f.sha256"
done
# Release notes come from changelog/<version>/RELEASE.md, written during release preparation and
# committed BEFORE the tag (the release job runs on the tag's checkout, so a file added afterwards
# is invisible here). Present and non-empty -> published verbatim as the body; absent -> GitHub
# generates a body from the merged PRs. Either way the Release can never ship an empty body, which
# is what happened to v0.1.1: the step passed neither body nor generate_release_notes, the action
# left the body unset, and the omission was only visible once the Release was public.
- name: Resolve release notes
id: notes
env:
TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
run: |
NOTES="changelog/${TAG#v}/RELEASE.md"
if [ -s "$NOTES" ]; then
echo "Publishing curated release notes from $NOTES"
echo "body_path=$NOTES" >> "$GITHUB_OUTPUT"
echo "generate=false" >> "$GITHUB_OUTPUT"
else
echo "No $NOTES; falling back to GitHub-generated notes."
echo "body_path=" >> "$GITHUB_OUTPUT"
echo "generate=true" >> "$GITHUB_OUTPUT"
fi
# On tag-push use the ref name; on manual dispatch use the input tag.
# An empty body_path is falsy for the action and simply ignored (it never tries to read it), so the
# fallback branch cleanly leaves generate_release_notes to compose the body on its own.
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
body_path: ${{ steps.notes.outputs.body_path }}
generate_release_notes: ${{ steps.notes.outputs.generate }}
files: |
dist-artifacts/*.tar.gz
dist-artifacts/*.sha256
+5
View File
@@ -86,6 +86,11 @@ pnpm test:e2e # core live-model e2e, need
`changelog/<version>/README.md`. The layout is documented in
[`changelog/README.md`](changelog/README.md). Related changes may share one entry
file (extending its details) instead of opening a new file per small change.
- **A release ships its own announcement**: `changelog/<version>/RELEASE.md` is published
verbatim as the GitHub Release body. Write it during release preparation and **commit it
before creating the tag** — the release workflow reads it from the tag's checkout, so a
file added later never reaches the Release page. Without it the workflow falls back to
GitHub's auto-generated notes.
- README assets under `assets/readme/` are generated — the benchmark charts from the
landing benchmark data, and the demo screenshots via
`node packages/landing/scripts/capture-readme-demo.mjs` (build first; needs Playwright
+38
View File
@@ -0,0 +1,38 @@
PenguinHarness 0.1.1 — Gemini 3.6 support, a self-upgrading CLI, and the skills that let an agent serve and fine-tune its own models.
## Install
```sh
curl -fsSL https://penguin.ooo/install.sh | sh
penguin web
```
Linux and macOS, x64 and arm64, with a bundled Node runtime. Or via npm (needs Node >= 24):
```sh
npm install -g @prismshadow/penguin-cli
```
## Highlights
**Gemini 3.6.** `gemini-3.6-flash` and `gemini-3.5-flash-lite` are in the model catalog, on both the Google endpoint and OpenRouter, with the full 1,048,576-token context and vision. The rest of the catalog was rebuilt against AgentHub 0.4.1's supported-model registry and grew from 59 to 70 entries — Claude 5 on Anthropic, Kimi K3 on Moonshot, and more on OpenRouter and SiliconFlow.
**Serve and tune your own models, by asking.** Three new skills — vLLM, Ollama and LlamaFactory — teach an agent to stand up and fine-tune the models it runs on: describe what you want in plain language and it serves the model, scores itself, trains on what it got wrong, redeploys and measures again. With a local engine the data never leaves the machine.
**`penguin update`.** Upgrades an existing install through the mechanism it was installed with — the tarball installer or a global npm/pnpm/yarn/bun package — after showing exactly what it will do. `--check` reports without changing anything, and your data root is never touched.
**A sidebar that scales.** Conversations group by Workspace (or by Agent), groups can be pinned, sessions created by subagents and scheduled tasks file into their own folders, and long lists load a page at a time. Collapsed, the sidebar is now an eight-entry navigation rail with bilingual tooltips.
## Notable in this release
- **Subagents follow the parent session.** A spawned subagent inherits the parent's model and thinking level instead of falling back to the Project default, and a resumed session restores the level its Trace recorded.
- **Empty tool lists stay off the wire.** Strict OpenAI-compatible servers such as vLLM reject `tools: []`; tool-less requests (the connectivity probe, title generation, the vision describer) now omit the field entirely.
- **Two new prompt guardrails.** The agent no longer kills processes on the harness's own service ports — it picks a free port instead — and on an API key error it retries once, then stops and asks you to update the key outside the chat.
- **Per-model max output tokens.** A 32k-context model no longer 400s because the agent-level output cap does not fit its window.
- **Thinking level moved into the conversation**, next to the model picker, and writes through to the Agent's settings.
## Requirements
Linux or macOS (x64 / arm64). The installer bundles its own Node runtime; installing from npm needs Node >= 24. All data stays under `~/.penguin/data`.
Full detail: [changelog/0.1.1/](https://github.com/Prism-Shadow/penguin-harness/tree/main/changelog/0.1.1)
+3 -1
View File
@@ -4,7 +4,9 @@ The root [../CHANGELOG.md](../CHANGELOG.md) keeps one brief line per release. Wo
- `<folder>/README.md` — the summary: one brief line per change, each linking its detail file, e.g. `- [YYYY-MM-DD] Brief description. ([details](YYYY-MM-DD-short-slug.md))`
- `<folder>/YYYY-MM-DD-short-slug.md` — one detail file per entry, named by the entry date: an H1 title, then what changed and why, using `##` sections once the entry covers more than one thing.
- `<version>/RELEASE.md` — the announcement published verbatim as the GitHub Release body: a lead sentence, then `## Install`, `## Highlights`, `## Notable in this release`, `## Requirements`, and a closing link to this folder. Only a numbered folder has one; it is written at release, when the version is finally known.
- Entries are grouped by the surface they change — Models, Web App, landing site, skills, docs, tooling — rather than one file per commit. A related change extends the existing file and its summary line instead of opening a new one.
- Unreleased changes go in `unreleased/`, never in a numbered folder: the next version number is not knowable while the work is being written — the batch that accumulated as `0.2.0/` shipped as 0.1.1 — so a guessed number only creates a rename to get wrong later. At release, rename `unreleased/` to the version actually shipped, swap its `# Unreleased` heading for `# Version X.Y.Z` plus a `Released on <date>.` line, add the release line to the root file, and create a fresh empty `unreleased/`. Released folders are frozen.
- Unreleased changes go in `unreleased/`, never in a numbered folder: the next version number is not knowable while the work is being written — the batch that accumulated as `0.2.0/` shipped as 0.1.1 — so a guessed number only creates a rename to get wrong later. At release, rename `unreleased/` to the version actually shipped, swap its `# Unreleased` heading for `# Version X.Y.Z` plus a `Released on <date>.` line, write `RELEASE.md`, add the release line to the root file, and create a fresh empty `unreleased/`. Released folders are frozen.
- `RELEASE.md` must be **committed before the tag is created**: the release workflow reads it from the tag's own checkout, so a file added afterwards is never published. When it is missing, the workflow falls back to notes GitHub generates from the merged PRs rather than publishing an empty body.
Written in English. History starts after the v0.0.1 release (2026-07-19); earlier changes are not backfilled.