Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 65 additions & 14 deletions .agents/skills/create-draft-release-notes/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
name: create-draft-release-notes
description: Create or update draft GitHub releases for the current project's main GitHub repository, then organize GitHub-generated release notes into user-friendly sections without rewriting release note items. Use for preparing, formatting, categorizing, creating, or updating GitHub release notes or draft releases, including optional highlights when the user asks for them.
description: Create or update draft GitHub release notes, or output organized Markdown when draft creation is unavailable. Use for release notes, draft releases, release PR checks, npm staged publishing checks, and optional highlights.
---

# Create Draft Release Notes

## Overview

Create a GitHub draft release, organize the generated notes by conventional commit type, and save the organized body back to the draft. Preserve each release note item exactly; only split accidentally joined bullets, move bullets into sections, and adjust headings. Add a top `## Highlights` section only when the user explicitly asks for highlights.
Create a GitHub draft release when possible, organize the generated notes by conventional commit type, and save the organized body back to the draft. If `gh` cannot create or edit the draft, return the organized Markdown in the conversation with manual creation steps. Preserve each release note item exactly; only split accidentally joined bullets, move bullets into sections, and adjust headings. Add a top `## Highlights` section only when the user explicitly asks for highlights.

## Security Notes

Expand All @@ -28,54 +28,105 @@ Input: a release tag/title such as `v2.0.6`. If title and tag differ, ask for th
release_title="$release_tag"
```

3. Verify access and ensure the release does not already exist:
3. Verify access and whether the release already exists:

```bash
gh auth status
gh repo view "$repo" --json nameWithOwner --jq '.nameWithOwner'
gh repo view "$repo" --json nameWithOwner,defaultBranchRef,viewerPermission
gh release view "$release_tag" -R "$repo" --json tagName,isDraft,url
```

If the release exists, stop unless the user explicitly asked to update that draft.

4. Infer the previous tag:
If `gh` is not logged in, `viewerPermission` is below `WRITE`, or release create/edit later fails for permissions, continue with the [Markdown Fallback Workflow](#markdown-fallback-workflow).

4. Infer the default branch and previous tag:

```bash
default_branch="$(gh repo view "$repo" --json defaultBranchRef --jq '.defaultBranchRef.name')"
previous_tag="$(gh release list -R "$repo" --exclude-drafts --exclude-pre-releases --limit 1 --json tagName --jq '.[0].tagName')"
gh release list -R "$repo" --exclude-drafts --exclude-pre-releases --limit 5
```

Ask for confirmation if the previous tag is missing, surprising, or part of a non-standard range.

5. Before creating anything, state the repo and range: `previous_tag -> release_tag`. If the user did not explicitly ask to create the draft in this turn, ask for confirmation.
5. Check the latest release PR before generating notes. Prefer repository conventions; otherwise search release-like PR titles or branches targeting the default branch.

```bash
gh pr list -R "$repo" --base "$default_branch" --state open --search "release in:title" --limit 20 --json number,title,url,headRefName,updatedAt
gh pr list -R "$repo" --base "$default_branch" --state all --search "release in:title" --limit 10 --json number,title,state,mergedAt,url,headRefName,headRefOid,updatedAt
```

If a release PR for this release is still open, or the latest release PR candidate has `mergedAt: null`, stop and ask the user to merge it into the default branch first.

6. If the repository uses npm staged publishing, verify packages from the latest merged release PR are already live on npm.

```bash
rg -n "\b(npm|pnpm)\s+stage(\s+publish)?\b" package.json pnpm-workspace.yaml .github 2>/dev/null
release_pr_number="<latest-merged-release-pr-number>"
gh pr diff "$release_pr_number" -R "$repo" --name-only | rg '(^|/)package\.json$'
npm view "$package_name@$package_version" version --json
```

For changed public packages, read `name` and `version` from the PR head or merged branch. Skip `"private": true`. If any version is missing from npm, stop and list the missing packages; tell the user to approve the staged packages with `npm stage approve <stage-id>` or from the npm website's Staged Packages tab, then rerun the workflow.

7. Before creating anything, state the repo and range: `previous_tag -> release_tag`. If the user did not explicitly ask to create the draft in this turn, ask for confirmation.

6. Create the draft with GitHub-generated notes:
8. Create the draft with GitHub-generated notes:

```bash
gh release create "$release_tag" -R "$repo" --draft --generate-notes --notes-start-tag "$previous_tag" --title "$release_title"
```

Add `--verify-tag` when the release must use an existing remote tag.
Add `--verify-tag` when the release must use an existing remote tag. If this fails because of auth or permissions, switch to the [Markdown Fallback Workflow](#markdown-fallback-workflow).

Comment thread
chenjiahan marked this conversation as resolved.
7. Organize the draft body:
9. Organize the draft body:

```bash
tmp_dir="$(mktemp -d)"
gh release view "$release_tag" -R "$repo" --json body --jq '.body' > "$tmp_dir/generated.md"
node .agents/skills/create-draft-release-notes/scripts/create-draft-release-notes.mjs "$tmp_dir/generated.md" > "$tmp_dir/organized.md"
```

8. Select the final notes file. Use `$tmp_dir/organized.md` by default. If the user asked for highlights, run the [Optional Highlights Workflow](#optional-highlights-workflow), write the result to `$tmp_dir/final.md`, and use that file instead.
10. Select the final notes file. Use `$tmp_dir/organized.md` by default. If the user asked for highlights, run the [Optional Highlights Workflow](#optional-highlights-workflow), write the result to `$tmp_dir/final.md`, and use that file instead.

9. Save the final body:
11. Save the final body:

```bash
gh release edit "$release_tag" -R "$repo" --draft --title "$release_title" --notes-file "$tmp_dir/organized.md"
```

Replace `$tmp_dir/organized.md` with `$tmp_dir/final.md` when highlights were generated. If editing fails because of auth or permissions, return the final notes through the [Markdown Fallback Workflow](#markdown-fallback-workflow).

12. Return the draft URL with `gh release view "$release_tag" -R "$repo" --json url --jq '.url'`.

## Markdown Fallback Workflow

Use this whenever `gh` is not logged in or cannot create/edit the draft release. Still run the release PR and staged publishing checks whenever repository metadata is available.

1. Generate notes without creating a release when read access is available:

```bash
gh release edit "$release_tag" -R "$repo" --draft --title "$release_title" --notes-file "$tmp_dir/organized.md"
tmp_dir="$(mktemp -d)"
gh api "repos/$repo/releases/generate-notes" \
-f tag_name="$release_tag" \
-f previous_tag_name="$previous_tag" \
-f name="$release_title" \
--jq '.body' > "$tmp_dir/generated.md"
node .agents/skills/create-draft-release-notes/scripts/create-draft-release-notes.mjs "$tmp_dir/generated.md" > "$tmp_dir/organized.md"
```
Comment thread
chenjiahan marked this conversation as resolved.

Replace `$tmp_dir/organized.md` with `$tmp_dir/final.md` when highlights were generated.
If generated notes cannot be fetched, ask the user to provide the GitHub-generated Markdown or log in with repository read access.

2. Apply the [Optional Highlights Workflow](#optional-highlights-workflow) if requested.

3. Return the final Markdown in a fenced `markdown` block and state that no draft was created because of auth or permissions.

10. Return the draft URL with `gh release view "$release_tag" -R "$repo" --json url --jq '.url'`.
4. Give concise manual creation guidance:
- Open `https://github.com/<owner>/<repo>/releases/new`.
- Use tag `$release_tag` and title `$release_title`.
- Paste the Markdown body exactly as provided.
- Save it as a draft release after any missing staged npm packages have been approved.

