name: Deploy Jury Voting on: push: branches: - main workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: contents: read jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v5 - name: Set up Node.js uses: actions/setup-node@v5 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Build frontend env: NODE_ENV: production run: npm run build - name: Create deployment archive run: | tar czf deploy.tar.gz \ --exclude='*.pdf' \ --exclude='*.doc' \ --exclude='*.xlsx' \ --exclude='Teams' \ --exclude='node_modules' \ --exclude='.git' \ dist/ \ server/ \ shared/ \ package.json \ package-lock.json \ jury-voting.service \ tsconfig.json \ tsconfig.node.json - name: Deploy to VPS uses: appleboy/ssh-action@v1 with: host: 217.160.174.2 username: root key: ${{ secrets.DEPLOY_SSH_KEY }} script: | mkdir -p /opt/jury-voting/server/data - name: Upload archive uses: appleboy/scp-action@v0.1.7 with: host: 217.160.174.2 username: root key: ${{ secrets.DEPLOY_SSH_KEY }} source: deploy.tar.gz target: /tmp/ - name: Extract and start service uses: appleboy/ssh-action@v1 with: host: 217.160.174.2 username: root key: ${{ secrets.DEPLOY_SSH_KEY }} script: | set -e # Install Node.js if not present if ! command -v node &> /dev/null; then curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs fi # Extract archive (preserve session.json) cd /opt/jury-voting tar xzf /tmp/deploy.tar.gz --overwrite rm -f /tmp/deploy.tar.gz # Install production dependencies npm ci --omit=dev # Seed data if first run if [ ! -f server/data/session.json ]; then cp server/data/seed.json server/data/session.json fi # Install and restart systemd service cp jury-voting.service /etc/systemd/system/jury-voting.service systemctl daemon-reload systemctl enable jury-voting systemctl restart jury-voting # Verify sleep 2 curl -sf http://localhost:3002/api/health && echo "Deploy successful!" || (journalctl -u jury-voting -n 20 --no-pager && exit 1)