release-post
The release-post skill generates professional blog posts announcing R and Python package releases for either the Tidyverse blog (using hugodown) or Shiny blog (using Quarto). Use this when publishing a new package version and needing formatted documentation that follows established conventions, includes installation instructions, highlights major features and changes, and acknowledges contributors.
git clone --depth 1 https://github.com/posit-dev/skills /tmp/release-post && cp -r /tmp/release-post/open-source/release-post ~/.claude/skills/release-postSKILL.md
# Package Release Post
Create professional R/Python package release blog posts following Tidyverse or Shiny blog conventions.
## Quick Start
1. **Identify the blog platform**: Tidyverse (tidyverse.org) or Shiny (shiny.posit.co)
2. Verify NEWS.md or changelog exists for the package
3. Gather package info: name, version, repository (e.g., "tidyverse/dplyr")
4. Follow the workflow below
5. Use `scripts/get_contributors.R` to generate acknowledgments
6. Reference the appropriate formatting guide for final polish
## Platform Selection
This skill supports two blog platforms with different formatting requirements:
- **Tidyverse blog** (tidyverse.org)
- Uses hugodown
- R packages primarily
- More rigid structure and conventions
- See `references/tidyverse-formatting.md`
- **Shiny blog** (shiny.posit.co)
- Uses Quarto
- R and Python packages
- More flexible, feature-focused structure
- See `references/shiny-formatting.md`
**First, determine which platform the post is for**, then follow the general workflow and apply platform-specific formatting.
## General Workflow
These steps apply to both platforms. Content guidelines are based on Tidyverse best practices but adapt them as needed for Shiny posts.
### Step 1: Gather Information
Collect required information:
- **Platform**: Tidyverse or Shiny blog?
- **Package name and version**: e.g., "dplyr 1.2.0" or "shiny 1.9.0"
- **Repository**: GitHub repo in "owner/repo" format
- **Package language**: R or Python
- **NEWS content**: Read the package's NEWS.md, CHANGELOG, or NEWS
- **Package description**: One-sentence core purpose
- **Previous release tag**: For contributor fetching (optional)
- **Featured image**: For frontmatter (optional but recommended)
### Step 2: Structure the Post
Create the post outline following this order:
1. **Frontmatter**: Platform-specific YAML (see formatting references)
2. **Title and Opening**:
- Title: Package name and version
- Opening: Announcement with one-sentence package description
- Installation: Code block with installation command
- Overview: Brief summary with link to full release notes
3. **Main Content** (choose appropriate sections):
- **Migration guide** (if breaking changes) - Always first when present
- **Lifecycle changes** (deprecations, soft-deprecations, defunct)
- **Feature sections** (one per major feature, descriptive headings)
- **Minor improvements** (bulleted list)
4. **Acknowledgements** (when appropriate):
- Use `scripts/get_contributors.R`
- Format: "A big thank you to all the folks who helped make this release happen:"
- Comma-separated GitHub links
### Step 3: Apply Content Guidelines
Follow the best practices in `references/content-guidelines.md`:
- **Opening style**: "We're [random adjective expressing excitement] to announce the release of..."
- **Section organization**: Migration → Lifecycle → Features → Improvements → Acknowledgements
- **Tone**: Conversational, professional, enthusiastic but authentic
- **Technical precision**: Use exact function names in backticks
- **Focus on benefits**: Explain "why" not just "what"
- **Code examples**: Realistic, well-commented, properly formatted
### Step 4: Transform NEWS Content
Convert NEWS.md bullets to blog-friendly content:
- **Research features thoroughly**: Don't just copy NEWS bullets—read function docs, check PRs, understand the context
- **Expand context**: Why changes matter, not just what changed
- **Add complete code examples**: Show realistic usage with full workflows, not just function signatures
- **Explain concepts first**: For unfamiliar features, explain what they are and how they work before showing code
- **Group thematically**: Combine related NEWS items into coherent sections
- **Use conversational tone**: Transform terse bullets into prose
- **Link documentation**: Add relevant links to docs and resources
- **Highlight breaking changes**: Make migration paths clear
- **Multi-language parity** (Shiny only): For R+Python packages on the Shiny blog, ensure all examples show both languages in tabsets
### Step 5: Apply Platform-Specific Formatting
**For Tidyverse posts**, read `references/tidyverse-formatting.md` and apply:
- hugodown frontmatter with `slug`, `photo.url`, `photo.author`
- Specific slug format: `packagename-x-y-z` (hyphens replace dots)
- R code blocks with `r` language identifier
- Acknowledgements always included as final section
**For Shiny posts**, read `references/shiny-formatting.md` and apply:
- Quarto frontmatter with YAML anchors for social media
- Flexible title formatting
- Use tabsets for Python/R or Express/Core variations
- Platform-specific code block attributes
- Acknowledgements optional, varies by post type
- May use lead paragraphs, callouts, embedded media
### Step 6: Generate Acknowledgements
Run the contributor script:
```bash
Rscript scripts/get_contributors.R "owner/repo"
```
Or with a specific starting tag for the previous version (or tag used for last release post):
```bash
Rscript scripts/get_contributors.R "owner/repo" "v1.0.0"
```
Copy the markdown output into the Acknowledgements section.
### Step 7: Review and Polish
Platform-agnostic checklist:
- [ ] Frontmatter complete with all required fields
- [ ] Opening clearly states package purpose
- [ ] Installation code block present (both languages if applicable)
- [ ] Sections organized logically
- [ ] Code examples use proper syntax highlighting
- [ ] Function names in backticks with parentheses: `` `function()` ``
- [ ] Package names are not backticked or otherwise styled
- [ ] Tone is conversational but not marketing-speak
- [ ] No superlatives ("powerful", "rich", "seamless", etc.)
- [ ] Features explained with context, not just listed
- [ ] Concepts explained before showing code
- [ ] All examples show R and Python variants (if applicable)
- [ ] Links to full release notes included
Platform-specific checklist:
**Tidyverse:**
- [ ] Slug format:>
Create and use brand.yml files for consistent branding across Shiny apps and Quarto documents. Covers: (1) Creating new _brand.yml files, (2) Applying to Shiny (R and Python), (3) Using in Quarto, (4) Modifying existing files, and (5) Troubleshooting. Includes complete specifications and integration guides.
Write ggsql queries — a grammar of graphics for SQL. Use when the user wants to create, modify, or understand a ggsql visualization query.
Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes. Activate when the user says "create pr", "make a pr", "open pull request", "submit pr", "pr for these changes", or wants to get their current work into a reviewable PR. Assumes the project uses git, is hosted on GitHub, and has GitHub Actions CI with automated checks (lint, build, tests, etc.). Does NOT merge - stops when CI passes and provides the PR link.
Address PR review feedback by systematically working through every unresolved PR review thread on the current branch's PR - analyze each comment, make the requested code changes (with tests where useful), commit, and optionally reply and resolve.
Bulk resolve unresolved PR review threads on the current branch’s PR — typically after threads have been addressed manually or via /pr-threads-address
>
Guide for drafting issue closure and decline responses as an open-source package maintainer. Use when helping compose a reply that says \"no\" to a feature request, closes an issue as won't-fix, redirects a user to a different package, explains why a design choice is intentional, or otherwise declines or closes a community contribution. Also use when the maintainer needs to explain a deprecation, point out a user misunderstanding, or communicate an effort/scope tradeoff to a contributor.