diff --git a/.agents/skills/release-note/SKILL.md b/.agents/skills/release-note/SKILL.md new file mode 100644 index 000000000..b3bc7f17d --- /dev/null +++ b/.agents/skills/release-note/SKILL.md @@ -0,0 +1,71 @@ +--- +name: release-note +description: + Write a user-facing Discord release announcement for the mittwald CLI (command + `mw`) from a git commit log and code diff. Trigger when asked to generate, + summarize, or write a release note/announcement for a release tag. +--- + +# Release note + +Write a short, friendly release announcement for the **mittwald CLI** (the `mw` +command), suitable for posting in a Discord channel aimed at users of the CLI. + +## Determining what changed + +You are given a release **tag** (e.g. `v1.20.0`). You run inside a full checkout +of the repository, so all tags and history are available. Collect the commit log +and the code diff for everything since the previous stable minor/major release +by running this in the repository root: + +```bash +TAG="" + +# All stable minor/major tags (patch == 0), sorted ascending by version. +MINORS=$(git tag --list 'v*' | grep -E '^v[0-9]+\.[0-9]+\.0$' | sort -V) + +# The stable minor tag immediately preceding TAG (empty if TAG is the first one). +PREV=$(echo "$MINORS" | grep -B1 -x "$TAG" | grep -v -x "$TAG" | tail -1) + +# Range to diff: previous minor..current, or just TAG if there is no predecessor. +if [[ -z "$PREV" ]]; then RANGE="$TAG"; else RANGE="$PREV..$TAG"; fi + +# Commit log — for orientation only. +git log --no-merges --pretty=format:'- %s (%h)' $RANGE > changes.txt + +# The actual code diff. Exclude generated docs and lockfiles (they are noise), +# and cap the size so it stays within the model's context window. +git diff --stat $RANGE -- \ + ':(exclude)docs/**' ':(exclude)**/*.lock' \ + ':(exclude)yarn.lock' ':(exclude)package-lock.json' > diff.txt +echo "" >> diff.txt +git diff $RANGE -- \ + ':(exclude)docs/**' ':(exclude)**/*.lock' \ + ':(exclude)yarn.lock' ':(exclude)package-lock.json' >> diff.txt +head -c 200000 diff.txt > diff.trimmed.txt && mv diff.trimmed.txt diff.txt +``` + +Then read `changes.txt` and `diff.txt`. **Base the release note on what the diff +actually changes**, not merely on what the commit subjects claim; use the commit +log only for orientation / grouping. + +## Rules for the note + +- Use GitHub-flavored Markdown and a few tasteful emoji. +- Group related changes into a handful of bullet points; focus on user-facing + highlights. +- Mention affected command names in the form `mw ` explicitly, + wherever the diff makes them clear. +- Skip pure dependency bumps, chores and internal refactors unless notable. +- No preamble and no heading with the version number (a heading is added + separately by the publishing step). +- Keep it under ~1200 characters. + +## Output + +Write **only** the finished release note to a file named `note.md` in the +current working directory, using your file-writing tool. + +The content of `note.md` is the sole deliverable. Anything you say in the chat +is discarded, and any stray text in `note.md` will be posted verbatim to +Discord. diff --git a/.github/workflows/release-announcement.yml b/.github/workflows/release-announcement.yml index fc725802d..fbf7d8257 100644 --- a/.github/workflows/release-announcement.yml +++ b/.github/workflows/release-announcement.yml @@ -46,31 +46,6 @@ jobs: with: node-version: "24" - - name: Determine previous minor release and collect changes - if: steps.check.outputs.should_run == 'true' - id: changes - run: | - TAG="${{ steps.check.outputs.tag }}" - - # All stable minor/major tags, sorted ascending by version. - MINORS=$(git tag --list 'v*' | grep -E '^v[0-9]+\.[0-9]+\.0$' | sort -V) - - # The stable minor tag immediately preceding the current one. - PREV=$(echo "$MINORS" | grep -B1 -x "$TAG" | grep -v -x "$TAG" | tail -1) - - if [[ -z "$PREV" ]]; then - echo "::notice::No previous minor release found; using full history." - RANGE="$TAG" - else - RANGE="$PREV..$TAG" - fi - echo "prev=$PREV" >> "$GITHUB_OUTPUT" - echo "range=$RANGE" >> "$GITHUB_OUTPUT" - - # Collect the commit log for the range into a file for the model. - git log --no-merges --pretty=format:'- %s (%h)' $RANGE > changes.txt - echo "Collected $(wc -l < changes.txt) commits for range $RANGE" - - name: Install OpenCode CLI if: steps.check.outputs.should_run == 'true' run: npm install -g opencode-ai @@ -93,11 +68,18 @@ jobs: "apiKey": "{env:MITTWALD_AI_API_KEY}" }, "models": { - "Ministral-3-14B-Instruct-2512": { - "name": "Ministral-3-14B-Instruct-2512" + "Mistral-Medium-3.5-128B": { + "name": "mistral-medium-3.5" } } } + }, + "permission": { + "skill": "allow", + "read": "allow", + "write": "allow", + "edit": "allow", + "bash": "allow" } } EOF @@ -109,22 +91,17 @@ jobs: MITTWALD_AI_API_KEY: ${{ secrets.MITTWALD_AI_API_KEY }} run: | TAG="${{ steps.check.outputs.tag }}" - PREV="${{ steps.changes.outputs.prev }}" - - PROMPT="You are writing a release announcement for the mittwald CLI (command 'mw'). - Below is the git commit log for release ${TAG}${PREV:+ (changes since ${PREV})}. - Write a short, friendly release note aimed at users, suitable for posting in Discord. - Rules: - - Use GitHub-flavored Markdown and a few tasteful emoji. - - Group related changes into a handful of bullet points; focus on user-facing highlights. - - Skip pure dependency bumps, chores and internal refactors unless notable. - - No preamble, no heading with the version (that is added separately), max ~1200 characters. - - Commit log: - $(cat changes.txt)" - - # 'opencode run' executes a single non-interactive prompt and prints the response. - opencode run -m mittwald/Ministral-3-14B-Instruct-2512 "$PROMPT" > note.md + + # Make sure a stale note.md can't leak into the announcement. + rm -f note.md + + # 'opencode run' executes a single non-interactive prompt. + opencode run -m mittwald/mistral-medium-3.5 "/release-note ${TAG}" + + if [[ ! -s note.md ]]; then + echo "::error::OpenCode did not produce a note.md file." + exit 1 + fi echo "----- Generated note -----" cat note.md