ci: deploy over a pinned, single-purpose key instead of root

deploy-vps reached subquery1 as root, through appleboy/ssh-action referenced
by tag, with a key whose comment (mamostehp@MamostePC) made it look like a
person's. It now uses plain ssh with SUBQUERY_DEPLOY_KEY, which the host pins
(authorized_keys restrict,command=) to ops/host/subquery-deploy-ssh: the
commit SHA is its only input. subquery-deploy, run through sudo, does what
the workflow's script did, with three changes:

- It deploys exactly the SHA CI was triggered for, and only a commit on main.
- The host's local edits to tracked files (the indexer manifests) are put
  back whether the deploy succeeds or fails. Before, a failed build exited
  before `stash pop` and left them stashed.
- Only tracked files are stashed. Stashing untracked ones too (.yarn/, which
  yarn install recreates) made every pop fail half-way; that is how 13 stash
  entries piled up on the host.

test-deploy.sh covers this against a scratch clone (red with the restore
trap removed); CI runs it with shellcheck. subquery1's host key is pinned.
The indexer endpoints themselves are unchanged. Actions pinned to SHAs; the
secret scanner's own AGPL licence is allowed in dependency review.
This commit is contained in:
Satoshi Qazi Muhammed authored and SatoshiQaziMuhammed committed 2026-10-09 06:57:03 +04:00
1 parent 01a4903337
commit 7ec6d9971f
9 files changed
+190 -41

No files matched your search

+23 -16
View File
@@ -2,24 +2,31 @@ name: Deploy to VPS
on:
push:
branches: [main]
concurrency:
group: deploy-vps
cancel-in-progress: false
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# The deploy key is pinned on the host to ops/host/subquery-deploy-ssh
# (authorized_keys restrict,command=): the commit SHA is its only input.
# subquery-deploy, run through sudo, brings /opt/subquery to exactly that
# commit of main, keeps the host's local edits, and rebuilds the stack.
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: root
key: ${{ secrets.VPS_SSH_KEY }}
script: |
set -e
cd /opt/subquery
git stash --include-untracked || true
git pull origin main
yarn install --frozen-lockfile
./node_modules/.bin/subql codegen pezkuwi-governance.yaml
./node_modules/.bin/subql build pezkuwi.yaml
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml up -d
git stash pop || true
env:
DEPLOY_KEY: ${{ secrets.SUBQUERY_DEPLOY_KEY }}
# subquery1's host key, read from the host itself; any other key fails.
KNOWN_HOST: "158.220.93.26 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINtnaMWZ0RZDD6yt+6WdtU/rpEz4pyHmo7otkbmgTpkA"
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" \
subquery-deploy@158.220.93.26 "$GITHUB_SHA"