Skip to content

Commit a5b5b74

Browse files
committed
updated readme
1 parent d94bbe6 commit a5b5b74

File tree

2 files changed

+188
-3
lines changed

2 files changed

+188
-3
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ cupertino save
152152
{
153153
"mcpServers": {
154154
"cupertino": {
155-
"command": "/usr/local/bin/cupertino"
155+
"command": "/opt/homebrew/bin/cupertino"
156156
}
157157
}
158158
}
159159
```
160160

161-
> **Note:** The `cupertino` command defaults to `cupertino serve` when run without arguments.
161+
> **Note:** Use `/opt/homebrew/bin/cupertino` for Homebrew on Apple Silicon, `/usr/local/bin/cupertino` for Intel or manual install. Run `which cupertino` to find your path.
162162
163163
2. **Restart Claude Desktop**
164164

@@ -172,7 +172,7 @@ cupertino save
172172
If you're using [Claude Code](https://docs.anthropic.com/en/docs/claude-code), you can add Cupertino as an MCP server with a single command:
173173

174174
```bash
175-
claude mcp add cupertino --scope user -- /usr/local/bin/cupertino
175+
claude mcp add cupertino --scope user -- $(which cupertino)
176176
```
177177

178178
This registers Cupertino globally for all your projects. Claude Code will automatically have access to Apple documentation search.
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Releasing Cupertino 4.0.0: New Features and Hard Lessons in Release Engineering
2+
3+
**December 9, 2025**
4+
5+
Today I released Cupertino 4.0.0, and it was... an adventure. What should have been a straightforward release turned into a masterclass in why release engineering is hard and why automation exists.
6+
7+
## What's New in 4.0.0
8+
9+
First, the good stuff. This release brings some significant improvements:
10+
11+
### Human Interface Guidelines Support
12+
13+
Cupertino can now crawl and index Apple's Human Interface Guidelines. This was issue #69, and it's been on my list for a while.
14+
15+
```bash
16+
cupertino fetch --type hig
17+
```
18+
19+
There's also a new `search_hig` MCP tool that lets AI agents search design guidelines with platform and category filters. So now when you ask Claude "what are Apple's recommendations for buttons?", it can actually look it up.
20+
21+
### Framework Aliases
22+
23+
This one's subtle but important. Before, if you searched for "Core Animation", you might not find results indexed under "QuartzCore" (the actual framework import name). Now there are 249 framework aliases in the database, so searches work regardless of which name variant you use:
24+
25+
- `QuartzCore``CoreAnimation``Core Animation`
26+
- `CoreGraphics``Quartz2D``Quartz 2D`
27+
28+
### Swift.org Fixes
29+
30+
The Swift.org crawler was broken. The base URL had changed from `docs.swift.org` to `www.swift.org/documentation/`, and the indexer was looking for `.md` files when the crawler was saving `.json` files. Classic.
31+
32+
## The Release Process Disaster
33+
34+
Here's where it gets interesting. I had all the code ready, all the tests passing, and I was ready to ship. The process seemed simple:
35+
36+
1. Bump version in `Constants.swift`
37+
2. Update `README.md` and `CHANGELOG.md`
38+
3. Create git tag
39+
4. Push tag (triggers GitHub Actions build)
40+
5. Upload databases to `cupertino-docs`
41+
6. Update Homebrew formula
42+
43+
What could go wrong?
44+
45+
### The Tag Timing Problem
46+
47+
I merged my feature branch, created the tag, pushed it... and then realized I hadn't committed the version bump to `main` yet. The tag pointed to a commit where `Constants.swift` still said `0.3.5`.
48+
49+
GitHub Actions dutifully built a beautiful, signed, notarized universal binary... that reported version `0.3.5`.
50+
51+
```bash
52+
$ cupertino --version
53+
0.3.5
54+
```
55+
56+
When users ran `cupertino setup`, it tried to download databases from `v0.3.5` instead of `v4.0.0`. Everything was broken.
57+
58+
### The Fix
59+
60+
I had to:
61+
62+
1. Delete the tag on GitHub
63+
2. Delete the local tag
64+
3. Make sure the version bump commit was pushed to `main`
65+
4. Verify the built binary reports correct version **before** tagging
66+
5. Recreate the tag
67+
6. Wait for GitHub Actions to rebuild
68+
7. Update the Homebrew formula with the new SHA256 (because the binary changed)
69+
70+
### The SHA256 Dance
71+
72+
Speaking of Homebrew—when I first updated the formula, I grabbed the SHA256 from the old (broken) binary. After rebuilding, the checksum changed. Users got:
73+
74+
```
75+
Error: Formula reports different checksum: cf035352...
76+
SHA-256 checksum of downloaded file: 5c5cf7ab...
77+
```
78+
79+
Another round of updating the tap.
80+
81+
## The Current Release Process
82+
83+
After today's adventures, here's what the release process actually looks like:
84+
85+
```bash
86+
# 1. Update version everywhere
87+
edit Packages/Sources/Shared/Constants.swift # version = "X.Y.Z"
88+
edit README.md # Version: X.Y.Z
89+
edit CHANGELOG.md # Add new section
90+
91+
# 2. Commit and push (BEFORE tagging!)
92+
git add -A && git commit -m "chore: bump version to X.Y.Z"
93+
git push origin main
94+
95+
# 3. Verify version is correct
96+
grep 'version = ' Packages/Sources/Shared/Constants.swift
97+
make build && ./Packages/.build/release/cupertino --version
98+
99+
# 4. Only now create the tag
100+
git tag -a vX.Y.Z -m "vX.Y.Z - Description"
101+
git push origin vX.Y.Z
102+
103+
# 5. Wait for GitHub Actions to build (~5 min)
104+
105+
# 6. Create GitHub release with notes
106+
107+
# 7. Build locally and install
108+
make build && sudo make install
109+
110+
# 8. Upload databases
111+
export GITHUB_TOKEN="cupertino-docs-token"
112+
cupertino release
113+
114+
# 9. Get new SHA256
115+
curl -sL https://github.com/.../cupertino-vX.Y.Z-macos-universal.tar.gz.sha256
116+
117+
# 10. Update Homebrew tap
118+
cd /tmp && git clone .../homebrew-tap.git
119+
# Edit Formula/cupertino.rb with new version and SHA256
120+
git commit && git push
121+
122+
# 11. Verify on fresh machine
123+
brew update && brew install cupertino
124+
cupertino --version
125+
cupertino setup
126+
```
127+
128+
That's 11 steps across 4 different repositories (`cupertino`, `cupertino-docs`, `homebrew-tap`, and GitHub Actions). Each step depends on the previous one. Miss one, and you're rebuilding everything.
129+
130+
## Time for Automation?
131+
132+
I'm seriously considering writing a release script. The question is: Swift or Bash?
133+
134+
**Arguments for Swift:**
135+
- It's what the project is written in
136+
- Type safety would catch some mistakes
137+
- Could reuse existing code (like the GitHub API client from `ReleaseCommand.swift`)
138+
- Cross-platform if we ever need it
139+
140+
**Arguments for Bash:**
141+
- Simpler for orchestrating CLI commands
142+
- No compilation step
143+
- Everyone knows Bash (sort of)
144+
- GitHub Actions scripts are basically Bash anyway
145+
146+
I'm leaning toward Swift, honestly. The `cupertino release` command already handles database uploads with proper GitHub API integration. Extending it to handle the full release workflow would be cleaner than maintaining a separate Bash script.
147+
148+
Something like:
149+
150+
```bash
151+
cupertino release --full
152+
```
153+
154+
That would:
155+
1. Check for uncommitted changes
156+
2. Verify version consistency across all files
157+
3. Build and verify the binary version matches
158+
4. Create and push the tag
159+
5. Wait for GitHub Actions
160+
6. Upload databases
161+
7. Update the Homebrew tap
162+
163+
## Lessons Learned
164+
165+
1. **Order matters.** Commit the version bump before creating the tag. Seems obvious in retrospect.
166+
167+
2. **Verify before you ship.** Build the binary locally and check `--version` before tagging. Don't trust that "it should work."
168+
169+
3. **Document your release process.** I now have a detailed `DEPLOYMENT.md` with warnings about the order of operations.
170+
171+
4. **Automate what hurts.** If you make the same mistake twice, write a script. I made this mistake once—hopefully that's enough motivation.
172+
173+
## What's Next
174+
175+
- Fix the setup command animations (#96—they're completely broken)
176+
- Consider that release automation script
177+
- Maybe look at semantic-release or similar tools
178+
179+
For now, 4.0.0 is out. HIG support works. Framework aliases work. Swift.org is properly indexed again.
180+
181+
And I've learned more about release engineering than I wanted to in one afternoon.
182+
183+
---
184+
185+
*Cupertino is an Apple Documentation MCP Server. Check it out at [github.com/mihaelamj/cupertino](https://github.com/mihaelamj/cupertino).*

0 commit comments

Comments
 (0)