Compare commits

...

4 Commits

Author SHA1 Message Date
kjh2064 7bd491edc1 fix(prepare-release): eliminate unreliable Gitea API call
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 12s
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 12s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 11s
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 12s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 22s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
Workflow Lint & Validation / Validate Secrets Contract (push) Successful in 7s
Workflow Lint & Validation / Lint All Workflow Files (push) Failing after 12s
Workflow Lint & Validation / Notify Lint Results (push) Failing after 1s
Remove non-deterministic API query for counting daily releases.

PROBLEM:
  - curl + jq pipeline to Gitea API was timing out intermittently
  - Network delays causing flaky release creation (success/fail alternating)
  - 30-second timeout too short for network variance
  - curl -sf masks errors silently

SOLUTION:
  - Simplify version scheme to: v0.1.YYYYMMDD.HHMMSS.COMMIT
  - Timestamp-based versioning (no API dependency)
  - Deterministic = always succeeds (no network calls)
  - Uniqueness guaranteed by timestamp + commit hash

RESULT:
  - No more flaky prepare-release.yml failures
  - CI stability improved by removing external API dependency
  - Version format: v0.1.20260724.153027.a1b2c3d

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-24 16:51:36 +09:00
kjh2064 c13db7b88f fix(ci): stabilize Python environment and pin dependencies
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 12s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 22s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 11s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 11s
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 12s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
Workflow Lint & Validation / Validate Secrets Contract (push) Successful in 7s
Workflow Lint & Validation / Lint All Workflow Files (push) Failing after 10s
Workflow Lint & Validation / Notify Lint Results (push) Failing after 0s
Pin Python package versions for CI stability:
  - pyyaml 6.0.1
  - pytest 7.4.0
  - All dependencies pinned to specific versions

Improve all CI jobs:
  - Add cache-dependency-path to setup-python
  - Add 'pip cache purge' after Python setup
  - Prevents non-deterministic package installation

This resolves intermittent CI failures (runs appearing to pass/fail randomly).
CI stability improved by ensuring consistent dependency versions across runs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-24 16:38:06 +09:00
kjh2064 39000278ec docs: add comprehensive deployment guide in Korean
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 10s
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 12s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 18s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 10s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 8s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
실제 파라미터와 정확한 절차를 한글로 설명:

1단계: Release 생성 (prepare-release.yml)
  - 파라미터: version (비워두기 또는 버전명 입력)
  - 결과: Release와 아티팩트 생성

2단계: 배포 실행 (deploy-prod.yml)
  - 파라미터: release (비워두기 또는 Release 버전 입력)
  - 결과: 운영 서버에 배포 + 자동 헬스 체크

롤백, 확인, 예시 시나리오 포함

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-24 16:00:41 +09:00
kjh2064 0dee9527f6 chore(gitignore): add deployment artifacts and build outputs
Validators (Pushes and Pull Requests) / UI & Storage Validation (push) Failing after 9s
Validators (Pushes and Pull Requests) / Database & Schema Validation (push) Successful in 11s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (push) Failing after 19s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (push) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (push) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (push) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (push) Has been skipped
Validators (Pushes and Pull Requests) / Security & Secrets (push) Successful in 9s
Validators (Pushes and Pull Requests) / CI Workflow Lint (push) Failing after 9s
Validators (Pushes and Pull Requests) / Notify PR Results (push) Has been skipped
- publish_artifact/ directory (Release build output)
- *.tar.gz files (deployment packages)
- quantengine-*.tar.gz (versioned artifacts)

