Skip to content

Commit c0e5c10

Browse files
obj-pclaude
andauthored
Add CI, release workflow, and Homebrew distribution (#1)
* Add CI, release workflow, Homebrew distribution, and fix --help - GitHub Actions CI: build + test on push/PR to main - Release workflow: build binary, create GitHub Release, update Homebrew tap - Homebrew formula generator script (obj-p/homebrew-tap) - README: add brew install instructions - Fix --help printing raw error by routing HelpCommand through non-NSApp path Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use Xcode 26.3 in CI and release workflows Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dd4aea8 commit c0e5c10

5 files changed

Lines changed: 150 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: macos-15
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Select Xcode
16+
run: sudo xcode-select -s /Applications/Xcode_26.3.app
17+
18+
- name: Build
19+
run: swift build
20+
21+
- name: Test
22+
run: swift test --filter "PreviewsCoreTests"

.github/workflows/release.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
runs-on: macos-15
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Select Xcode
18+
run: sudo xcode-select -s /Applications/Xcode_26.3.app
19+
20+
- name: Get version from tag
21+
id: version
22+
run: |
23+
VERSION=${GITHUB_REF#refs/tags/v}
24+
echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
25+
26+
- name: Build release binary
27+
run: swift build -c release
28+
29+
- name: Package binary
30+
env:
31+
VERSION: ${{ steps.version.outputs.VERSION }}
32+
run: |
33+
STAGING="previewsmcp-${VERSION}-darwin-arm64"
34+
mkdir -p "$STAGING"
35+
cp .build/release/previewsmcp "$STAGING/"
36+
cp LICENSE "$STAGING/"
37+
cp README.md "$STAGING/"
38+
tar -czf "${STAGING}.tar.gz" "$STAGING"
39+
shasum -a 256 "${STAGING}.tar.gz" > "${STAGING}.tar.gz.sha256"
40+
41+
- name: Create GitHub Release
42+
env:
43+
GH_TOKEN: ${{ github.token }}
44+
VERSION: ${{ steps.version.outputs.VERSION }}
45+
run: |
46+
STAGING="previewsmcp-${VERSION}-darwin-arm64"
47+
gh release create "v${VERSION}" \
48+
"${STAGING}.tar.gz" \
49+
"${STAGING}.tar.gz.sha256" \
50+
--title "v${VERSION}" \
51+
--generate-notes
52+
53+
- name: Update Homebrew tap
54+
env:
55+
VERSION: ${{ steps.version.outputs.VERSION }}
56+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
57+
run: |
58+
if [ -z "$HOMEBREW_TAP_TOKEN" ]; then
59+
echo "HOMEBREW_TAP_TOKEN not set, skipping Homebrew tap update"
60+
exit 0
61+
fi
62+
63+
STAGING="previewsmcp-${VERSION}-darwin-arm64"
64+
SHA256="$(awk '{print $1}' "${STAGING}.tar.gz.sha256")"
65+
URL="https://github.com/obj-p/PreviewsMCP/releases/download/v${VERSION}/${STAGING}.tar.gz"
66+
67+
bash scripts/generate-formula.sh "$VERSION" "$URL" "$SHA256" > previewsmcp.rb
68+
69+
git clone "https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/obj-p/homebrew-tap.git" tap-repo
70+
mkdir -p tap-repo/Formula
71+
cp previewsmcp.rb tap-repo/Formula/previewsmcp.rb
72+
cd tap-repo
73+
git config user.name "github-actions[bot]"
74+
git config user.email "github-actions[bot]@users.noreply.github.com"
75+
git add Formula/previewsmcp.rb
76+
if git diff --cached --quiet; then
77+
echo "Formula already up to date"
78+
exit 0
79+
fi
80+
git commit -m "previewsmcp ${VERSION}"
81+
git push origin main

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ Render and interact with SwiftUI previews outside of Xcode. Works as a CLI tool
1313

1414
## Installation
1515

16+
### Homebrew
17+
18+
```bash
19+
brew tap obj-p/tap
20+
brew install previewsmcp
21+
```
22+
1623
### From source
1724

1825
```bash

Sources/PreviewsCLI/PreviewsMCPApp.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ struct PreviewsMCPApp {
1818
PreviewsMCPCommand.exit(withError: error)
1919
}
2020

21-
// ListCommand doesn't need NSApplication
22-
if command is ListCommand {
21+
// Commands that don't need NSApplication (list, help, etc.)
22+
if command is ListCommand || !(command is RunCommand || command is ServeCommand || command is SnapshotCommand) {
2323
do {
2424
var mutable = command
2525
try mutable.run()
@@ -45,8 +45,7 @@ struct PreviewsMCPApp {
4545
var mutable = command
4646
try mutable.run()
4747
} catch {
48-
print("Error: \(error)")
49-
NSApp.terminate(nil)
48+
PreviewsMCPCommand.exit(withError: error)
5049
}
5150
}
5251
}

scripts/generate-formula.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
# Generates a Homebrew formula for previewsmcp
3+
# Usage: generate-formula.sh <version> <url> <sha256>
4+
set -euo pipefail
5+
6+
VERSION="$1"
7+
URL="$2"
8+
SHA256="$3"
9+
10+
cat <<EOF
11+
class Previewsmcp < Formula
12+
desc "SwiftUI preview renderer with MCP server for AI-driven UI development"
13+
homepage "https://github.com/obj-p/PreviewsMCP"
14+
license "MIT"
15+
version "${VERSION}"
16+
17+
url "${URL}"
18+
sha256 "${SHA256}"
19+
20+
depends_on :macos
21+
22+
def install
23+
bin.install "previewsmcp"
24+
end
25+
26+
def caveats
27+
<<~EOS
28+
previewsmcp requires Xcode 16+ to compile SwiftUI previews at runtime.
29+
For iOS simulator support, Apple Silicon is required.
30+
EOS
31+
end
32+
33+
test do
34+
assert_match "SwiftUI previews", shell_output("#{bin}/previewsmcp --help")
35+
end
36+
end
37+
EOF

0 commit comments

Comments
 (0)