create-milestone
$
npx mdskill add agentic-community/mcp-gateway-registry/create-milestonePlan GitHub releases by gathering changes and drafting milestones.
- Automates release planning by analyzing merged PRs and closed issues.
- Integrates with GitHub to fetch releases, PRs, and issues data.
- Decides content by comparing current state against a selected baseline.
- Delivers draft milestones with approval tables and assigns approved items.
SKILL.md
.github/skills/create-milestoneView on GitHub ↗
---
name: create-milestone
description: "Create a GitHub milestone for an upcoming release. Suggests the next version based on the latest release, gathers all merged PRs and closed issues since that release, presents a draft with two tables (Issues and PRs) for user approval, then creates the milestone and assigns all approved items."
license: Apache-2.0
metadata:
author: mcp-gateway-registry
version: "2.0"
---
# Create Milestone Skill
Use this skill when the user wants to plan and create a GitHub milestone for an upcoming release. The skill identifies what has changed since a baseline release, presents a draft for approval, and creates the milestone with all approved items.
Supports creating multiple milestones in sequence (e.g., v1.0.20, v1.0.21) by letting the user choose the baseline and which items belong to which release.
## Input
The skill accepts optional parameters:
```
/create-milestone [VERSION] [DATE] [NOTES]
```
- **VERSION** - Target version (e.g., `v1.0.20`). If not provided, suggest based on latest release.
- **DATE** - Target release date (e.g., `2026-04-21`). If not provided, ask the user.
- **NOTES** - Optional theme or notes (e.g., "security hardening", "federation improvements").
## Output
- A GitHub milestone with description containing two tables (Issues and PRs)
- A local draft file at `.scratchpad/{version}-release-notes.md` with detailed release notes
## Workflow
### Step 1: Discover Releases and Milestones
Gather the current state of releases and milestones:
```bash
# Get recent releases (tags + dates)
gh release list --limit 10 --json tagName,publishedAt,name \
--jq '.[] | "\(.tagName)\t\(.publishedAt)\t\(.name)"'
# Get existing milestones (to avoid duplicates and show what's already planned)
gh api repos/{owner}/{repo}/milestones --jq '.[] | "\(.number)\t\(.title)\t\(.due_on)\t\(.open_issues)\t\(.closed_issues)"'
# Git tags for reference
git tag --sort=-v:refname | grep '^v[0-9]' | head -10
```
### Step 2: Ask the User What They Want
Present findings and ask the user to specify:
1. **Which version** to create a milestone for (suggest next patch bump from latest release)
2. **Target date** for the release
3. **Baseline release** to diff from -- this is critical for flexibility
4. **Theme or notes** for this release
**Example prompt:**
```
Current state:
- Latest release: v1.0.19 (published April 14, 2026)
- Existing milestones: v1.0.19 (due Apr 14, 30 closed / 3 open)
Suggested next milestone: v1.0.20
Questions:
1. What version? (default: v1.0.20)
2. What is the target release date?
3. Which release should I diff from? (default: v1.0.19, the latest)
- Other options: v1.0.18, v1.0.17, v1.0.16, ...
4. Any theme or notes? (e.g., "external registry federation")
```
**Baseline flexibility:** The user may say:
- "everything since last release" -- use the latest release as baseline
- "everything since v1.0.17" -- use a specific older release as baseline
- "pick everything since the last known release" -- same as latest release
- "I want to plan two releases: v1.0.20 and v1.0.21" -- run the workflow twice
Wait for the user to respond before proceeding. Do not create anything until the user confirms.
### Step 3: Gather Changes Since Baseline
Once the user confirms version, date, and baseline, gather all changes:
```bash
# Get the baseline release publish timestamp for precise cutoff
RELEASE_DATE=$(gh release view {baseline_version} --json publishedAt --jq '.publishedAt')
# List all PRs merged after the baseline release
gh pr list --state merged --search "merged:>=$RELEASE_DATE" \
--json number,title,mergedAt,body --limit 100 \
--jq '.[] | "\(.number)\t\(.mergedAt)\t\(.title)"'
# Get all commits since the baseline tag
git log {baseline_version}..HEAD --oneline
# Also get open PRs that might be targeting this release
gh pr list --state open --json number,title --limit 30 \
--jq '.[] | "\(.number)\t\(.title)"'
```
### Step 4: Find Corresponding Issues
For each merged PR, extract linked issue numbers from:
1. PR title: patterns like `(#123)`, `(#123, #456)`
2. PR body: patterns like `Fixes #123`, `Closes #123`, `Resolves #123`
```bash
# For each PR, get the body and extract issue references
gh pr view {pr_number} --json title,body \
--jq '{title: .title, body: (.body // "" | split("\n")[0:10] | join("\n"))}'
```
Build a mapping of PR -> Issues.
### Step 5: Exclude Items Already in Other Milestones
Check which items are already assigned to existing milestones:
```bash
# For each candidate item, check if it already has a milestone
gh api repos/{owner}/{repo}/issues/{number} --jq '.milestone.title // "none"'
```
If an item is already assigned to a different milestone, mark it in the draft so the user can decide. Do not silently skip items.
### Step 6: Present Draft for Approval
Present the draft to the user with two tables and clear guidance on what to include/exclude.
**Start with a default recommendation:** Proactively offer to include all closed issues and merged PRs since the baseline as the starting point. This saves the user from having to say "pick everything." Frame it as:
```
I found {N} merged PRs and {M} related issues since {baseline_version}.
Want me to include all of them as a starting point?
You can then add or remove specific items.
```
If the user says yes (or "pick everything", "include all", "yes go ahead"), proceed with the full list. If they want to be selective, present the tables for cherry-picking.
**Draft format:**
```
Here's what I found since {baseline_version} ({N} PRs merged, {M} issues referenced):
Items already in other milestones are marked with [in {milestone}].
## Issues ({count})
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #814 | Add GitHub private repo auth env vars | Open | |
| #660 | Support authenticated GitHub access | Open | |
| #764 | Disable demo server auto-registration | Closed | [in v1.0.19] |
...
## Pull Requests ({count})
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #782 | feat: GitHub private repo auth | Open | |
| #820 | fix: search pagination | Closed | |
| #815 | Add config propagation check | Closed | [in v1.0.19] |
...
## Open PRs (not yet merged, consider including?)
| # | Title |
|---|-------|
| #825 | feat: webhook notifications |
...
Options:
- "yes, include all" -- add everything listed above (the default)
- "exclude items already in other milestones" -- skip [in vX.X.X] items
- "only include #814, #782, #820" -- cherry-pick specific items
- "exclude #764, #815" -- remove specific items
- "also add #825" -- include an open PR not in the list
```
**Important:** In both tables, always show Open items first, then Closed items. Within each group, sort by number ascending.
Wait for the user to confirm or adjust the list before creating anything.
### Step 7: Create the Milestone
Once approved, create the milestone:
```bash
# First check it doesn't already exist
gh api repos/{owner}/{repo}/milestones --jq '.[] | select(.title == "{version}") | .number'
# Create the milestone
gh api repos/{owner}/{repo}/milestones \
-f title="{version}" \
-f due_on="{date}T07:00:00Z" \
-f description="$DESCRIPTION"
```
The description should contain two markdown tables (Issues and PRs) with clickable links. Format:
```markdown
Release {version} - targeting {day_of_week} {month} {day}, {year}.
{User's theme/notes if provided}
## Issues
| # | Title | Status |
|---|-------|--------|
| [#{num}](https://github.com/{owner}/{repo}/issues/{num}) | {title} | {status} |
## Pull Requests
| # | Title | Status |
|---|-------|--------|
| [#{num}](https://github.com/{owner}/{repo}/pull/{num}) | {title} | {status} |
```
**Table sort order:** Open items first, then Closed items. Within each group, sort by number ascending.
### Step 8: Assign Items to the Milestone
Add all approved PRs and issues to the milestone:
```bash
# Get milestone number from creation response
MILESTONE_NUMBER={number from Step 7 response}
# Add each item (use --field for integer type)
for item in {list_of_numbers}; do
gh api repos/{owner}/{repo}/issues/$item \
--method PATCH --field milestone=$MILESTONE_NUMBER --silent
done
```
**Note:** If an item is being moved from another milestone, `--field milestone=N` will reassign it. The user must have approved this in Step 6.
### Step 9: Create Local Release Notes Draft
Create a detailed release notes draft at `.scratchpad/{version}-release-notes.md` containing:
- Highlights section listing major features
- Breaking changes (if any)
- Tables for: New Features, Bug Fixes, Infrastructure, Documentation, Dependency Updates
- New environment variables introduced
- Open items that must close before release
- Stats (total PRs, issues closed/open, contributors)
This file serves as the starting point for the actual release notes when the release is cut (using the `/release-notes` skill).
### Step 10: Present Summary and Ask About Next Milestone
After creating everything, present:
1. Link to the milestone on GitHub
2. Stats: total items, open vs closed
3. Path to the local release notes draft
4. Reminder of open items that need to close before release
Then ask:
```
Milestone {version} created.
Would you like to create another milestone? For example:
- "create v1.0.21 targeting April 21" -- I'll use {version} as the new baseline
- "no, I'm done" -- we're finished
```
This enables the user to plan multiple sequential releases in one session. When creating the next milestone, the baseline automatically shifts to the version just created, and items already assigned to previous milestones are flagged.
## Multiple Milestone Planning
When the user wants to plan multiple releases at once (e.g., "I want to plan v1.0.20 and v1.0.21"):
1. **First milestone:** Run the full workflow above for the first version.
2. **Second milestone:** Use the first version as the new baseline. When gathering changes:
- Items already assigned to the first milestone are shown with `[in {first_version}]`
- The user picks from the remaining items plus any new open PRs/issues
3. **Repeat** for additional milestones as needed.
**Example flow:**
```
User: I want to plan v1.0.20 for Monday and v1.0.21 for next Friday
Step 1: Create v1.0.20 milestone
- Baseline: v1.0.19 (latest release)
- User picks items for v1.0.20
Step 2: Create v1.0.21 milestone
- Baseline: v1.0.19 (same release baseline, but now items in v1.0.20 are flagged)
- User picks remaining items + new items for v1.0.21
```
## Important Rules
- **Always ask the user to confirm** version, date, and baseline before creating anything.
- **Always present the draft** and wait for approval before creating the milestone.
- **Always ask which baseline to diff from.** Default to the latest release, but let the user choose an older one.
- **Never create a milestone that already exists.** Check first. If it exists, ask the user if they want to update it or choose a different version.
- **Never silently skip items.** If an item is in another milestone, show it and let the user decide.
- **Never include emojis** in any output or milestone descriptions.
- **Table sort order** is always: Open items first, then Closed items. Within each status group, sort by number ascending.
- **Two separate tables** are required: one for Issues, one for Pull Requests.
- **Clickable links** in the milestone description must use full URLs, not shorthand `#123` (GitHub does not auto-link in milestone descriptions).
- **Use `--field` (not `-f`)** when setting the milestone number on issues/PRs, since it must be an integer.
- **After creating a milestone, offer to create the next one.** This supports sequential release planning.
## Example Usage
### Minimal input (suggest everything)
```
User: /create-milestone
```
Response:
```
Current state:
- Latest release: v1.0.19 (published April 14, 2026)
- Existing milestones: v1.0.19 (due Apr 14, 30 closed / 3 open)
Suggested next milestone: v1.0.20
1. What version? (default: v1.0.20)
2. Target release date?
3. Diff from which release? (default: v1.0.19)
4. Theme or notes?
```
### With version and date
```
User: /create-milestone v1.0.20 2026-04-21
```
Response:
```
I'll create a v1.0.20 milestone targeting Monday April 21, 2026.
Diffing from v1.0.19 (latest release, published April 14).
Let me gather all changes since v1.0.19...
[presents draft tables for approval]
```
### Pick everything since a specific older release
```
User: /create-milestone v1.0.20 2026-04-21
User (in response to baseline question): everything since v1.0.17
```
Response:
```
Diffing from v1.0.17 (published March 31).
Note: This spans v1.0.18 and v1.0.19 -- items already in those milestones will be flagged.
[presents draft tables with [in v1.0.18] and [in v1.0.19] annotations]
```
### Plan two releases at once
```
User: I want to plan v1.0.20 for Monday and v1.0.21 for next Friday
```
Response:
```
I'll plan both milestones. Starting with v1.0.20.
[runs full workflow for v1.0.20, then asks about v1.0.21]
```
### Cherry-pick specific items
```
User: only include #820, #821, #814, and #782
```
Response:
```
Got it. Creating milestone with just those 4 items.
[creates milestone with only the specified items]
```
## Error Handling
- **Milestone already exists**: Tell the user and ask if they want to update it, add more items to it, or choose a different version.
- **No changes found since baseline**: Tell the user there are no merged PRs since the baseline release. Ask if they want to create an empty milestone for tracking open issues/PRs, or choose an older baseline.
- **Item already in another milestone**: Show it in the draft with `[in {milestone}]` annotation. If the user includes it, reassign it to the new milestone.
- **gh CLI not authenticated**: Tell the user to run `gh auth login`.
More from agentic-community/mcp-gateway-registry
- agentcore-registerGiven an MCP server URL, probe the server via curl to discover its metadata and tools, then generate a markdown file with copy-pasteable content for each field in the Amazon Bedrock AgentCore "Create record" form.
- generate-agent-cardGenerate an A2A agent card JSON by analyzing agent source code in a folder or GitHub URL. Studies the code to detect agent name, skills, tools, auth, protocol, and generates a spec-compliant agent card.
- generate-server-cardGenerate an MCP server card JSON (mcp-gateway-registry format) by analyzing server source code in a folder or GitHub URL. Studies code to detect server name, tools, transport, auth, and generates a registry-compatible config.
- macos-setupComplete macOS setup and teardown for MCP Gateway & Registry (AI-registry). Clones the repository, installs all services, configures Keycloak auth, registers the Cloudflare docs server, and verifies the full stack. Also supports complete teardown. Can be run directly from its GitHub URL without the repository already cloned. Uses an interactive or default-values mode chosen at startup.
- new-feature-designDesign and document new features with GitHub issue, low-level design (LLD), expert review, and testing plan. Creates structured documentation in .scratchpad/ with issue spec, technical design with diagrams and pseudo-code, multi-persona expert review, and a testing plan covering functional (curl and registry_management.py), backwards-compatibility, UX, ECS/terraform, and E2E API tests. Supports starting from a user description OR an existing GitHub issue URL. Folder naming: issue-{number}/ for existing issues, {feature-name}/ for new features.
- release-notesCreate release notes for a new version tag. Gathers all commits, PRs, issues fixed, and breaking changes since a previous release. Creates the release notes markdown file, tags the repo, and pushes. Asks the user to confirm the base version to diff against.
- usage-reportGenerate a usage report for MCP Gateway Registry by SSHing into the telemetry bastion host, exporting telemetry data from DocumentDB, and producing a formatted markdown report with deployment insights.