refactor: extract SessionWebSocketManager from SessionDO #136
Workflow file for this run
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: Terraform | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "terraform/**" | |
| - "scripts/**" | |
| - "packages/control-plane/**" | |
| - "packages/slack-bot/**" | |
| - "packages/modal-infra/**" | |
| - "packages/shared/**" | |
| - ".github/workflows/terraform.yml" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "terraform/**" | |
| - "scripts/**" | |
| - "packages/control-plane/**" | |
| - "packages/slack-bot/**" | |
| - "packages/modal-infra/**" | |
| - "packages/shared/**" | |
| - ".github/workflows/terraform.yml" | |
| workflow_dispatch: # Allow manual trigger | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| concurrency: | |
| group: terraform-${{ github.ref }} | |
| cancel-in-progress: false # Don't cancel terraform operations | |
| env: | |
| TF_VERSION: "1.9.0" | |
| TF_WORKING_DIR: terraform/environments/production | |
| jobs: | |
| check-secrets: | |
| name: Check Secrets | |
| runs-on: ubuntu-latest | |
| outputs: | |
| has-secrets: ${{ steps.check.outputs.has-secrets }} | |
| steps: | |
| - name: Check if secrets are configured | |
| id: check | |
| run: | | |
| if [ -n "${{ secrets.CLOUDFLARE_API_TOKEN }}" ] && [ -n "${{ secrets.R2_ACCESS_KEY_ID }}" ]; then | |
| echo "has-secrets=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has-secrets=false" >> $GITHUB_OUTPUT | |
| echo "::notice::Terraform plan/apply skipped - secrets not configured. See docs/GETTING_STARTED.md for setup instructions." | |
| fi | |
| validate: | |
| name: Validate | |
| runs-on: ubuntu-latest | |
| needs: [check-secrets] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Terraform Format Check | |
| id: fmt | |
| run: terraform fmt -check -recursive | |
| working-directory: terraform | |
| continue-on-error: true | |
| - name: Terraform Init | |
| id: init | |
| run: | | |
| terraform init -backend=false | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| - name: Terraform Validate | |
| id: validate | |
| run: terraform validate -no-color | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| - name: Post Validation Results | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const hasSecrets = '${{ needs.check-secrets.outputs.has-secrets }}' === 'true'; | |
| const planNote = hasSecrets | |
| ? '' | |
| : '\n\n> **Note:** Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) for setup instructions.'; | |
| const output = `### Terraform Validation Results | |
| | Step | Status | | |
| |------|--------| | |
| | Format | ${{ steps.fmt.outcome == 'success' && '✅' || '⚠️' }} | | |
| | Init | ${{ steps.init.outcome == 'success' && '✅' || '❌' }} | | |
| | Validate | ${{ steps.validate.outcome == 'success' && '✅' || '❌' }} | | |
| ${planNote} | |
| *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: output | |
| }); | |
| plan: | |
| name: Plan | |
| runs-on: ubuntu-latest | |
| needs: [validate, check-secrets] | |
| if: github.event_name == 'pull_request' && needs.check-secrets.outputs.has-secrets == 'true' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build worker packages | |
| run: | | |
| npm run build -w @open-inspect/shared | |
| npm run build -w @open-inspect/control-plane | |
| npm run build -w @open-inspect/slack-bot | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Terraform Init | |
| run: | | |
| terraform init \ | |
| -backend-config="access_key=${{ secrets.R2_ACCESS_KEY_ID }}" \ | |
| -backend-config="secret_key=${{ secrets.R2_SECRET_ACCESS_KEY }}" \ | |
| -backend-config='endpoints={s3="https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com"}' | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| - name: Terraform Plan | |
| id: plan | |
| run: | | |
| terraform plan -no-color -out=tfplan 2>&1 | tee plan_output.txt | |
| echo "plan<<EOF" >> $GITHUB_OUTPUT | |
| cat plan_output.txt | head -c 60000 >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| continue-on-error: true | |
| env: | |
| TF_VAR_cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| TF_VAR_cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| TF_VAR_cloudflare_worker_subdomain: ${{ secrets.CLOUDFLARE_WORKER_SUBDOMAIN }} | |
| TF_VAR_vercel_api_token: ${{ secrets.VERCEL_API_TOKEN }} | |
| TF_VAR_vercel_team_id: ${{ secrets.VERCEL_TEAM_ID }} | |
| TF_VAR_modal_token_id: ${{ secrets.MODAL_TOKEN_ID }} | |
| TF_VAR_modal_token_secret: ${{ secrets.MODAL_TOKEN_SECRET }} | |
| TF_VAR_modal_workspace: ${{ secrets.MODAL_WORKSPACE }} | |
| TF_VAR_github_client_id: ${{ secrets.GH_OAUTH_CLIENT_ID }} | |
| TF_VAR_github_client_secret: ${{ secrets.GH_OAUTH_CLIENT_SECRET }} | |
| TF_VAR_github_app_id: ${{ secrets.GH_APP_ID }} | |
| TF_VAR_github_app_private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| TF_VAR_github_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} | |
| TF_VAR_slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} | |
| TF_VAR_slack_signing_secret: ${{ secrets.SLACK_SIGNING_SECRET }} | |
| TF_VAR_anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| TF_VAR_token_encryption_key: ${{ secrets.TOKEN_ENCRYPTION_KEY }} | |
| TF_VAR_repo_secrets_encryption_key: ${{ secrets.REPO_SECRETS_ENCRYPTION_KEY }} | |
| TF_VAR_internal_callback_secret: ${{ secrets.INTERNAL_CALLBACK_SECRET }} | |
| TF_VAR_nextauth_secret: ${{ secrets.NEXTAUTH_SECRET }} | |
| TF_VAR_modal_api_secret: ${{ secrets.MODAL_API_SECRET }} | |
| TF_VAR_allowed_users: ${{ secrets.ALLOWED_USERS }} | |
| TF_VAR_allowed_email_domains: ${{ secrets.ALLOWED_EMAIL_DOMAINS }} | |
| TF_VAR_deployment_name: ${{ secrets.DEPLOYMENT_NAME }} | |
| - name: Post Plan Results | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const planOutcome = '${{ steps.plan.outcome }}'; | |
| const plan = `${{ steps.plan.outputs.plan }}`; | |
| const truncatedPlan = plan.length > 60000 | |
| ? plan.substring(0, 60000) + '\n... (truncated)' | |
| : plan; | |
| const output = `### Terraform Plan Results | |
| **Status:** ${planOutcome === 'success' ? '✅ Success' : '❌ Failed'} | |
| <details><summary>Show Plan</summary> | |
| \`\`\`terraform | |
| ${truncatedPlan} | |
| \`\`\` | |
| </details> | |
| *Pushed by: @${{ github.actor }}*`; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: output | |
| }); | |
| - name: Plan Status | |
| if: steps.plan.outcome == 'failure' | |
| run: exit 1 | |
| apply: | |
| name: Apply | |
| runs-on: ubuntu-latest | |
| needs: [validate, check-secrets] | |
| if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' && needs.check-secrets.outputs.has-secrets == 'true' | |
| environment: production | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build worker packages | |
| run: | | |
| npm run build -w @open-inspect/shared | |
| npm run build -w @open-inspect/control-plane | |
| npm run build -w @open-inspect/slack-bot | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install Modal CLI and dependencies | |
| run: pip install modal fastapi pydantic httpx PyJWT | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Terraform Init | |
| run: | | |
| terraform init \ | |
| -backend-config="access_key=${{ secrets.R2_ACCESS_KEY_ID }}" \ | |
| -backend-config="secret_key=${{ secrets.R2_SECRET_ACCESS_KEY }}" \ | |
| -backend-config='endpoints={s3="https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com"}' | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| - name: Terraform Apply | |
| run: terraform apply -auto-approve | |
| working-directory: ${{ env.TF_WORKING_DIR }} | |
| env: | |
| TF_VAR_cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| TF_VAR_cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| TF_VAR_cloudflare_worker_subdomain: ${{ secrets.CLOUDFLARE_WORKER_SUBDOMAIN }} | |
| TF_VAR_vercel_api_token: ${{ secrets.VERCEL_API_TOKEN }} | |
| TF_VAR_vercel_team_id: ${{ secrets.VERCEL_TEAM_ID }} | |
| TF_VAR_modal_token_id: ${{ secrets.MODAL_TOKEN_ID }} | |
| TF_VAR_modal_token_secret: ${{ secrets.MODAL_TOKEN_SECRET }} | |
| TF_VAR_modal_workspace: ${{ secrets.MODAL_WORKSPACE }} | |
| TF_VAR_github_client_id: ${{ secrets.GH_OAUTH_CLIENT_ID }} | |
| TF_VAR_github_client_secret: ${{ secrets.GH_OAUTH_CLIENT_SECRET }} | |
| TF_VAR_github_app_id: ${{ secrets.GH_APP_ID }} | |
| TF_VAR_github_app_private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| TF_VAR_github_app_installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }} | |
| TF_VAR_slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} | |
| TF_VAR_slack_signing_secret: ${{ secrets.SLACK_SIGNING_SECRET }} | |
| TF_VAR_anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| TF_VAR_token_encryption_key: ${{ secrets.TOKEN_ENCRYPTION_KEY }} | |
| TF_VAR_repo_secrets_encryption_key: ${{ secrets.REPO_SECRETS_ENCRYPTION_KEY }} | |
| TF_VAR_internal_callback_secret: ${{ secrets.INTERNAL_CALLBACK_SECRET }} | |
| TF_VAR_nextauth_secret: ${{ secrets.NEXTAUTH_SECRET }} | |
| TF_VAR_modal_api_secret: ${{ secrets.MODAL_API_SECRET }} | |
| TF_VAR_allowed_users: ${{ secrets.ALLOWED_USERS }} | |
| TF_VAR_allowed_email_domains: ${{ secrets.ALLOWED_EMAIL_DOMAINS }} | |
| TF_VAR_deployment_name: ${{ secrets.DEPLOYMENT_NAME }} | |
| MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }} | |
| MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }} | |
| - name: Post Apply Results | |
| if: always() | |
| run: | | |
| echo "### Terraform Apply Results" | |
| echo "Status: ${{ job.status }}" | |
| echo "Commit: ${{ github.sha }}" | |
| echo "Environment: production" | |
| echo "Applied by: ${{ github.actor }}" |