---
name: Deploy
slug: deploy-2
category: DevOps
description: "Deploy runs the Agent Sessions release flow: version bumping, changelog updates, build, signing, notarization, appcast publishing, and GitHub release creation. Use it when shipping a new app release from the local checkout."
github: "https://github.com/jazzyalex/agent-sessions/tree/main/.claude/skills/deploy"
language: Swift
stars: 806
forks: 52
install: "npx degit https://github.com/jazzyalex/agent-sessions/tree/main/.claude/skills/deploy ~/.claude/skills/deploy"
installs_to: ~/.claude/skills/deploy
source_path: .claude/skills/deploy/SKILL.md
collection_size: 8
category_size: 798
collection_url: "https://dirskills.com/collections/jazzyalex/agent-sessions"
added: 2026-08-22T05:22:14.379Z
last_synced: 2026-08-22T05:22:14.379Z
canonical_url: "https://dirskills.com/skills/deploy-2"
---

# Deploy

Deploy runs the Agent Sessions release flow: version bumping, changelog updates, build, signing, notarization, appcast publishing, and GitHub release creation. Use it when shipping a new app release from the local checkout.

**Install:**

```bash
npx degit https://github.com/jazzyalex/agent-sessions/tree/main/.claude/skills/deploy ~/.claude/skills/deploy
```

## README

# Deployment Skill (Agent Sessions)

This skill is an agent-facing entrypoint that avoids duplicating the deployment runbook.

## Canonical Sources (Single Source of Truth)

- Runbook: `docs/deployment.md`
- Unified tool: `tools/release/deploy` (see `tools/release/deploy --help`)
- Recommended pre-release QA checklist: `docs/release/pre-release-qa.md`

If anything here disagrees with the runbook, follow `docs/deployment.md`.

## Workspace Policy (Hard Rule)

- Always run deployment from the user's current local repository checkout.
- Do not clone to temporary directories and do not switch to alternate worktrees as a deployment workaround.
- If the local worktree is dirty, stop and tell the user to clean the tree first (commit, stash, or discard), then continue in the same local repo.

## QA Gate (Mandatory — Run Automatically Before Deploy)

- **Always run QA automatically** before any bump/release/verify step, unless the user explicitly says to skip it (e.g. "skip QA", "no QA").
- Do not ask whether to run QA — just run it.
- QA execution order:
  1. **Scope** — `git log --oneline --decorate -n 30` and `git diff --name-only <LAST_TAG>..HEAD`; identify high-risk areas.
  2. **Build** — `xcodebuild -project AgentSessions.xcodeproj -scheme AgentSessions -configuration Debug build`
  3. **Full test suite** — `./scripts/xcode_test_stable.sh`
  4. **Targeted tests** — run suites for touched high-risk areas (session parsing, usage tracking, onboarding, etc.)
  5. **Warnings sweep** — flag any new actionable warnings in build output.
  6. **Manual smoke reminder** — list the manual steps from `docs/release/pre-release-qa.md` §3–4 and ask the user to confirm GO/NO-GO after completing them.
- If automated gates fail → stop, report failure, do not proceed to bump/release.
- If user says "skip QA" or "no QA" → proceed without running, note it was skipped.

## Before Starting (Ask the User)

1. Target version (`X.Y` for major/minor releases, `X.Y.Z` only for patch releases; never ship `X.Y.0`)
2. Any headline changes (new agents, major features) that must be reflected in `docs/CHANGELOG.md`
3. Whether this is a major release that requires onboarding updates
4. Public copy updates needed for README/GitHub Pages (major changes to highlight, renamed features, or outdated wording to fix)

**Do NOT ask about QA status** — QA always runs automatically as part of pre-deploy (see QA Gate above).

## Public Copy Update (Required for All Releases)

### Always update (every release)
- `README.md` download link: `v{VERSION}/AgentSessions-{VERSION}.dmg` and label `Download Agent Sessions {VERSION} (DMG)`
- `README.md` Option A download link (second occurrence under Install section)
- `docs/index.html` download button URL and label
- `docs/index.html` `<meta name="description">` content (mention current version + key change)
- `docs/index.html` `<meta property="og:description">` content
- `docs/index.html` `<meta name="twitter:description">` content

### Update for minor/major or user-visible feature releases
- `README.md` "What's New in X.Y" section: update heading to new version, rewrite TL;DR and Highlights to reflect this release's key changes (do not keep old version's copy)
- `docs/index.html` hero/feature copy if features were renamed or new agents added

### Never add
- Versioned "What's New in X.Y" section to `docs/index.html`
- Detailed release notes to README or website (those live in `docs/CHANGELOG.md`)

## Never Announce a Bug the User Never Had (Hard Rule)

**A fix to a feature that ships in this same release is not a Bug Fix. It is development.**

When a feature is new in X.Y, every defect found and fixed in it before X.Y shipped was
never in anyone's hands. Listing those under "Bug Fixes" invents a history of breakage
users never experienced, and buries the actual feature under a list of things that sound
broken. Ship the feature; the fixes are part of it.

Before writing any Bug Fix entry, ask: **which released version had this bug?** If the
answer is "none — the code is new in this release", the entry does not exist. Fold
anything user-visible into the feature's own Highlight instead.

