Skip to content

Commit efbb74f

Browse files
committed
docs: rewrite release script
1 parent 757eb6b commit efbb74f

1 file changed

Lines changed: 59 additions & 158 deletions

File tree

‎RELEASING.md‎

Lines changed: 59 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,49 @@
11
# Releasing CodexMonitor (macOS)
22

3-
This guide is written for fresh agents and humans. It assumes the machine has
4-
no access to private keys by default. Signing and notarization require the
5-
Developer ID certificate and notarization credentials, which must be provided
6-
by a human.
7-
8-
## Prereqs (Human-Provided)
9-
10-
- Apple Developer account with Team ID.
11-
- Developer ID Application certificate installed in Keychain.
12-
- Notarization credentials for `notarytool`:
13-
- Apple ID + app-specific password, or
14-
- App Store Connect API key.
15-
16-
## Versioning
17-
18-
Read the current version and decide the next release tag:
3+
This is a copy/paste friendly script-style guide. It assumes you have a
4+
Developer ID Application certificate installed and a `notarytool` keychain
5+
profile named `codexmonitor-notary`.
196

207
```bash
21-
cat src-tauri/tauri.conf.json
22-
cat package.json
23-
```
8+
set -euo pipefail
249

25-
Bump both to the release version before building. After the release is published, bump both to the next minor.
26-
27-
## Build (Signed for Updater)
28-
29-
The updater requires signing artifacts during the build. Export the private key
30-
before `tauri build`:
31-
32-
```bash
33-
export TAURI_SIGNING_PRIVATE_KEY=~/.tauri/codexmonitor.key
34-
# optional if you set a password
35-
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
36-
```
10+
# --- Set versions ---
11+
# Update these two values each release.
12+
RELEASE_VERSION="0.4.3"
13+
PREV_VERSION="0.4.2"
3714

38-
```bash
15+
# --- Update version fields (manual check afterwards) ---
16+
perl -pi -e "s/\"version\": \"[^\"]+\"/\"version\": \"${RELEASE_VERSION}\"/" package.json
17+
perl -pi -e "s/\"version\": \"[^\"]+\"/\"version\": \"${RELEASE_VERSION}\"/" src-tauri/tauri.conf.json
3918
npm install
40-
npm run tauri build
41-
```
42-
43-
The app bundle is produced at:
44-
45-
```
46-
src-tauri/target/release/bundle/macos/CodexMonitor.app
47-
```
4819

49-
## Bundle OpenSSL (Required for distribution)
20+
# --- Commit + push version bump ---
21+
git add package.json package-lock.json src-tauri/tauri.conf.json
22+
git commit -m "chore: bump version to ${RELEASE_VERSION}"
23+
git push origin main
5024

51-
The app links to OpenSSL. Bundle and re-sign the OpenSSL dylibs:
25+
# --- Build (signed for updater) ---
26+
export TAURI_SIGNING_PRIVATE_KEY=~/.tauri/codexmonitor.key
27+
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="release"
28+
npm run tauri -- build --bundles app
5229

53-
```bash
54-
CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
30+
# --- Bundle OpenSSL + re-sign app ---
31+
CODESIGN_IDENTITY="Developer ID Application: Thomas Ricouard (Z6P74P6T99)" \
5532
scripts/macos-fix-openssl.sh
56-
```
5733

58-
## Sign + Notarize + Staple (Human Step)
59-
60-
1) Confirm signing identity (from Keychain):
61-
62-
```bash
63-
security find-identity -v -p codesigning
64-
```
65-
66-
2) Zip the app:
67-
68-
```bash
34+
# --- Zip, notarize, staple ---
6935
ditto -c -k --keepParent \
7036
src-tauri/target/release/bundle/macos/CodexMonitor.app \
7137
CodexMonitor.zip
72-
```
7338

74-
3) Store notary credentials (one-time per machine):
75-
76-
```bash
77-
xcrun notarytool store-credentials codexmonitor-notary \
78-
--apple-id "you@apple.com" \
79-
--team-id "TEAMID" \
80-
--password "app-specific-password"
81-
```
82-
83-
If the profile already exists in Keychain, reuse it:
84-
85-
```bash
86-
--keychain-profile "codexmonitor-notary"
87-
```
88-
89-
Validate the profile (works even if listing is unsupported):
90-
91-
```bash
92-
xcrun notarytool history --keychain-profile "codexmonitor-notary"
93-
```
94-
95-
4) Submit for notarization and wait:
96-
97-
```bash
9839
xcrun notarytool submit CodexMonitor.zip \
99-
--keychain-profile "codexmonitor-notary" \
40+
--keychain-profile codexmonitor-notary \
10041
--wait
101-
```
102-
103-
5) Staple the app:
10442

105-
```bash
10643
xcrun stapler staple \
10744
src-tauri/target/release/bundle/macos/CodexMonitor.app
108-
```
109-
110-
## Package Release Artifacts
11145

112-
Note: Tauri's DMG bundling can fail if the generated `bundle_dmg.sh` script
113-
is invoked without arguments. The manual packaging flow below is the fallback
114-
and is the expected path if that happens.
115-
116-
```bash
46+
# --- Package ZIP + DMG from stapled app ---
11747
mkdir -p release-artifacts release-artifacts/dmg-root
11848
rm -rf release-artifacts/dmg-root/CodexMonitor.app
11949
ditto src-tauri/target/release/bundle/macos/CodexMonitor.app \
@@ -126,90 +56,61 @@ ditto -c -k --keepParent \
12656
hdiutil create -volname "CodexMonitor" \
12757
-srcfolder release-artifacts/dmg-root \
12858
-ov -format UDZO \
129-
release-artifacts/CodexMonitor_<RELEASE_VERSION>_aarch64.dmg
130-
```
131-
132-
## Rebuild Updater Bundle (After Stapling)
133-
134-
After stapling, rebuild the updater tarball and re-sign it so the signature
135-
matches the stapled app:
59+
release-artifacts/CodexMonitor_${RELEASE_VERSION}_aarch64.dmg
13660

