more work
This commit is contained in:
108
BUILD.md
Normal file
108
BUILD.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Building RideAware Trainer
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Local Development Build
|
||||
```bash
|
||||
npm run electron:dev
|
||||
```
|
||||
|
||||
### Production Builds
|
||||
|
||||
#### Linux (from Linux)
|
||||
```bash
|
||||
npm run electron:build:linux
|
||||
```
|
||||
Builds: AppImage, deb, rpm (requires Ubuntu/Debian for deb/rpm)
|
||||
|
||||
#### Windows (from Windows)
|
||||
```bash
|
||||
npm run electron:build:win
|
||||
```
|
||||
Builds: NSIS installer (.exe)
|
||||
|
||||
#### macOS (from macOS)
|
||||
```bash
|
||||
npm run electron:build:mac
|
||||
```
|
||||
Builds: DMG, ZIP
|
||||
|
||||
## Cross-Platform Builds with GitHub Actions
|
||||
|
||||
The easiest way to build for all platforms is using GitHub Actions:
|
||||
|
||||
### Automatic Release Build
|
||||
```bash
|
||||
git tag v1.0.1
|
||||
git push origin v1.0.1
|
||||
```
|
||||
|
||||
This triggers the workflow which:
|
||||
1. Builds on Windows, macOS, and Linux runners
|
||||
2. Creates a GitHub Release
|
||||
3. Uploads all installers (exe, dmg, AppImage, deb, rpm)
|
||||
|
||||
### Manual Build
|
||||
Go to: GitHub → Actions → Build and Release → Run workflow
|
||||
|
||||
## Build Artifacts
|
||||
|
||||
After building, files are in the `release/` directory:
|
||||
|
||||
- **Windows**: `RideAware Trainer Setup 1.0.0.exe`
|
||||
- **macOS**: `RideAware Trainer-1.0.0-arm64.dmg`, `RideAware Trainer-1.0.0-arm64-mac.zip`
|
||||
- **Linux**:
|
||||
- `RideAware Trainer-1.0.0.AppImage` (universal)
|
||||
- `rideaware-trainer_1.0.0_amd64.deb` (Debian/Ubuntu)
|
||||
- `rideaware-trainer-1.0.0.x86_64.rpm` (Fedora/RHEL)
|
||||
|
||||
## Platform Limitations
|
||||
|
||||
### Building from Linux
|
||||
- ✅ Linux packages (AppImage always works, deb/rpm need Ubuntu)
|
||||
- ❌ macOS DMG (requires macOS-specific dependencies)
|
||||
- ❌ Windows EXE (requires Windows or Wine)
|
||||
|
||||
### Building from macOS
|
||||
- ✅ macOS packages (DMG, ZIP)
|
||||
- ✅ Linux packages (with Docker)
|
||||
- ❌ Windows EXE (requires Windows or Wine)
|
||||
|
||||
### Building from Windows
|
||||
- ✅ Windows packages (EXE)
|
||||
- ✅ Linux packages (with WSL/Docker)
|
||||
- ❌ macOS DMG (requires macOS)
|
||||
|
||||
**Recommendation**: Use GitHub Actions for cross-platform builds.
|
||||
|
||||
## Icon Requirements
|
||||
|
||||
Place app icons in the `build/` directory:
|
||||
- `build/icon.ico` - Windows (256x256)
|
||||
- `build/icon.icns` - macOS (1024x1024)
|
||||
- `build/icon.png` - Linux (512x512)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "dmg-license not found" on Linux
|
||||
This is expected. Build macOS packages on macOS or use GitHub Actions.
|
||||
|
||||
### "libcrypt.so.1 not found" on Fedora
|
||||
Install compatibility package or use GitHub Actions (runs on Ubuntu).
|
||||
|
||||
### Build hangs on "packaging"
|
||||
Check available disk space. Electron builds can use 500MB+ per platform.
|
||||
|
||||
## GitHub Actions Workflow
|
||||
|
||||
The workflow file is at `.github/workflows/build.yml`.
|
||||
|
||||
**Triggers:**
|
||||
- Push to `main` branch (builds but doesn't release)
|
||||
- Push tag starting with `v` (builds and creates release)
|
||||
- Manual workflow dispatch
|
||||
- Pull requests (builds but doesn't release)
|
||||
|
||||
**Permissions needed:**
|
||||
- Repository Settings → Actions → General → Workflow permissions
|
||||
- Enable "Read and write permissions"
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
getWorkoutsByMonth,
|
||||
getTodaysWorkouts,
|
||||
getWeeksWorkouts,
|
||||
markWorkoutComplete,
|
||||
completeWorkout as apiCompleteWorkout,
|
||||
} from '../services/api';
|
||||
import type { ApiWorkout } from '../types/api';
|
||||
import type { Workout, WorkoutInterval } from '../types/workout';
|
||||
@@ -166,17 +166,19 @@ export function useCalendarWorkouts(): UseCalendarWorkoutsReturn {
|
||||
maxPower?: number;
|
||||
maxHr?: number;
|
||||
caloriesBurned?: number;
|
||||
syncToStrava?: boolean;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
await markWorkoutComplete(workoutId, {
|
||||
duration: Math.round(metrics.duration / 60),
|
||||
await apiCompleteWorkout(workoutId, {
|
||||
duration: Math.round(metrics.duration),
|
||||
distance: metrics.distance,
|
||||
avg_power: metrics.avgPower,
|
||||
avg_hr: metrics.avgHr,
|
||||
max_power: metrics.maxPower,
|
||||
max_hr: metrics.maxHr,
|
||||
calories_burned: metrics.caloriesBurned,
|
||||
sync_to_strava: metrics.syncToStrava ?? true,
|
||||
});
|
||||
await refresh();
|
||||
} catch (err) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { api } from './client';
|
||||
import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload } from '../../types/api';
|
||||
import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload, WorkoutCompletionPayload } from '../../types/api';
|
||||
|
||||
export async function getWorkouts(): Promise<ApiWorkout[]> {
|
||||
return api.get<ApiWorkout[]>('/protected/workouts');
|
||||
@@ -35,6 +35,13 @@ export async function markWorkoutComplete(
|
||||
});
|
||||
}
|
||||
|
||||
export async function completeWorkout(
|
||||
id: number,
|
||||
completionData: WorkoutCompletionPayload
|
||||
): Promise<ApiWorkout> {
|
||||
return api.post<ApiWorkout>(`/protected/workouts/complete?id=${id}`, completionData);
|
||||
}
|
||||
|
||||
export async function skipWorkout(id: number, notes?: string): Promise<ApiWorkout> {
|
||||
return api.put<ApiWorkout>(`/protected/workouts?id=${id}`, {
|
||||
status: 'skipped',
|
||||
|
||||
@@ -151,3 +151,15 @@ export interface WorkoutUpdatePayload {
|
||||
calories_burned?: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface WorkoutCompletionPayload {
|
||||
duration: number;
|
||||
distance?: number;
|
||||
avg_power?: number;
|
||||
avg_hr?: number;
|
||||
max_power?: number;
|
||||
max_hr?: number;
|
||||
calories_burned?: number;
|
||||
notes?: string;
|
||||
sync_to_strava?: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user