Move ChatPanel into component directory #182
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: AWS/Web Release | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'api/**' | |
| - 'apps/auth/**' | |
| - 'apps/backend/**' | |
| - 'apps/web/**' | |
| - 'apps/admin/**' | |
| - 'db/**' | |
| - 'infra/**' | |
| - 'scripts/check-agent-api-smoke.sh' | |
| - 'scripts/check-api-health.sh' | |
| - 'scripts/check-demo-cognito-users.sh' | |
| - 'scripts/check-public-endpoints.sh' | |
| - 'scripts/deploy-admin.sh' | |
| - 'scripts/deploy-web.sh' | |
| - 'scripts/generate-global-metrics-snapshot.sh' | |
| - 'scripts/migrate-aws.sh' | |
| - 'scripts/write-ci-cdk-context.py' | |
| - '.github/workflows/aws-web-release.yml' | |
| workflow_dispatch: | |
| concurrency: | |
| group: main-release | |
| cancel-in-progress: false | |
| permissions: | |
| actions: read | |
| checks: read | |
| contents: read | |
| id-token: write | |
| env: | |
| AWS_REGION: ${{ vars.AWS_REGION }} | |
| STACK_NAME: FlashcardsOpenSourceApp | |
| jobs: | |
| changes: | |
| name: Detect changed areas | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| aws_changed: ${{ steps.detect.outputs.aws_changed }} | |
| api_changed: ${{ steps.detect.outputs.api_changed }} | |
| auth_changed: ${{ steps.detect.outputs.auth_changed }} | |
| backend_changed: ${{ steps.detect.outputs.backend_changed }} | |
| web_changed: ${{ steps.detect.outputs.web_changed }} | |
| admin_changed: ${{ steps.detect.outputs.admin_changed }} | |
| infra_changed: ${{ steps.detect.outputs.infra_changed }} | |
| changed_files: ${{ steps.detect.outputs.changed_files }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed files | |
| id: detect | |
| env: | |
| PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| run: | | |
| set -euo pipefail | |
| aws_release_script_pattern='^scripts/(check-agent-api-smoke\.sh|check-api-health\.sh|check-demo-cognito-users\.sh|check-public-endpoints\.sh|deploy-admin\.sh|deploy-web\.sh|generate-global-metrics-snapshot\.sh|migrate-aws\.sh|write-ci-cdk-context\.py)$' | |
| changed_files_path="${RUNNER_TEMP}/changed-files.txt" | |
| before_sha="${PUSH_BEFORE_SHA:-}" | |
| if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | |
| printf '%s\n' 'workflow_dispatch (forced AWS deploy)' > "${changed_files_path}" | |
| elif [[ "${GITHUB_EVENT_NAME}" == "push" ]] && [[ -n "${before_sha}" ]] && [[ "${before_sha}" != "0000000000000000000000000000000000000000" ]]; then | |
| git diff --name-only "${before_sha}" "${GITHUB_SHA}" > "${changed_files_path}" | |
| elif git rev-parse HEAD^ >/dev/null 2>&1; then | |
| git diff --name-only HEAD^ HEAD > "${changed_files_path}" | |
| else | |
| git ls-files > "${changed_files_path}" | |
| fi | |
| aws_changed=false | |
| if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | |
| aws_changed=true | |
| elif grep -Eq "^(api/|apps/auth/|apps/backend/|apps/web/|apps/admin/|db/|infra/|\\.github/workflows/aws-web-release\\.yml$)" "${changed_files_path}" || grep -Eq "${aws_release_script_pattern}" "${changed_files_path}"; then | |
| aws_changed=true | |
| fi | |
| api_changed=false | |
| auth_changed=false | |
| backend_changed=false | |
| web_changed=false | |
| admin_changed=false | |
| infra_changed=false | |
| if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | |
| api_changed=true | |
| auth_changed=true | |
| backend_changed=true | |
| web_changed=true | |
| admin_changed=true | |
| infra_changed=true | |
| else | |
| if grep -Eq '^(api/|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| api_changed=true | |
| fi | |
| if grep -Eq '^(apps/auth/|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| auth_changed=true | |
| fi | |
| if grep -Eq '^(apps/backend/|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| backend_changed=true | |
| fi | |
| if grep -Eq '^(apps/web/|apps/backend/src/schedule\.ts$|apps/backend/src/workspaceSchedulerConfig\.ts$|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| web_changed=true | |
| fi | |
| if grep -Eq '^(apps/admin/|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| admin_changed=true | |
| fi | |
| if grep -Eq '^(infra/|\.github/workflows/aws-web-release\.yml$)' "${changed_files_path}"; then | |
| infra_changed=true | |
| fi | |
| fi | |
| { | |
| echo "aws_changed=${aws_changed}" | |
| echo "api_changed=${api_changed}" | |
| echo "auth_changed=${auth_changed}" | |
| echo "backend_changed=${backend_changed}" | |
| echo "web_changed=${web_changed}" | |
| echo "admin_changed=${admin_changed}" | |
| echo "infra_changed=${infra_changed}" | |
| echo 'changed_files<<EOF' | |
| cat "${changed_files_path}" | |
| echo 'EOF' | |
| } >> "${GITHUB_OUTPUT}" | |
| - name: Summarize changed areas | |
| env: | |
| CHANGED_FILES: ${{ steps.detect.outputs.changed_files }} | |
| run: | | |
| { | |
| echo "## Release scope" | |
| echo "" | |
| echo "- AWS changed: \`${{ steps.detect.outputs.aws_changed }}\`" | |
| echo "- API changed: \`${{ steps.detect.outputs.api_changed }}\`" | |
| echo "- Auth changed: \`${{ steps.detect.outputs.auth_changed }}\`" | |
| echo "- Backend changed: \`${{ steps.detect.outputs.backend_changed }}\`" | |
| echo "- Web changed: \`${{ steps.detect.outputs.web_changed }}\`" | |
| echo "- Admin changed: \`${{ steps.detect.outputs.admin_changed }}\`" | |
| echo "- Infra changed: \`${{ steps.detect.outputs.infra_changed }}\`" | |
| echo "" | |
| echo "### Changed files" | |
| echo "" | |
| if [[ -n "${CHANGED_FILES}" ]]; then | |
| printf '%s\n' "${CHANGED_FILES}" | |
| else | |
| echo "No changed files detected." | |
| fi | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| pre_deploy_checks: | |
| name: Pre-deploy checks | |
| needs: changes | |
| if: ${{ needs.changes.outputs.aws_changed == 'true' }} | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: | | |
| api/package-lock.json | |
| apps/auth/package-lock.json | |
| apps/backend/package-lock.json | |
| apps/web/package-lock.json | |
| apps/admin/package-lock.json | |
| infra/aws/package-lock.json | |
| - name: Install dependencies | |
| run: | | |
| npm ci --prefix api | |
| npm ci --prefix apps/auth | |
| npm ci --prefix apps/backend | |
| npm ci --prefix apps/web | |
| npm ci --prefix apps/admin | |
| npm ci --prefix infra/aws | |
| - name: Lint OpenAPI spec | |
| if: ${{ needs.changes.outputs.api_changed == 'true' }} | |
| run: npm run lint --prefix api | |
| - name: Bundle OpenAPI spec | |
| run: npm run bundle --prefix api | |
| - name: Build auth app | |
| if: ${{ needs.changes.outputs.auth_changed == 'true' }} | |
| run: npm run build --prefix apps/auth | |
| - name: Test auth app | |
| if: ${{ needs.changes.outputs.auth_changed == 'true' }} | |
| run: npm run test --prefix apps/auth | |
| - name: Lint backend | |
| if: ${{ needs.changes.outputs.backend_changed == 'true' }} | |
| run: npm run lint --prefix apps/backend | |
| - name: Build backend | |
| if: ${{ needs.changes.outputs.backend_changed == 'true' }} | |
| run: npm run build --prefix apps/backend | |
| - name: Build web app | |
| if: ${{ needs.changes.outputs.web_changed == 'true' }} | |
| run: npm run build --prefix apps/web | |
| - name: Build admin app | |
| if: ${{ needs.changes.outputs.admin_changed == 'true' }} | |
| run: npm run build --prefix apps/admin | |
| - name: Build infra | |
| if: ${{ needs.changes.outputs.infra_changed == 'true' }} | |
| run: npm run build --prefix infra/aws | |
| - name: Synthesize infra | |
| working-directory: infra/aws | |
| env: | |
| AWS_DEPLOY_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} | |
| CDK_CONTEXT_ALERT_EMAIL: ${{ vars.CDK_ALERT_EMAIL }} | |
| CDK_CONTEXT_ANALYTICS_SSH_ALLOWED_CIDRS: ${{ vars.CDK_ANALYTICS_SSH_ALLOWED_CIDRS }} | |
| CDK_CONTEXT_ANALYTICS_SSH_PUBLIC_KEYS: ${{ vars.CDK_ANALYTICS_SSH_PUBLIC_KEYS }} | |
| CDK_CONTEXT_ANALYTICS_SSH_USERNAME: ${{ vars.CDK_ANALYTICS_SSH_USERNAME }} | |
| CDK_CONTEXT_ANTHROPIC_API_KEY_SECRET_ARN: ${{ vars.CDK_ANTHROPIC_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_API_CERTIFICATE_ARN: ${{ vars.CDK_API_CERTIFICATE_ARN }} | |
| CDK_CONTEXT_APEX_REDIRECT_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_APEX_REDIRECT_CERTIFICATE_ARN_US_EAST_1 }} | |
| CDK_CONTEXT_AUTH_CERTIFICATE_ARN: ${{ vars.CDK_AUTH_CERTIFICATE_ARN }} | |
| CDK_CONTEXT_ADMIN_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_ADMIN_CERTIFICATE_ARN_US_EAST_1 }} | |
| CDK_CONTEXT_ADMIN_EMAILS: ${{ vars.CDK_ADMIN_EMAILS }} | |
| CDK_CONTEXT_DEMO_EMAIL_DOSTIP: ${{ vars.CDK_DEMO_EMAIL_DOSTIP }} | |
| CDK_CONTEXT_DEMO_PASSWORD_SECRET_ARN: ${{ vars.CDK_DEMO_PASSWORD_SECRET_ARN }} | |
| CDK_CONTEXT_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} | |
| CDK_CONTEXT_GITHUB_REPO: ${{ vars.CDK_GITHUB_REPO }} | |
| CDK_CONTEXT_GLOBAL_METRICS_VISIBLE: ${{ vars.CDK_GLOBAL_METRICS_VISIBLE }} | |
| CDK_CONTEXT_GUEST_AI_WEIGHTED_MONTHLY_TOKEN_CAP: ${{ vars.CDK_GUEST_AI_WEIGHTED_MONTHLY_TOKEN_CAP }} | |
| CDK_CONTEXT_LANGFUSE_BASE_URL: ${{ vars.CDK_LANGFUSE_BASE_URL }} | |
| CDK_CONTEXT_LANGFUSE_PUBLIC_KEY_SECRET_ARN: ${{ vars.CDK_LANGFUSE_PUBLIC_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_LANGFUSE_SECRET_KEY_SECRET_ARN: ${{ vars.CDK_LANGFUSE_SECRET_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_OPENAI_API_KEY_SECRET_ARN: ${{ vars.CDK_OPENAI_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_REGION: ${{ vars.AWS_REGION }} | |
| CDK_CONTEXT_RESEND_API_KEY_SECRET_ARN: ${{ vars.CDK_RESEND_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_RESEND_SENDER_EMAIL: ${{ vars.CDK_RESEND_SENDER_EMAIL }} | |
| CDK_CONTEXT_WEB_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_WEB_CERTIFICATE_ARN_US_EAST_1 }} | |
| run: | | |
| python3 ../../scripts/write-ci-cdk-context.py \ | |
| --output cdk.context.local.json \ | |
| --aws-deploy-role-arn "${AWS_DEPLOY_ROLE_ARN}" | |
| npm run synth | |
| aws_deploy: | |
| name: Deploy AWS release | |
| needs: | |
| - changes | |
| - pre_deploy_checks | |
| if: ${{ needs.changes.outputs.aws_changed == 'true' && needs.pre_deploy_checks.result == 'success' }} | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: | | |
| api/package-lock.json | |
| apps/auth/package-lock.json | |
| apps/backend/package-lock.json | |
| apps/web/package-lock.json | |
| apps/admin/package-lock.json | |
| infra/aws/package-lock.json | |
| - name: Configure AWS credentials (OIDC) | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Install dependencies | |
| run: | | |
| npm ci --prefix api | |
| npm ci --prefix apps/auth | |
| npm ci --prefix apps/backend | |
| npm ci --prefix apps/web | |
| npm ci --prefix apps/admin | |
| npm ci --prefix infra/aws | |
| - name: Bundle OpenAPI spec | |
| run: npm run bundle --prefix api | |
| - name: CDK deploy | |
| working-directory: infra/aws | |
| env: | |
| AWS_DEPLOY_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }} | |
| CDK_CONTEXT_ALERT_EMAIL: ${{ vars.CDK_ALERT_EMAIL }} | |
| CDK_CONTEXT_ANALYTICS_SSH_ALLOWED_CIDRS: ${{ vars.CDK_ANALYTICS_SSH_ALLOWED_CIDRS }} | |
| CDK_CONTEXT_ANALYTICS_SSH_PUBLIC_KEYS: ${{ vars.CDK_ANALYTICS_SSH_PUBLIC_KEYS }} | |
| CDK_CONTEXT_ANALYTICS_SSH_USERNAME: ${{ vars.CDK_ANALYTICS_SSH_USERNAME }} | |
| CDK_CONTEXT_ANTHROPIC_API_KEY_SECRET_ARN: ${{ vars.CDK_ANTHROPIC_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_API_CERTIFICATE_ARN: ${{ vars.CDK_API_CERTIFICATE_ARN }} | |
| CDK_CONTEXT_APEX_REDIRECT_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_APEX_REDIRECT_CERTIFICATE_ARN_US_EAST_1 }} | |
| CDK_CONTEXT_AUTH_CERTIFICATE_ARN: ${{ vars.CDK_AUTH_CERTIFICATE_ARN }} | |
| CDK_CONTEXT_ADMIN_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_ADMIN_CERTIFICATE_ARN_US_EAST_1 }} | |
| CDK_CONTEXT_ADMIN_EMAILS: ${{ vars.CDK_ADMIN_EMAILS }} | |
| CDK_CONTEXT_DEMO_EMAIL_DOSTIP: ${{ vars.CDK_DEMO_EMAIL_DOSTIP }} | |
| CDK_CONTEXT_DEMO_PASSWORD_SECRET_ARN: ${{ vars.CDK_DEMO_PASSWORD_SECRET_ARN }} | |
| CDK_CONTEXT_DOMAIN_NAME: ${{ vars.CDK_DOMAIN_NAME }} | |
| CDK_CONTEXT_GITHUB_REPO: ${{ vars.CDK_GITHUB_REPO }} | |
| CDK_CONTEXT_GLOBAL_METRICS_VISIBLE: ${{ vars.CDK_GLOBAL_METRICS_VISIBLE }} | |
| CDK_CONTEXT_GUEST_AI_WEIGHTED_MONTHLY_TOKEN_CAP: ${{ vars.CDK_GUEST_AI_WEIGHTED_MONTHLY_TOKEN_CAP }} | |
| CDK_CONTEXT_LANGFUSE_BASE_URL: ${{ vars.CDK_LANGFUSE_BASE_URL }} | |
| CDK_CONTEXT_LANGFUSE_PUBLIC_KEY_SECRET_ARN: ${{ vars.CDK_LANGFUSE_PUBLIC_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_LANGFUSE_SECRET_KEY_SECRET_ARN: ${{ vars.CDK_LANGFUSE_SECRET_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_OPENAI_API_KEY_SECRET_ARN: ${{ vars.CDK_OPENAI_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_REGION: ${{ vars.AWS_REGION }} | |
| CDK_CONTEXT_RESEND_API_KEY_SECRET_ARN: ${{ vars.CDK_RESEND_API_KEY_SECRET_ARN }} | |
| CDK_CONTEXT_RESEND_SENDER_EMAIL: ${{ vars.CDK_RESEND_SENDER_EMAIL }} | |
| CDK_CONTEXT_WEB_CERTIFICATE_ARN_US_EAST_1: ${{ vars.CDK_WEB_CERTIFICATE_ARN_US_EAST_1 }} | |
| run: | | |
| python3 ../../scripts/write-ci-cdk-context.py \ | |
| --output cdk.context.local.json \ | |
| --aws-deploy-role-arn "${AWS_DEPLOY_ROLE_ARN}" | |
| npx cdk deploy --all --require-approval never | |
| - name: Check demo Cognito users | |
| run: bash scripts/check-demo-cognito-users.sh --stack-name ${{ env.STACK_NAME }} --region ${{ env.AWS_REGION }} | |
| - name: Run database migrations | |
| run: bash scripts/migrate-aws.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Seed global metrics snapshot | |
| run: bash scripts/generate-global-metrics-snapshot.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Build web app | |
| run: npm run build --prefix apps/web | |
| - name: Build admin app | |
| run: npm run build --prefix apps/admin | |
| - name: Deploy web assets | |
| run: bash scripts/deploy-web.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Deploy admin assets | |
| run: bash scripts/deploy-admin.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Check API health | |
| run: bash scripts/check-api-health.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Check public custom domains | |
| run: bash scripts/check-public-endpoints.sh --stack-name ${{ env.STACK_NAME }} | |
| - name: Summarize deployed release | |
| run: | | |
| { | |
| echo "## AWS deploy" | |
| echo "" | |
| echo "- Deployed SHA: \`${GITHUB_SHA}\`" | |
| echo "- Web post-deploy smoke: pending next job" | |
| echo "- Agent API post-deploy smoke: pending next job" | |
| echo "" | |
| echo "Manual admin smoke remains required for \`https://admin.<domain>\`." | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| web_smoke: | |
| name: Web post-deploy smoke | |
| needs: | |
| - changes | |
| - aws_deploy | |
| if: ${{ needs.changes.outputs.aws_changed == 'true' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: apps/web/package-lock.json | |
| - name: Install web dependencies | |
| run: npm ci --prefix apps/web | |
| - name: Build web app for live smoke | |
| env: | |
| VITE_APP_BASE_URL: https://app.flashcards-open-source-app.com | |
| VITE_API_BASE_URL: https://api.flashcards-open-source-app.com/v1 | |
| VITE_AUTH_BASE_URL: https://auth.flashcards-open-source-app.com | |
| run: npm run build --prefix apps/web | |
| - name: Install Playwright Chromium | |
| working-directory: apps/web | |
| run: npx playwright install --with-deps chromium | |
| - name: Run live web smoke test | |
| id: live_smoke | |
| working-directory: apps/web | |
| env: | |
| FLASHCARDS_E2E_APP_BASE_URL: https://app.flashcards-open-source-app.com | |
| FLASHCARDS_E2E_AUTH_BASE_URL: https://auth.flashcards-open-source-app.com | |
| FLASHCARDS_LIVE_REVIEW_EMAIL: google-review@example.com | |
| run: | | |
| set -euo pipefail | |
| cert_dir="${RUNNER_TEMP}/web-live-e2e-cert" | |
| cert_path="${cert_dir}/app.flashcards-open-source-app.com.crt" | |
| key_path="${cert_dir}/app.flashcards-open-source-app.com.key" | |
| server_log_path="${RUNNER_TEMP}/web-live-e2e-server.log" | |
| mkdir -p "${cert_dir}" | |
| openssl req \ | |
| -x509 \ | |
| -newkey rsa:2048 \ | |
| -sha256 \ | |
| -nodes \ | |
| -days 1 \ | |
| -subj "/CN=app.flashcards-open-source-app.com" \ | |
| -addext "subjectAltName=DNS:app.flashcards-open-source-app.com" \ | |
| -keyout "${key_path}" \ | |
| -out "${cert_path}" | |
| printf '127.0.0.1 app.flashcards-open-source-app.com\n' | sudo tee -a /etc/hosts >/dev/null | |
| sudo env PATH="${PATH}" node scripts/serve-dist-https.mjs \ | |
| --host 0.0.0.0 \ | |
| --port 443 \ | |
| --dir dist \ | |
| --cert "${cert_path}" \ | |
| --key "${key_path}" >"${server_log_path}" 2>&1 & | |
| server_pid=$! | |
| cleanup() { | |
| sudo kill "${server_pid}" >/dev/null 2>&1 || true | |
| } | |
| trap cleanup EXIT | |
| for _ in $(seq 1 30); do | |
| if curl --silent --show-error --fail --insecure https://app.flashcards-open-source-app.com/ >/dev/null; then | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| curl --silent --show-error --fail --insecure https://app.flashcards-open-source-app.com/ >/dev/null | |
| npm run test:e2e | |
| - name: Upload Playwright report | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: web-playwright-report | |
| if-no-files-found: ignore | |
| path: apps/web/playwright-report | |
| - name: Upload Playwright test results | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: web-playwright-test-results | |
| if-no-files-found: ignore | |
| path: apps/web/test-results | |
| - name: Summarize smoke result | |
| if: always() | |
| run: | | |
| { | |
| echo "## Web post-deploy smoke" | |
| echo "" | |
| echo "- Deployed SHA: \`${GITHUB_SHA}\`" | |
| echo "- Result: \`${{ steps.live_smoke.outcome }}\`" | |
| echo "- Artifacts: \`web-playwright-report\`, \`web-playwright-test-results\`" | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| agent_api_smoke: | |
| name: Agent API post-deploy smoke | |
| needs: | |
| - changes | |
| - aws_deploy | |
| if: ${{ needs.changes.outputs.aws_changed == 'true' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Run agent API smoke test | |
| id: agent_smoke | |
| env: | |
| FLASHCARDS_AGENT_SMOKE_AUTH_BASE_URL: https://auth.flashcards-open-source-app.com | |
| FLASHCARDS_AGENT_SMOKE_API_BASE_URL: https://api.flashcards-open-source-app.com/v1 | |
| FLASHCARDS_AGENT_SMOKE_DEMO_EMAIL: google-review@example.com | |
| FLASHCARDS_AGENT_SMOKE_WORKSPACE_PREFIX: "E2E agent api " | |
| FLASHCARDS_AGENT_SMOKE_CONNECTION_LABEL_PREFIX: "E2E agent api " | |
| run: bash scripts/check-agent-api-smoke.sh | |
| - name: Summarize smoke result | |
| if: always() | |
| run: | | |
| { | |
| echo "## Agent API post-deploy smoke" | |
| echo "" | |
| echo "- Deployed SHA: \`${GITHUB_SHA}\`" | |
| echo "- Result: \`${{ steps.agent_smoke.outcome }}\`" | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| aws_release_status: | |
| name: Resolve AWS release outcome | |
| needs: | |
| - changes | |
| - pre_deploy_checks | |
| - aws_deploy | |
| - web_smoke | |
| - agent_api_smoke | |
| if: ${{ always() }} | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| aws_release_status: ${{ steps.resolve.outputs.aws_release_status }} | |
| steps: | |
| - name: Resolve AWS release status | |
| id: resolve | |
| run: | | |
| set -euo pipefail | |
| aws_release_status="no_aws_changes" | |
| if [[ "${{ needs.changes.outputs.aws_changed }}" == "true" ]]; then | |
| if [[ "${{ needs.pre_deploy_checks.result }}" != "success" ]]; then | |
| aws_release_status="pre_deploy_checks_failed" | |
| elif [[ "${{ needs.aws_deploy.result }}" != "success" ]]; then | |
| aws_release_status="deployment_failed" | |
| elif [[ "${{ needs.web_smoke.result }}" != "success" ]]; then | |
| aws_release_status="web_smoke_failed" | |
| elif [[ "${{ needs.agent_api_smoke.result }}" != "success" ]]; then | |
| aws_release_status="agent_api_smoke_failed" | |
| else | |
| aws_release_status="released" | |
| fi | |
| fi | |
| echo "aws_release_status=${aws_release_status}" >> "${GITHUB_OUTPUT}" | |
| - name: Summarize AWS release outcome | |
| run: | | |
| { | |
| echo "## AWS release outcome" | |
| echo "" | |
| echo "- AWS release status: \`${{ steps.resolve.outputs.aws_release_status }}\`" | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| release_summary: | |
| name: AWS/Web release summary | |
| if: ${{ always() }} | |
| needs: | |
| - changes | |
| - pre_deploy_checks | |
| - aws_deploy | |
| - web_smoke | |
| - agent_api_smoke | |
| - aws_release_status | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Summarize release outcome | |
| run: | | |
| { | |
| echo "## AWS/Web release summary" | |
| echo "" | |
| echo "- AWS changed: \`${{ needs.changes.outputs.aws_changed }}\`" | |
| echo "- Pre-deploy checks job: \`${{ needs.pre_deploy_checks.result }}\`" | |
| echo "- AWS release status: \`${{ needs.aws_release_status.outputs.aws_release_status }}\`" | |
| echo "- AWS deploy job: \`${{ needs.aws_deploy.result }}\`" | |
| echo "- Web smoke job: \`${{ needs.web_smoke.result }}\`" | |
| echo "- Agent API smoke job: \`${{ needs.agent_api_smoke.result }}\`" | |
| echo "- Run details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| - name: Fail workflow when AWS/Web release is not healthy | |
| run: | | |
| set -euo pipefail | |
| aws_release_status="${{ needs.aws_release_status.outputs.aws_release_status }}" | |
| if [[ "${aws_release_status}" != "no_aws_changes" ]] && [[ "${aws_release_status}" != "released" ]]; then | |
| echo "AWS release finished in non-healthy state: ${aws_release_status}" >&2 | |
| exit 1 | |
| fi |