Skip to content

Commit 2019cd5

Browse files
committed
Codex fixes.
1 parent 1257e2e commit 2019cd5

File tree

3 files changed

+52
-58
lines changed

3 files changed

+52
-58
lines changed

.github/workflows/release.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,6 @@ jobs:
7575
standalone/src-tauri/target/${{ matrix.target }}/release/nsis/x64/plugins/
7676
shell: bash
7777

78-
- name: Stage updater bundles
79-
run: |
80-
dest="standalone/src-tauri/target/${{ matrix.target }}/release/updater-bundles"
81-
mkdir -p "$dest"
82-
find standalone/src-tauri/target/${{ matrix.target }}/release/bundle \
83-
\( -name "*.tar.gz" -o -name "*.tar.gz.sig" -o -name "*.nsis.zip" -o -name "*.nsis.zip.sig" \) \
84-
-exec cp {} "$dest/" \;
85-
echo "Staged updater bundles:"
86-
ls -la "$dest/" 2>/dev/null || echo "(empty)"
87-
shell: bash
88-
8978
- name: Upload artifacts
9079
uses: actions/upload-artifact@v4
9180
with:
@@ -97,7 +86,6 @@ jobs:
9786
standalone/src-tauri/target/${{ matrix.target }}/release/bundle/**/*.dmg
9887
standalone/src-tauri/target/${{ matrix.target }}/release/bundle/**/*.app
9988
standalone/src-tauri/target/${{ matrix.target }}/release/bundle/**/*.AppImage
100-
standalone/src-tauri/target/${{ matrix.target }}/release/updater-bundles/*
10189
standalone/src-tauri/target/${{ matrix.target }}/release/bundle/nsis/**
10290
standalone/src-tauri/target/${{ matrix.target }}/release/nsis/**
10391
standalone/sidecar/**

docs/specs/deploy.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ Every release produces three artifact groups under one version and changelog:
77
| Artifact | Format | Destination |
88
|----------|--------|-------------|
99
| VSCode extension | `.vsix` | VS Code Marketplace + OpenVSX |
10-
| Standalone (Windows) | `.nsis.zip` (contains NSIS installer) | GitHub Release + Tauri updater |
10+
| Standalone (Windows) | `.exe` (NSIS installer) | GitHub Release + Tauri updater |
1111
| Standalone (macOS, Apple Silicon) | `.tar.gz` (contains signed `.app`) | GitHub Release + Tauri updater |
12-
| Standalone (Linux) | `.AppImage.tar.gz` (contains AppImage) | GitHub Release + Tauri updater |
12+
| Standalone (Linux) | `.AppImage` | GitHub Release + Tauri updater |
1313

1414
## Release checklist
1515

@@ -34,7 +34,7 @@ Human-driven steps, in order:
3434
9. **Verify the release**
3535
- Check GitHub Release assets are correct
3636
- On a Mac: extract the `.tar.gz`, open the `.app`, confirm no Gatekeeper warnings
37-
- On Windows: extract the `.nsis.zip`, run the installer, confirm no SmartScreen warnings
37+
- On Windows: run the `.exe` installer, confirm no SmartScreen warnings
3838
- Confirm Tauri auto-updater picks up the new version (test from a previous version)
3939
- Confirm VSCode extension is live on Marketplace and OpenVSX
4040

@@ -158,13 +158,13 @@ There are two independent signing layers. OS signing proves the executable is fr
158158
| Layer | What it signs | Who verifies | What happens without it |
159159
|-------|--------------|--------------|------------------------|
160160
| OS (codesign / jsign) | The executable (`.app` / `.exe`) | The OS, on launch | Gatekeeper / SmartScreen warnings |
161-
| Tauri updater (ed25519) | The update bundle (`.tar.gz` / `.nsis.zip`) | The running app, on update | Updater rejects the download |
161+
| Tauri updater (ed25519) | The update bundle (`.tar.gz` / `.exe` / `.AppImage`) | The running app, on update | Updater rejects the download |
162162

163163
**Order matters:** OS-sign the inner executable first, then package it into the update bundle, then Tauri-sign the bundle. The `.sig` file is generated from the final bundle that already contains the OS-signed binary.
164164

165165
```
166166
codesign/jsign the executable
167-
→ package into update bundle (.tar.gz / .nsis.zip)
167+
→ package into update bundle (.tar.gz for macOS; installer/AppImage directly on Windows/Linux)
168168
→ Tauri-sign the bundle → produces .sig file
169169
→ upload bundle + .sig to GitHub Release
170170
```
@@ -186,14 +186,15 @@ codesign/jsign the executable
186186
4. **Sign Windows** (OS layer)
187187
- Sign the inner exe: `jsign --storetype PIV --storepass "$PIN" --alias AUTHENTICATION --tsaurl http://ts.ssl.com --tsmode RFC3161 MouseTerm.exe`
188188
- Rebuild the NSIS installer around the signed exe
189-
- Sign the installer exe: `jsign ... MouseTerm-windows-x64.exe`
189+
- Sign the installer exe: `jsign ... MouseTerm-windows-x64-setup.exe`
190190
5. **Sign update bundles** (Tauri layer)
191-
- Tauri-sign each update bundle (the `.tar.gz` and `.nsis.zip` from steps 3-4) using `TAURI_SIGNING_PRIVATE_KEY`
191+
- Tauri-sign each update bundle using `TAURI_SIGNING_PRIVATE_KEY`
192+
- Current Tauri v2 output mode (`createUpdaterArtifacts: true`) uses the NSIS installer `.exe` directly on Windows and the `.AppImage` directly on Linux
192193
- This produces a `.sig` file per bundle
193194
- Build the update manifest JSON (see below) with the `.sig` contents inline
194195
6. **Create GitHub Release**
195196
- `gh release create v0.1.0 --title "v0.1.0" --notes-file CHANGELOG.md`
196-
- Upload: update bundles (`.tar.gz`, `.nsis.zip`, `.AppImage.tar.gz`)
197+
- Upload: update bundles (`.tar.gz`, `.exe`, `.AppImage`)
197198
7. **Verify** — spot-check signatures, confirm release assets are correct
198199
199200
### Resuming after failure
@@ -202,6 +203,7 @@ codesign/jsign the executable
202203
./scripts/sign-and-deploy.sh resume 0.1.0 # re-download + sign + release
203204
./scripts/sign-and-deploy.sh sign-mac # re-sign macOS only
204205
./scripts/sign-and-deploy.sh sign-win # re-sign Windows only
206+
./scripts/sign-and-deploy.sh sign-updates 0.1.0 # regenerate updater signatures from existing signed work
205207
./scripts/sign-and-deploy.sh release 0.1.0 # re-create GitHub Release only
206208
```
207209

@@ -211,18 +213,18 @@ All release assets use **stable filenames** (no version in the name). This allow
211213

212214
| Asset | Filename | Purpose |
213215
|-------|----------|---------|
214-
| Windows | `MouseTerm-windows-x64.nsis.zip` | Download + Tauri updater |
216+
| Windows | `MouseTerm-windows-x64-setup.exe` | Download + Tauri updater |
215217
| macOS | `MouseTerm-macos-aarch64.tar.gz` | Download + Tauri updater |
216-
| Linux | `MouseTerm-linux-x86_64.AppImage.tar.gz` | Download + Tauri updater |
218+
| Linux | `MouseTerm-linux-x86_64.AppImage` | Download + Tauri updater |
217219

218220
### Download hotlinks
219221

220222
The mouseterm.com download page can link directly to the latest release with no server-side logic:
221223

222224
```
223-
https://github.com/diffplug/mouseterm/releases/latest/download/MouseTerm-windows-x64.nsis.zip
225+
https://github.com/diffplug/mouseterm/releases/latest/download/MouseTerm-windows-x64-setup.exe
224226
https://github.com/diffplug/mouseterm/releases/latest/download/MouseTerm-macos-aarch64.tar.gz
225-
https://github.com/diffplug/mouseterm/releases/latest/download/MouseTerm-linux-x86_64.AppImage.tar.gz
227+
https://github.com/diffplug/mouseterm/releases/latest/download/MouseTerm-linux-x86_64.AppImage
226228
```
227229

228230
These can later be migrated to `mouseterm.com/download/...` URLs backed by Cloudflare R2 (for analytics) without changing anything in the app — only the website links and the updater endpoint URL in `tauri.conf.json` would change.
@@ -249,6 +251,8 @@ In `standalone/src-tauri/tauri.conf.json`:
249251
}
250252
```
251253

254+
`createUpdaterArtifacts: true` is the Tauri v2 artifact mode. In this mode Windows updates use the NSIS installer `.exe` directly, Linux updates use the `.AppImage` directly, and macOS updates use the `.app.tar.gz` archive. Do not configure `"v1Compatible"` unless intentionally producing legacy `.nsis.zip` and `.AppImage.tar.gz` updater bundles for old Tauri v1 clients.
255+
252256
And in the Rust app bootstrap (`standalone/src-tauri/src/lib.rs`), the updater plugin is registered with:
253257

254258
```rust
@@ -268,15 +272,15 @@ Generated by the local script after signing. The script writes it to `website/pu
268272
"pub_date": "2026-03-25T12:00:00Z",
269273
"platforms": {
270274
"windows-x86_64": {
271-
"url": "https://github.com/diffplug/mouseterm/releases/download/v0.1.0/MouseTerm-windows-x64.nsis.zip",
275+
"url": "https://github.com/diffplug/mouseterm/releases/download/v0.1.0/MouseTerm-windows-x64-setup.exe",
272276
"signature": "<contents of .sig file>"
273277
},
274278
"darwin-aarch64": {
275279
"url": "https://github.com/diffplug/mouseterm/releases/download/v0.1.0/MouseTerm-macos-aarch64.tar.gz",
276280
"signature": "<contents of .sig file>"
277281
},
278282
"linux-x86_64": {
279-
"url": "https://github.com/diffplug/mouseterm/releases/download/v0.1.0/MouseTerm-linux-x86_64.AppImage.tar.gz",
283+
"url": "https://github.com/diffplug/mouseterm/releases/download/v0.1.0/MouseTerm-linux-x86_64.AppImage",
280284
"signature": "<contents of .sig file>"
281285
}
282286
}

scripts/sign-and-deploy.sh

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ TSA_URL="http://ts.ssl.com"
4646
GITHUB_REPO="diffplug/mouseterm"
4747

4848
# Stable filenames for release assets (update bundles only)
49-
FNAME_WIN="MouseTerm-windows-x64.nsis.zip"
49+
FNAME_WIN="MouseTerm-windows-x64-setup.exe"
5050
FNAME_MAC="MouseTerm-macos-aarch64.tar.gz"
51-
FNAME_LINUX="MouseTerm-linux-x86_64.AppImage.tar.gz"
51+
FNAME_LINUX="MouseTerm-linux-x86_64.AppImage"
5252

5353
# =============================================================================
5454
# Helper Functions
@@ -507,39 +507,33 @@ sign_updates() {
507507
prompt_secret_multiline TAURI_SIGNING_PRIVATE_KEY "Enter Tauri signing private key"
508508

509509
local release_dir="$WORK_DIR/release-assets"
510+
rm -rf "$release_dir"
510511
mkdir -p "$release_dir"
511512

512513
# Collect update bundles with stable filenames
513514
# macOS .tar.gz (created by notarize step from signed+notarized .app)
514-
[[ -f "$SIGN_DIR/$FNAME_MAC" ]] && cp "$SIGN_DIR/$FNAME_MAC" "$release_dir/"
515-
516-
# Windows NSIS zip — rebuild with signed installer
517-
local win_nsis
518-
win_nsis=$(find "$SIGN_DIR/standalone-win-x64" -path "*/updater-bundles/*.nsis.zip" -o -name "*.nsis.zip" | head -1)
519-
if [[ -n "$win_nsis" ]]; then
520-
log "Rebuilding NSIS zip with signed installer..."
521-
local signed_installer="$SIGN_DIR/standalone-win-x64/bundle/nsis/"
522-
local nsis_tmp="$SIGN_DIR/nsis-repack"
523-
mkdir -p "$nsis_tmp"
524-
unzip -o "$win_nsis" -d "$nsis_tmp"
525-
# Find the signed installer and replace the one in the zip
526-
local signed_setup
527-
signed_setup=$(find "$SIGN_DIR/standalone-win-x64" -name "*setup*.exe" | head -1)
528-
if [[ -n "$signed_setup" ]]; then
529-
local inner_setup
530-
inner_setup=$(find "$nsis_tmp" -name "*setup*.exe" | head -1)
531-
if [[ -n "$inner_setup" ]]; then
532-
cp "$signed_setup" "$inner_setup"
533-
fi
534-
fi
535-
(cd "$nsis_tmp" && zip -r "$release_dir/$FNAME_WIN" .)
536-
rm -rf "$nsis_tmp"
537-
fi
538-
539-
# Linux AppImage.tar.gz
515+
[[ -f "$SIGN_DIR/$FNAME_MAC" ]] || error "macOS update bundle not found at $SIGN_DIR/$FNAME_MAC. Run signing and notarization first."
516+
cp "$SIGN_DIR/$FNAME_MAC" "$release_dir/"
517+
518+
# Windows NSIS installer. With Tauri v2 createUpdaterArtifacts=true,
519+
# the installer itself is the updater bundle; there is no .nsis.zip.
520+
local signed_setup
521+
signed_setup=$(find "$SIGN_DIR/standalone-win-x64" \
522+
-path "*/release/bundle/nsis/*setup*.exe" \
523+
-type f \
524+
| head -1)
525+
[[ -n "$signed_setup" ]] || error "Windows NSIS installer not found. Run Windows signing first."
526+
cp "$signed_setup" "$release_dir/$FNAME_WIN"
527+
528+
# Linux AppImage. With Tauri v2 createUpdaterArtifacts=true,
529+
# the AppImage itself is the updater bundle; there is no .AppImage.tar.gz.
540530
local linux_update
541-
linux_update=$(find "$SIGN_DIR/standalone-linux-x64" -path "*/updater-bundles/*.AppImage.tar.gz" -o -name "*.AppImage.tar.gz" | head -1)
542-
[[ -n "$linux_update" ]] && cp "$linux_update" "$release_dir/$FNAME_LINUX"
531+
linux_update=$(find "$SIGN_DIR/standalone-linux-x64" \
532+
-path "*/release/bundle/appimage/*.AppImage" \
533+
-type f \
534+
| head -1)
535+
[[ -n "$linux_update" ]] || error "Linux AppImage not found in signed work directory."
536+
cp "$linux_update" "$release_dir/$FNAME_LINUX"
543537

544538
# Generate .sig files for update bundles using Tauri CLI
545539
for bundle in "$release_dir/$FNAME_MAC" \
@@ -567,6 +561,10 @@ sign_updates() {
567561
[[ -f "$release_dir/$FNAME_WIN.sig" ]] && { sig_win=$(cat "$release_dir/$FNAME_WIN.sig"); rm "$release_dir/$FNAME_WIN.sig"; }
568562
[[ -f "$release_dir/$FNAME_LINUX.sig" ]] && { sig_linux=$(cat "$release_dir/$FNAME_LINUX.sig"); rm "$release_dir/$FNAME_LINUX.sig"; }
569563

564+
[[ -n "$sig_mac" ]] || error "Missing Tauri signature for $FNAME_MAC"
565+
[[ -n "$sig_win" ]] || error "Missing Tauri signature for $FNAME_WIN"
566+
[[ -n "$sig_linux" ]] || error "Missing Tauri signature for $FNAME_LINUX"
567+
570568
local website_manifest="$REPO_ROOT/website/public/standalone-latest.json"
571569
cat > "$website_manifest" <<EOF
572570
{
@@ -609,6 +607,9 @@ create_release() {
609607
check_command gh "brew install gh && gh auth login"
610608

611609
[[ -d "$release_dir" ]] || error "Release assets not found at $release_dir. Run signing steps first."
610+
for asset in "$FNAME_MAC" "$FNAME_WIN" "$FNAME_LINUX"; do
611+
[[ -f "$release_dir/$asset" ]] || error "Release asset missing: $release_dir/$asset. Run sign-updates first."
612+
done
612613

613614
# Extract changelog for this version
614615
local notes_file="$WORK_DIR/release-notes.md"
@@ -660,7 +661,7 @@ Commands:
660661
sign-mac Re-sign macOS app bundles
661662
notarize Re-notarize macOS apps
662663
sign-win Re-sign Windows executable
663-
sign-updates VER Re-generate Tauri update signatures and manifest
664+
sign-updates VER Re-generate Tauri update signatures and manifest from existing signed work
664665
release VERSION Re-create GitHub Release from existing signed assets
665666
666667
Environment Variables:
@@ -673,6 +674,7 @@ Examples:
673674
$(basename "$0") all 0.1.0 # Full pipeline
674675
$(basename "$0") resume 0.1.0 # Resume after CI completed
675676
$(basename "$0") sign-mac # Re-sign macOS only
677+
$(basename "$0") sign-updates 0.1.0 # Re-sign update bundles only
676678
$(basename "$0") release 0.1.0 # Re-create GitHub Release
677679
EOF
678680
}
@@ -730,7 +732,7 @@ main() {
730732
sign-updates)
731733
local version="${2:-}"
732734
[[ -z "$version" ]] && error "Usage: $(basename "$0") sign-updates <version>"
733-
prepare_sign_dir
735+
[[ -d "$SIGN_DIR" ]] || error "Signed work directory not found at $SIGN_DIR. Run all/resume first."
734736
sign_updates "$version"
735737
;;
736738
release)

0 commit comments

Comments
 (0)