## Markdown-Only Workflow

Expand Down
9 changes: 8 additions & 1 deletion .agents/skills/release-blog-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,25 @@ Use the project's existing blog metadata and component conventions. If the produ
Each feature section should usually follow this pattern:

- Describe the change clearly so readers understand its background, purpose, use cases, and user-facing benefits such as performance gains.
- If a code or configuration example is useful, include one precise and concise example that makes the change easy to understand at a glance.
- Avoid exhaustive API lists; select the key APIs or behaviors readers need, and when useful, use one precise code or configuration example to make the change clear at a glance.

## Headings

- Use sentence case for titles and headings.
- Keep headings short and specific.
- Keep anchors stable and readable.
- If the website is built with Rspress, use the Rspress anchor syntax, such as `\{#foo-bar}`.
- For multilingual posts, treat the English post as the source of truth for section anchors. Matching headings in other languages should resolve to the same final anchor as the English heading, adding `\{#anchor-id}` when their generated anchor would differ.
- Default English anchors are generated by lowercasing the heading, removing punctuation, replacing whitespace with hyphens, and appending numeric suffixes for duplicates. If the English heading is long or the generated anchor is not stable enough, choose a short semantic custom anchor and apply it to every language version.
- Do not add a custom anchor when it is identical to the default generated anchor.

