Skip to content

release: 0.10.4

release: 0.10.4 #14

Workflow file for this run

name: Desktop Release
on:
push:
tags:
- "v*"
permissions:
contents: write
jobs:
build-macos:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: npm
- name: Install dependencies
run: npm install
- name: Build Next.js
run: npm run build
- name: Compile Electron
run: npm run electron:compile
- name: Build macOS app
run: npx electron-builder --mac --publish always
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: macos-build
path: release/*.dmg
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: npm
- name: Install dependencies
run: npm install
- name: Build Next.js
run: npm run build
- name: Compile Electron
run: npm run electron:compile
- name: Build Windows app
run: npx electron-builder --win --publish always
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: windows-build
path: release/*.exe
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: npm
- name: Install dependencies
run: npm install
- name: Build Next.js
run: npm run build
- name: Compile Electron
run: npm run electron:compile
- name: Build Linux app
run: npx electron-builder --linux --publish always
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: linux-build
path: release/*.AppImage
update-release-notes:
needs: [build-macos, build-windows, build-linux]
runs-on: ubuntu-latest
steps:
- name: Update release notes
uses: actions/github-script@v7
with:
script: |
const tag = context.ref.replace('refs/tags/', '');
const { data: releases } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const release = releases.find(r => r.tag_name === tag);
if (!release) {
core.setFailed(`Release for tag ${tag} not found`);
return;
}
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
draft: false,
body: [
`## Altnautica Command ${tag}`,
'',
'Two weeks of work since 0.3.0. Polish, decomposition, a stronger type story across the agent boundary, and some real user-facing wins.',
'',
'---',
'',
'### Agent connection and cloud resilience',
'',
'- Capability negotiation at handshake. The GCS reads version and feature flags from the agent on connect and adapts the UI to what the agent actually supports. Older agents stay usable.',
'- Cloud relay paths bound their upstream proxy fetches with abort controllers, surface MQTT broker errors, and log reconnect attempts.',
'- Agent connection state reorganized into per-concern slices for cleaner separation of local vs cloud state.',
'',
'### Flight history and replay',
'',
'- Cloud-backed flight log pagination. The history pane fetches in pages instead of pulling all logs at once, which keeps load fast even after a long ops season.',
'- Locale-aware number rendering across history and stats surfaces using `Intl.NumberFormat` for currency, percent, and decimal.',
'',
'### Telemetry and HUD',
'',
'- TopBar tree memoized through a dedicated hook that subscribes only to telemetry version and ring-buffer references. Removes per-tick re-renders during flight data updates.',
'- Stale-data badges on system resource gauges, sparklines, and service tables when data is older than 45 seconds.',
'',
'### Video pipeline',
'',
'- Video store reads slimmed via selector slicing.',
'- WebRTC peer cleanup stops both receiver and sender tracks before closing the connection. No more leaked tracks on disconnect.',
'- Single timer replaces the 1-second retry countdown for streaming reconnect.',
'',
'### Flight controller panels',
'',
'- Six FC panels (Rate Profile, Power, VTX, Ports, GPS, LED) now use a shared `useParamPanelActions` hook with one canonical save / flash / revert path. Less drift between panels.',
'- iNav configuration panels and the Drone Configure tab decomposed via re-export aggregators. Imports unchanged for callers.',
'- Mock protocol corrections for iNav: MSP command IDs, decoder entry sizes, and settings marshaling now match real hardware.',
'',
'### Type safety',
'',
'- Seventeen new Zod schemas validate agent API responses at the boundary.',
'- Fifty-plus `any` casts removed from the agent client manager. Thirteen endpoints are now safely parsed.',
'- New `npm run generate:agent-types` produces a typed agent API client from the OpenAPI spec.',
'',
'### UI polish',
'',
'- Three-group visual layout for Command sub-tabs with keyboard navigation.',
'- Fleet sidebar virtualizes when more than twelve drones are connected.',
'- Persisted Zustand stores carry version numbers and migration handlers, so future schema changes do not strand existing user data.',
'',
'### Bug fixes',
'',
'- Cloud sync auto-walks paginated flight logs.',
'- Panel params hook accepts `readonly string[]` for `paramNames`, preventing inline-spread arrays from triggering refetch loops.',
'- MQTT subscription failures surface broker rejections in the UI.',
'- Changelog timeline query skips when Convex is unavailable instead of crashing.',
'- WebRTC track lifecycle hardened.',
'',
'---',
'',
'### Downloads',
'',
'- **macOS:** `.dmg` (Intel and Apple Silicon)',
'- **Windows:** `.exe` installer',
'- **Linux:** `.AppImage`',
'',
'> Desktop builds may lag behind the web version.',
'> For the latest, use [command.altnautica.com](https://command.altnautica.com)',
'> or clone the repo and run locally (`npm install && npm run dev`).',
].join('\n'),
});