Sifa professional network API (Fastify, AT Protocol, Jetstream)
sifa.id/
1name: Deploy
2on:
3 push:
4 branches: [main]
5
6jobs:
7 deploy:
8 runs-on: ubuntu-latest
9 permissions:
10 contents: read
11 packages: write
12
13 steps:
14 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
15
16 - name: Log in to GHCR
17 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
18 with:
19 registry: ghcr.io
20 username: ${{ github.actor }}
21 password: ${{ secrets.GITHUB_TOKEN }}
22
23 - name: Build and push Docker image
24 uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
25 with:
26 context: .
27 push: true
28 tags: ghcr.io/singi-labs/sifa-api:latest,ghcr.io/singi-labs/sifa-api:${{ github.sha }}
29
30 - name: Deploy to VPS
31 uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1
32 with:
33 host: ${{ secrets.VPS_HOST }}
34 username: ${{ secrets.VPS_USER }}
35 key: ${{ secrets.VPS_SSH_KEY }}
36 script: |
37 cd /opt/sifa
38 docker compose pull sifa-api
39 docker compose up -d --force-recreate --no-deps sifa-api
40 docker image prune -af
41
42 - name: Verify deployment health
43 uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1
44 with:
45 host: ${{ secrets.VPS_HOST }}
46 username: ${{ secrets.VPS_USER }}
47 key: ${{ secrets.VPS_SSH_KEY }}
48 script: |
49 for i in $(seq 1 10); do
50 status=$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:3100/api/health/ready 2>/dev/null || echo "000")
51 if [ "$status" = "200" ]; then
52 echo "API healthy after $((i * 3))s"
53 # Verify OAuth is functional (should return 400 not 503)
54 oauth_status=$(curl -sf -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:3100/oauth/login -H 'Content-Type: application/json' -d '{"handle":"test.invalid"}' 2>/dev/null || echo "000")
55 if [ "$oauth_status" = "503" ]; then
56 echo "FATAL: OAuth not configured — keys may be missing"
57 exit 1
58 fi
59 echo "OAuth endpoint responding (status: $oauth_status)"
60 exit 0
61 fi
62 echo "Waiting for API... (attempt $i, status: $status)"
63 sleep 3
64 done
65 echo "FATAL: API did not become healthy within 30s"
66 exit 1