137-
```bash
138-
tar -czf src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz \
61+
# --- Rebuild updater tarball without AppleDouble files ---
62+
COPYFILE_DISABLE=1 tar -czf \
63+
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz \
13964
-C src-tauri/target/release/bundle/macos CodexMonitor.app
14065

14166
npm run tauri signer sign -- \
14267
-f ~/.tauri/codexmonitor.key \
143-
-p "<PASSWORD_IF_SET>" \
68+
-p "release" \
14469
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz
145-
```
146-
147-
## Generate Changelog (from git log)
148-
149-
Create release notes from the tag range using plain git log:
150-
151-
```bash
152-
git log --name-only --pretty=format:"%h %s" v<PREV_VERSION>..v<RELEASE_VERSION>
153-
```
154-
155-
Summarize user-facing changes into short bullet points and use them in the GitHub release notes.
156-
157-
## Tag, Release, and Updater Manifest (with gh)
158-
159-
Tag first so the changelog is tied to the release tag:
16070

161-
```bash
162-
git tag v<RELEASE_VERSION>
163-
git push origin v<RELEASE_VERSION>
164-
```
71+
# --- Changelog (for release notes) ---
72+
git log --name-only --pretty=format:"%h %s" v${PREV_VERSION}..v${RELEASE_VERSION}
16573

166-
Create the GitHub release with artifacts:
74+
# --- Tag ---
75+
git tag v${RELEASE_VERSION}
76+
git push origin v${RELEASE_VERSION}
16777

168-
```bash
169-
gh release create v<RELEASE_VERSION> \
170-
--title "v<RELEASE_VERSION>" \
171-
--notes "Signed + notarized macOS release." \
172-
release-artifacts/CodexMonitor.zip \
173-
release-artifacts/CodexMonitor_<RELEASE_VERSION>_aarch64.dmg
174-
```
78+
# --- Build latest.json for updater ---
79+
PUB_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
80+
SIGNATURE=$(cat src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz.sig)
17581

176-
Generate `latest.json` for the Tauri updater and upload it alongside the
177-
signed artifacts. The updater manifest should include short notes and point at
178-
the released artifacts + signatures.
179-
180-
```json
82+
cat <<EOF > release-artifacts/latest.json
18183
{
182-
"version": "<RELEASE_VERSION>",
183-
"notes": "- Short update notes\n- Keep it brief",
184-
"pub_date": "2025-01-01T12:00:00Z",
84+
"version": "${RELEASE_VERSION}",
85+
"notes": "- Short update notes",
86+
"pub_date": "${PUB_DATE}",
18587
"platforms": {
18688
"darwin-aarch64": {
187-
"url": "https://github.com/Dimillian/CodexMonitor/releases/download/v<RELEASE_VERSION>/CodexMonitor.app.tar.gz",
188-
"signature": "<BASE64_SIGNATURE>"
89+
"url": "https://github.com/Dimillian/CodexMonitor/releases/download/v${RELEASE_VERSION}/CodexMonitor.app.tar.gz",
90+
"signature": "${SIGNATURE}"
18991
}
19092
}
19193
}
192-
```
193-
194-
Signatures are generated during the build and emitted as `.sig` files next to
195-
the bundles. Upload both the `.sig` files and `latest.json` to the same release:
94+
EOF
19695

197-
```bash
198-
gh release upload v<RELEASE_VERSION> \
96+
# --- Create GitHub release with artifacts ---
97+
gh release create v${RELEASE_VERSION} \
98+
--title "v${RELEASE_VERSION}" \
99+
--notes "- Short update notes" \
199100
release-artifacts/CodexMonitor.zip \
200-
release-artifacts/CodexMonitor_<RELEASE_VERSION>_aarch64.dmg \
101+
release-artifacts/CodexMonitor_${RELEASE_VERSION}_aarch64.dmg \
201102
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz \
202103
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz.sig \
203-
latest.json \
104+
release-artifacts/latest.json
105+
106+
# --- If you need to update assets later ---
107+
gh release upload v${RELEASE_VERSION} \
108+
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz \
109+
src-tauri/target/release/bundle/macos/CodexMonitor.app.tar.gz.sig \
110+
release-artifacts/latest.json \
204111
--clobber
205112
```
206113

207-
After uploading, edit the GitHub release notes to use the changelog summary.
208-
209-
## Notes
210-
211-
- Signing/notarization cannot be performed without the Developer ID certificate
212-
and notarization credentials.
213-
- If the app fails to launch on another machine, verify OpenSSL is bundled:
214-
`otool -L .../CodexMonitor.app/Contents/MacOS/codex-monitor` should show
215-
`@rpath/libssl.3.dylib` and `@rpath/libcrypto.3.dylib`.
114+
Notes:
115+
- Never commit `~/.tauri/codexmonitor.key`.
116+
- If notarization fails, run `xcrun notarytool log <ID> --keychain-profile codexmonitor-notary`.

0 commit comments

Comments
 (0)