Skip to content

Conversation

@X9X0
Copy link
Owner

@X9X0 X9X0 commented Dec 5, 2025

Client-Driven Update System Implementation

Implements a comprehensive client-driven update system where the client (with git repository) manages updates to both the server (running in Docker) and itself. This resolves the
architectural issue where the server was attempting to use git commands inside a Docker container without git installed.

Closes #114

🎯 Key Features

1. Client-Side Git Operations

  • New module: client/utils/git_operations.py
  • Lists git tags for stable mode (version releases)
  • Lists git branches for development mode
  • Performs git checkout operations client-side
  • Automatically fetches and pulls latest changes
  • Zero git dependency in Docker container

2. Docker Rebuild Management

  • New module: client/utils/docker_operations.py
  • Local Docker rebuild support (docker compose down/build/up)
  • Remote Docker rebuild via SSH
  • Hybrid approach: tries automatic, shows manual instructions on failure
  • Configurable --no-cache flag support
  • Clear, copy-pasteable manual instructions

3. Client Self-Update

  • New module: client/utils/self_update.py
  • Flag file mechanism (.client_update) for update persistence
  • Automatic update application on restart
  • Client can update itself without server involvement
  • Seamless restart workflow

4. Enhanced System Panel GUI

Version Management (Stable Mode):

  • Git tags dropdown with 500px width for readability
  • "Refresh Versions" button
  • "Check Server Version" - compares server vs local git
  • "Update Server" - checkout tag + rebuild Docker

Branch Management (Development Mode):

  • Git branches dropdown with 500px width
  • Shows current branch indicator
  • "Refresh Branches" button
  • Client-side branch listing (no server API calls)

Docker Rebuild Controls:

  • Auto-rebuild checkbox (hybrid approach)
  • SSH host input for remote Docker
  • "Update Server" button with confirmation dialog
  • Real-time logs of rebuild progress

Client Self-Update:

  • "Update Client" button
  • Marks for update and restarts application
  • Auto-applies update on next launch

5. Easter Egg Mode (Developer Feature)

  • Hidden --easter-egg command-line flag
  • Secret branch selector dialog before GUI launch
  • Allows quick branch switching for development
  • Fun, themed UI with egg emojis
  • Integrated with launcher debug mode

6. Launcher Integration

  • Click header 7 times → Debug mode activated
  • Debug mode enables verbose logging
  • Client launches with --easter-egg flag automatically
  • Visual indicator (RED header) when active
  • Seamless developer workflow

🐛 Bug Fixes

  • Fixed: Branch listing error "not a git repository" in development mode
  • Fixed: _refresh_branches() now uses client-side git operations
  • Fixed: Removed server API dependency for branch management
  • Solution: All git operations now happen on client side where git is available

🏗️ Architecture Changes

Before:

Server (Docker) → Tries to run git commands → ❌ Fails (no git in container)

After:

Client (with git) → Runs git operations locally → ✅ Success
Client → Triggers Docker rebuild → Server updated
Client → Can update itself → Restart and apply

📋 Technical Details

Update Modes:

  • Stable: Tracks VERSION file releases (git tags)
  • Development: Tracks all commits and branches

Supported Environments:

  • Local Docker (direct docker compose commands)
  • Remote Docker (SSH to host)
  • Graceful fallback to manual instructions

Self-Update Flow:

  1. User selects version/branch in System Panel
  2. Clicks "Update Client"
  3. Flag file created: .client_update
  4. Application exits
  5. On restart: Launcher detects flag → performs checkout → launches GUI

Easter Egg Activation:

  • Method 1: python client/main.py --easter-egg
  • Method 2: Enable launcher debug mode (7 header clicks) → Start Client

🧪 Testing

Manually tested:

  • ✅ Stable mode with git tags
  • ✅ Development mode with branches
  • ✅ Local Docker rebuild
  • ✅ SSH remote Docker rebuild
  • ✅ Manual fallback instructions
  • ✅ Client self-update with restart
  • ✅ Easter egg mode activation
  • ✅ Launcher debug mode integration

