Continuous Deployment (CD) #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Continuous Deployment (CD) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| model_name: | |
| description: "Model to deploy" | |
| required: true | |
| type: choice | |
| options: | |
| - all | |
| - smollm3-pruna | |
| - phi4-reasoning-plus-unsloth | |
| - flux-fast-lora-hotswap | |
| - flux-fast-lora-hotswap-img2img | |
| - gemma-torchao | |
| permissions: | |
| contents: read | |
| env: | |
| PYTHON_VERSION: "3.12" | |
| jobs: | |
| # -------------------------------------------------- | |
| # 🎯 Setup (resolve model matrix) | |
| # -------------------------------------------------- | |
| setup: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| models: ${{ steps.matrix.outputs.models }} | |
| steps: | |
| - id: matrix | |
| run: | | |
| if [ "${{ github.event.inputs.model_name }}" = "all" ]; then | |
| echo 'models=["smollm3-pruna","phi4-reasoning-plus-unsloth","flux-fast-lora-hotswap","flux-fast-lora-hotswap-img2img","gemma-torchao"]' >> $GITHUB_OUTPUT | |
| else | |
| echo 'models=["${{ github.event.inputs.model_name }}"]' >> $GITHUB_OUTPUT | |
| fi | |
| # -------------------------------------------------- | |
| # ✅ CI (per model, installs deps) | |
| # -------------------------------------------------- | |
| ci: | |
| name: ✅ CI (${{ matrix.model }}) | |
| needs: setup | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 30 | |
| strategy: | |
| matrix: | |
| model: ${{ fromJson(needs.setup.outputs.models) }} | |
| fail-fast: false | |
| env: | |
| MODEL_NAME: ${{ matrix.model }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} | |
| - run: make install-deps | |
| - run: make ci | |
| # -------------------------------------------------- | |
| # 🚀 Deploy (per model) | |
| # -------------------------------------------------- | |
| deploy: | |
| name: 🚀 Deploy (${{ matrix.model }}) | |
| needs: [setup, ci] | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 60 | |
| strategy: | |
| matrix: | |
| model: ${{ fromJson(needs.setup.outputs.models) }} | |
| fail-fast: false | |
| outputs: | |
| candidate_model_id: ${{ steps.capture.outputs.candidate_model_id }} | |
| env: | |
| MODEL_NAME: ${{ matrix.model }} | |
| REPLICATE_API_TOKEN: ${{ secrets.REPLICATE_API_TOKEN }} | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| steps: | |
| - uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: true | |
| large-packages: true | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Setup Cog | |
| uses: replicate/setup-cog@v2 | |
| with: | |
| cog-version: "v0.16.9" | |
| token: ${{ secrets.REPLICATE_API_TOKEN }} | |
| - name: Install jq | |
| run: sudo apt-get update && sudo apt-get install -y jq | |
| - run: make install-deps | |
| - run: make deploy | |
| - name: Capture deployed model version | |
| id: capture | |
| run: | | |
| echo "🔎 Capturing deployed version for ${MODEL_NAME}" | |
| VERSION=$(replicate model versions list \ | |
| paragekbote/${MODEL_NAME} \ | |
| --json | jq -r '.[0].id') | |
| if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then | |
| echo "❌ Failed to resolve deployed version" | |
| exit 1 | |
| fi | |
| echo "candidate_model_id=paragekbote/${MODEL_NAME}:${VERSION}" >> $GITHUB_OUTPUT | |
| echo "✅ Candidate model: paragekbote/${MODEL_NAME}:${VERSION}" | |
| # -------------------------------------------------- | |
| # 🧪 Integration | |
| # -------------------------------------------------- | |
| integration: | |
| name: 🧪 Integration (${{ matrix.model }}) | |
| needs: [setup, deploy] | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 30 | |
| strategy: | |
| matrix: | |
| model: ${{ fromJson(needs.setup.outputs.models) }} | |
| fail-fast: false | |
| env: | |
| MODEL_NAME: ${{ matrix.model }} | |
| REPLICATE_API_TOKEN: ${{ secrets.REPLICATE_API_TOKEN }} | |
| CANDIDATE_MODEL_ID: ${{ needs.deploy.outputs.candidate_model_id }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - run: make install-deps | |
| - run: make integration | |
| # -------------------------------------------------- | |
| # 🐦 Canary | |
| # -------------------------------------------------- | |
| canary: | |
| name: 🐦 Canary (${{ matrix.model }}) | |
| needs: [setup, deploy, integration] | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 45 | |
| strategy: | |
| matrix: | |
| model: ${{ fromJson(needs.setup.outputs.models) }} | |
| fail-fast: false | |
| env: | |
| MODEL_NAME: ${{ matrix.model }} | |
| REPLICATE_API_TOKEN: ${{ secrets.REPLICATE_API_TOKEN }} | |
| CANDIDATE_MODEL_ID: ${{ needs.deploy.outputs.candidate_model_id }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - run: make install-deps | |
| - name: Validate stable baselines (warn-only) | |
| run: | | |
| python scripts/validate_stable_and_candidate.py >> $GITHUB_ENV || \ | |
| echo "⚠️ Stable baseline validation failed — canary may be degraded" | |
| - run: make canary | |
| # -------------------------------------------------- | |
| # 🎉 Summary | |
| # -------------------------------------------------- | |
| summary: | |
| name: Summary | |
| needs: [deploy, integration, canary] | |
| runs-on: ubuntu-22.04 | |
| if: always() | |
| steps: | |
| - run: | | |
| echo "## 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Model:** ${{ github.event.inputs.model_name }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- 🚀 Deploy: ${{ needs.deploy.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- 🧪 Integration: ${{ needs.integration.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- 🐦 Canary: ${{ needs.canary.result }}" >> $GITHUB_STEP_SUMMARY |