Fixes false validation failures when "interface online" message scrolls
out of view due to verbose BLE startup logging (100+ lines in first minute).
Changes:
- Clear logfile before starting rnsd (new step 7/8)
- Separate stop and start into distinct steps for cleaner restart
- Validate from first 200 lines (head) instead of last 100 (tail)
- Rename RECENT_LOGS to STARTUP_LOGS for clarity
This ensures "interface online" is always in the validation window
regardless of time delay between deployment and validation jobs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The validation script checks ~/.reticulum/logfile for BLE interface
status, but this file is only created when rnsd is started with the
-s (service/syslog) flag.
Without -s flag:
- rnsd runs but doesn't write to ~/.reticulum/logfile
- Validation script fails: "Log file not found"
- Deployment appears successful but validation always fails
With -s flag:
- rnsd writes logs to ~/.reticulum/logfile
- Validation can check for "interface online" message
- Full deployment + validation cycle works
Note: Only affects manual rnsd startup (non-systemd path). Systemd
installations should have -s configured in the service file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Completely refactored the deployment workflow to create separate
GitHub Actions nodes for each Pi, with independent deploy and
validation steps. This provides much better visibility and control.
New Architecture:
1. **setup** job: Parses PI_HOSTS into JSON matrix
2. **deploy** job: Matrix execution (one instance per Pi)
3. **validate** job: Matrix execution (one instance per Pi)
4. **summary** job: Aggregate results
GitHub Actions Graph View (2 Pis):
```
setup ━┳━> deploy-pi-0 ━> validate-pi-0
┗━> deploy-pi-1 ━> validate-pi-1
```
Features:
- **Parallel execution**: All Pis deploy simultaneously
- **Independent nodes**: Each Pi has its own deploy + validate node
- **fail-fast: false**: One Pi failure doesn't block others
- **Per-Pi logs**: Clean, isolated logs for each device
- **Comprehensive validation**:
* Wait 5s for startup
* Check rnsd process
* Verify BLE interface online (retry 3x with 3s delay)
* Check Bluetooth adapter powered
* Display adapter MAC address
- **Better error reporting**: Shows which specific Pi failed
- **Granular status**: See each Pi's status independently
Validation Checks:
✓ rnsd process running
✓ Log file exists
✓ No critical errors in logs
✓ "interface online" message found
✓ Bluetooth adapter powered
✓ Retry logic for startup delays
Benefits:
- Easier to identify which Pi has issues
- Can re-run individual Pi jobs
- Faster deployment (parallel vs sequential)
- Clearer progression in GitHub UI
- Each Pi's logs are isolated and clean
Example UI with failure:
```
setup ✓
├─ deploy-pi-0 ✓
│ └─ validate-pi-0 ✗ (BLE failed to start)
└─ deploy-pi-1 ✓
└─ validate-pi-1 ✓ (BLE online)
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The deploy workflow was failing to start rnsd because the SSH session's
PATH doesn't include ~/.local/bin where rnsd is installed.
Issue:
- rnsd installed at ~/.local/bin/rnsd (pip install --user)
- Non-interactive SSH session doesn't have ~/.local/bin in PATH
- Command "nohup rnsd" failed: "command not found"
- Deployment reported "Failed to start rnsd"
Fix:
- Define RNSD_BIN="$HOME/.local/bin/rnsd"
- Use full path when starting rnsd via nohup
- Works regardless of SSH session PATH configuration
Now deployment will successfully restart rnsd after copying updated files.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The deploy workflow was failing when manually triggered via workflow_dispatch
because it only checked for github.event.workflow_run.head_branch, which is
empty for manual triggers.
Issue:
- Manual trigger: gh workflow run deploy.yml --ref refactor/abstraction-layer
- BRANCH_NAME was empty ("")
- git checkout "" failed: "empty string is not a valid pathspec"
- Deployment failed on all Pis
Fix:
- Use fallback operator: github.event.workflow_run.head_branch || github.ref_name
- workflow_run trigger: uses head_branch (branch that triggered the tests)
- workflow_dispatch trigger: uses ref_name (branch being run on)
Now works for both:
- Automatic deployment after tests complete
- Manual deployment via workflow_dispatch or gh CLI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added workflow_dispatch trigger to allow manual deployment without
waiting for test workflow completion. This is useful for:
- Testing the deployment workflow
- Deploying when automatic trigger doesn't fire
- Re-deploying without pushing new code
Usage:
- Go to Actions → Deploy to Raspberry Pi → Run workflow
- Or via CLI: gh workflow run deploy.yml
Updated the if condition to run on either:
- Automatic trigger when tests complete successfully
- Manual trigger via workflow_dispatch
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The branches filter in workflow_run triggers can cause workflow validation
errors: "The workflow must contain at least one job with no dependencies."
According to GitHub Actions documentation, the branches/branches-ignore
filters are not well-supported in workflow_run triggers and can cause
validation issues.
Removed the branches filter - the workflow will now trigger when the
"Tests" workflow completes on any branch, which is the intended behavior.
Fixes workflow validation error on Line 11, Col 3.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed from invalid cross-workflow job dependency (needs) to workflow_run
trigger. Deploy now runs after "Tests" workflow completes successfully.
Changes:
- Trigger on workflow_run instead of push
- Only run if test workflow conclusion is success
- Use workflow_run event refs for branch/commit/actor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced heredoc syntax with a bash variable to avoid YAML parsing issues.
The deployment script is now stored in DEPLOY_SCRIPT variable and piped
to ssh via echo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed heredoc delimiter from EOF to DEPLOY_SCRIPT to avoid YAML parsing
issues. Also explicitly pass environment variables to SSH remote command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds continuous deployment workflow that automatically deploys code changes
to Raspberry Pi devices after tests pass.
Features:
- Runs on self-hosted runner after unit/integration tests complete
- Supports containerized runners (k3s/Docker) via SSH key secrets
- Deploys to multiple Pis in sequence with detailed logging
- Automatically restarts rnsd service after code update
- Fails entire job if any Pi deployment fails
Required secrets: PI_HOSTS, PI_REPO_PATH, PI_USER, PI_SSH_KEY
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>