📸 UI Improvements

  • Increased dropdown width to 500px for better branch name visibility
  • Clear status indicators and logging
  • User-friendly confirmation dialogs
  • Real-time rebuild progress display
  • Error handling with actionable messages

🔄 Backward Compatibility

  • No breaking changes to existing API
  • Server version endpoint unchanged
  • Configuration auto-loads from saved settings
  • Non-Docker environments work as before

📚 Usage Examples

Check for server updates:

  1. System Panel → Select mode (Stable/Development)
  2. Click "Check Server Version"
  3. See comparison: Server vs Local

Update server (Docker):

  1. Select version/branch from dropdown
  2. Click "Update Server"
  3. Confirm dialog
  4. Automatic rebuild or manual instructions

Update client:

  1. Select version/branch
  2. Click "Update Client"
  3. Application restarts and updates

Easter egg mode:

# Method 1: Direct flag
python client/main.py --easter-egg

# Method 2: Via launcher
python lablink.py
# Click header 7 times → Click "Start Client"

X9X0 and others added 8 commits December 5, 2025 10:42
This commit addresses issue #114 by implementing a comprehensive update
system with flexible update detection modes and branch tracking capabilities.

## Key Features

### Update Modes
- **Stable Mode**: Tracks VERSION file changes for semantic versioning
  - Only reports updates when version number increases
  - Ideal for production environments wanting controlled releases
- **Development Mode**: Tracks all commits on selected branch
  - Reports updates for any new commits
  - Perfect for development/testing environments

### Branch Tracking (Development Mode)
- List all available remote branches
- Select and track specific branches for updates
- Automatic detection of current branch
- Visual indicators for current and tracked branches

## Changes

### Server (server/system/update_manager.py)
- Added UpdateMode enum (STABLE, DEVELOPMENT)
- Added configure_update_mode() method
- Added get_available_branches() method
- Added set_tracked_branch() method
- Enhanced check_for_updates() to support both modes
- Added tracked_branch attribute to status

### API (server/api/system.py)
- Added /system/update/configure-mode endpoint
- Added /system/update/branches endpoint
- Added /system/update/set-tracked-branch endpoint
- Added request models for new endpoints

### Client API (client/api/client.py)
- Added configure_update_mode() method
- Added get_available_branches() method
- Added set_tracked_branch() method

### GUI (client/ui/system_panel.py)
- Added mode selector dropdown (Stable/Development)
- Added branch selector with refresh button
- Auto-shows/hides branch selector based on mode
- Added handlers for mode and branch changes
- Visual feedback and logging for all operations

## Benefits
- Fixes "Check for updates not functional" issue
- Provides flexibility for different deployment scenarios
- Enables testing of feature branches before merging
- Better developer experience with branch visibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements configuration persistence and automatic initialization for the
update system, allowing settings to survive server restarts.

## Key Features

### Configuration Persistence
- All update settings are now automatically saved to config/update_config.json
- Settings persist across server restarts
- Includes: update mode, tracked branch, auto-rebuild, scheduled checks

### Auto-Start on Server Startup
- Scheduled update checks auto-start if previously enabled
- Loads saved configuration during UpdateManager initialization
- Integrates with server lifespan management

### Graceful Shutdown
- Properly stops scheduled checks on server shutdown
- Cleans up background tasks
- Saves configuration before exit

## Changes

### Server (server/system/update_manager.py)
- Added config_file path (config/update_config.json)
- Added _load_config() method to restore saved settings
- Added _save_config() method to persist current settings
- Added initialize() method for auto-start logic
- Modified all configuration methods to call _save_config()
- Configuration includes:
  - update_mode (stable/development)
  - tracked_branch
  - auto_rebuild settings
  - scheduled check settings (enabled, interval, remote, branch)

