name: Deploy to Raspberry Pi on: workflow_run: workflows: ["Tests"] types: - completed workflow_dispatch: jobs: deploy: name: Deploy to Raspberry Pis runs-on: self-hosted # Only run if tests passed (for workflow_run) or if manually triggered if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} steps: - name: Validate required secrets run: | if [ -z "${{ secrets.PI_HOSTS }}" ]; then echo "Error: PI_HOSTS secret is not set" echo "Please set PI_HOSTS secret with comma-separated hostnames (e.g., 'pi1.local,pi2.local')" exit 1 fi if [ -z "${{ secrets.PI_REPO_PATH }}" ]; then echo "Error: PI_REPO_PATH secret is not set" echo "Please set PI_REPO_PATH secret with repository path (e.g., '/home/pi/ble-reticulum')" exit 1 fi if [ -z "${{ secrets.PI_USER }}" ]; then echo "Error: PI_USER secret is not set" echo "Please set PI_USER secret with SSH username (e.g., 'pi')" exit 1 fi if [ -z "${{ secrets.PI_SSH_KEY }}" ]; then echo "Error: PI_SSH_KEY secret is not set" echo "Please set PI_SSH_KEY secret with SSH private key for Pi access" exit 1 fi echo "All required secrets are configured" - name: Setup SSH key env: PI_SSH_KEY: ${{ secrets.PI_SSH_KEY }} run: | # Create .ssh directory if it doesn't exist mkdir -p ~/.ssh chmod 700 ~/.ssh # Write SSH private key to file echo "$PI_SSH_KEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 # Disable strict host key checking for known local hosts cat >> ~/.ssh/config <>> Deploying to $HOST..." # Create deployment script DEPLOY_SCRIPT="set -e echo ' [1/7] Navigating to repository...' cd '$PI_REPO_PATH' || exit 1 echo ' [2/7] Fetching latest changes...' git fetch --all || exit 1 echo ' [3/7] Checking out branch: $BRANCH_NAME...' git checkout '$BRANCH_NAME' || exit 1 echo ' [4/7] Pulling latest code...' git pull || exit 1 echo ' [5/7] Creating ~/.reticulum/interfaces directory...' mkdir -p ~/.reticulum/interfaces || exit 1 echo ' [6/7] Copying interface files...' cp -v src/RNS/Interfaces/*.py ~/.reticulum/interfaces/ || exit 1 echo ' [7/7] Restarting rnsd...' RNSD_BIN=\"\$HOME/.local/bin/rnsd\" if systemctl is-active --quiet rnsd 2>/dev/null; then sudo systemctl restart rnsd || exit 1 echo ' ✓ rnsd restarted via systemd' else pkill -9 rnsd 2>/dev/null || true sleep 1 nohup \"\$RNSD_BIN\" > /dev/null 2>&1 & sleep 2 if pgrep -x rnsd > /dev/null; then echo ' ✓ rnsd started successfully' else echo ' ✗ Failed to start rnsd' exit 1 fi fi echo ' ✓ Deployment successful!'" # Deploy with error handling if echo "$DEPLOY_SCRIPT" | ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "$PI_USER@$HOST" bash; then echo "✓ Successfully deployed to $HOST" SUCCESSFUL_HOSTS+=("$HOST") else echo "✗ Failed to deploy to $HOST" FAILED_HOSTS+=("$HOST") fi echo "" done # Print summary echo "===================================" echo "Deployment Summary" echo "===================================" echo "Successful: ${#SUCCESSFUL_HOSTS[@]}/${#HOSTS[@]}" if [ ${#SUCCESSFUL_HOSTS[@]} -gt 0 ]; then printf ' ✓ %s\n' "${SUCCESSFUL_HOSTS[@]}" fi if [ ${#FAILED_HOSTS[@]} -gt 0 ]; then echo "" echo "Failed: ${#FAILED_HOSTS[@]}/${#HOSTS[@]}" printf ' ✗ %s\n' "${FAILED_HOSTS[@]}" echo "" echo "===================================" exit 1 fi echo "===================================" - name: Cleanup SSH key if: always() run: | # Remove SSH key for security rm -f ~/.ssh/id_ed25519 echo "SSH key cleaned up" - name: Deployment status if: always() run: | echo "## Deployment Results" >> $GITHUB_STEP_SUMMARY echo "- **Branch:** ${{ github.event.workflow_run.head_branch }}" >> $GITHUB_STEP_SUMMARY echo "- **Commit:** ${{ github.event.workflow_run.head_sha }}" >> $GITHUB_STEP_SUMMARY echo "- **Triggered by:** ${{ github.event.workflow_run.actor.login }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [ "${{ job.status }}" == "success" ]; then echo "✓ All Raspberry Pis deployed successfully" >> $GITHUB_STEP_SUMMARY else echo "✗ Deployment failed on one or more Raspberry Pis" >> $GITHUB_STEP_SUMMARY echo "Check the job logs for details" >> $GITHUB_STEP_SUMMARY fi