Files
pezkuwi-telegram-miniapp/.github/workflows/deploy.yml
T
SatoshiQaziMuhammed 07cd642051 ops: run the Telegram bots and the assistant on vps3 (#46)
* ops: run the Telegram bots and the assistant on vps3

telegram-bot and ask ran on the free cloud project, which paused itself
after a quiet week; every bot went silent and the deploy job failed against
the paused project. They now run in their own edge-runtime container on vps3
(bots/), from /opt/pezkuwi-bots.

Separate from the shared functions runtime because that one verifies a JWT
on every request, which Telegram cannot send, and holds the platform's wallet
keys, which a public bot feeding user text to a language model should not
sit next to. The new runtime holds only the keys the two functions read.

- telegram-bot refuses updates without Telegram's secret-token header
  (TELEGRAM_WEBHOOK_SECRET); the main slot reads TELEGRAM_BOT_TOKEN_MAIN,
  since TELEGRAM_BOT_TOKEN on vps3 is the miniapp's sign-in check.
- nginx keeps the public URL shape:
  supabase.pezkuwichain.io/functions/v1/{telegram-bot,ask}.
- deploy.yml ships them with a new bots-deploy verb on the existing deploy
  key; the host script accepts exactly main, telegram-bot and ask, restarts
  the container and fails unless the bot comes back refusing unsigned updates.
- Registry: _cloud_hosted becomes _hosted_elsewhere; the gate refuses those
  names in the shared volume and reports any copy there as stale.

* ask: send the legacy service key as a bearer token on vps3

The vps3 gateway has no opaque sb_secret keys and honours the service_role JWT
only as a bearer token; sent on apikey alone it reads as anon, the limiter's
count fails, and every question is refused as rate-limited.
2026-10-22 13:51:35 +04:00

126 lines
5.7 KiB
YAML

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