name: Deploy on: workflow_run: workflows: ["CI"] types: [completed] branches: [main] workflow_dispatch: permissions: contents: read concurrency: group: deploy cancel-in-progress: true env: VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }} VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }} VITE_DEPOSIT_TON_ADDRESS: ${{ secrets.VITE_DEPOSIT_TON_ADDRESS }} VITE_DEPOSIT_POLKADOT_ADDRESS: ${{ secrets.VITE_DEPOSIT_POLKADOT_ADDRESS }} jobs: deploy: name: Deploy to VPS runs-on: ubuntu-latest if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm run build - name: Deploy to telegram.pezkiwi.app env: DEPLOY_KEY: ${{ secrets.MINIAPP_SITE_DEPLOY_KEY }} # VPS3's host key, read from the host itself; any other key fails. KNOWN_HOST: "217.77.6.126 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMxxRmMEYyng+B9O3jcUCMnUa31SyWQ+l7aj18/soWtJ" run: | umask 077 printf '%s\n' "$DEPLOY_KEY" > "$RUNNER_TEMP/deploy_key" printf '%s\n' "$KNOWN_HOST" > "$RUNNER_TEMP/known_hosts" # The key is pinned on the host to ops/host/miniapp-site-receive # (authorized_keys restrict,command=): the site tar on stdin, then the # cleanup of earlier deploys' assets; nothing else. tar -C dist -cf - . | ssh -i "$RUNNER_TEMP/deploy_key" -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" miniapp-deploy@217.77.6.126 deploy # Edge functions live in a Supabase volume shared with other projects, so they # are written through the ownership gate on the host rather than copied in # directly. The gate refuses any name this project does not own, which is what # stops a repeat of the 2026-06-28 incident where another project's deploy # silently replaced telegram-auth and broke sign-in for a month. deploy-functions: name: Deploy edge functions (self-hosted) needs: deploy runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 # telegram-bot and ask are excluded on purpose: they run in their own # runtime (bots/, deployed by the deploy-bots job), not in this volume. - name: Package functions run: | tar czf functions.tgz -C supabase \ --exclude='functions/telegram-bot' \ --exclude='functions/ask' \ functions # The ownership gate and its registry guard every project's functions # in the shared volume, so this deploy does not install them; root does, # from ops/ here. What the deploy does is refuse to run when the host's # copy is not the one in this repository. - name: Deploy through ownership gate env: DEPLOY_KEY: ${{ secrets.MINIAPP_FUNCTIONS_DEPLOY_KEY }} # VPS3's host key, read from the host itself; any other key fails. KNOWN_HOST: "217.77.6.126 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMxxRmMEYyng+B9O3jcUCMnUa31SyWQ+l7aj18/soWtJ" run: | umask 077 printf '%s\n' "$DEPLOY_KEY" > "$RUNNER_TEMP/deploy_key" printf '%s\n' "$KNOWN_HOST" > "$RUNNER_TEMP/known_hosts" # The key is pinned on the host to ops/host/miniapp-functions-ssh. want="$(sha256sum ops/supabase-deploy-functions ops/functions-registry.json | awk '{print $1}')" have="$(ssh -i "$RUNNER_TEMP/deploy_key" -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" miniapp-deploy@217.77.6.126 gate-sha)" if [ "$want" != "$have" ]; then echo "::error::the host's ownership gate or registry is not the one in ops/; install them as root (ops/host/README.md), then re-run" exit 1 fi ssh -i "$RUNNER_TEMP/deploy_key" -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" miniapp-deploy@217.77.6.126 deploy < functions.tgz # The Telegram bots' webhook (telegram-bot) and the assistant behind # news.pex.mom and ick.pezkiwi.app (ask) run in their own runtime on vps3, # /opt/pezkuwi-bots (bots/ here), reached at # supabase.pezkuwichain.io/functions/v1/{telegram-bot,ask}. Until 2026-10-22 # they ran on the free cloud project, which pauses itself after a quiet week # and took every bot down with it. deploy-bots: name: Deploy bots runtime needs: deploy runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - name: Package bots run: | mkdir bundle cp -r bots/main bundle/main cp -r supabase/functions/telegram-bot supabase/functions/ask bundle/ tar czf bots.tgz -C bundle ask main telegram-bot - name: Deploy to vps3 env: DEPLOY_KEY: ${{ secrets.MINIAPP_FUNCTIONS_DEPLOY_KEY }} KNOWN_HOST: "217.77.6.126 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMxxRmMEYyng+B9O3jcUCMnUa31SyWQ+l7aj18/soWtJ" run: | umask 077 printf '%s\n' "$DEPLOY_KEY" > "$RUNNER_TEMP/deploy_key" printf '%s\n' "$KNOWN_HOST" > "$RUNNER_TEMP/known_hosts" ssh -i "$RUNNER_TEMP/deploy_key" -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" miniapp-deploy@217.77.6.126 bots-deploy < bots.tgz