Pulse/.github/workflows/update-demo-server.yml
rcourtman 3c134ff4b8 fix(ci): pass explicit version to demo server update
Previously the workflow ran install.sh without --version, which caused it
to download the latest stable release instead of the target release tag.

This was causing the demo server to downgrade from RC versions to stable
when triggered via workflow_dispatch.
2025-12-15 16:11:49 +00:00

151 lines
6 KiB
YAML

name: Update Demo Server
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to deploy (e.g., v4.29.0)'
required: true
type: string
jobs:
update-demo:
# Only run for stable releases (not pre-releases) or manual dispatch
if: github.event_name == 'workflow_dispatch' || github.event.release.prerelease == false
runs-on: ubuntu-latest
steps:
- name: Resolve target tag
id: target
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ inputs.tag }}"
else
TAG="${{ github.event.release.tag_name }}"
fi
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- name: Skip if not latest published release
id: gate
if: github.event_name == 'release'
env:
GH_TOKEN: ${{ github.token }}
run: |
TARGET="${{ steps.target.outputs.tag }}"
LATEST=$(gh api "repos/${{ github.repository }}/releases/latest" --jq '.tag_name')
echo "Target tag: $TARGET"
echo "Latest published tag: $LATEST"
if [ "$TARGET" != "$LATEST" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Release is not the latest; skipping demo update."
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Check release type
if: steps.gate.outputs.skip != 'true'
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "Manual deployment triggered for: ${{ inputs.tag }}"
else
echo "Release: ${{ github.event.release.tag_name }}"
echo "Prerelease: ${{ github.event.release.prerelease }}"
echo "Updating demo server to latest stable release..."
fi
- name: Wait for release assets
if: steps.gate.outputs.skip != 'true'
run: |
TAG="${{ steps.target.outputs.tag }}"
echo "Waiting for release assets to be available..."
MAX_ATTEMPTS=30
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
echo "Checking for assets (attempt $((ATTEMPT + 1))/$MAX_ATTEMPTS)..."
# Check if checksums.txt and linux-amd64 tarball exist
CHECKSUMS_STATUS=$(curl -sL -o /dev/null -w "%{http_code}" \
"https://github.com/rcourtman/Pulse/releases/download/${TAG}/checksums.txt")
TARBALL_STATUS=$(curl -sL -o /dev/null -w "%{http_code}" \
"https://github.com/rcourtman/Pulse/releases/download/${TAG}/pulse-${TAG}-linux-amd64.tar.gz")
echo "checksums.txt: $CHECKSUMS_STATUS, tarball: $TARBALL_STATUS"
if [ "$CHECKSUMS_STATUS" = "200" ] && [ "$TARBALL_STATUS" = "200" ]; then
echo "✅ Release assets are available!"
exit 0
fi
ATTEMPT=$((ATTEMPT + 1))
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
echo "Assets not ready yet, waiting 10 seconds..."
sleep 10
fi
done
echo "❌ Timeout waiting for release assets"
exit 1
- name: Setup SSH
if: steps.gate.outputs.skip != 'true'
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEMO_SERVER_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H ${{ secrets.DEMO_SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Check current demo version
if: steps.gate.outputs.skip != 'true'
id: current
run: |
TARGET="${{ steps.target.outputs.tag }}"
TARGET_STRIPPED="${TARGET#v}"
CURRENT=$(ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEMO_SERVER_USER }}@${{ secrets.DEMO_SERVER_HOST }} \
"curl -s http://localhost:7655/api/version | jq -r .version")
echo "Current demo version: ${CURRENT}"
if [ "$CURRENT" = "$TARGET" ] || [ "$CURRENT" = "$TARGET_STRIPPED" ] || [ "v${CURRENT}" = "$TARGET" ]; then
echo "skip_current=true" >> "$GITHUB_OUTPUT"
echo "Demo server already on target version; skipping update."
else
echo "skip_current=false" >> "$GITHUB_OUTPUT"
fi
- name: Update demo server
if: steps.gate.outputs.skip != 'true' && steps.current.outputs.skip_current != 'true'
run: |
TAG="${{ steps.target.outputs.tag }}"
ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEMO_SERVER_USER }}@${{ secrets.DEMO_SERVER_HOST }} \
"curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | sudo bash -s -- --version $TAG"
- name: Verify update
if: steps.gate.outputs.skip != 'true' && steps.current.outputs.skip_current != 'true'
run: |
# Wait a moment for service to restart
sleep 5
# Check version endpoint
VERSION=$(ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEMO_SERVER_USER }}@${{ secrets.DEMO_SERVER_HOST }} \
"curl -s http://localhost:7655/api/version | jq -r .version")
echo "Demo server is now running version: $VERSION"
# Verify mock mode is active by authenticating and checking node count
NODES=$(ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEMO_SERVER_USER }}@${{ secrets.DEMO_SERVER_HOST }} \
'curl -s -c /tmp/demo-cookies.txt http://localhost:7655/api/login -X POST -H "Content-Type: application/json" -d "{\"username\":\"demo\",\"password\":\"demo\"}" > /dev/null && curl -s -b /tmp/demo-cookies.txt http://localhost:7655/api/state | jq -r ".nodes | length" && rm -f /tmp/demo-cookies.txt')
echo "Mock nodes detected: $NODES"
if [ "$NODES" -ge 1 ]; then
echo "✅ Demo server successfully updated and verified!"
else
echo "⚠️ Demo server updated but mock mode may not be active"
exit 1
fi
- name: Cleanup SSH key
if: always() && steps.gate.outputs.skip != 'true'
run: rm -f ~/.ssh/id_ed25519