diff --git a/.github/workflows/cd-staging.yml b/.github/workflows/cd-staging.yml new file mode 100644 index 0000000..7d8fc6e --- /dev/null +++ b/.github/workflows/cd-staging.yml @@ -0,0 +1,95 @@ +name: Deploy Kaapi Guardrails Staging To EC2 + +on: + push: + branches: [main] + +concurrency: + group: guardrail-staging-ec2-deploy + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-latest + environment: AWS_ENV_SECRETS + + permissions: + id-token: write + contents: read + + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v6 + with: + role-to-assume: ${{ secrets.EC2_DEPLOY_ROLE_ARN }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Trigger deploy on EC2 via SSM + id: ssm + env: + INSTANCE_ID: ${{ secrets.STAGING_EC2_INSTANCE_ID }} + BUILD_DIRECTORY: ${{ secrets.BUILD_DIRECTORY }} + run: | + DEPLOY_CMD='sudo -iu ec2-user bash -lc \"cd '"${BUILD_DIRECTORY}"' && git fetch origin && git reset --hard origin/main && docker compose build && docker compose run --rm --entrypoint \\\"\\\" backend uv run alembic upgrade head && docker compose up -d --remove-orphans && docker image prune -f\"' + + CMD_ID=$(aws ssm send-command \ + --instance-ids "$INSTANCE_ID" \ + --document-name "AWS-RunShellScript" \ + --comment "Deploy kaapi-guardrails staging" \ + --parameters commands="[\"set -eux\",\"sudo chown -R ec2-user:ec2-user ${BUILD_DIRECTORY}\",\"${DEPLOY_CMD}\"]" \ + --query "Command.CommandId" \ + --output text) + + echo "cmd_id=$CMD_ID" >> "$GITHUB_OUTPUT" + echo "Sent SSM command: $CMD_ID" + + - name: Wait for SSM command to finish + env: + INSTANCE_ID: ${{ secrets.STAGING_EC2_INSTANCE_ID }} + CMD_ID: ${{ steps.ssm.outputs.cmd_id }} + run: | + for i in {1..20}; do + STATUS=$(aws ssm get-command-invocation \ + --command-id "$CMD_ID" \ + --instance-id "$INSTANCE_ID" \ + --query "Status" \ + --output text) + + echo "Current Status: $STATUS" + + if [ "$STATUS" = "Success" ]; then + echo "Deployment completed successfully." + + aws ssm get-command-invocation \ + --command-id "$CMD_ID" \ + --instance-id "$INSTANCE_ID" \ + --query '{Status:Status,Stdout:StandardOutputContent,Stderr:StandardErrorContent}' \ + --output json + + exit 0 + fi + + if [ "$STATUS" = "Failed" ] || [ "$STATUS" = "Cancelled" ] || [ "$STATUS" = "TimedOut" ]; then + echo "Deployment failed." + + aws ssm get-command-invocation \ + --command-id "$CMD_ID" \ + --instance-id "$INSTANCE_ID" \ + --query '{Status:Status,Stdout:StandardOutputContent,Stderr:StandardErrorContent}' \ + --output json + + exit 1 + fi + + sleep 15 + done + + echo "Deployment timed out after waiting too long." + + aws ssm get-command-invocation \ + --command-id "$CMD_ID" \ + --instance-id "$INSTANCE_ID" \ + --query '{Status:Status,Stdout:StandardOutputContent,Stderr:StandardErrorContent}' \ + --output json + + exit 1 \ No newline at end of file diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous-integration.yml similarity index 100% rename from .github/workflows/continuous_integration.yml rename to .github/workflows/continuous-integration.yml diff --git a/backend/app/api/docs/guardrails/run_guardrails.md b/backend/app/api/docs/guardrails/run_guardrails.md index 19cba14..d0f1c7f 100644 --- a/backend/app/api/docs/guardrails/run_guardrails.md +++ b/backend/app/api/docs/guardrails/run_guardrails.md @@ -19,7 +19,7 @@ Behavior notes: | `no_illegal_drugs` | No illegal drugs | | `no_encourage_self_harm` | No encouragement of self-harm | - `rephrase_needed=true` means the system could not safely auto-fix the input/output and wants the user to retry with a rephrased query. -- When a validator with `on_fail=fix` has no programmatic fix (e.g. `profanity_free`), `safe_text` will be `""` and the response `metadata.reason` will explain which validator caused the empty output. +- When a validator with `on_fail=fix` has no programmatic fix (e.g. `profanity_free`), `safe_text` will be an empty string and the response `metadata.reason` will explain which validator caused the empty output. Failure behavior: - `success=false` is returned when validation fails without a recoverable fix or an internal runtime error occurs. diff --git a/backend/app/schemas/guardrail_config.py b/backend/app/schemas/guardrail_config.py index f66c8d4..968c260 100644 --- a/backend/app/schemas/guardrail_config.py +++ b/backend/app/schemas/guardrail_config.py @@ -84,6 +84,7 @@ def normalize_validators_from_config_api(cls, data): "is_enabled", "created_at", "updated_at", + "name", } for validator in validators: