release
Cut a Ducko release: update CHANGELOG.md on main, then push the X.Y.Z tag that triggers the release.yml CI workflow (build, sign, notarize, DMG, Sparkle…
Skill by ducko-im
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/ducko-im-release
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: devops, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/release
What's inside
- Skill name
release- Description
- Cut a Ducko release: update CHANGELOG.md on main, then push the X.Y.Z tag that triggers the release.yml CI workflow (build, sign, notarize, DMG, Sparkle appcast, GitHub Release). Use when the user asks to "cut a release", "publish a new version", "prepare a release", "tag a release", or "ship it".
- License
- GPL-3.0
- Instructions
- 90 lines in SKILL.md · view on GitHub
Files (2)
- SKILL.md
- local-release.md · references/
SKILL.md (first lines)
# Release
Cut a release straight from `main`: update the changelog, then push an `X.Y.Z` tag. CI does the build — the tag triggers `.github/workflows/release.yml`, which builds, signs, notarizes, packages a DMG, regenerates the Sparkle appcast, publishes a GitHub Release whose body comes from `CHANGELOG.md`, and asks ducko.im to rebuild. The signing, Sparkle and site rebuild secrets are already configured in CI. Releases are built exclusively via GitHub Actions — never locally.
There is no version file to bump — the marketing version comes from the tag, and `CHANGELOG.md` is the only prep artifact (`version.env` holds names, not the version; the build number is the commit count).
## Step 1: Determine the version
If the user did not give one, infer the next `X.Y.Z` from the latest tag and propose a patch/minor/major bump, then confirm:
```bash
git tag --sort=-v:refname | head -1
```
## Step 2: Update the changelog
Make sure `main` is clean and current (`git checkout main && git pull origin main`). `CHANGELOG.md` keeps a running `## [Unreleased]` section, so a release completes that section and then promotes it to a version heading.
**Scope: user-facing only, framed as a net delta.** `CHANGELOG.md` becomes the GitHub Release notes and the Sparkle update notes, so it must describe only what a user experiences between releases. Before promoting, review every `[Unreleased]` entry and:
- **Drop non-user changes.** CI, scripts, skills, tests, and refactors don't ship to users. `DuckoCLI`-only changes belong only when the CLI is part of what the release ships.
- **State the net delta from the last released version, not the development history.** The `[Unreleased]` section accumulates commit-by-commit, so it collects entries that only make sense relative to an intermediate unreleased build (e.g. "no longer does X" / "removed the Y glitch" where X or the Y bug never shipped). Rewrite or drop those so each entry reads as a change the previous release's users will actually notice.
- **Check each entry's subject against the last tag, don't just scan the phrasing.** A positively-phrased entry hides the same trap: a fix for a feature that arrived in this same cycle reads like something users would notice, but nobody on the previous release ever hit that bug. For every entry, confirm the thing it changes or fixes existed at the last tag — `git show <last-tag>:<path>`, plus `git log --follow -- <path>` when the file moved. When it did not, fold the entry into whatever introduced the feature, or drop it. One entry per net user-visible change, not one per commit.
- **Describe the experience, not the mechanism.** "Rooms remember their bookmark autojoin flag" is what a user sees; the stanza or storage detail belongs in the commit, not the release notes.
1. **Complete `[Unreleased]` via `/update-changelog`.** Run it to capture anything missing, then double-check completeness against `git log <last-tag>..HEAD --oneline` — that range always includes the prior `Update appcast.xml for <last>` commit (CI pushes it to `main` after the tag) as noise, and real changes can land *after* it, so don't stop scanning there.
2. **Promote** by inserting the version heading (`## [X.Y.Z] - YYYY-MM-DD`, today's date) under the kept-empty `## [Unreleased]` heading so the accumulated entries fall under the new version, add the `[X.Y.Z]: https://github.com/ducko-im/ducko/compare/<last-tag>...X.Y.Z` link reference (`.../releases/tag/X.Y.Z` for the first release), and repoint `[Unreleased]` to `compare/X.Y.Z...HEAD` (mirror the previous `Prepare release X.Y.Z` commit's changelog diff). `release.yml` extracts this version section as the GitHub Release notes.
## Step 3: Commit and push to main
```bash
git add CHANGELOG.md
git commit -m "Prepare release X.Y.Z"
git push origin main
```
The tag must land on a `main` commit: `release.yml` signs only commits reachable from `origin/main`, and it reads `CHANGELOG.md` at the tagged commit.
## Step 4: Tag and trigger the release
Dispatch a dry run and wait for it to pass before tagging when the signing or packaging inputs changed since the last tag:
```bash
git diff --stat <last-tag>..HEAD -- Package.swift Resources/Entitlements.plist Scripts/package_app.sh Scripts/create_dmg.sh Scripts/release.sh .github/workflows/release.yml
```
**Skip** the dry run when that diff is empty. It is the only check that signs, notarizes, and staples the real arm64 build, since CI's release smoke test stubs those tools:
```bash
gh workflow run release.yml --ref main -f version=X.Y.Z -f dry_run=true
gh run list --workflow release.yml --limit 1 # run ID, when the dispatch prints no URL
gh run watch <run-id> --exit-status
```
If the dry run fails, fix the cause on `main`, push, and dispatch again. Tag only after a dry run passes. A passing dry run uploads its artifacts for inspection.
Tag the latest `main` commit (the changelog commit, or a later dry-run fix) and push the tag — this is what starts CI:
```bash
git tag -a X.Y.Z -m "X.Y.Z"
git push origin X.Y.Z
```
`release.yml` then builds, signs, notarizes, generates the appcast, creates the `X.Y.Z` GitHub Release (notes from the changelog section), commits the updated `appcast.xml` back to `main`, and asks ducko.im to rebuild for the new version.
## Step 5: Finish
```bash
git pull origin main # pick up the appcast commit CI pushed
gh release view X.Y.Z # verify the Release and its assets
gh run list --commit "$(git rev-parse X.Y.Z^{commit})" # every workflow on the tagged commit
```
`ci.yml` runs on the tagged commit from its push to `main`, separately from `release.yml`, so a passing release run does not cover it. Report the release as done only once both have passed, waiting on an unfinished run with `gh run watch <run-id> --exit-status`. When the CI run failed, name the failure and fix it on `main`.
When only the release run's last step, `Rebuild ducko.im`, failed, the release is already published, so don't re-run the release. That step authenticates with `SITE_DISPATCH_TOKEN`, a fine-grained token with Actions: Read and write on `ducko-im/ducko-im.github.io`. Renew it when it has expired, then ask for the rebuild by hand:
```bash
gh workflow run deploy.yml -R ducko-im/ducko-im.github.io --ref main -f version=X.Y.Z
```
Without that, the site picks up the release on its next daily build.
## Notes
- Reserve each `X.Y.Z` for one set of artifacts — re-tagging a published version reuses the Release and appcast URLs for different content.
- The Sparkle EdDSA private key lives in the login Keychain under `generate_keys --account ducko` and is backed up in 1Password. `.build/artifacts/sparkle/Sparkle/bin/generate_keys --account ducko -p` must print the `SUPublicEDKey` in `Scripts/package_app.sh`. GitHub cannot show the `SPARKLE_PRIVATE_KEY` secret, so when its contents are in doubt, re-set it from that key (`generate_keys --account ducko -x <file>`, then `gh secret set SPARKLE_PRIVATE_KEY < <file>` and delete the file) rather than generating a new pair. A mismatched pair still publishes a release, but every later update fails signature verification for its users.
- If CI is unavailable, see [references/local-release.md](references/local-release.md) for the manual release procedure.From ducko-im/ducko, GPL-3.0.
More from ducko-im/ducko
- 0.629score
swift-testing
ducko-im
Expert guidance on Swift Testing for writing, reviewing, migrating, and debugging tests.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
accessibility
ducko-im
Apply platform accessibility best practices to SwiftUI, UIKit, and AppKit code.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
macos-ui-testing
ducko-im
Background-safe macOS app UI testing using Peekaboo CLI and osascript.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swiftui
ducko-im
Write, review, or improve SwiftUI code across state management, view composition, performance, modern APIs, navigation, animation, accessibility, Liquid Glass…
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swiftui-performance-audit
ducko-im
Audit and improve SwiftUI runtime performance from code review and architecture.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
writing-for-interfaces
ducko-im
Use when someone asks to write, rewrite, review, or improve text that appears inside a product or interface.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
macos-spm-app-packaging
ducko-im
Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-concurrency
ducko-im
Expert guidance on Swift Concurrency correctness, modern API usage, and async/await pitfalls in Swift 6.2+.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-language
ducko-im
Write, review, or improve Swift APIs and value-display formatting.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-security
ducko-im
Use when working with iOS/macOS Keychain Services (SecItem queries, kSecClass, OSStatus errors), biometric authentication (LAContext, Face ID, Touch ID)…
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swiftdata
ducko-im
Expert guidance for designing, writing, reviewing, and debugging SwiftData persistence in Swift and SwiftUI apps.
SkillAFreshness: A★ 7Claude Code +9 - 0.625score
lume-vm
ducko-im
Run Ducko UI work inside a disposable Lume macOS VM instead of on the host desktop: start and stop the VM, run commands in its logged-in GUI session…
SkillAFreshness: A★ 7Claude Code +9
Signals
- Stars
- 7
- Forks
- 0
- Open issues
- 4
- Last commit (this folder)
- Oct 18, 2026 (10 days ago)
- Last release
- Oct 23, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- GPL-3.0
- Repository
- github.com/ducko-im/ducko
- Website
- ducko.im
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from ducko-im
- 0.629score
swiftdata
ducko-im
Expert guidance for designing, writing, reviewing, and debugging SwiftData persistence in Swift and SwiftUI apps.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-security
ducko-im
Use when working with iOS/macOS Keychain Services (SecItem queries, kSecClass, OSStatus errors), biometric authentication (LAContext, Face ID, Touch ID)…
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-language
ducko-im
Write, review, or improve Swift APIs and value-display formatting.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
macos-spm-app-packaging
ducko-im
Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swift-concurrency
ducko-im
Expert guidance on Swift Concurrency correctness, modern API usage, and async/await pitfalls in Swift 6.2+.
SkillAFreshness: A★ 7Claude Code +9 - 0.629score
swiftui
ducko-im
Write, review, or improve SwiftUI code across state management, view composition, performance, modern APIs, navigation, animation, accessibility, Liquid Glass…
SkillAFreshness: A★ 7Claude Code +9
Cite this page
release skill. Agent Mart. https://agentmart.dev/skills/ducko-im-release (last updated 2026-10-24)