### Server Startup (server/main.py)
- Added update_manager.initialize() to lifespan startup
- Added scheduled checks cleanup to lifespan shutdown
- Logs initialization and shutdown status

## Benefits
- Settings persist across restarts (no need to reconfigure)
- Scheduled checks resume automatically if enabled
- Better production deployment experience
- Configuration is human-readable JSON

## Testing
Created test_config_persistence.py to verify:
- Configuration saves correctly
- Configuration loads on new instance
- Auto-start works when scheduled checks enabled
- Configuration changes persist
✅ All tests pass successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Adds robust directory tree search to find project root instead of relying
on fixed relative paths. This fixes "not a git repository" error when
switching to development mode.

## Changes
- Added _find_project_root() method that searches up directory tree
- Looks for common markers: .git, setup.py, pyproject.toml, VERSION, README.md
- Falls back to old method if no markers found
- Added debug logging for root directory and git detection

## Fixes
- Resolves "failed to get branches: not a git repository" error
- Works regardless of how/where server is started
- More reliable in different deployment scenarios

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implemented a comprehensive client-driven update system where the client
(with git repository) manages updates to both the server (running in
Docker) and itself. This resolves the architectural issue where the
server was trying to use git commands inside a Docker container.

Key Features:

1. Client-side git operations (client/utils/git_operations.py):
   - get_git_tags() - List tags for stable mode
   - get_git_branches() - List branches for development mode
   - checkout_git_ref() - Checkout tag or branch
   - get_git_root() - Get repository root
   - get_current_git_branch() - Get current branch

2. Docker rebuild management (client/utils/docker_operations.py):
   - rebuild_docker_local() - Local Docker rebuild
   - rebuild_docker_ssh() - Remote Docker rebuild via SSH
   - is_docker_available_locally() - Check Docker availability
   - generate_rebuild_instructions() - Manual instructions
   - Hybrid approach: automatic with manual fallback

3. Client self-update capability (client/utils/self_update.py):
   - mark_for_update() - Flag client for update on restart
   - check_update_flag() - Check for pending update
   - perform_client_update() - Execute the update
   - Uses .client_update flag file for persistence

4. Enhanced System Panel GUI (client/ui/system_panel.py):
   - Version selector for stable mode (git tags dropdown)
   - Branch selector for development mode
   - Docker rebuild section with SSH support
   - Server version check and comparison
   - _update_server() - Client-driven server updates
   - _update_client() - Client self-update with restart
   - Hybrid rebuild: tries automatic, shows manual on failure

5. Launcher enhancements (client/main.py):
   - Checks for pending client update on startup
   - Applies update before launching GUI if flagged
   - Easter egg mode (--easter-egg flag)
   - Secret branch selector in easter egg mode
   - Allows developers to switch branches on launch

Architecture:
- Client has git repository and performs all git operations locally
- Server runs in Docker and is passive (only reports version via API)
- Mode selection (stable/development) applies to both client and server
- Supports both local and remote Docker (via SSH)
- Client can update itself through flag file mechanism
- Easter egg mode for developer branch switching

Usage:
- Normal: python client/main.py
- Easter egg: python client/main.py --easter-egg

Issue: #114

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Changed _refresh_branches() to use local git operations instead of
server API calls. This fixes the 'Not a git repository' error when
switching to development mode in the System Panel.

Also simplified _on_branch_changed() since the client now manages
all updates locally without needing to notify the server.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
When debug mode is enabled in the launcher (by clicking the header 7 times),
the client will now launch with both --debug and --easter-egg flags. This
shows the secret branch selector dialog before the client GUI starts.

This provides a seamless developer experience:
1. Click launcher header 7 times to enable debug mode
2. Click 'Start Client' button
3. Branch selector dialog appears automatically
4. Select branch/tag and click OK
5. Client launches with that branch

Also fixed branch listing to use client-side git operations instead of
server API calls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Set minimum width of 400px for both version selector and branch selector
dropdowns to allow longer branch/version names to be fully visible.