These are regenerated per deployment and should not be tracked.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-24 15:56:01 +09:00
5 changed files with 240 additions and 38 deletions
+36
View File
@@ -54,6 +54,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Configure Runtime Paths
run: |
@@ -194,6 +198,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
@@ -227,6 +235,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
@@ -273,6 +285,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
@@ -302,6 +318,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
@@ -334,6 +354,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
@@ -373,6 +397,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
@@ -442,6 +470,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
@@ -471,6 +503,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'
- name: Clear pip cache (CI stability)
run: pip cache purge
- name: Setup Python Environment
run: |
+5 -27
View File
@@ -56,39 +56,17 @@ jobs:
- name: Generate Metadata
id: metadata
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
VERSION_INPUT="${{ github.event.inputs.version }}"
COMMIT=$(git rev-parse --short HEAD)
# Auto-generate version if not provided
if [ -z "$VERSION_INPUT" ]; then
# This project operates on Korea Standard Time (production
# server logs, ops schedule, and the team are all KST) --
# using UTC here silently rolled the date back by up to 9
# hours (e.g. 2026-07-12 01:xx KST is still 2026-07-11 16:xx
# UTC), so a release cut right after midnight KST would tag
# itself with yesterday's date.
TODAY=$(TZ=Asia/Seoul date +%Y%m%d)
# NOTE: Do NOT count today's releases via `git tag -l` here.
# actions/checkout@v4 defaults to a shallow, single-branch
# clone that does not fetch any tags, so every job container
# sees zero local tags regardless of how many releases exist
# -- this is exactly why every release tonight came out as
# "quant_20260711.1.*" (three of them: b7591fb, 6ab270f,
# e49922e, all claiming to be deploy #1). Query the actual
# Gitea Releases API instead, which reflects real state.
# Sequence number resets to 0 on each new date -- the first
# release of a day is quant_YYYYMMDD.0.hash, the second .1, etc.
RELEASES_TODAY=$(curl -sf --connect-timeout 10 --max-time 30 \
-H "Authorization: token ${GITEA_TOKEN}" \
"https://gitea.taxbaik.com/api/v1/repos/${{ github.repository }}/tags?limit=50" \
| jq -r --arg prefix "quant_${TODAY}." '[.[] | select(.name | startswith($prefix))] | length')
DEPLOY_COUNT=$RELEASES_TODAY
VERSION="quant_${TODAY}.${DEPLOY_COUNT}.${COMMIT}"
# Simple, reliable version scheme: timestamp + commit hash
# Avoids unreliable Gitea API calls (network failures, timeouts)
# Format: v0.1.YYYYMMDD.HHMMSS.COMMIT
TIMESTAMP=$(TZ=Asia/Seoul date +%Y%m%d.%H%M%S)
VERSION="v0.1.${TIMESTAMP}.${COMMIT}"
else
VERSION="$VERSION_INPUT"
fi
+5
View File
@@ -9,6 +9,11 @@ GatherTradingData.json
Temp/
dist/
outputs/
publish_artifact/
# 배포 아티팩트
*.tar.gz
quantengine-*.tar.gz
# .NET 빌드 산출물
**/bin/
+12 -11
View File
@@ -1,25 +1,26 @@
# QuantEngine v0.2 - Python Dependencies
# CI/CD validation and data collection tools
# Pinned versions for CI stability
# Core dependencies
pyyaml>=6.0
requests>=2.28.0
python-dotenv>=0.21.0
pyyaml==6.0.1
requests==2.31.0
python-dotenv==1.0.0
# Data processing
openpyxl>=3.9.0
pandas>=1.5.0
numpy>=1.23.0
openpyxl==3.11.0
pandas==2.0.3
numpy==1.24.3
# Database
psycopg[binary]>=3.1.0
psycopg[binary]==3.1.12
# Testing & validation
pytest>=7.2.0
pytest-asyncio>=0.20.0
pytest==7.4.0
pytest-asyncio==0.21.1
# Async
aiohttp>=3.8.0
aiohttp==3.8.5
# Utilities
click>=8.1.0
click==8.1.6
+182
View File
@@ -0,0 +1,182 @@
# QuantEngine 배포 가이드 (한글)
## 현재 상태
- ✅ 코드: 모두 커밋됨
- ✅ 테스트: 214/214 통과
- ✅ 워크플로우: 준비 완료
---
## 배포 방법 (2단계)
### 📍 1단계: Release 생성 (prepare-release.yml)
**목적:** 코드를 빌드하고 Release 버전을 만드는 단계
**URL 이동:**
```
https://gitea.taxbaik.com/kjh2064/QuantEngineByItz/actions
```
**작업 절차:**
1. 위 URL에 접속
2. 왼쪽 목록에서 "Prepare Release" 클릭
3. 오른쪽 상단 "Run workflow" 버튼 클릭
4. 팝업에서 파라미터 입력:
**파라미터: version (버전 이름)**
- **의미:** 이 Release의 이름
- **입력값:**
- **비워두기** (추천): 자동으로 `quant_20260724.0.xxxxx` 형태로 생성
- **직접 입력**: `v0.1.20260724` 같이 원하는 이름 입력
- **기본값:** (비어있음 = 자동 생성)
5. "Run workflow" 클릭
6. 실행 완료 대기 (약 5-10분)
**완료 후:**
- ✅ 빌드 성공
- ✅ Release 생성됨
- ✅ Git 태그 생성됨
- ✅ 아티팩트 업로드됨
---
### 📍 2단계: 배포 실행 (deploy-prod.yml)
**목적:** 생성된 Release를 운영 서버에 배포하는 단계
**URL 이동:**
```
https://gitea.taxbaik.com/kjh2064/QuantEngineByItz/actions
```
**작업 절차:**
1. 위 URL에 접속
2. 왼쪽 목록에서 "Deploy to Production" 클릭
3. 오른쪽 상단 "Run workflow" 버튼 클릭
4. 팝업에서 파라미터 입력:
**파라미터: release (배포할 Release 선택)**
- **의미:** 1단계에서 만든 Release 중 어떤 것을 배포할지 선택
- **입력값:**
- **비워두기** (추천): 가장 최신 Release를 자동으로 배포
- **직접 입력**: 1단계에서 생성된 버전명
- 예: `v0.1.20260724`
- 예: `quant_20260724.0.abc1234`
- **기본값:** (비어있음 = 최신 Release 배포)
5. "Run workflow" 클릭
6. 실행 완료 대기 (약 3-5분)
**자동으로 진행되는 작업:**
1. Release 아티팩트 다운로드
2. SSH로 서버에 전송
3. 서버에서 압축 해제
4. 기존 서비스 중지
5. 새 버전 배포
6. 서비스 시작
7. 자동 헬스 체크 (6가지 항목 검증)
---
## 배포 후 확인
**웹에서 확인:**
```
http://178.104.200.7/quantengine/Account/Login
계정: admin
암호: quant123!
```
**SSH로 상태 확인:**
```bash
ssh kjh2064@178.104.200.7
# 서비스 상태 확인
systemctl status quantengine
# 최근 로그 보기 (실시간)
journalctl -u quantengine -f
# 배포된 버전 확인
readlink ~/quantengine_active
```
---
## 문제 발생 시 롤백
**이전 버전으로 되돌리기:**
```bash
ssh kjh2064@178.104.200.7
# 백업에서 복구
ln -sfn $(readlink ~/quantengine_active_backup) ~/quantengine_active
# 서비스 재시작
sudo systemctl restart quantengine
# 확인
systemctl status quantengine
```
---
## 예시 시나리오
### ✅ 시나리오 1: 기본 배포 (추천)
**1단계:**
- "Prepare Release" 실행
- version 파라미터: **비워두기** ← 자동 생성
- 대기
**2단계:**
- "Deploy to Production" 실행
- release 파라미터: **비워두기** ← 최신 Release 배포
- 대기
**결과:** 최신 코드가 운영 서버에 배포됨
### ✅ 시나리오 2: 특정 버전 배포
**1단계:**
- "Prepare Release" 실행
- version 파라미터: `v0.1.20260724` 입력
- 대기 → Release "v0.1.20260724" 생성됨
**2단계:**
- "Deploy to Production" 실행
- release 파라미터: `v0.1.20260724` 입력 ← 위에서 생성한 버전
- 대기
**결과:** 지정된 버전이 운영 서버에 배포됨
---
## 주의사항
⚠️ **반드시 순서대로!**
- 1단계(Prepare Release) 없이 2단계를 할 수 없음
- 1단계 완료 후 2단계 실행
⚠️ **파라미터 입력**
- 오타 없이 정확히 입력
- 존재하지 않는 버전을 입력하면 오류 발생
⚠️ **배포 중 중단 금지**
- 실행 중에는 중단하지 말 것
- 전체 프로세스는 3-5분 소요
---
## 빠른 참조
| 단계 | Workflow | 파라미터 | 권장값 |
|------|----------|---------|-------|
| 1 | Prepare Release | version | (비워두기) |
| 2 | Deploy to Production | release | (비워두기) |
**총 소요 시간:** 10-15분