Skip to content

Continuous Deployment (CD) #26

Continuous Deployment (CD)

Continuous Deployment (CD) #26

Workflow file for this run

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
# --------------------------------------------------
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: ${{ matrix.model }}-${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
- run: make install-deps
- run: make ci
# --------------------------------------------------
# 🚀 Deploy
# --------------------------------------------------
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.deploy.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
android: true
dotnet: true
haskell: true
docker-images: true
swap-storage: 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_CLI_AUTH_TOKEN }}
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ matrix.model }}-${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
- run: make install-deps
- name: Deploy model
id: deploy
env:
MODEL_NAME: ${{ matrix.model }}
REPLICATE_CLI_AUTH_TOKEN: ${{ secrets.REPLICATE_CLI_AUTH_TOKEN }}
run: |
set -euo pipefail
echo "🚀 Deploying ${MODEL_NAME}…"
DEPLOY_LOG=$(make deploy)
echo "$DEPLOY_LOG"
VERSION_ID=$(echo "$DEPLOY_LOG" | grep -Eo 'sha256:[a-f0-9]{64}' | head -n1 | sed 's/^sha256://')
if [ -z "$VERSION_ID" ]; then
echo "❌ Failed to extract version hash from deploy output"
exit 1
fi
MODEL_ID="paragekbote/${MODEL_NAME}:${VERSION_ID}"
echo "candidate_model_id=${MODEL_ID}" >> "$GITHUB_OUTPUT"
echo "✅ Deployed candidate: ${MODEL_ID}"
# --------------------------------------------------
# 🧪 Integration
# --------------------------------------------------
integration:
name: 🧪 Run Integration Tests (${{ 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 }}
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ matrix.model }}-${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
- run: make install-deps
- run: make integration
# --------------------------------------------------
# 🐦 Canary
# --------------------------------------------------
canary:
name: 🐦 Run Canary Tests (${{ 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 }}
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ matrix.model }}-${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
- name: Verify candidate model id
run: |
if [ -z "${CANDIDATE_MODEL_ID}" ]; then
echo "ERROR: CANDIDATE_MODEL_ID is not set"
exit 1
fi
- run: make install-deps
- 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