Add a smoke test after deployment #65
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: Deploy to Azure | |
| on: | |
| workflow_dispatch: | |
| push: | |
| # Run when commits are pushed to mainline branch | |
| branches: | |
| - main | |
| pull_request: | |
| # Run the same validation (provision+deploy+smoke) for PRs targeting main | |
| branches: | |
| - main | |
| # GitHub Actions workflow to deploy to Azure using azd | |
| # To configure required secrets for connecting to Azure, simply run `azd pipeline config` | |
| # Set up permissions for deploying with secretless Azure federated credentials | |
| # https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Clinux#set-up-azure-login-with-openid-connect-authentication | |
| permissions: | |
| id-token: write | |
| contents: read | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| env: | |
| AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }} | |
| AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }} | |
| AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }} | |
| AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} | |
| # Project-specific variables | |
| AZURE_OPENAI_LOCATION: ${{ vars.AZURE_OPENAI_LOCATION }} | |
| AZURE_OPENAI_MODEL: ${{ vars.AZURE_OPENAI_MODEL }} | |
| AZURE_OPENAI_MODEL_VERSION: ${{ vars.AZURE_OPENAI_MODEL_VERSION }} | |
| AZURE_OPENAI_DEPLOYMENT: ${{ vars.AZURE_OPENAI_DEPLOYMENT }} | |
| AZURE_OPENAI_DEPLOYMENT_CAPACITY: ${{ vars.AZURE_OPENAI_DEPLOYMENT_CAPACITY }} | |
| AZURE_OPENAI_DEPLOYMENT_SKU_NAME: ${{ vars.AZURE_OPENAI_DEPLOYMENT_SKU_NAME }} | |
| AZURE_OPENAI_RESOURCE: ${{ vars.AZURE_OPENAI_RESOURCE }} | |
| AZURE_OPENAI_RESOURCE_GROUP: ${{ vars.AZURE_OPENAI_RESOURCE_GROUP }} | |
| AZURE_OPENAI_RESOURCE_GROUP_LOCATION: ${{ vars.AZURE_OPENAI_RESOURCE_GROUP_LOCATION }} | |
| AZURE_OPENAI_SKU_NAME: ${{ vars.AZURE_OPENAI_SKU_NAME }} | |
| AZURE_OPENAI_API_VERSION: ${{ vars.AZURE_OPENAI_API_VERSION }} | |
| CREATE_AZURE_OPENAI: ${{ vars.CREATE_AZURE_OPENAI }} | |
| AZURE_OPENAI_KEY_FOR_CHATVISION: ${{ vars.AZURE_OPENAI_KEY_FOR_CHATVISION }} | |
| AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }} | |
| CREATE_ROLE_FOR_USER: ${{ vars.CREATE_ROLE_FOR_USER }} | |
| SERVICE_ACA_RESOURCE_EXISTS: ${{ vars.SERVICE_ACA_RESOURCE_EXISTS }} | |
| DISABLE_KEY_BASED_AUTH: ${{ vars.DISABLE_KEY_BASED_AUTH }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Install azd | |
| uses: Azure/setup-azd@v2.2.0 | |
| - name: Log in with Azure (Federated Credentials) | |
| run: | | |
| azd auth login ` | |
| --client-id "$Env:AZURE_CLIENT_ID" ` | |
| --federated-credential-provider "github" ` | |
| --tenant-id "$Env:AZURE_TENANT_ID" | |
| shell: pwsh | |
| - name: Provision Infrastructure | |
| run: | | |
| azd env set CREATE_ROLE_FOR_USER false --no-prompt | |
| azd provision --no-prompt | |
| env: | |
| AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }} | |
| AZURE_LOCATION: ${{ vars.AZURE_LOCATION }} | |
| AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }} | |
| - name: Deploy Application | |
| run: azd deploy --no-prompt | |
| env: | |
| AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }} | |
| AZURE_LOCATION: ${{ vars.AZURE_LOCATION }} | |
| AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }} | |
| - name: Smoke Test Chat Endpoint | |
| # Simple post-deploy health check to ensure /chat/stream responds with HTTP 200 | |
| shell: bash | |
| env: | |
| AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }} | |
| run: | | |
| set -euo pipefail | |
| echo "Fetching deployed service base URI from azd environment..." | |
| BASE_URL="$(azd env get-value SERVICE_ACA_URI || true)" | |
| if [ -z "$BASE_URL" ]; then | |
| echo "ERROR: SERVICE_ACA_URI not found in azd environment." >&2 | |
| exit 1 | |
| fi | |
| # Trim possible trailing slash | |
| BASE_URL="${BASE_URL%/}" | |
| echo "Base URL: $BASE_URL" | |
| PAYLOAD='{"messages":[{"role":"user","content":"Hello from smoke test"}],"context":{"file":null},"temperature":0}' | |
| MAX_RETRIES=6 | |
| SLEEP_SECONDS=20 | |
| attempt=1 | |
| while [ $attempt -le $MAX_RETRIES ]; do | |
| echo "Attempt $attempt of $MAX_RETRIES..." | |
| # Capture HTTP status code; allow curl to fail without aborting loop | |
| HTTP_CODE=$(curl -sS -o smoke_response.txt -w "%{http_code}" \ | |
| -H 'Content-Type: application/json' \ | |
| -X POST "$BASE_URL/chat/stream" \ | |
| --max-time 45 \ | |
| -d "$PAYLOAD" || echo "000") | |
| echo "HTTP_CODE=$HTTP_CODE" | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "Smoke test succeeded (received 200). Showing first line of stream:" | |
| head -n 1 smoke_response.txt || true | |
| exit 0 | |
| fi | |
| echo "Non-200 response (code=$HTTP_CODE). Waiting $SLEEP_SECONDS seconds before retry..." | |
| sleep $SLEEP_SECONDS | |
| attempt=$((attempt+1)) | |
| done | |
| echo "Smoke test failed after $MAX_RETRIES attempts. Last response body (first 50 lines):" >&2 | |
| head -n 50 smoke_response.txt >&2 || true | |
| exit 1 |