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>
187 lines
6.2 KiB
YAML
187 lines
6.2 KiB
YAML
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 <<EOF
|
|
Host *.local 192.168.*
|
|
StrictHostKeyChecking no
|
|
UserKnownHostsFile /dev/null
|
|
LogLevel ERROR
|
|
EOF
|
|
chmod 600 ~/.ssh/config
|
|
|
|
echo "SSH key configured successfully"
|
|
|
|
- name: Deploy to Raspberry Pis
|
|
env:
|
|
PI_HOSTS: ${{ secrets.PI_HOSTS }}
|
|
PI_REPO_PATH: ${{ secrets.PI_REPO_PATH }}
|
|
PI_USER: ${{ secrets.PI_USER }}
|
|
BRANCH_NAME: ${{ github.event.workflow_run.head_branch }}
|
|
run: |
|
|
# Split comma-separated PI_HOSTS into array
|
|
IFS=',' read -ra HOSTS <<< "$PI_HOSTS"
|
|
|
|
echo "==================================="
|
|
echo "Deployment Configuration"
|
|
echo "==================================="
|
|
echo "Branch: $BRANCH_NAME"
|
|
echo "Target Pis: ${#HOSTS[@]}"
|
|
echo "Repository Path: $PI_REPO_PATH"
|
|
echo "User: $PI_USER"
|
|
echo "==================================="
|
|
echo ""
|
|
|
|
# Track deployment status
|
|
FAILED_HOSTS=()
|
|
SUCCESSFUL_HOSTS=()
|
|
|
|
# Deploy to each Pi
|
|
for HOST in "${HOSTS[@]}"; do
|
|
# Trim whitespace
|
|
HOST=$(echo "$HOST" | xargs)
|
|
|
|
echo ">>> 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...'
|
|
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 > /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
|