fix(ci): harden deploy SSH verification
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 0s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 12s

This commit is contained in:
2026-07-12 22:40:28 +09:00
parent 0c37bfa13c
commit 9c01c60f7c
+43 -48
View File
@@ -21,6 +21,7 @@ env:
DEPLOY_PORT: 22
SERVICE_NAME: quantengine
REPO: kjh2064/QuantEngineByItz
SSH_KNOWN_HOSTS: ~/.ssh/known_hosts
jobs:
deploy:
@@ -36,19 +37,18 @@ jobs:
steps:
- name: Verify SSH Key and Secrets
run: |
# SSH_PRIVATE_KEY is the actual secret name registered in this repo
# (verified via GET /repos/{r}/actions/secrets -- DEPLOY_SSH_KEY_B64 /
# DEPLOY_SSH_KEY were never actually created despite CLAUDE.md
# claiming so; kept as fallback names in case they're added later).
set -euo pipefail
SSH_KEY="${{ secrets.SSH_PRIVATE_KEY }}"
SSH_KEY_B64="${{ secrets.DEPLOY_SSH_KEY_B64 }}"
SSH_KEY_RAW="${{ secrets.DEPLOY_SSH_KEY }}"
if [ -z "$SSH_KEY" ] && [ -z "$SSH_KEY_B64" ] && [ -z "$SSH_KEY_RAW" ]; then
echo "ERROR: No SSH key secret configured (checked SSH_PRIVATE_KEY, DEPLOY_SSH_KEY_B64, DEPLOY_SSH_KEY)"
TOKEN="${{ secrets.GITEA_TOKEN }}"
if [ -z "$SSH_KEY" ]; then
echo "ERROR: SSH_PRIVATE_KEY secret not configured"
exit 1
fi
[ -z "${{ secrets.GITEA_TOKEN }}" ] && { echo "ERROR: GITEA_TOKEN not configured"; exit 1; }
echo "✓ SSH key and GITEA_TOKEN configured"
if [ -z "$TOKEN" ]; then
echo "ERROR: GITEA_TOKEN not configured"
exit 1
fi
echo "✓ Required deployment secrets configured"
- name: Fetch Release Info
id: fetch
@@ -116,51 +116,44 @@ jobs:
- name: Setup SSH
run: |
set -euo pipefail
mkdir -p ~/.ssh
SSH_KNOWN_HOSTS="$HOME/.ssh/known_hosts"
SSH_KEY="${{ secrets.SSH_PRIVATE_KEY }}"
SSH_KEY_B64="${{ secrets.DEPLOY_SSH_KEY_B64 }}"
SSH_KEY_RAW="${{ secrets.DEPLOY_SSH_KEY }}"
write_key() {
# $1 = raw secret value; auto-detects PEM vs base64
if printf '%s' "$1" | grep -q 'BEGIN.*PRIVATE KEY'; then
printf '%b\n' "$1" > ~/.ssh/deploy_key
else
printf '%s' "$1" | base64 -d > ~/.ssh/deploy_key
fi
}
if [ -n "$SSH_KEY" ]; then
write_key "$SSH_KEY"
elif [ -n "$SSH_KEY_B64" ]; then
printf '%s' "$SSH_KEY_B64" | base64 -d > ~/.ssh/deploy_key
elif [ -n "$SSH_KEY_RAW" ]; then
write_key "$SSH_KEY_RAW"
else
echo "ERROR: No SSH key configured"
if [ -z "$SSH_KEY" ]; then
echo "ERROR: SSH_PRIVATE_KEY not configured"
exit 1
fi
if printf '%s' "$SSH_KEY" | grep -q 'BEGIN.*PRIVATE KEY'; then
printf '%b\n' "$SSH_KEY" > ~/.ssh/deploy_key
else
printf '%s' "$SSH_KEY" | base64 -d > ~/.ssh/deploy_key
fi
sed -i 's/\r$//' ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -p ${{ env.DEPLOY_PORT }} ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
ssh-keyscan -p ${{ env.DEPLOY_PORT }} ${{ env.DEPLOY_HOST }} > "$SSH_KNOWN_HOSTS" 2>/dev/null || true
echo "✓ SSH configured"
- name: Upload Release Artifact
run: |
SSH_KNOWN_HOSTS="$HOME/.ssh/known_hosts"
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
echo "Uploading: $ARTIFACT"
ls -lh "$ARTIFACT"
scp -i ~/.ssh/deploy_key \
-P ${{ env.DEPLOY_PORT }} \
-o StrictHostKeyChecking=accept-new \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=yes \
-o UserKnownHostsFile="${SSH_KNOWN_HOSTS}" \
-o ConnectTimeout=10 \
"$ARTIFACT" ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }}:/tmp/
echo "✓ Release artifact uploaded"
- name: Deploy & Verify
run: |
SSH_KNOWN_HOSTS="$HOME/.ssh/known_hosts"
ARTIFACT="${{ steps.fetch.outputs.artifact }}"
RELEASE_TAG="${{ steps.fetch.outputs.tag }}"
COMMIT="${{ steps.fetch.outputs.commit }}"
@@ -178,7 +171,9 @@ jobs:
# remote script's environment.
ssh -i ~/.ssh/deploy_key \
-p ${{ env.DEPLOY_PORT }} \
-o StrictHostKeyChecking=accept-new \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=yes \
-o UserKnownHostsFile="${SSH_KNOWN_HOSTS}" \
-o ConnectTimeout=10 \
${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} \
"ARTIFACT='$ARTIFACT' RELEASE_TAG='$RELEASE_TAG' COMMIT='$COMMIT' SERVICE_NAME='$SERVICE_NAME' bash -s" << 'REMOTE'
@@ -234,28 +229,26 @@ jobs:
steps:
- name: Setup SSH (for service check)
run: |
set -euo pipefail
mkdir -p ~/.ssh
SSH_KNOWN_HOSTS="$HOME/.ssh/known_hosts"
SSH_KEY="${{ secrets.SSH_PRIVATE_KEY }}"
SSH_KEY_B64="${{ secrets.DEPLOY_SSH_KEY_B64 }}"
SSH_KEY_RAW="${{ secrets.DEPLOY_SSH_KEY }}"
if [ -n "$SSH_KEY" ]; then
if printf '%s' "$SSH_KEY" | grep -q 'BEGIN.*PRIVATE KEY'; then
printf '%b\n' "$SSH_KEY" > ~/.ssh/deploy_key
else
printf '%s' "$SSH_KEY" | base64 -d > ~/.ssh/deploy_key
fi
elif [ -n "$SSH_KEY_B64" ]; then
printf '%s' "$SSH_KEY_B64" | base64 -d > ~/.ssh/deploy_key
elif [ -n "$SSH_KEY_RAW" ]; then
printf '%s' "$SSH_KEY_RAW" | base64 -d > ~/.ssh/deploy_key
if [ -z "$SSH_KEY" ]; then
echo "ERROR: SSH_PRIVATE_KEY not configured"
exit 1
fi
if printf '%s' "$SSH_KEY" | grep -q 'BEGIN.*PRIVATE KEY'; then
printf '%b\n' "$SSH_KEY" > ~/.ssh/deploy_key
else
printf '%s' "$SSH_KEY" | base64 -d > ~/.ssh/deploy_key
fi
chmod 600 ~/.ssh/deploy_key 2>/dev/null || true
ssh-keyscan -p 22 ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
ssh-keyscan -p ${{ env.DEPLOY_PORT }} ${{ env.DEPLOY_HOST }} > "$SSH_KNOWN_HOSTS" 2>/dev/null || true
- name: Health Check
run: |
SSH_KNOWN_HOSTS="$HOME/.ssh/known_hosts"
# IMPORTANT: quantengine.service binds ASPNETCORE_URLS to
# http://127.0.0.1:5000 (loopback only) -- Nginx is the only
# thing that reaches it from outside, via quant.taxbaik.com.
@@ -272,7 +265,9 @@ jobs:
# checks already correctly do via SSH.
ssh -i ~/.ssh/deploy_key \
-p ${{ env.DEPLOY_PORT }} \
-o StrictHostKeyChecking=accept-new \
-o IdentitiesOnly=yes \
-o StrictHostKeyChecking=yes \
-o UserKnownHostsFile="${SSH_KNOWN_HOSTS}" \
-o ConnectTimeout=10 \
${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} bash -s << 'REMOTE'
set -e