# 워크플로우 감시 및 개선 보고서 (2026-07-24) ## 🔍 전체 스캔 결과 ### 파일별 상태 분석 | 파일명 | 상태 | 심각도 | 주요 이슈 | |--------|------|--------|---------| | `ci.yml` | ⚠️ 개선필요 | 중간 | Python 중복 설정, DOTNET_VERSION 오류 | | `ci_lint.yml` | ✅ 양호 | 낮음 | job dependency 일관성 | | `deploy-prod.yml` | ⚠️ 개선필요 | 높음 | SSH 코드 중복, 주석 과다 | | `kis_data_collection.yml` | ⚠️ 개선필요 | 중간 | Daily validator 미통합 | | `prepare-release.yml` | ✅ 양호 | 낮음 | 불필요한 echo 중복 | | `qualitative_sell_strategy.yml` | ⚠️ 개선필요 | 중간 | pytest `|| true` 위험 | | `snapshot_admin.yml` | ✅ 양호 | 낮음 | PYTHONPATH 일관성 | --- ## 🐛 발견된 오류 및 개선사항 ### 1. ci.yml **❌ 오류 1: DOTNET_VERSION 버전 지정 오류** ```yaml # Line 15 env: DOTNET_VERSION: '10.0.x' # ← 오류: .NET 10.0은 존재하지 않음 ``` **수정:** ```yaml env: DOTNET_VERSION: '9.0.x' # ✓ 실제 존재하는 버전 ``` **❌ 오류 2: 중복된 Python 환경설정 (8회 반복)** - core, wbs-audit, dotnet-contracts, ui-storage, database-schema, calibration-pipeline, operational-reporting, security-validation, workflow-lint - 각 job마다 동일한 코드: `mkdir -p "$PYTHON_DEPS"`, `pip install`, `echo` - 결과: ~100줄 낭비 **수정:** Composite action 또는 공유 setup script로 추출 **❌ 오류 3: PostgreSQL 마이그레이션 적용 후 트리거 검증 없음** - V*.sql 파일 적용 후 `kis_*_audit` 테이블/트리거 실제 생성 확인 불가 - 데이터베이스 오류가 조용하게 무시될 수 있음 **수정:** 마이그레이션 후 검증 쿼리 추가 ```bash for f in $(ls src/dotnet/.../V*.sql | sort -V); do psql ... -f "$f" done # ✓ 추가: 트리거 생성 확인 psql -U quantengine_ci -d quantenginedb -c "SELECT COUNT(*) FROM information_schema.triggers WHERE trigger_schema='quantengine';" | grep -q "[0-9]" || exit 1 ``` --- ### 2. ci_lint.yml **⚠️ 문제: `notify-results` job 없음** - ci.yml의 다른 모든 job은 `notify-results`로 끝나지만, ci_lint.yml은 없음 - 불일치 → 워크플로우 완료 알림 누락 **수정:** ```yaml notify-results: name: "Notify Lint Results" if: always() needs: [lint-workflows, validate-secrets-contract] runs-on: ubuntu-latest steps: - name: Report Lint Status run: | LINT_STATUS=${{ needs.lint-workflows.result }} SECRETS_STATUS=${{ needs.validate-secrets-contract.result }} if [ "$LINT_STATUS" = "success" ] && [ "$SECRETS_STATUS" = "success" ]; then echo "✅ All workflow validations passed" exit 0 else echo "❌ Workflow validation failed" exit 1 fi ``` --- ### 3. deploy-prod.yml (높은 심각도) **❌ 오류 1: SSH key setup 코드 반복** - Lines 266-296: setup-ssh in deploy job - Lines 384-411: setup-ssh in post-deploy-check job - **중복된 20줄 코드** **수정:** ```yaml # ✓ 방법 1: Reusable composite action # .github/actions/setup-ssh/action.yml name: Setup SSH Deployment Key runs: using: composite steps: - run: | mkdir -p ~/.ssh SSH_KEY="${{ inputs.ssh_key }}" SSH_KEY_B64="${{ inputs.ssh_key_b64 }}" write_key() { 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 } [ -n "$SSH_KEY" ] && write_key "$SSH_KEY" || \ [ -n "$SSH_KEY_B64" ] && printf '%s' "$SSH_KEY_B64" | base64 -d > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -p 22 ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true ``` **❌ 오류 2: 주석 과다로 인한 가독성 저하** - Line 315-327: 13줄 주석 - Line 415-428: 14줄 주석 - Line 468-480: 13줄 주석 **수정:** 주석 요약본 + 링크 형식 ```yaml # 상세 문서: CLAUDE.md → "Local Development & Testing" # 요약: SSH 계정 선택 우선순위: SSH_PRIVATE_KEY > DEPLOY_SSH_KEY_B64 > DEPLOY_SSH_KEY ``` **❌ 오류 3: 헬스 체크에서 DB 검증 로직 복잡** - Line 481: `grep -c` 패턴이 복잡함 - `|| echo "0"` 사용으로 "0\n0" 발생 가능 (실제로 발생했었음) **이미 수정됨** (Line 481에 `|| true` 사용) --- ### 4. kis_data_collection.yml (중간 심각도) **❌ 오류 1: Daily validator 미통합** - Phase 0에서 `validate_data_consistency_daily_v1.py` 구현됨 - kis_data_collection.yml에는 아직 통합되지 않음 **수정:** ```yaml validate-data-quality: name: "Validate Daily Data Consistency" runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v3 - name: Setup Python & PostgreSQL Client run: | PYTHON_DEPS="$HOME/python_deps/quality" mkdir -p "$PYTHON_DEPS" /usr/bin/python3 -m pip install --disable-pip-version-check --quiet \ --target "$PYTHON_DEPS" psycopg2-binary pyyaml export PYTHONPATH="$PYTHON_DEPS:${PYTHONPATH:-}" echo "PYTHONPATH=$PYTHON_DEPS:${PYTHONPATH:-}" >> "$GITHUB_ENV" - name: "Run Daily Data Consistency Check" env: # SSH 터널로 원격 DB 접속: localhost:5432 → production DB DB_CONNECTION: "postgresql://quantengine_app:quantengine_app@localhost:5432/quantenginedb" run: | python3 tools/validate_data_consistency_daily_v1.py --mode warn ``` **❌ 오류 2: outputs 변수 선언 후 미사용** ```yaml # Line 22-23: 선언 outputs: mock-valid: ${{ steps.mock.outcome }} prod-valid: ${{ steps.prod.outcome }} # Line 101: 사용하지 않음 (notify-status에서 needs.validate-credentials.outputs를 참조하지 않음) ``` **수정:** ```yaml notify-status: needs: [validate-credentials, validate-database-pipeline, validate-data-quality] # ... env: MOCK_VALID: ${{ needs.validate-credentials.outputs.mock-valid }} PROD_VALID: ${{ needs.validate-credentials.outputs.prod-valid }} run: | echo "Mock credentials: $MOCK_VALID" echo "Prod credentials: $PROD_VALID" ``` --- ### 5. prepare-release.yml **⚠️ 문제 1: 불필요한 echo 반복** ```yaml # Lines 158-160: Package Artifact echo "artifact=${ARTIFACT}" >> $GITHUB_OUTPUT # ✓ 필요 echo "✓ Package: $(du -sh $ARTIFACT | cut -f1)" # 이미 위에서 표시됨 file "$ARTIFACT" # 너무 자세함 ``` **수정:** 간결하게 ```yaml - name: Package Artifact run: | VERSION="${{ steps.metadata.outputs.version }}" ARTIFACT="quantengine_${VERSION}.tar.gz" tar -czf "$ARTIFACT" -C ./publish . echo "artifact=${ARTIFACT}" >> $GITHUB_OUTPUT echo "✓ Package created: $(du -sh $ARTIFACT | awk '{print $1}')" ``` **⚠️ 문제 2: 매니페스트 생성 후 검증 없음** - 매니페스트 JSON 생성 후 유효성 검사 없음 - 파일이 비어있거나 형식이 잘못되어도 통과 **수정:** ```yaml - name: Validate Release Manifest run: | MANIFEST="${{ steps.metadata.outputs.artifact }}.manifest.json" python3 -c " import json with open('$MANIFEST') as f: data = json.load(f) assert 'version' in data and data['version'] assert 'commit' in data and data['commit'] assert 'sha256' in data and data['sha256'] print('✓ Manifest valid') " ``` --- ### 6. qualitative_sell_strategy.yml **❌ 오류 1: pytest 실패해도 무시됨** ```yaml # Line 50 python3 -m pytest tests/unit/test_qualitative_sell_strategy_store_v1.py -v || true # ← || true는 실패를 pass로 변환함 ``` **수정:** 실패 시 작업 실패로 전환 ```yaml - name: Validate Strategy Store (Integration) run: | python3 -m pytest tests/unit/test_qualitative_sell_strategy_store_v1.py -v \ --tb=short \ --no-header continue-on-error: false # ← 명시적으로 설정 ``` --- ### 7. snapshot_admin.yml **⚠️ 문제: PYTHONPATH 불일치** ```yaml # Line 17 (validate-workflow) env: PYTHONPATH: "$HOME/python_deps/snapshot:." # Line 45 (validate-ui) env: PYTHONPATH: "$HOME/python_deps/ui:." ``` **수정:** 일관된 PATH ```yaml jobs: setup-python: runs-on: ubuntu-latest outputs: python-path: ${{ steps.setup.outputs.path }} steps: - id: setup run: | PYTHON_DEPS="$HOME/python_deps/snapshot" mkdir -p "$PYTHON_DEPS" /usr/bin/python3 -m pip install --disable-pip-version-check --quiet \ --target "$PYTHON_DEPS" pyyaml pytest echo "path=$PYTHON_DEPS" >> $GITHUB_OUTPUT ``` --- ## 📋 종합 개선 체크리스트 ### Priority P0 (즉시 필요) - [ ] ci.yml: DOTNET_VERSION 수정 (10.0.x → 9.0.x) - [ ] deploy-prod.yml: SSH setup 코드 중복 제거 (20줄 → composite action) - [ ] kis_data_collection.yml: Daily validator 통합 - [ ] qualitative_sell_strategy.yml: pytest `|| true` 제거 ### Priority P1 (주간 중) - [ ] ci.yml: Python 환경설정 공유 스크립트로 추출 (60줄 → 10줄) - [ ] ci_lint.yml: `notify-results` job 추가 - [ ] prepare-release.yml: 매니페스트 검증 추가 - [ ] deploy-prod.yml: 주석 요약본으로 정리 ### Priority P2 (선택) - [ ] 모든 job에 명시적 timeout 설정 - [ ] 일관된 artifact naming convention - [ ] 각 job 성공 기준 명시 --- ## 🚀 다음 단계 **1단계 (30분)**: P0 오류 수정 (4개 파일) **2단계 (1시간)**: P1 개선 (4개 파일) **3단계 (로컬 테스트)**: 각 워크플로우 YAML 문법 검증 **4단계 (푸시)**: main에 커밋 및 CI 실행 --- 이 보고서는 **PHASE0_WEEKLY_EXECUTION_TRACKER.md**의 Week 1 일일 작업으로 통합 가능합니다.