diff --git a/.gitea/workflows/deploy-prod.yml b/.gitea/workflows/deploy-prod.yml
index 2c5aaab..29e5b8d 100644
--- a/.gitea/workflows/deploy-prod.yml
+++ b/.gitea/workflows/deploy-prod.yml
@@ -2,193 +2,190 @@ name: Deploy to Production
on:
push:
- branches: [ main ]
+ branches:
+ - main
workflow_dispatch:
+concurrency:
+ group: deploy-prod-main
+ cancel-in-progress: true
+
env:
- DEPLOY_HOST: 172.17.0.1
+ DEPLOY_HOST: 178.104.200.7
DEPLOY_USER: kjh2064
- DEPLOY_PATH: /home/kjh2064/quantengine_active
SERVICE_NAME: quantengine
DOTNET_VERSION: '10.0.x'
- TELEGRAM_BOT_TOKEN_DEFAULT: "8734507814:AAFyacLMai8GB4K-hQ_Nd3t3D01A-h1ZdV0"
+ TELEGRAM_BOT_TOKEN_DEFAULT: "8734507814:AAFyacLMai8GB4K-hQ_Nd3t3D01A-H1ZdV0"
TELEGRAM_CHAT_ID_DEFAULT: "-5460205872"
jobs:
build-and-deploy:
name: Build & Deploy to Production
runs-on: ubuntu-latest
+ timeout-minutes: 15
steps:
- - name: Checkout Code
- uses: actions/checkout@v3
- with:
- fetch-depth: 0
+ - name: Checkout Code
+ uses: actions/checkout@v3
- - name: Setup .NET
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
- - name: Setup Python
- uses: actions/setup-python@v4
- with:
- python-version: '3.10'
+ - name: Setup Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
- - name: Install Python Dependencies
- run: pip install pyyaml openpyxl requests
+ - name: Install Python Dependencies
+ run: pip install pyyaml openpyxl requests
- - name: "[GATE] Run Core Validations"
- run: |
- echo "๐ Running critical CI validations..."
- python3 tools/validate_no_direct_api_trading_v1.py || exit 1
- python3 tools/validate_specs.py || exit 1
- echo "โ
All critical validations passed"
+ - name: "[GATE] Run Core Validations"
+ run: |
+ echo "๐ Running critical CI validations..."
+ python3 tools/validate_no_direct_api_trading_v1.py || exit 1
+ python3 tools/validate_specs.py || exit 1
+ echo "โ
All critical validations passed"
- - name: Ensure Temp Directory and Mock Packet
- run: |
- mkdir -p Temp
- # ๋น ํจํท ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ dotnet test/run ์ IO Exception ๋ฐฉ์ด
- if [ ! -f Temp/final_decision_packet_active.json ]; then
- echo '{"active_decision": "PASS", "details": "CI dummy packet"}' > Temp/final_decision_packet_active.json
- fi
+ - name: Ensure Temp Directory and Mock Packet
+ run: |
+ mkdir -p Temp
+ if [ ! -f Temp/final_decision_packet_active.json ]; then
+ echo '{"active_decision": "PASS", "details": "CI dummy packet"}' > Temp/final_decision_packet_active.json
+ fi
- - name: Restore Dependencies
- run: dotnet restore src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj
+ - name: Restore Dependencies
+ run: dotnet restore src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj
- - name: Build Release
- run: |
- dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
- -c Release \
- --no-restore \
- -p:Version=1.0.${{ github.run_number }}
+ - name: Build Release
+ run: |
+ dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
+ -c Release \
+ --no-restore
- - name: Run Unit Tests
- run: |
- if [ -d tests/unit ]; then
- dotnet test tests/unit \
+ - name: Run Unit Tests
+ run: |
+ dotnet test src/dotnet/QuantEngine.Core.Tests/QuantEngine.Core.Tests.csproj \
+ -c Release \
+ --no-build
+
+ - name: Publish Release Package
+ run: |
+ dotnet publish src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
-c Release \
--no-build \
- || echo "โ ๏ธ Some tests failed (non-blocking for web service)"
- fi
+ -o ./publish
- - name: Publish Release Package
- run: |
- dotnet publish src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
- -c Release \
- --no-build \
- -o ./publish-output
+ - name: Generate Build Info
+ run: |
+ COMMIT_HASH=$(git rev-parse --short HEAD)
+ BUILD_TIME=$(date -d "+9 hours" +'%Y-%m-%d %H:%M:%S KST')
+ mkdir -p ./publish/wwwroot
+ printf '{\n "version": "1.0.%s-%s",\n "built": "%s"\n}\n' "${{ github.run_number }}" "$COMMIT_HASH" "$BUILD_TIME" > ./publish/wwwroot/version.json
+ echo "โ Generated version info: 1.0.${{ github.run_number }}-$COMMIT_HASH @ $BUILD_TIME"
- - name: Generate Build Info
- run: |
- COMMIT_HASH=$(git rev-parse --short HEAD)
- BUILD_TIME=$(date -d "+9 hours" +'%Y-%m-%d %H:%M:%S KST')
- mkdir -p ./publish-output/wwwroot
- printf '{\n "version": "1.0.%s-%s",\n "built": "%s"\n}\n' "${{ github.run_number }}" "$COMMIT_HASH" "$BUILD_TIME" > ./publish-output/wwwroot/version.json
- echo "โ Generated version info: 1.0.${{ github.run_number }}-$COMMIT_HASH @ $BUILD_TIME"
-
-
- - name: Setup SSH
- run: |
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- # SSH_PRIVATE_KEY๊ฐ ํ๋ฌธ PEM์ด๋ base64๋ ์ ์ฐํ๊ฒ ์ฒ๋ฆฌ
- if echo "${{ secrets.SSH_PRIVATE_KEY }}" | grep -q "BEGIN"; then
- echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
- else
- echo "${{ secrets.SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_ed25519 || echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
- fi
- chmod 600 ~/.ssh/id_ed25519
- ssh-keyscan -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
-
- - name: Package Artifact
- run: |
- tar -czf quant_engine_deploy.tgz -C ./publish-output .
- echo "โ Package size: $(du -sh quant_engine_deploy.tgz | cut -f1)"
-
- - name: Deploy & Verify on Server
- run: |
- set -e
- TIMESTAMP=$(date +%Y%m%d_%H%M%S)
- COMMIT=$(git rev-parse --short HEAD)
- DEPLOY_HOST="${{ env.DEPLOY_HOST }}"
- DEPLOY_USER="${{ env.DEPLOY_USER }}"
-
- # ํ
๋ ๊ทธ๋จ ์ค์ ๋ฐ์ธ๋ฉ (Secret์ ์์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ๊ฐ ๋ฐฑ์
์ฌ์ฉ)
- TELEGRAM_BOT_TOKEN="${{ secrets.TELEGRAM_BOT_TOKEN }}"
- [ -z "$TELEGRAM_BOT_TOKEN" ] && TELEGRAM_BOT_TOKEN="${{ env.TELEGRAM_BOT_TOKEN_DEFAULT }}"
- TELEGRAM_CHAT_ID="${{ secrets.TELEGRAM_CHAT_ID }}"
- [ -z "$TELEGRAM_CHAT_ID" ] && TELEGRAM_CHAT_ID="${{ env.TELEGRAM_CHAT_ID_DEFAULT }}"
-
- send_telegram() {
- local text="$1"
- curl -fsS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
- -d "chat_id=${TELEGRAM_CHAT_ID}" \
- --data-urlencode "text=${text}" \
- -d "parse_mode=HTML" >/dev/null || true
- }
-
- notify_failure() {
- local exit_code=$?
- send_telegram "โ QuantEngine ๋ฐฐํฌ ์คํจ
-
- ์ปค๋ฐ: ${COMMIT}
- ์๊ฐ: ${TIMESTAMP}
- ๋จ๊ณ: deploy-to-prod (SSH Execution)"
- exit "$exit_code"
- }
-
- trap notify_failure ERR
-
- echo "=== Deploying QuantEngine $COMMIT ($TIMESTAMP) ==="
-
- # 1. ์ํฐํฉํธ ๋ณต์ฌ
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
- quant_engine_deploy.tgz "$DEPLOY_USER@$DEPLOY_HOST:/tmp/quantengine_${TIMESTAMP}.tgz"
-
- # 2. ์๊ฒฉ ๋ฐฐํฌ ๋ช
๋ น์ด ํตํฉ (SSH 1ํ ์ฐ๊ฒฐ)
- ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
- -o ServerAliveInterval=10 \
- "$DEPLOY_USER@$DEPLOY_HOST" bash << REMOTE
- set -e
- DEPLOY_HOME="/home/kjh2064"
- DEPLOY_DIR="\$DEPLOY_HOME/deployments/quantengine_${TIMESTAMP}"
-
- echo "--- [1/4] ์์ถ ํด์ ---"
- mkdir -p "\$DEPLOY_DIR"
- tar -xzf "/tmp/quantengine_${TIMESTAMP}.tgz" -C "\$DEPLOY_DIR"
- rm -f "/tmp/quantengine_${TIMESTAMP}.tgz"
-
- echo "--- [2/4] ์ฌ๋ณผ๋ฆญ ๋งํฌ ์ ํ ---"
- ln -sfn "\$DEPLOY_DIR" "${{ env.DEPLOY_PATH }}"
-
- echo "--- [3/4] ์๋น์ค ์ฌ์์ ---"
- sudo /usr/bin/systemctl restart ${{ env.SERVICE_NAME }}
-
- echo "--- [4/4] ํฌ์ค ์ฒดํฌ ---"
- ATTEMPTS=20
- for i in \$(seq 1 \$ATTEMPTS); do
- STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/ 2>/dev/null || echo "000")
- if [ "\$STATUS" = "200" ]; then
- echo "โ ํฌ์ค์ฒดํฌ ์ฑ๊ณต (์๋ \$i/\$ATTEMPTS, HTTP 200)"
- # ๊ตฌ ๋ฐฐํฌ ํด๋ ์ ๋ฆฌ (์ต๊ทผ 5๊ฐ๋ง ๋ณด์กด)
- ls -1dt \$DEPLOY_HOME/deployments/quantengine_* 2>/dev/null | tail -n +6 | xargs rm -rf 2>/dev/null || true
- exit 0
+ - name: Setup SSH
+ run: |
+ mkdir -p ~/.ssh
+ chmod 700 ~/.ssh
+ if echo "${{ secrets.SSH_PRIVATE_KEY }}" | grep -q "BEGIN"; then
+ echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
+ else
+ echo "${{ secrets.SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_ed25519 || echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
fi
- if [ "\$i" -eq "\$ATTEMPTS" ]; then
- echo "=== FATAL: ์๋น์ค๊ฐ ํฌ์ค์ฒดํฌ ์๋ต์ ํ์ง ์์ ===" >&2
- systemctl is-active ${{ env.SERVICE_NAME }} >&2 || true
- journalctl -u ${{ env.SERVICE_NAME }} --no-pager -n 50 >&2
+ chmod 600 ~/.ssh/id_ed25519
+ ssh-keyscan -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
+
+ - name: Package Artifact
+ run: |
+ tar -czf quantengine.tar.gz -C ./publish .
+ echo "โ Package size: $(du -sh quantengine.tar.gz | cut -f1)"
+
+ - name: Deploy & Verify on Server
+ run: |
+ set -e
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
+ COMMIT=$(git rev-parse --short HEAD)
+ DEPLOY_HOST="${{ env.DEPLOY_HOST }}"
+ DEPLOY_USER="${{ env.DEPLOY_USER }}"
+
+ TELEGRAM_BOT_TOKEN="${{ secrets.TELEGRAM_BOT_TOKEN }}"
+ [ -z "$TELEGRAM_BOT_TOKEN" ] && TELEGRAM_BOT_TOKEN="${{ env.TELEGRAM_BOT_TOKEN_DEFAULT }}"
+ TELEGRAM_CHAT_ID="${{ secrets.TELEGRAM_CHAT_ID }}"
+ [ -z "$TELEGRAM_CHAT_ID" ] && TELEGRAM_CHAT_ID="${{ env.TELEGRAM_CHAT_ID_DEFAULT }}"
+
+ send_telegram() {
+ local text="$1"
+ curl -fsS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
+ -d "chat_id=${TELEGRAM_CHAT_ID}" \
+ --data-urlencode "text=${text}" \
+ -d "parse_mode=HTML" >/dev/null || true
+ }
+
+ notify_failure() {
+ local exit_code=$?
+ send_telegram "โ QuantEngine ๋ฐฐํฌ ์คํจ
+
+ ์ปค๋ฐ: ${COMMIT}
+ ์๊ฐ: ${TIMESTAMP}
+ ๋จ๊ณ: deploy-to-prod (SSH Execution)"
+ exit "$exit_code"
+ }
+
+ trap notify_failure ERR
+
+ echo "=== Deploying QuantEngine $COMMIT ($TIMESTAMP) ==="
+
+ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
+ "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p /home/kjh2064/tmp"
+ scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
+ quantengine.tar.gz "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/quantengine.tar.gz"
+ scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
+ tools/deploy_quantengine.sh "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/deploy.sh"
+
+ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
+ "$DEPLOY_USER@$DEPLOY_HOST" "chmod +x /home/kjh2064/tmp/deploy.sh && CI_DEPLOY=1 /home/kjh2064/tmp/deploy.sh"
+
+ echo "=== Verifying Loopback Health ==="
+ loopback_html=$(ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 "$DEPLOY_USER@$DEPLOY_HOST" "curl -sf http://127.0.0.1:5000/ || true")
+ if ! printf '%s' "$loopback_html" | grep -q "Quant Engine"; then
+ echo "Loopback health check failed for quantengine" >&2
exit 1
fi
- echo " ๋๊ธฐ ์ค... (\$i/\$ATTEMPTS, HTTP \$STATUS)"
- sleep 3
- done
- REMOTE
- echo "โ ๋ฐฐํฌ ์๋ฃ: quantengine_${TIMESTAMP} @ $DEPLOY_HOST"
- send_telegram "โ
QuantEngine ๋ฐฐํฌ ์๋ฃ
-
- ์ปค๋ฐ: ${COMMIT}
- ์๊ฐ: ${TIMESTAMP}
- ๋์: ${DEPLOY_HOST}"
+ echo "=== Verifying Favicon Assets ==="
+ favicon_svg_code=$(curl -s -o /dev/null -w "%{http_code}" "http://${DEPLOY_HOST}/favicon.svg")
+ favicon_png_code=$(curl -s -o /dev/null -w "%{http_code}" "http://${DEPLOY_HOST}/favicon.png")
+ echo "/favicon.svg -> ${favicon_svg_code}"
+ echo "/favicon.png -> ${favicon_png_code}"
+ if [ "$favicon_svg_code" != "200" ] && [ "$favicon_png_code" != "200" ]; then
+ echo "Favicon assets are not reachable after deploy" >&2
+ exit 1
+ fi
+
+ echo "=== Verifying Public Routes ==="
+ root_html=$(curl -sf "http://${DEPLOY_HOST}/" 2>/dev/null || echo "")
+ ops_html=$(curl -sf "http://${DEPLOY_HOST}/operations" 2>/dev/null || echo "")
+
+ root_code=$(printf '%s' "$root_html" | grep -q "Quant Engine" && echo 200 || echo 500)
+ ops_code=$(printf '%s' "$ops_html" | grep -q "Operational Report" && echo 200 || echo 500)
+
+ echo "/ -> ${root_code}"
+ echo "/operations -> ${ops_code}"
+
+ if [ "$root_code" != "200" ]; then
+ echo "Deployment content check failed for /" >&2
+ exit 1
+ fi
+ if [ "$ops_code" != "200" ]; then
+ echo "Deployment content check failed for /operations" >&2
+ exit 1
+ fi
+
+ echo "โ ๋ฐฐํฌ ์๋ฃ: quantengine_${TIMESTAMP} @ $DEPLOY_HOST"
+ send_telegram "โ
QuantEngine ๋ฐฐํฌ ์๋ฃ
+
+ ์ปค๋ฐ: ${COMMIT}
+ ์๊ฐ: ${TIMESTAMP}
+ ๋์: ${DEPLOY_HOST}"
diff --git a/.gitea/workflows/snapshot_admin_deploy.yml b/.gitea/workflows/snapshot_admin_deploy.yml
deleted file mode 100644
index 4ea2a2c..0000000
--- a/.gitea/workflows/snapshot_admin_deploy.yml
+++ /dev/null
@@ -1,148 +0,0 @@
-name: Snapshot Admin Deployment
-
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-concurrency:
- group: snapshot-admin-deploy-main
- cancel-in-progress: true
-
-env:
- DEPLOY_HOST: 178.104.200.7
- DEPLOY_USER: kjh2064
- TELEGRAM_BOT_TOKEN_DEFAULT: "8734507814:AAFyacLMai8GB4K-hQ_Nd3t3D01A-h1ZdV0"
- TELEGRAM_CHAT_ID_DEFAULT: "-5460205872"
-
-jobs:
- build-and-deploy:
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - name: Checkout Code
- uses: actions/checkout@v3
-
- - name: Setup .NET SDK
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: '10.0.x'
-
- - name: Publish Blazor Web App
- run: |
- echo "[deploy] publishing .NET 10 Blazor app"
- dotnet publish src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj -c Release -o ./publish
-
- - name: Generate Build Info
- run: |
- COMMIT_HASH=$(git rev-parse --short HEAD)
- BUILD_TIME=$(date -d "+9 hours" +'%Y-%m-%d %H:%M:%S KST')
- mkdir -p ./publish/wwwroot
- printf '{\n "version": "1.0.%s-%s",\n "built": "%s"\n}\n' "${{ github.run_number }}" "$COMMIT_HASH" "$BUILD_TIME" > ./publish/wwwroot/version.json
- echo "โ Generated version info: 1.0.${{ github.run_number }}-$COMMIT_HASH @ $BUILD_TIME"
-
-
- - name: Compress Artifact
- run: |
- echo "[deploy] compressing publish output"
- tar -czf quantengine.tar.gz -C ./publish .
-
- - name: Setup SSH
- run: |
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- if echo "${{ secrets.SSH_PRIVATE_KEY }}" | grep -q "BEGIN"; then
- echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
- else
- echo "${{ secrets.SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_ed25519 || echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
- fi
- chmod 600 ~/.ssh/id_ed25519
- ssh-keyscan -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
-
- - name: Deploy & Verify on Server
- run: |
- set -e
- TIMESTAMP=$(date +%Y%m%d_%H%M%S)
- COMMIT=$(git rev-parse --short HEAD)
- DEPLOY_HOST="${{ env.DEPLOY_HOST }}"
- DEPLOY_USER="${{ env.DEPLOY_USER }}"
-
- TELEGRAM_BOT_TOKEN="${{ secrets.TELEGRAM_BOT_TOKEN }}"
- [ -z "$TELEGRAM_BOT_TOKEN" ] && TELEGRAM_BOT_TOKEN="${{ env.TELEGRAM_BOT_TOKEN_DEFAULT }}"
- TELEGRAM_CHAT_ID="${{ secrets.TELEGRAM_CHAT_ID }}"
- [ -z "$TELEGRAM_CHAT_ID" ] && TELEGRAM_CHAT_ID="${{ env.TELEGRAM_CHAT_ID_DEFAULT }}"
-
- send_telegram() {
- local text="$1"
- curl -fsS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
- -d "chat_id=${TELEGRAM_CHAT_ID}" \
- --data-urlencode "text=${text}" \
- -d "parse_mode=HTML" >/dev/null || true
- }
-
- notify_failure() {
- local exit_code=$?
- send_telegram "โ Snapshot Admin ๋ฐฐํฌ ์คํจ
-
- ์ปค๋ฐ: ${COMMIT}
- ์๊ฐ: ${TIMESTAMP}
- ๋จ๊ณ: snapshot_admin_deploy (Deploy Execution)"
- exit "$exit_code"
- }
-
- trap notify_failure ERR
-
- echo "=== Deploying Snapshot Admin $COMMIT ($TIMESTAMP) ==="
-
- # 1. ์๊ฒฉ์ง ์์ ํด๋ ์์ฑ ๋ฐ ์
๋ก๋
- ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p /home/kjh2064/tmp"
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 quantengine.tar.gz "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/quantengine.tar.gz"
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 tools/deploy_quantengine.sh "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/deploy.sh"
-
- # 2. ๋ฐฐํฌ ์คํฌ๋ฆฝํธ ์คํ
- ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 "$DEPLOY_USER@$DEPLOY_HOST" "chmod +x /home/kjh2064/tmp/deploy.sh && CI_DEPLOY=1 /home/kjh2064/tmp/deploy.sh"
-
- # 3. ๋ฐฐํฌ ์ฑ๊ณต ๊ฒ์ฆ
- echo "=== Verifying Loopback Health ==="
- loopback_html=$(ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 "$DEPLOY_USER@$DEPLOY_HOST" "curl -sf http://127.0.0.1:5000/ || true")
- if ! printf '%s' "$loopback_html" | grep -q "Quant Engine"; then
- echo "Loopback health check failed for quantengine" >&2
- exit 1
- fi
-
- echo "=== Verifying Favicon Assets ==="
- favicon_svg_code=$(curl -s -o /dev/null -w "%{http_code}" "http://${DEPLOY_HOST}/favicon.svg")
- favicon_png_code=$(curl -s -o /dev/null -w "%{http_code}" "http://${DEPLOY_HOST}/favicon.png")
- echo "/favicon.svg -> ${favicon_svg_code}"
- echo "/favicon.png -> ${favicon_png_code}"
- if [ "$favicon_svg_code" != "200" ] && [ "$favicon_png_code" != "200" ]; then
- echo "Favicon assets are not reachable after deploy" >&2
- exit 1
- fi
-
- echo "=== Verifying Public Routes ==="
- root_html=$(curl -sf "http://${DEPLOY_HOST}/" 2>/dev/null || echo "")
- ops_html=$(curl -sf "http://${DEPLOY_HOST}/operations" 2>/dev/null || echo "")
-
- root_code=$(printf '%s' "$root_html" | grep -q "Quant Engine" && echo 200 || echo 500)
- ops_code=$(printf '%s' "$ops_html" | grep -q "Operational Report" && echo 200 || echo 500)
-
- echo "/ -> ${root_code}"
- echo "/operations -> ${ops_code}"
-
- if [ "$root_code" != "200" ]; then
- echo "Deployment content check failed for /" >&2
- exit 1
- fi
- if [ "$ops_code" != "200" ]; then
- echo "Deployment content check failed for /operations" >&2
- exit 1
- fi
-
- echo "โ ๋ฐฐํฌ ์๋ฃ: quantengine_${TIMESTAMP} @ $DEPLOY_HOST"
- send_telegram "โ
Snapshot Admin ๋ฐฐํฌ ์๋ฃ
-
- ์ปค๋ฐ: ${COMMIT}
- ์๊ฐ: ${TIMESTAMP}
- ๋์: ${DEPLOY_HOST}"
diff --git a/AGENTS.md b/AGENTS.md
index ba04c47..06b7ef8 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -110,7 +110,7 @@
- D+2 ์์
์ผ ๊ธฐ์ค ํ๊ธ์ ์ฆ์๋ฐฉ์ด ์์ฐ์ผ๋ก ๊ฐ์ฃผํ๊ณ , ๋ชฉํ ์์ฐ 5์ต ์์ ๊ธฐ์ค์ผ๋ก ํฌ์ง์
์ฌ์ด์ง ๋ฐ ๋ฆฌ์คํฌ ๋ฒํท์ ์ ์ดํ๋ค.
- ๋งค์ฃผ ์ฃผ๋ง ๋ฆฌ๋ฐธ๋ฐ์ฑ(rebalance_required=true) ๋ฐ ๋งค์ 1์ผ/11์ผ/21์ผ ์ค๊ฐ์ ๊ฒ(mid_check_required=true) ์ด์ cadence๋ฅผ ์ค์ํ๋ค.
- ์ปค๋ฐ, ํธ์ฌ, PR ์์
์ ๋ฐ๋์ ๋ก์ปฌ์ .gs ํ์ผ์ Google Apps Script ์๊ฒฉ ํ๋ก์ ํธ์ ์
๋ก๋(python tools/deploy_gas.py ์คํ)ํ๊ณ , ์ฌ์ฉ์์๊ฒ ์คํ๋ ๋์ํธ ์์ ์คํฌ๋ฆฝํธ ์คํ(์: runDataFeed)์ ํตํ ๊ฒ์ฆ์ ์ ๋ ๋ฐ ๊ฐ์ด๋ํด์ผ ํ๋ค.
-- QuantEngine ๋ฐฐํฌ๋ CI ์ ์ฉ์ด๋ค. ๋ก์ปฌ์์ ์๋ฒ๋ก ์ฐ์ถ๋ฌผ์ ์ง์ ์
๋ก๋ํ๊ฑฐ๋ `scp`/`rsync`๋ก ์๋ ๋ฐ์ํ์ง ์๋๋ค. ์ค๋ฐฐํฌ๋ `.gitea/workflows/snapshot_admin_deploy.yml`๋ง ์ฌ์ฉํ๋ฉฐ, ๋ก์ปฌ ์คํฌ๋ฆฝํธ๋ CI ํ๊ฒฝ์์๋ง ์คํ ๊ฐ๋ฅํด์ผ ํ๋ค.
+- QuantEngine ๋ฐฐํฌ๋ CI ์ ์ฉ์ด๋ค. ๋ก์ปฌ์์ ์๋ฒ๋ก ์ฐ์ถ๋ฌผ์ ์ง์ ์
๋ก๋ํ๊ฑฐ๋ `scp`/`rsync`๋ก ์๋ ๋ฐ์ํ์ง ์๋๋ค. ์ค๋ฐฐํฌ๋ `.gitea/workflows/deploy-prod.yml`๋ง ์ฌ์ฉํ๋ฉฐ, ๋ก์ปฌ ์คํฌ๋ฆฝํธ๋ CI ํ๊ฒฝ์์๋ง ์คํ ๊ฐ๋ฅํด์ผ ํ๋ค.
- ์๊ฒฉ ์๋ฒ ํ์ธ์ด ํ์ํ๋ฉด `ssh kjh2064@178.104.200.7` ์ ์์ ๋จผ์ ์๋ํ๊ณ , ์ฌ์ฉ์์๊ฒ ๋งค๋ฒ ์ ์ ํ์ธ์ ์๊ตฌํ์ง ๋ง๊ณ ์ง์ ์ํ/๋ก๊ทธ/ํฌ์ค์ฒดํฌ๋ฅผ ์์งํ ๋ค ๊ฒฐ๊ณผ๋ง ๋ณด๊ณ ํ๋ค.
## 4. ๋ณด๊ณ ๊ท์น
diff --git a/README.md b/README.md
index f1a4691..d06443a 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,7 @@ npm run prepare-upload-zip
## CI / ๋ฐฐํฌ ๋ถ๋ฆฌ
- `.gitea/workflows/ci.yml`์ ๊ฒ์ฆ ์ ์ฉ์ด๋ค.
-- `.gitea/workflows/snapshot_admin_deploy.yml`์ ์ค๋ฐฐํฌ ์ ์ฉ์ด๋ค.
+- `.gitea/workflows/deploy-prod.yml`์ ์ค๋ฐฐํฌ ์ ์ฉ์ด๋ค.
- ๊ณต๊ฐ URL `http://178.104.200.7/quant/` ๊ฐฑ์ ์ deploy workflow ์ฑ๊ณต ์ฌ๋ถ๋ก ํ๋จํ๋ค.
## ์ด์ ๋ฆฌํฌํธ ๊ณ์ฝ
diff --git a/docs/CLOUD_SERVER_SETUP.md b/docs/CLOUD_SERVER_SETUP.md
index 35058dc..5e2b629 100644
--- a/docs/CLOUD_SERVER_SETUP.md
+++ b/docs/CLOUD_SERVER_SETUP.md
@@ -206,9 +206,9 @@ services:
### 6.4. CI / ๋ฐฐํฌ ๋ถ๋ฆฌ
- `.gitea/workflows/ci.yml`: ๊ฒ์ฆ ์ ์ฉ. ์คํ/๊ณต์/๋ฆฌํฌํธ/์ํฐํฉํธ ์์ฑ๊น์ง๋ง ์ํํ๋ค.
-- `.gitea/workflows/snapshot_admin_deploy.yml`: ์ค๋ฐฐํฌ ์ ์ฉ. `dotnet publish` ํ `tools/deploy_quantengine.sh`๋ฅผ ์ด์ฉํด `/home/kjh2064/quantengine_active`๋ก ๋ฐ์ํ๋ค.
+- `.gitea/workflows/deploy-prod.yml`: ์ค๋ฐฐํฌ ์ ์ฉ. `dotnet publish` ํ `tools/deploy_quantengine.sh`๋ฅผ ์ด์ฉํด `/home/kjh2064/quantengine_active`๋ก ๋ฐ์ํ๋ค.
- ์๋ ๋ฐฐํฌ ๊ธ์ง: ๋ก์ปฌ์์ `scp`/`rsync`๋ก `quantengine_active`๋ฅผ ๊ฐฑ์ ํ์ง ์๋๋ค. ๋ฐฐํฌ๋ CI๊ฐ ์๊ฒฉ์์๋ง ์ํํ๊ณ , ๋ก์ปฌ ์คํฌ๋ฆฝํธ๋ `CI_DEPLOY=1` ์์ด ์คํ๋๋ฉด ์คํจํด์ผ ํ๋ค.
-- ๊ณต๊ฐ URL `/quant/` ๊ฐฑ์ ์ `snapshot_admin_deploy.yml`์ ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋จํ๋ค.
+- ๊ณต๊ฐ URL ๊ฐฑ์ ์ `deploy-prod.yml`์ ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋จํ๋ค.
### 6.2. ๋ฌ๋ ์ค์
@@ -404,7 +404,7 @@ docker ps -a
```bash
# CI์์๋ง ๋ฐฐํฌ
# ๋ก์ปฌ์์ scp/rsync๋ก quantengine_active๋ฅผ ๊ฐฑ์ ํ์ง ์๋๋ค.
-# ๋ฐฐํฌ๋ .gitea/workflows/snapshot_admin_deploy.yml ์คํ ๊ฒฐ๊ณผ๋ก๋ง ๋ฐ์ํ๋ค.
+# ๋ฐฐํฌ๋ .gitea/workflows/deploy-prod.yml ์คํ ๊ฒฐ๊ณผ๋ก๋ง ๋ฐ์ํ๋ค.
```
### Gitea Act Runner ๋ฑ๋ก
diff --git a/docs/ROADMAP_WBS.md b/docs/ROADMAP_WBS.md
index 2ecf19e..d73b47f 100644
--- a/docs/ROADMAP_WBS.md
+++ b/docs/ROADMAP_WBS.md
@@ -925,7 +925,7 @@ python tools/validate_specs.py โ PASS
|------|------|
| **์์
** | `src/quant_engine/snapshot_admin_server_v1.py`(Python ์ด๋๋ฏผ ์น UI)๋ฅผ Gitea CI/CD ๋ฐฐํฌ ์คํ
์ ํตํด Synology NAS์์ ์์ ์๋น์ค๋ก ์ด์ํ ์ ์๋์ง ๊ฒํ |
| **ํ์ฌ ์ํ** | **๊ธฐ์ ์ ์ผ๋ก๋ ๊ฐ๋ฅ**. ๊ธฐ๋ณธ ๋ฃจํ๋ฐฑ ๋ณดํธ + Basic Auth ๊ฒ์ดํธ๋ฅผ ์ถ๊ฐํ๊ณ , Synology ์ธ๋ถ ๋
ธ์ถ์ ๋ฆฌ๋ฒ์ค ํ๋ก์ ๊ธฐ๋ฐ POC๋ก ๊ฐ์ด๋ํจ. ์ค๋ฐฐํฌ ๊ฒ์ฆ์ ์์ง ํ์ |
-| **์ด์ ๋ถ๋ฆฌ** | `snapshot_admin.yml`์ `push`์ฉ smoke ๊ฒ์ฆ๊ณผ `workflow_dispatch`์ฉ full ๊ฒ์ฆ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ๋ฐฐํฌ๋ ๋ณ๋ `snapshot_admin_deploy.yml` `workflow_dispatch`๋ก ๋ผ์ด๋๋ค. `push`์์๋ `Validate Snapshot Admin Workflow`๊น์ง๋ง, full ๊ฒ์ฆ์์๋ `Validate Snapshot Admin Web UI`๊น์ง ์ํํ๋ค. |
+| **์ด์ ๋ถ๋ฆฌ** | `snapshot_admin.yml`์ `push`์ฉ smoke ๊ฒ์ฆ๊ณผ `workflow_dispatch`์ฉ full ๊ฒ์ฆ์ผ๋ก ๋ถ๋ฆฌํ๊ณ , ๋ฐฐํฌ๋ ๋ณ๋ `deploy-prod.yml` `workflow_dispatch`๋ก ๋ผ์ด๋๋ค. `push`์์๋ `Validate Snapshot Admin Workflow`๊น์ง๋ง, full ๊ฒ์ฆ์์๋ `Validate Snapshot Admin Web UI`๊น์ง ์ํํ๋ค. |
| **runner ์ฃผ์** | Gitea runner๋ฅผ Docker mode๋ก ๋๋ฉด job ์ข
๋ฃ ์ `Cleaning up container` ๋ก๊ทธ๊ฐ ๋จ๋๋ค. host label๋ก ์ฌ๋ฑ๋กํ๋ฉด job container ์ ๋ฆฌ ๋ก๊ทธ๋ฅผ ํผํ ์ ์๋ค. |
| **KIS ๋ถ๋ฆฌ** | `kis_data_collection.yml`์ `workflow_dispatch`์ฉ mock/config smoke์ `schedule`์ฉ live collection์ผ๋ก ๋ถ๋ฆฌํ๋ค. ์๋ ๋์คํจ์น๋ ์ค์ ์์ง์ ๋๋ฆฌ์ง ์๊ณ , ์ค์์ง์ ์ค์ผ์ค ์ ์ฉ์ด๋ค. |
| **๋ด๋น ํ์ผ** | `.gitea/workflows/ci.yml`, `tools/run_snapshot_admin_server_v1.py`, `src/quant_engine/snapshot_admin_server_v1.py`, `docs/SYNOLOGY_SNAPSHOT_ADMIN_POC.md`, `docs/WBS_7_9_EVIDENCE_PACKET_FINAL.md` |
@@ -1651,7 +1651,7 @@ WBS-10.1 (๊ธฐ๋ฐ ๊ฒฐํจ ์์ )
| 10.10.2 | Dashboard ์ํ ํ์ด์ง โ ๋ฐ์ดํฐ ๋น์์กดํ ์์ฝ์ผ๋ก ๋จ์ํ | DB ์คํจ ์์๋ 200 ์๋ต (์๋ฃ) |
| 10.10.3 | Counter.razor / Weather.razor ๊ธฐ๋ณธ ํ์ด์ง ์ญ์ , NavMenu ์ ๋น | ๋ถํ์ ํ์ด์ง 0๊ฑด, NavMenu์ Dashboard/Operations๋ง ํ์ (์๋ฃ) |
| 10.10.4 | ๋คํฌ ๋ชจ๋ + ๋ฐ์ํ ๋ ์ด์์ ์ ์ฉ | ๋ธ๋ผ์ฐ์ ๋ ๋๋ง ์ ์ ํ์ธ (์๋ฃ) |
-| 10.10.5 | ๋ฐฐํฌ ๋๊ธฐํ | `snapshot_admin_deploy.yml`๊ฐ `/quant/`์ `/quant/operations` ๊ณต๊ฐ ๋ผ์ฐํธ๋ฅผ ๋ฐฐํฌ ํ ๊ฒ์ฆํ๋๋ก ๊ตฌ์ฑ๋จ (์๋ฃ) |
+| 10.10.5 | ๋ฐฐํฌ ๋๊ธฐํ | `deploy-prod.yml`๊ฐ ๊ณต๊ฐ ๋ผ์ฐํธ๋ฅผ ๋ฐฐํฌ ํ ๊ฒ์ฆํ๋๋ก ๊ตฌ์ฑ๋จ (์๋ฃ) |
**์ฑ๊ณต ํ๋ค์ค (๋ฐ์ดํฐ ๊ธฐ์ค)**:
```