Worked example (4.8, Grok CLI's first release):
- ❌ "A Grok session shows the title its own sidecar records" — Grok shipped in 4.8; no
  user ever saw the wrong title.
- ❌ "Grok transcripts open with content in them" — same.
- ❌ "A Grok session's message count matches its transcript" — same.
- ✅ "Grok CLI is the eleventh current agent source…" — the Highlight, which already says
  transcripts, images, Analytics and resume work.

Mixed entries need splitting, not deleting: a fix spanning shipped **and** new sources is
real for the shipped ones. Describe it in terms of those, and drop the new source from the
list. In 4.8 the CLI PATH-masking fix covered Cursor, Kimi and Pi (all shipped) plus Grok
(new) — it stayed, naming only the three.

This applies identically to `docs/CHANGELOG.md`, the Sparkle notes, the GitHub release
body, and the README "What's New". The changelog is the source all of them derive from, so
fix it there first.

### After pushing
- Verify GitHub Pages reflects updated `docs/index.html` (check meta description and download button)

## Pre-Deploy Checklist (Run Before Bump)

- [ ] `docs/CHANGELOG.md` `[Unreleased]` section has full, accurate content for this release (this is the only changelog — root `CHANGELOG.md` is a pointer to it, not a copy to sync)
- [ ] Every Bug Fix entry names a defect that existed in a **released** version — no fixes to features shipping in this same release (see "Never Announce a Bug the User Never Had")
- [ ] In-app What's New has an entry for this version in `AgentSessions/Onboarding/Models/WhatsNewCatalog.swift` — both a `teasers` line and a `bundled` array. `hasContent` goes true on the auto-generated new-provider row alone, so a forgotten release still shows the card, just with one generic line and no teaser. Do not author a row for a new source by hand: `providerHighlights(for:)` generates it from `versionIntroduced`, and authoring it again shows it twice.
- [ ] README.md download links updated to new version (both occurrences)
- [ ] README.md "What's New" section updated to new version heading + rewritten highlights
- [ ] `docs/index.html` download button URL and label updated
- [ ] `docs/index.html` meta description, og:description, twitter:description updated with version + key change
- [ ] All above files committed before running `deploy bump` (or bump will overwrite)

## Sparkle Notes Are Short and Fun (Hard Rule)

Sparkle notes appear in a small update window. Nobody reads prose there. The 5.0 notes
shipped as full changelog paragraphs and had to be republished after the fact — don't
repeat that.

- **Highlight**: 2–4 sentences, hard max. Lead with the change, keep one concrete number
  if there is one, cut everything a curious reader can find in the changelog.
- **Feature / Bug Fix bullets**: 1–2 sentences. One for what changed, at most one for
  why it was wrong before. A good bug-fix line can be a single sentence
  ("Five agents used to skip it silently.").
- **Whole notes**: aim under ~250 words. If the preview scrolls, it's too long.
- **Tone**: dry fun is welcome — "takes no for an answer", "Bring the agent you use".
  Personality yes, marketing-speak no, emoji never.
- The full detail lives in `docs/CHANGELOG.md`; the notes may compress it freely.
  If an entry can't be compressed without losing the point, the changelog entry is
  overweight — tighten it there first (changelog entries also don't need to be essays).
- Links in changelog entries that feed the notes must be **absolute URLs** — relative
  links break in the appcast and the GitHub release body.
- To republish notes after a release: edit `docs/CHANGELOG.md`, then
  `python3 tools/release/sparkle_release_notes.py --version <V> --changelog docs/CHANGELOG.md --appcast docs/appcast.xml --github-url <release-url> --lint --out-text /tmp/notes.txt`,
  then `gh release edit v<V> --notes-file /tmp/notes.txt`, commit and push the appcast.

## Sparkle Release Notes (Approval Gate)

- The release pipeline generates **structured Sparkle notes** from `docs/CHANGELOG.md`:
  - Highlights or grouped current-release changes
  - Other changes (summary)
  - Reminder from the baseline release (for patch releases: `A.B`)
- During `tools/release/deploy release <VERSION>`, the deploy script prints a **Sparkle release notes preview** after build/sign/notarization and appcast validation.
- Treat the preview as user-facing product copy, not raw commit history:
  - Lead with the headline change the user should care about.
  - Do not include internal cleanup, validation fixes, or pre-release stabilization as “Bug Fixes” if users never received that broken behavior.
  - If the preview is misleading, stop and edit `docs/CHANGELOG.md` before publishing.
- If `SKIP_CONFIRM` is not `1`, it will pause and ask for approval before publishing (pushing appcast, updating Homebrew, updating the GitHub release).
- `SKIP_CONFIRM=1` requires `RELEASE_NOTES_REVIEWED=1` at the appcast publish gate; set it only after manually inspecting the Sparkle preview or for a rerun whose notes were already reviewed.
- The notes generator fails before publishing if notes contain obvious internal/process wording or put Bug Fixes ahead of a headline section.
- GitHub Release notes must use the same curated/linted notes as Sparkle, not raw commit history or raw changelog extraction.
- If the current release has no structured bullets, the generator adds a fallback highlight: `Small bug fixes and stability improvements.`

## Standard Workflow (Use the Unified Tool)

```bash
tools/release/deploy changelog [FROM_TAG]
tools/release/deploy bump [patch|minor|major]
git push origin main
tools/release/deploy release <VERSION> [--dry-run]
tools/release/deploy verify <VERSION>
```

## Failure Handling

- First stop: `docs/deployment.md` → Troubleshooting, logs, and rollback guidance.
- Rollback only after reviewing logs: `tools/release/rollback-release.sh <VERSION>`.