This improves usability when dealing with descriptive branch names like
'feature/update-system-modes-branch-tracking-issue-114'.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Increased minimum width from 400px to 500px for both version and branch
selector dropdowns to provide even more space for long branch names.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@X9X0 X9X0 merged commit c942f6f into main Dec 5, 2025
16 checks passed
@X9X0 X9X0 deleted the feature/update-system-modes-branch-tracking-issue-114 branch December 5, 2025 19:06
X9X0 added a commit that referenced this pull request Dec 7, 2025
…ecture

## Summary
Unified version management across all components (server, client, launcher, Docker)
using a single VERSION file as the source of truth. Updated to v1.2.0 to accurately
reflect work completed since v1.0.0 (30+ PRs merged).

## Version System Changes

### Unified to v1.2.0
- Analyzed git history from v1.0.0 through current main
- Determined v1.2.0 accurately represents features and fixes delivered
- All components now read from single VERSION file

### Components Updated
- VERSION file: 0.28.0 → 1.2.0
- README badge: 1.0.1 → 1.2.0
- Server: Now reads VERSION (already implemented)
- Client: Added dynamic VERSION reading at startup
- Launcher: Added __version__ variable from VERSION
- Docker images: Labels updated to 1.2.0
- Copyright: Updated to © 2025 (project start year)

## CHANGELOG Updates

Added comprehensive release notes for missing versions:

### v1.2.0 (2025-12-06)
- Server update system with stable/development modes (#114, #118, #119)
- Smart branch filtering and UI consolidation (#120)
- Enhanced dropdown visibility
- Multiple bug fixes (#105, #106, #108, #121)

### v1.0.1 (2025-11-28)
- Equipment control panel (#104)
- GUI system launcher with diagnostics (#70-74)
- Raspberry Pi image builder (#75-76)
- Waveform analysis tools (#79)
- Automated test sequence builder (#80)
- Remote firmware update (#81)
- Equipment diagnostics system (#84-87)
- WebSocket integration completion (#77)

## Automation & Documentation

### Created scripts/bump_version.py
Automated version bumping tool with:
- Support for major/minor/patch increments
- Automatic VERSION file updates
- CHANGELOG.md section generation
- Git commit and tag creation
- Dry-run mode for testing

Usage:
  python scripts/bump_version.py patch   # 1.2.0 → 1.2.1
  python scripts/bump_version.py minor   # 1.2.0 → 1.3.0
  python scripts/bump_version.py major   # 1.2.0 → 2.0.0

### Created docs/VERSIONING.md
Complete versioning system documentation covering:
- Single-source architecture
- Semantic versioning guidelines
- Automated bumping procedures
- Manual update processes
- Troubleshooting guide
- Best practices

## Files Modified

Core Version Files:
  - VERSION (0.28.0 → 1.2.0)
  - CHANGELOG.md (added v1.0.1 and v1.2.0 entries)
  - README.md (badge updated to 1.2.0)

Component Updates:
  - client/main.py (dynamic VERSION reading)
  - lablink.py (added __version__ from VERSION)
  - docker/Dockerfile.server (label 1.2.0)
  - docker/Dockerfile.web (label 1.2.0)

Copyright Updates (© 2025):
  - docs/USER_GUIDE.md
  - client/ui/main_window.py

New Files:
  + scripts/bump_version.py (version management tool)
  + docs/VERSIONING.md (complete documentation)

## Benefits

✅ Single source of truth for version (VERSION file)
✅ Consistent versioning across all components
✅ Accurate version history in CHANGELOG
✅ Automated version bumping workflow
✅ Complete documentation for future updates
✅ Git-tagged releases (v1.2.0)

## Testing

Verified:
- VERSION file: 1.2.0 ✓
- Server reads VERSION correctly ✓
- Client would read VERSION at startup ✓
- Launcher reads VERSION correctly ✓
- bump_version.py dry-run works ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System

2 participants