---
name: cut-release
description: >-
  Cut (publish) a release of meshery/schemas by publishing the current Release
  Drafter draft with the gh CLI. Use this whenever the user asks to "cut a
  release", "publish the release", "ship a release", "release schemas", "do a
  release", "release the latest merge", or wants the recently merged PR to go
  out. Handles waiting for the Release Drafter workflow to fold the just-merged
  PR into the draft notes, then flipping the draft to published so the
  publish-schemas workflow publishes the @meshery/schemas npm package, notifies
  dependents, and publishes the OpenAPI docs. The version tag is already set by
  Release Drafter and auto-increments after each release, so this skill never
  creates or bumps a tag.
---

# Cut a meshery/schemas release

Publishing a release here is intentionally a one-action step: **flip the existing
Release Drafter draft from draft to published.** Everything downstream is automated
by GitHub Actions - most importantly, **publishing the release is what publishes the
`@meshery/schemas` npm package.**

## How releasing works in this repo

- `.github/workflows/release-drafter.yml` runs on **every push to `master`**. As PRs
  merge, it maintains a single **draft** GitHub Release whose tag auto-increments (the
  patch version bumps after each publish). There is always exactly one draft waiting to
  be published.
- Publishing that draft (the release `published` event) triggers
  `.github/workflows/publish-schemas.yml`, which:
  - waits for any in-flight `generate-artifacts-from-schemas.yml` run to settle so it
    publishes generated artifacts rather than stale sources,
  - stamps the release version into `schemas/base_cloud.yml` and `schemas/base_meshery.yml`
    and commits it back to `master`,
  - **publishes the `@meshery/schemas` package to npm** (via `publish-npm-package.yml`,
    using OIDC trusted publishing with provenance),
  - notifies extension-partner dependents (`notify-dependents.yml`), and
  - publishes the OpenAPI docs (`publish-openapi-docs.yml`).

So the tag is already chosen and the notes are already drafted. Your job is only to make
sure the just-merged PR is reflected in the draft, then publish it. **Do not create a tag,
do not bump a version, do not write release notes by hand, and do not `npm publish` by
hand** - Release Drafter owns the tag/notes and the release event owns the npm publish.

## Steps

### 1. Confirm the Release Drafter run for the latest master commit has finished

The draft only includes a PR after the drafter workflow run for that merge commit completes.
If you publish too early, the just-merged PR is missing from the notes.

```bash
# Latest master commit that should be in the release
git fetch origin master --quiet && git rev-parse origin/master

# Most recent Release Drafter runs (headSha should match origin/master, status "completed")
gh run list --workflow="release-drafter.yml" --branch master --limit 3 \
  --json databaseId,status,conclusion,headSha,createdAt
```

If the run for the current `origin/master` SHA is still `in_progress` (or absent because the
push just landed), wait for it before publishing:

```bash
gh run watch <databaseId> --exit-status
```

A `conclusion` of `success` for the run whose `headSha` matches `origin/master` means the draft
is up to date. If the latest run **failed**, stop and surface that - do not publish stale notes.

### 2. Identify and inspect the draft

```bash
# Tag of the current draft (there is normally exactly one)
gh release list --limit 25 --json tagName,isDraft --jq '.[] | select(.isDraft) | .tagName'

# Read the draft notes and confirm the recently merged PR appears in them
gh release view <draftTag> --json tagName,name,isDraft,body --jq \
  '{tag: .tagName, name: .name, isDraft: .isDraft, body: .body}'
```

Verify the merged PR the user is releasing shows up under one of the category headings. If it
does not, the drafter run from step 1 has not yet indexed it - re-check step 1 rather than
publishing without it.

If more than one draft is ever returned, stop and ask the user which to publish rather than
guessing - publishing the wrong one ships an unintended version to npm.

### 3. Publish the draft

Flipping `--draft=false` publishes it and fires the `published` event that drives the npm
publish, dependent notifications, and OpenAPI-docs publish. Mark it `--latest` so it carries the
"Latest" badge.

```bash
gh release edit <draftTag> --draft=false --latest
```

### 4. Confirm it published

```bash
gh release view <draftTag> --json tagName,isDraft,isLatest,publishedAt --jq \
  '{tag: .tagName, isDraft: .isDraft, isLatest: .isLatest, publishedAt: .publishedAt}'

# Optionally watch the release fan-out (npm publish + notify + docs)
gh run list --workflow="publish-schemas.yml" --limit 3 \
  --json databaseId,status,conclusion,headBranch,createdAt
```

`isDraft: false` and a non-null `publishedAt` confirm the release is out. Report the published
version to the user and note that the `publish-schemas` workflow has been triggered by the release
event and will publish `@meshery/schemas` to npm, notify dependents, and publish the OpenAPI docs.

## What to watch for

- **Don't publish ahead of the drafter run.** The most common failure is publishing before the
  Release Drafter workflow has folded the merged PR into the notes, shipping a release whose notes
  omit the very change being released. Step 1 exists to prevent exactly this.
- **The release *is* the npm publish.** There is no separate "publish to npm" button - publishing
  the draft is what pushes `@meshery/schemas` to the registry. Treat the publish as production.
- **Never hand-author the tag or notes.** If you find yourself computing a version number or
  writing changelog entries, something is wrong - Release Drafter already did both.
- **One draft only.** If `gh release list` shows zero drafts, no drafter run has occurred since the
  last release; if it shows more than one, ask the user which to publish.
