release
Releases Plain packages with intelligent version suggestions and parallel release notes generation. Use when releasing packages to PyPI.
Best use case
release is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Releases Plain packages with intelligent version suggestions and parallel release notes generation. Use when releasing packages to PyPI.
Teams using release should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/release/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How release Compares
| Feature / Agent | release | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Releases Plain packages with intelligent version suggestions and parallel release notes generation. Use when releasing packages to PyPI.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Release Packages
Release Plain packages with version bumping, changelog generation, and git tagging.
## Arguments
- No args: discover all packages with changes, prompt for each
- Package names: only release specified packages
- The user may also specify a release type (major/minor/patch) to auto-select for all packages
## Scripts
All mechanical operations are handled by scripts in this skill directory:
| Script | Purpose |
| ------------------ | --------------------------------------------------------------- |
| `discover-changes` | Find packages with unreleased commits (outputs JSON) |
| `bump-versions` | Bump package versions (`<package>:<type> ...`) |
| `commit-and-push` | Format, sync, commit, tag, and push (`<package>:<version> ...`) |
| `add-hunks` | Stage specific uv.lock hunks by grep pattern (used internally) |
## Workflow
### Phase 1: Discover Packages with Changes
1. Run `git status --porcelain` to check for uncommitted changes.
2. Run discover-changes:
```
./.claude/skills/release/discover-changes
```
This outputs JSON with each package's name, current version, and commits since last release.
If specific packages were requested, filter the results to only those packages.
3. For each package that has changes to release, check if any of its files appear in the git status output. If so, **stop and warn the user** — uncommitted changes in a package being released could mean the release misses work or includes an inconsistent state. Ask them to commit or discard before proceeding. Changes in other directories (e.g. `work/`, `scripts/`) are fine to ignore.
### Phase 1b: First Release Detection
For any package with `current_version` of `0.0.0`:
1. Inform the user: "Package X has never been released (version 0.0.0)."
2. Ask what version to release:
- **0.1.0** - First development release (recommended)
- **1.0.0** - First stable release
3. Use `uv version <version>` in the package directory to set the version directly (instead of bump)
### Phase 2: Collect Release Decisions
For each package with changes:
1. Display the commits since last version change
2. **Analyze commits and suggest release type**:
- **Minor**: new features, breaking changes, significant additions, new APIs
- **Patch**: small bugfixes, minor tweaks, documentation updates, refactors
3. Ask user to confirm or adjust (minor/patch/skip)
- If user specified a release type, auto-select that type
- Default to skip if user just presses Enter
### Phase 3: Bump Versions
```
./.claude/skills/release/bump-versions <package>:<type> [<package>:<type> ...]
```
Example: `./.claude/skills/release/bump-versions plain-admin:patch plain-dev:minor`
### Phase 3b: Update Cross-Package Dependency Minimums
When a package is being released because it depends on changes in another package being released in the same batch, update its minimum version constraint in `pyproject.toml`.
For each sub-package being released, check if any of its dependencies (in `[project.dependencies]`) are also being released in this batch. If so, and the sub-package's changes are driven by the dependency's changes (e.g., adapting to a new API), update the constraint from `<1.0.0` to `>=<new_version>,<1.0.0`.
Example: if `plain-auth` is being released because it adapted to `plain` 0.113.0's new Request API, update its pyproject.toml:
- Before: `"plain<1.0.0"`
- After: `"plain>=0.113.0,<1.0.0"`
Only update constraints when there's an actual compatibility requirement — don't add minimums for packages whose changes are independent. Use the commit analysis from Phase 3 to determine this.
### Phase 4: Generate Release Notes
For each package to release, sequentially:
1. Get the file changes since the last release:
```
git diff <last_tag>..HEAD -- <name> ":(exclude)<name>/tests"
```
2. Read the existing `<changelog_path>` file.
3. Prepend a new release entry to the changelog with this format:
```
## [<new_version>](https://github.com/dropseed/plain/releases/<name>@<new_version>) (<today's date>)
### What's changed
- Summarize user-facing changes based on the actual diff (not just commit messages)
- Include commit hash links: ([abc1234](https://github.com/dropseed/plain/commit/abc1234))
- Skip test changes, internal refactors that don't affect public API
### Upgrade instructions
- Specific steps if any API changed
- If no changes required: "- No changes required."
```
### Phase 5: Commit, Tag, and Push
```
./.claude/skills/release/commit-and-push <package>:<version> [<package>:<version> ...]
```
This script handles everything: `uv sync`, `./scripts/fix`, staging files, committing each package separately, tagging, and pushing. Sub-packages are committed first, core `plain` last.
Example: `./.claude/skills/release/commit-and-push plain-admin:0.65.1 plain:0.103.0`
## Release Type Guidelines
Consider the current version when suggesting release types:
### Pre-1.0 packages (0.x.y)
Most Plain packages are pre-1.0. For these:
- **Minor (0.x.0)**: New features, breaking changes, new APIs, significant additions
- **Patch (0.0.x)**: Bugfixes, minor tweaks, documentation, refactors
- **Major (1.0.0)**: Only suggest if explicitly requested for stability milestone
### Post-1.0 packages (x.y.z where x >= 1)
Follow semver strictly:
- **Major (x.0.0)**: Breaking changes, API removals, incompatible changes
- **Minor (x.y.0)**: New features, new APIs, backwards-compatible additions
- **Patch (x.y.z)**: Bugfixes, minor tweaks, documentation, refactors
### Commit message indicators
- Breaking/major indicators: "breaking", "remove", "rename API", "redesign", "incompatible"
- Feature/minor indicators: "add", "new", "feature", "implement"
- Fix/patch indicators: "fix", "bugfix", "typo", "docs", "refactor", "update"Related Skills
plainx-release
Releases plainx packages with version suggestions, changelog generation, and git tagging. Use when releasing a package to PyPI.
plain-upgrade
Upgrades Plain packages and applies required migration changes. Use when updating to newer package versions.
plain-postgres-doctor
Check overall database health — schema correctness and operational health. Use when asked to check the database, validate schema, optimize indexes, or diagnose Postgres problems.
plain-portal
Open a remote Python shell on a production machine via encrypted tunnel. Use when you need to inspect production data, debug issues, run queries, or transfer files.
plain-optimize
Captures and analyzes performance traces to identify slow queries and N+1 problems. Use when a page is slow, there are too many queries, or the user asks about performance.
plain-install
Installs Plain packages and guides through setup steps. Use when adding new packages to a project.
plain-guide
Answer questions about the Plain framework by researching docs and source code. Use when asked "how do I...", "does Plain support...", or "how does X work?" questions.
plain-bug
Submit a bug report for the Plain framework. Use when the user wants to report a bug, error, or unexpected behavior. Collects context and creates a GitHub issue.
future
Navigate and manage the future/ directory — view dependency graphs, filter by arc, find unblocked futures, and identify what to work on next. Use when deciding what to work on, exploring planned work, or checking dependencies between futures.
mobile-release
Perform a regular mobile release from the dev branch. Gathers commits since last release, updates changelog, bumps version, updates iOS Info.plist, and creates release PR to mobile-main.
desktop-release
Perform a regular desktop release from the dev branch. Gathers commits since last release, updates changelog, evaluates mainHash changes, bumps version, and creates release PR.
release
Automated release workflow for oh-my-claudecode