name: Merge to Main - Full Pipeline on: push: branches: [ main ] workflow_dispatch: concurrency: group: merge-main cancel-in-progress: false env: DOTNET_VERSION: '10.0.x' jobs: stage-1-fast-gates: name: "Stage 1: Fast Gates" runs-on: ubuntu-latest timeout-minutes: 2 steps: - name: Checkout Code uses: actions/checkout@v3 - name: YAML Validation run: | python3 -m pip install -q yamllint yamllint -c "{extends: default}" .gitea/workflows/*.yml || true - name: Secret Scanning run: | ! grep -r "Password=" .gitea/workflows/ --include="*.yml" | grep -v "secrets\." || exit 1 - name: JSON Validation run: | python3 -c " import json, glob for f in glob.glob('**/*.json', recursive=True): try: with open(f) as file: json.load(file) except Exception as e: print(f'ERROR: {f}: {e}') exit(1) " - name: Report Tier 1 if: success() run: echo " Tier 1 (Fast Gates) passed" stage-2-critical-gates: name: "Stage 2: Critical Gates" runs-on: ubuntu-latest timeout-minutes: 5 needs: stage-1-fast-gates steps: - name: Checkout Code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: KIS API Governance run: | pip install -q pyyaml python3 tools/validate_no_direct_api_trading_v1.py || exit 1 - name: Database Schema Validation run: python3 tools/validate_postgresql_history_contract_v1.py || exit 1 - name: Report Tier 2 if: success() run: echo " Tier 2 (Critical Gates) passed" stage-3-validators-parallel: name: "Stage 3: Integration Tests" runs-on: ubuntu-latest timeout-minutes: 10 needs: stage-2-critical-gates continue-on-error: true steps: - name: Checkout Code uses: actions/checkout@v3 - name: Setup Python run: pip install -q pyyaml openpyxl requests - name: Validate Specs run: python3 tools/validate_specs.py || true - name: Validate Formula Registry run: python3 tools/validate_formula_registry.py || true - name: Report Tier 3 if: always() run: echo " Tier 3 (Integration Tests) completed" stage-4-build: name: "Stage 4: Build and Package" runs-on: ubuntu-latest timeout-minutes: 15 needs: - stage-1-fast-gates - stage-2-critical-gates - stage-3-validators-parallel if: needs.stage-1-fast-gates.result == 'success' && needs.stage-2-critical-gates.result == 'success' outputs: artifact-name: quantengine-${{ steps.metadata.outputs.commit }} steps: - name: Checkout Code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v3 with: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Generate Metadata id: metadata run: | COMMIT=$(git rev-parse --short HEAD) echo "commit=${COMMIT}" >> $GITHUB_OUTPUT echo "Commit: ${COMMIT}" - 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 - name: Unit Tests run: | dotnet test src/dotnet/QuantEngine.Core.Tests/QuantEngine.Core.Tests.csproj \ -c Release --no-build || true - name: Publish and Package run: | dotnet publish src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \ -c Release --no-build -o ./publish tar -czf quantengine-${{ steps.metadata.outputs.commit }}.tar.gz -C ./publish . echo "Package ready: quantengine-${{ steps.metadata.outputs.commit }}.tar.gz" - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: quantengine-${{ github.run_number }} path: quantengine-${{ steps.metadata.outputs.commit }}.tar.gz retention-days: 7 - name: Report Tier 4 if: success() run: echo " Tier 4 (Build) succeeded" stage-5-deploy: name: "Stage 5: Trigger Deploy Pipeline" runs-on: ubuntu-latest timeout-minutes: 5 needs: stage-4-build if: success() steps: - name: Trigger Deploy run: | echo "Build successful. Starting deployment via deploy-prod.yml..." echo "Artifact: quantengine-${{ needs.stage-4-build.outputs.artifact-name }}" summary: name: "Pipeline Summary" runs-on: ubuntu-latest if: always() needs: - stage-1-fast-gates - stage-2-critical-gates - stage-3-validators-parallel - stage-4-build - stage-5-deploy steps: - name: Generate Summary run: | echo "Pipeline Execution Summary" echo "Stage 1 (Fast Gates): ${{ needs.stage-1-fast-gates.result }}" echo "Stage 2 (Critical): ${{ needs.stage-2-critical-gates.result }}" echo "Stage 3 (Integration): ${{ needs.stage-3-validators-parallel.result }}" echo "Stage 4 (Build): ${{ needs.stage-4-build.result }}" echo "Stage 5 (Deploy Trigger): ${{ needs.stage-5-deploy.result }}"