Skip to content

Feature/feature x (#2) #2

Feature/feature x (#2)

Feature/feature x (#2) #2

name: CI Pipeline
permissions:
contents: read
actions: write
on:
push:
branches:
- develop
jobs:
unit-testing:
if: ${{ github.repository != 'Azure/llmops-project-template' }}
runs-on: ubuntu-latest
environment: dev
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
pip install -r requirements.txt
- name: Test with pytest
env:
PYTHONPATH: src
PYTHONWARNINGS: ignore::DeprecationWarning,ignore::RemovedInMarshmallow4Warning
run: pytest tests/ --doctest-modules --junitxml=junit/test-results-3.11.xml
- name: Upload pytest test results
uses: actions/upload-artifact@v4
with:
name: pytest-results-3.11
path: junit/test-results-3.11.xml
if: always()
code-standard-check:
runs-on: ubuntu-latest
environment: dev
steps:
- name: Check code standards
run: |
echo "Run Pylint"
setup-env-job:
if: ${{ github.repository != 'Azure/llmops-project-template' }}
needs: [unit-testing, code-standard-check]
runs-on: ubuntu-latest
environment: dev
outputs:
AZUREAI_PROJECT_NAME: ${{ steps.config-env.outputs.AZUREAI_PROJECT_NAME }}
AZURE_APP_SERVICE_NAME: ${{ steps.config-env.outputs.AZURE_APP_SERVICE_NAME }}
AZURE_APP_SERVICE_PLAN_NAME: ${{ steps.config-env.outputs.AZURE_APP_SERVICE_PLAN_NAME }}
AZURE_CONTAINER_REGISTRY_NAME: ${{ steps.config-env.outputs.AZURE_CONTAINER_REGISTRY_NAME }}
AZURE_CONTAINER_REPOSITORY_NAME: ${{ steps.config-env.outputs.AZURE_CONTAINER_REPOSITORY_NAME }}
AZURE_LOCATION: ${{ steps.config-env.outputs.AZURE_LOCATION }}
AZURE_OPENAI_API_VERSION: ${{ steps.config-env.outputs.AZURE_OPENAI_API_VERSION }}
AZURE_OPENAI_CHAT_DEPLOYMENT: ${{ steps.config-env.outputs.AZURE_OPENAI_CHAT_DEPLOYMENT }}
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: ${{ steps.config-env.outputs.AZURE_OPENAI_EMBEDDING_DEPLOYMENT }}
AZURE_OPENAI_EMBEDDING_MODEL: ${{ steps.config-env.outputs.AZURE_OPENAI_EMBEDDING_MODEL }}
AZURE_OPENAI_ENDPOINT: ${{ steps.config-env.outputs.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_NAME: ${{ steps.config-env.outputs.AZURE_OPENAI_NAME }}
AZURE_RESOURCE_GROUP: ${{ steps.config-env.outputs.AZURE_RESOURCE_GROUP }}
AZUREAI_RESOURCE_GROUP: ${{ steps.config-env.outputs.AZURE_RESOURCE_GROUP }}
AZURE_SEARCH_ENDPOINT: ${{ steps.config-env.outputs.AZURE_SEARCH_ENDPOINT }}
LOAD_AZURE_SEARCH_SAMPLE_DATA: ${{ steps.config-env.outputs.LOAD_AZURE_SEARCH_SAMPLE_DATA }}
AZURE_SEARCH_NAME: ${{ steps.config-env.outputs.AZURE_SEARCH_NAME }}
AZURE_SUBSCRIPTION_ID: ${{ steps.config-env.outputs.AZURE_SUBSCRIPTION_ID }}
PROMPTFLOW_SERVING_ENGINE: ${{ steps.config-env.outputs.PROMPTFLOW_SERVING_ENGINE }}
PROMPTFLOW_WORKER_NUM: ${{ steps.config-env.outputs.PROMPTFLOW_WORKER_NUM }}
AZURE_PRINCIPAL_ID: ${{ steps.config-env.outputs.AZURE_PRINCIPAL_ID }}
AZURE_STORAGE_ACCOUNT_NAME: ${{ steps.config-env.outputs.AZURE_STORAGE_ACCOUNT_NAME }}
steps:
- uses: actions/checkout@v4
- name: Config dev environment
uses: ./.github/actions/config-env
id: config-env
with:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }}
AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }}
AZURE_LOCATION: ${{ vars.AZURE_LOCATION }}
MANUAL_PROVISIONING: ${{ vars.MANUAL_PROVISIONING }}
AZURE_DEPLOY_APP_SERVICE: false
env:
AZUREAI_PROJECT_NAME: ${{ vars.AZUREAI_PROJECT_NAME }}
AZURE_APP_SERVICE_NAME: ${{ vars.AZURE_APP_SERVICE_NAME }}
AZURE_APP_SERVICE_PLAN_NAME: ${{ vars.AZURE_APP_SERVICE_PLAN_NAME }}
AZURE_CONTAINER_REGISTRY_NAME: ${{ vars.AZURE_CONTAINER_REGISTRY_NAME }}
AZURE_CONTAINER_REPOSITORY_NAME: ${{ vars.AZURE_CONTAINER_REPOSITORY_NAME }}
AZURE_OPENAI_API_VERSION: ${{ vars.AZURE_OPENAI_API_VERSION }}
AZURE_OPENAI_CHAT_DEPLOYMENT: ${{ vars.AZURE_OPENAI_CHAT_DEPLOYMENT }}
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: ${{ vars.AZURE_OPENAI_EMBEDDING_DEPLOYMENT }}
AZURE_OPENAI_EMBEDDING_MODEL: ${{ vars.AZURE_OPENAI_EMBEDDING_MODEL }}
AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_NAME: ${{ vars.AZURE_OPENAI_NAME }}
AZURE_RESOURCE_GROUP: ${{ vars.AZURE_RESOURCE_GROUP }}
AZUREAI_RESOURCE_GROUP: ${{ vars.AZURE_RESOURCE_GROUP }}
AZURE_SEARCH_ENDPOINT: ${{ vars.AZURE_SEARCH_ENDPOINT }}
LOAD_AZURE_SEARCH_SAMPLE_DATA: "false" # It's already populated during PR
AZURE_SEARCH_NAME: ${{ vars.AZURE_SEARCH_NAME }}
PROMPTFLOW_SERVING_ENGINE: ${{ vars.PROMPTFLOW_SERVING_ENGINE }}
PROMPTFLOW_WORKER_NUM: ${{ vars.PROMPTFLOW_WORKER_NUM }}
AZURE_PRINCIPAL_ID: ${{ vars.AZURE_PRINCIPAL_ID }}
AZUREAI_HUB_NAME: ${{ vars.AZUREAI_HUB_NAME }}
AZURE_APP_INSIGHTS_NAME: ${{ vars.AZURE_APP_INSIGHTS_NAME }}
AZURE_KEY_VAULT_NAME: ${{ vars.AZURE_KEY_VAULT_NAME }}
AZURE_LOG_ANALYTICS_NAME: ${{ vars.AZURE_LOG_ANALYTICS_NAME }}
AZURE_STORAGE_ACCOUNT_NAME: ${{ vars.AZURE_STORAGE_ACCOUNT_NAME }}
flow-evaluation:
needs: [setup-env-job, unit-testing, code-standard-check]
runs-on: ubuntu-latest
environment: dev
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Login to Azure CLI
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: AI-Based QA evaluation
env:
AZURE_SUBSCRIPTION_ID: ${{needs.setup-env-job.outputs.AZURE_SUBSCRIPTION_ID}}
AZURE_LOCATION: ${{needs.setup-env-job.outputs.AZURE_LOCATION}}
AZURE_RESOURCE_GROUP: ${{needs.setup-env-job.outputs.AZURE_RESOURCE_GROUP}}
AZURE_OPENAI_NAME: ${{needs.setup-env-job.outputs.AZURE_OPENAI_NAME}}
AZURE_OPENAI_ENDPOINT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_ENDPOINT}}
AZURE_SEARCH_ENDPOINT: ${{needs.setup-env-job.outputs.AZURE_SEARCH_ENDPOINT}}
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_EMBEDDING_DEPLOYMENT}}
AZURE_OPENAI_CHAT_DEPLOYMENT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_CHAT_DEPLOYMENT}}
AZURE_OPENAI_DEPLOYMENT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_CHAT_DEPLOYMENT}}
AZURE_OPENAI_EMBEDDING_MODEL: ${{needs.setup-env-job.outputs.AZURE_OPENAI_EMBEDDING_MODEL}}
AZURE_OPENAI_API_VERSION: ${{needs.setup-env-job.outputs.AZURE_OPENAI_API_VERSION}}
AZUREAI_PROJECT_NAME: ${{needs.setup-env-job.outputs.AZUREAI_PROJECT_NAME}}
PREFIX: ${{ github.sha }}
run: |
echo "Run AI-Based flow evaluation"
echo "AZURE_RESOURCE_GROUP=${AZURE_RESOURCE_GROUP}"
echo "AZURE_OPENAI_NAME=${AZURE_OPENAI_NAME}"
export AZURE_OPENAI_API_KEY=$(az cognitiveservices account keys list --resource-group ${AZURE_RESOURCE_GROUP} --name ${AZURE_OPENAI_NAME} --query "key1" --output tsv)
python evaluations/qa_quality_eval.py
shell: bash
- name: Upload evaluation results
uses: actions/upload-artifact@v4
with:
name: flow-eval-results
path: qa_flow_quality_eval.json
build-image:
runs-on: ubuntu-latest
needs: [setup-env-job, unit-testing, code-standard-check, flow-evaluation]
environment: dev
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Install Promptflow CLI
run: |
python -m pip install --upgrade pip
pip install promptflow --upgrade
pf --version
- name: Install required dependencies
run: |
pip cache purge
pip install --upgrade pip setuptools
pip install -r src/requirements.txt
- name: Create flow docker files
run: |
# reference: https://github.com/microsoft/promptflow/tree/main/examples/tutorials/flow-deploy/azure-app-service
pf flow build --source src --output dist --format docker
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
- name: Login to Azure CLI
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Build Image
env:
AZURE_CONTAINER_REPOSITORY_NAME: ${{needs.setup-env-job.outputs.AZURE_CONTAINER_REPOSITORY_NAME}}
run: |
echo "✅ Building docker image..."
path=dist
image_tag=$AZURE_CONTAINER_REPOSITORY_NAME:develop-${{ github.sha }}
echo "Change working directory to $path"
cd "$path"
docker build -t "$image_tag" .
- name: Run Container
env:
AZURE_SUBSCRIPTION_ID: ${{needs.setup-env-job.outputs.AZURE_SUBSCRIPTION_ID}}
AZURE_LOCATION: ${{needs.setup-env-job.outputs.AZURE_LOCATION}}
AZURE_RESOURCE_GROUP: ${{needs.setup-env-job.outputs.AZURE_RESOURCE_GROUP}}
AZUREAI_RESOURCE_GROUP: ${{needs.setup-env-job.outputs.AZURE_RESOURCE_GROUP}}
AZURE_SEARCH_ENDPOINT: ${{needs.setup-env-job.outputs.AZURE_SEARCH_ENDPOINT}}
AZURE_OPENAI_CHAT_DEPLOYMENT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_CHAT_DEPLOYMENT}}
AZURE_OPENAI_EMBEDDING_DEPLOYMENT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_EMBEDDING_DEPLOYMENT}}
AZURE_OPENAI_EMBEDDING_MODEL: ${{needs.setup-env-job.outputs.AZURE_OPENAI_EMBEDDING_MODEL}}
AZURE_OPENAI_API_VERSION: ${{needs.setup-env-job.outputs.AZURE_OPENAI_API_VERSION}}
AZURE_OPENAI_ENDPOINT: ${{needs.setup-env-job.outputs.AZURE_OPENAI_ENDPOINT}}
PROMPTFLOW_WORKER_NUM: ${{needs.setup-env-job.outputs.PROMPTFLOW_WORKER_NUM}}
PROMPTFLOW_SERVING_ENGINE: ${{needs.setup-env-job.outputs.PROMPTFLOW_SERVING_ENGINE}}
AZURE_CONTAINER_REPOSITORY_NAME: ${{needs.setup-env-job.outputs.AZURE_CONTAINER_REPOSITORY_NAME}}
run: |
echo "✅ Run image..."
image_tag=$AZURE_CONTAINER_REPOSITORY_NAME:develop-${{ github.sha }}
docker run -d -p 8080:8080 -e PROMPTFLOW_SERVING_ENGINE=$PROMPTFLOW_SERVING_ENGINE -e PROMPTFLOW_WORKER_NUM=$PROMPTFLOW_WORKER_NUM $image_tag
- name: Register Image
env:
AZURE_CONTAINER_REGISTRY_NAME: ${{needs.setup-env-job.outputs.AZURE_CONTAINER_REGISTRY_NAME}}
AZURE_CONTAINER_REPOSITORY_NAME: ${{needs.setup-env-job.outputs.AZURE_CONTAINER_REPOSITORY_NAME}}
run: |
image_tag=$AZURE_CONTAINER_REPOSITORY_NAME:develop-${{ github.sha }}
full_registry_name="$AZURE_CONTAINER_REGISTRY_NAME.azurecr.io"
echo "✅ Trying to login to $full_registry_name..."
az acr login -n "$full_registry_name"
acr_image_tag=$full_registry_name/$image_tag
echo "✅ ACR image tag: $acr_image_tag"
docker tag "$image_tag" "$acr_image_tag"
echo "✅ Start pushing image...$acr_image_tag"
docker push "$acr_image_tag"