## Tone

- Be professional, direct, and understated.
- Avoid vague claims such as "greatly improved" unless the improvement is explained or quantified.
- Avoid slogan-like positioning in feature updates unless intentionally discussing product vision.
- Qualify benchmark numbers with enough context to make them credible.
- When presenting performance gains, bold only the key improvement numbers, avoid frequent emphasis, and use tables or images when they make the comparison clearer at a glance.
- Use product and ecosystem terms consistently.
- Write naturally in the target language; do not let the prose read like a literal translation from another language.

Expand All @@ -52,6 +57,8 @@ Add links where they help readers continue:

Do not over-link common terms. Link the first meaningful occurrence or the option name users are likely to search for.

For Rstack documentation links on `rspack.rs`, `rsbuild.rs`, `rspress.rs`, `rslib.rs`, `rsdoctor.rs`, and `rstest.rs`, match the URL language to the blog language. In Chinese posts, prefer `/zh/` paths such as `https://rspack.rs/zh/`; in English posts, omit `/zh/` because the default docs are English. Apply the same rule to deeper documentation URLs.

## Revision behavior

When revising an existing blog:
Expand Down
4 changes: 2 additions & 2 deletions skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"source": "rstackjs/agent-skills",
"sourceType": "github",
"skillPath": "skills/create-draft-release-notes/SKILL.md",
"computedHash": "ac0fd0bc0eb7abde798501f8915a87905125c67a52cee37fb1913f178dbe517d"
"computedHash": "cb32485c5a35e45acba920a690a14d10f878c92fbbd2312ec3d0ce4bf2012abc"
},
"pr-creator": {
"source": "rstackjs/agent-skills",
Expand All @@ -17,7 +17,7 @@
"source": "rstackjs/agent-skills",
"sourceType": "github",
"skillPath": "skills/release-blog-writer/SKILL.md",
"computedHash": "964ac00607c45fd5004192f50e82019ee45b2c8e06e03fa7e06c35970b6388ce"
"computedHash": "24bdde0407813d43e4f42336fa0d433f53e5c5c8a516f46acbc3505c557f68ea"
},
"rspress-description-generator": {
"source": "rstackjs/agent-skills",
Expand Down
2 changes: 1 addition & 1 deletion website/docs/en/blog/_meta.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["index", "v2-0", "v1-0", "v0-7", "v0-6", "v0-5", "v0-4", "v0-3", "v0-2", "v0-1"]
["index", "v2-1", "v2-0", "v1-0", "v0-7", "v0-6", "v0-5", "v0-4", "v0-3", "v0-2", "v0-1"]
Comment thread
chenjiahan marked this conversation as resolved.
Loading
Loading