Skip to content

Commit 2fce8a7

Browse files
authored
Host release notes and project docs on the site (#271)
Adds scripts/build-site.mjs, which generates the pages that are derived from other sources: the changelog from GitHub Releases, plus notice, license, building and verification from the repo files. Markdown is rendered through GitHub's GFM endpoint so release notes look exactly as they do upstream without shipping a parser. Everything is baked at build time, so the published pages make no API calls. Adds a hand-written privacy page covering audio, text, each macOS permission and what declining it costs, and what touches the network. Repoints the homepage away from raw GitHub file links: release notes, build instructions, NOTICE, LICENSE and the verification checklist now resolve on the site. Outbound links remain only where GitHub is genuinely the destination — source, issues, wiki, and upstream VoiceInk. Sorting is by semantic version rather than release date: publishing the backfilled v1.0.4, v2.0.0 and v2.0.1 stamped them with today's published_at, which would have floated them above 2.6.1 and moved the "Latest" badge. Dates shown come from created_at, and the badge follows whichever release GitHub designates as latest. The release workflow regenerates and commits the pages whenever a release is published or edited, and `make site` does the same locally.
1 parent 18c63e0 commit 2fce8a7

11 files changed

Lines changed: 3064 additions & 11 deletions

File tree

.github/workflows/release.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ on:
2525
required: true
2626
type: string
2727

28+
# Keep the published changelog in step with GitHub Releases
29+
release:
30+
types: [published, edited, released, deleted]
31+
2832
permissions:
2933
contents: write
3034

@@ -60,3 +64,32 @@ jobs:
6064
echo "Upload a DMG with:"
6165
echo " gh release upload $TAG path/to/Zerm_VERSION_aarch64.dmg"
6266
fi
67+
68+
publish-changelog:
69+
name: Regenerate site changelog
70+
runs-on: ubuntu-latest
71+
steps:
72+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
73+
with:
74+
ref: Production
75+
76+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
77+
with:
78+
node-version: "22"
79+
80+
- name: Regenerate derived pages
81+
env:
82+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83+
run: node scripts/build-site.mjs
84+
85+
- name: Commit if changed
86+
run: |
87+
if git diff --quiet -- docs/; then
88+
echo "No changelog changes."
89+
exit 0
90+
fi
91+
git config user.name "github-actions[bot]"
92+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
93+
git add docs/
94+
git commit -m "Regenerate site changelog from releases"
95+
git push origin HEAD:Production

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,7 @@ help:
177177
@echo " dev Build and run the app (for development)"
178178
@echo " all Run full build process (default)"
179179
@echo " clean Remove build artifacts"
180-
@echo " help Show this help message"
180+
@echo " help Show this help message"
181+
# Regenerate the derived site pages (changelog, notice, license, building)
182+
site:
183+
node scripts/build-site.mjs

docs/building.html

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6+
<title>Build from source — Zerm</title>
7+
<meta name="description" content="Requirements, build commands, and release tooling for the native macOS app." />
8+
<meta name="theme-color" content="#0b0b0c" />
9+
<meta property="og:title" content="Build from source — Zerm" />
10+
<meta property="og:description" content="Requirements, build commands, and release tooling for the native macOS app." />
11+
<meta property="og:image" content="./icon.png" />
12+
<meta name="twitter:card" content="summary_large_image" />
13+
<link rel="icon" type="image/png" href="./icon.png" />
14+
<link rel="apple-touch-icon" href="./icon.png" />
15+
<link rel="stylesheet" href="./style.css" />
16+
</head>
17+
<body>
18+
<a class="skip" href="#main">Skip to content</a>
19+
20+
<header class="topbar">
21+
<div class="topbar-inner">
22+
<a class="brand" href="./" aria-label="Zerm home">
23+
<img src="./icon.png" alt="" class="brand-logo" width="28" height="28" />
24+
<span>Zerm</span>
25+
</a>
26+
<nav class="topbar-nav" aria-label="Primary">
27+
<a href="./#models">Models</a>
28+
<a href="./#dictation">Dictation</a>
29+
<a href="./#read-aloud">Read aloud</a>
30+
<a href="./privacy.html">Privacy</a>
31+
<a href="./changelog.html">Changelog</a>
32+
</nav>
33+
<div class="topbar-actions">
34+
<a class="ghost-link" href="https://github.com/arcusis/Zerm">GitHub</a>
35+
<a class="btn btn-light btn-sm" href="./#download">Download</a>
36+
</div>
37+
</div>
38+
</header>
39+
40+
<main id="main" class="page">
41+
<section class="page-hero">
42+
<p class="eyebrow">For developers</p>
43+
<h1>Build from source</h1>
44+
<p class="lede">Requirements, build commands, and release tooling for the native macOS app.</p>
45+
</section>
46+
<section class="doc"><div class="prose">
47+
<h1 dir="auto">Building Zerm</h1>
48+
<p dir="auto">This guide provides detailed instructions for building Zerm from source.</p>
49+
<h2 dir="auto">Prerequisites</h2>
50+
<p dir="auto">Before you begin, ensure you have:</p>
51+
<ul dir="auto">
52+
<li>macOS 14.4 or later</li>
53+
<li>Xcode (latest version recommended)</li>
54+
<li>Swift (latest version recommended)</li>
55+
<li>Git (for cloning repositories)</li>
56+
</ul>
57+
<h2 dir="auto">Quick Start with Makefile (Recommended)</h2>
58+
<p dir="auto">The easiest way to build Zerm is using the included Makefile, which automates the entire build process including building and linking the whisper framework.</p>
59+
<h3 dir="auto">Simple Build Commands</h3>
60+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#</span> Clone the repository</span>
61+
git clone https://github.com/Arcusis/Zerm.git
62+
<span class="pl-c1">cd</span> Zerm
63+
64+
<span class="pl-c"><span class="pl-c">#</span> Build everything (recommended for first-time setup)</span>
65+
make all
66+
67+
<span class="pl-c"><span class="pl-c">#</span> Or for development (build and run)</span>
68+
make dev</pre></div>
69+
<h3 dir="auto">Available Makefile Commands</h3>
70+
<ul dir="auto">
71+
<li><code class="notranslate">make check</code> or <code class="notranslate">make healthcheck</code> - Verify all required tools are installed</li>
72+
<li><code class="notranslate">make whisper</code> - Clone and build whisper.cpp XCFramework automatically</li>
73+
<li><code class="notranslate">make setup</code> - Prepare the whisper framework for linking</li>
74+
<li><code class="notranslate">make build</code> - Build the Zerm Xcode project</li>
75+
<li><code class="notranslate">make local</code> - Build for local use (no Apple Developer certificate needed)</li>
76+
<li><code class="notranslate">make release</code> - Build the Developer ID signed + notarized release DMG (maintainers only)</li>
77+
<li><code class="notranslate">make run</code> - Launch the built Zerm app</li>
78+
<li><code class="notranslate">make dev</code> - Build and run (ideal for development workflow)</li>
79+
<li><code class="notranslate">make all</code> - Complete build process (default)</li>
80+
<li><code class="notranslate">make clean</code> - Remove build artifacts and dependencies</li>
81+
<li><code class="notranslate">make help</code> - Show all available commands</li>
82+
</ul>
83+
<h3 dir="auto">How the Makefile Helps</h3>
84+
<p dir="auto">The Makefile automatically:</p>
85+
<ol dir="auto">
86+
<li><strong>Manages Dependencies</strong>: Creates a dedicated <code class="notranslate">~/Zerm-Dependencies</code> directory for all external frameworks</li>
87+
<li><strong>Builds Whisper Framework</strong>: Clones whisper.cpp and builds the XCFramework with the correct configuration</li>
88+
<li><strong>Handles Framework Linking</strong>: Sets up the whisper.xcframework in the proper location for Xcode to find</li>
89+
<li><strong>Verifies Prerequisites</strong>: Checks that git, xcodebuild, and swift are installed before building</li>
90+
<li><strong>Streamlines Development</strong>: Provides convenient shortcuts for common development tasks</li>
91+
</ol>
92+
<p dir="auto">This approach ensures consistent builds across different machines and eliminates manual framework setup errors.</p>
93+
<hr>
94+
<h2 dir="auto">Building for Local Use (No Apple Developer Certificate)</h2>
95+
<p dir="auto">If you don't have an Apple Developer certificate, use <code class="notranslate">make local</code>:</p>
96+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate">git clone https://github.com/Arcusis/Zerm.git
97+
<span class="pl-c1">cd</span> Zerm
98+
make <span class="pl-k">local</span>
99+
open <span class="pl-k">~</span>/Downloads/Zerm.app</pre></div>
100+
<p dir="auto">This builds Zerm with ad-hoc signing using a separate build configuration (<code class="notranslate">LocalBuild.xcconfig</code>) that requires no Apple Developer account.</p>
101+
<h3 dir="auto">How It Works</h3>
102+
<p dir="auto">The <code class="notranslate">make local</code> command uses:</p>
103+
<ul dir="auto">
104+
<li><code class="notranslate">LocalBuild.xcconfig</code> to override signing and entitlements settings</li>
105+
<li><code class="notranslate">Zerm.local.entitlements</code> (stripped-down, no CloudKit/keychain groups)</li>
106+
<li><code class="notranslate">LOCAL_BUILD</code> Swift compilation flag for conditional code paths</li>
107+
</ul>
108+
<p dir="auto">Your normal <code class="notranslate">make all</code> / <code class="notranslate">make build</code> commands are completely unaffected.</p>
109+
<hr>
110+
<h2 dir="auto">Building a Release (Maintainers)</h2>
111+
<p dir="auto">Public DMGs must be Developer ID signed <strong>and notarized</strong>, otherwise Gatekeeper<br>
112+
rejects the app on other Macs ("Zerm is damaged and can't be opened" /<br>
113+
"Apple could not verify Zerm is free of malware").</p>
114+
<p dir="auto">Requirements on the release machine:</p>
115+
<ul dir="auto">
116+
<li>The <code class="notranslate">Developer ID Application: Arcusis LTD (F9Z784RA6D)</code> certificate in the login keychain</li>
117+
<li>One-time notarization credential setup:</li>
118+
</ul>
119+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate">xcrun notarytool store-credentials zerm-notary \
120+
--key <span class="pl-k">~</span>/.appstoreconnect/private_keys/AuthKey_<span class="pl-k">&lt;</span>KEY-ID<span class="pl-k">&gt;</span>.p8 \
121+
--key-id <span class="pl-k">&lt;</span>KEY-ID<span class="pl-k">&gt;</span> \
122+
--issuer <span class="pl-k">&lt;</span>ISSUER-UUID<span class="pl-k">&gt;</span></pre></div>
123+
<p dir="auto">The issuer UUID is shown in App Store Connect under<br>
124+
<strong>Users and Access → Integrations → App Store Connect API</strong>.</p>
125+
<p dir="auto">Then build the release:</p>
126+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate">make release <span class="pl-c"><span class="pl-c">#</span> or: scripts/release.sh</span></pre></div>
127+
<p dir="auto">This builds the Release configuration, signs the app with Developer ID and the<br>
128+
hardened runtime, notarizes app and DMG with Apple, staples the tickets, and<br>
129+
verifies the result with <code class="notranslate">spctl</code>. The DMG lands in the repo root as<br>
130+
<code class="notranslate">Zerm_X.Y.Z_aarch64.dmg</code>, ready for <code class="notranslate">gh release upload</code>.</p>
131+
<p dir="auto"><code class="notranslate">SKIP_NOTARIZE=1 scripts/release.sh</code> does a signing-only dry run.</p>
132+
<hr>
133+
<h2 dir="auto">Manual Build Process (Alternative)</h2>
134+
<p dir="auto">If you prefer to build manually or need more control over the build process, follow these steps:</p>
135+
<h3 dir="auto">Building whisper.cpp Framework</h3>
136+
<ol dir="auto">
137+
<li>Clone and build whisper.cpp:</li>
138+
</ol>
139+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate">git clone https://github.com/ggerganov/whisper.cpp.git
140+
<span class="pl-c1">cd</span> whisper.cpp
141+
./build-xcframework.sh</pre></div>
142+
<p dir="auto">This will create the XCFramework at <code class="notranslate">build-apple/whisper.xcframework</code>.</p>
143+
<h3 dir="auto">Building Zerm</h3>
144+
<ol dir="auto">
145+
<li>Clone the Zerm repository:</li>
146+
</ol>
147+
<div class="highlight highlight-source-shell" dir="auto"><pre class="notranslate">git clone https://github.com/Arcusis/Zerm.git
148+
<span class="pl-c1">cd</span> Zerm</pre></div>
149+
<ol start="2" dir="auto">
150+
<li>
151+
<p dir="auto">Add the whisper.xcframework to your project:</p>
152+
<ul dir="auto">
153+
<li>Drag and drop <code class="notranslate">../whisper.cpp/build-apple/whisper.xcframework</code> into the project navigator, or</li>
154+
<li>Add it manually in the "Frameworks, Libraries, and Embedded Content" section of project settings</li>
155+
</ul>
156+
</li>
157+
<li>
158+
<p dir="auto">Build and Run</p>
159+
<ul dir="auto">
160+
<li>Build the project using Cmd+B or Product &gt; Build</li>
161+
<li>Run the project using Cmd+R or Product &gt; Run</li>
162+
</ul>
163+
</li>
164+
</ol>
165+
<h2 dir="auto">Development Setup</h2>
166+
<ol dir="auto">
167+
<li>
168+
<p dir="auto"><strong>Xcode Configuration</strong></p>
169+
<ul dir="auto">
170+
<li>Ensure you have the latest Xcode version</li>
171+
<li>Install any required Xcode Command Line Tools</li>
172+
</ul>
173+
</li>
174+
<li>
175+
<p dir="auto"><strong>Dependencies</strong></p>
176+
<ul dir="auto">
177+
<li>The project uses <a href="https://github.com/ggerganov/whisper.cpp" rel="noopener noreferrer" target="_blank">whisper.cpp</a> for transcription</li>
178+
<li>Ensure the whisper.xcframework is properly linked in your Xcode project</li>
179+
<li>Test the whisper.cpp installation independently before proceeding</li>
180+
</ul>
181+
</li>
182+
<li>
183+
<p dir="auto"><strong>Building for Development</strong></p>
184+
<ul dir="auto">
185+
<li>Use the Debug configuration for development</li>
186+
<li>Enable relevant debugging options in Xcode</li>
187+
</ul>
188+
</li>
189+
<li>
190+
<p dir="auto"><strong>Testing</strong></p>
191+
<ul dir="auto">
192+
<li>Run the test suite before making changes</li>
193+
<li>Ensure all tests pass after your modifications</li>
194+
</ul>
195+
</li>
196+
</ol>
197+
<h2 dir="auto">Troubleshooting</h2>
198+
<p dir="auto">If you encounter any build issues:</p>
199+
<ol dir="auto">
200+
<li>Clean the build folder (Cmd+Shift+K)</li>
201+
<li>Clean the build cache (Cmd+Shift+K twice)</li>
202+
<li>Check Xcode and macOS versions</li>
203+
<li>Verify all dependencies are properly installed</li>
204+
<li>Make sure whisper.xcframework is properly built and linked</li>
205+
</ol>
206+
<p dir="auto">For more help, please check the <a href="https://github.com/Arcusis/Zerm/issues" rel="noopener noreferrer" target="_blank">issues</a> section or create a new issue.</p>
207+
</div></section>
208+
</main>
209+
210+
<footer class="site-foot">
211+
<div class="foot-inner">
212+
<div class="foot-brand">
213+
<img src="./icon.png" alt="" width="24" height="24" />
214+
<span>Zerm</span>
215+
</div>
216+
<nav class="foot-links" aria-label="Footer">
217+
<a href="./#download">Download</a>
218+
<a href="./changelog.html">Changelog</a>
219+
<a href="./privacy.html">Privacy</a>
220+
<a href="./building.html">Build from source</a>
221+
<a href="./notice.html">Attribution</a>
222+
<a href="./license.html">License</a>
223+
</nav>
224+
<p class="foot-legal">
225+
© <span id="year"></span> Arcusis · GPLv3 · Based on VoiceInk by Beingpax
226+
</p>
227+
</div>
228+
</footer>
229+
230+
<script src="./site.js" defer></script>
231+
</body>
232+
</html>

0 commit comments

Comments
 (0)