fix: invite redirect after login and auto-share encryption keys with … #122
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
| # SimpleNotes CI/CD Pipeline | |
| # Tests via reusable workflows from ci-templates | |
| # Deploy is project-specific (terraform workspaces + config.js injection) | |
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main, staging] | |
| pull_request: | |
| branches: [main, staging] | |
| concurrency: | |
| group: deploy-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| # ============================================ | |
| # Tests (reusable workflows) | |
| # ============================================ | |
| test-backend: | |
| uses: voidreamer/ci-templates/.github/workflows/test-python.yml@main | |
| with: | |
| python-version: "3.11" | |
| lint: false | |
| test-command: "pytest tests/ -v --cov=app --cov-report=term-missing" | |
| test-env: | | |
| ENVIRONMENT=test | |
| AWS_REGION=ca-central-1 | |
| USERS_TABLE=test-users | |
| HOUSEHOLDS_TABLE=test-households | |
| LISTS_TABLE=test-lists | |
| INVITES_TABLE=test-invites | |
| SUPABASE_URL=https://test.supabase.co | |
| SUPABASE_JWT_SECRET=test-jwt-secret | |
| test-frontend: | |
| uses: voidreamer/ci-templates/.github/workflows/test-node.yml@main | |
| with: | |
| node-version: "20" | |
| test-command: "npm test -- --passWithNoTests || true" | |
| lint: false | |
| # ============================================ | |
| # Deploy to Staging | |
| # ============================================ | |
| deploy-staging: | |
| name: Deploy to Staging | |
| needs: [test-backend, test-frontend] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/staging' | |
| environment: staging | |
| env: | |
| AWS_REGION: ca-central-1 | |
| TF_VERSION: "1.6.0" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install backend deps | |
| working-directory: backend | |
| run: pip install -r requirements.txt -t . | |
| - name: Terraform init | |
| working-directory: terraform | |
| run: | | |
| terraform init | |
| terraform workspace select staging || terraform workspace new staging | |
| - name: Terraform plan | |
| working-directory: terraform | |
| env: | |
| TF_VAR_ses_email: ${{ secrets.SES_EMAIL }} | |
| TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} | |
| TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} | |
| TF_VAR_domain_name: "" | |
| TF_VAR_acm_certificate_arn: "" | |
| TF_VAR_environment: staging | |
| run: terraform plan -out=tfplan | |
| - name: Terraform apply | |
| working-directory: terraform | |
| env: | |
| TF_VAR_ses_email: ${{ secrets.SES_EMAIL }} | |
| TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} | |
| TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} | |
| TF_VAR_domain_name: "" | |
| TF_VAR_acm_certificate_arn: "" | |
| TF_VAR_environment: staging | |
| run: terraform apply -auto-approve tfplan | |
| - name: Get outputs | |
| id: tf | |
| working-directory: terraform | |
| run: | | |
| echo "bucket=$(terraform output -raw frontend_bucket)" >> $GITHUB_OUTPUT | |
| echo "url=$(terraform output -raw frontend_url)" >> $GITHUB_OUTPUT | |
| echo "cf_id=$(terraform output -raw cloudfront_distribution_id)" >> $GITHUB_OUTPUT | |
| echo "api=$(terraform output -raw api_gateway_url)" >> $GITHUB_OUTPUT | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Build frontend | |
| working-directory: frontend | |
| run: | | |
| npm ci | |
| npm run build | |
| - name: Inject runtime config | |
| run: | | |
| cat > frontend/dist/config.js << 'ENDOFCONFIG' | |
| window.APP_CONFIG = { | |
| API_URL: "${{ steps.tf.outputs.api }}", | |
| SUPABASE_URL: "${{ secrets.SUPABASE_URL }}", | |
| SUPABASE_ANON_KEY: "${{ secrets.SUPABASE_ANON_KEY }}" | |
| }; | |
| ENDOFCONFIG | |
| - name: Deploy to S3 | |
| run: | | |
| aws s3 sync frontend/dist s3://${{ steps.tf.outputs.bucket }} \ | |
| --delete --cache-control "max-age=31536000,public" \ | |
| --exclude "index.html" --exclude "config.js" | |
| aws s3 cp frontend/dist/index.html \ | |
| s3://${{ steps.tf.outputs.bucket }}/index.html \ | |
| --cache-control "no-cache,no-store,must-revalidate" | |
| aws s3 cp frontend/dist/config.js \ | |
| s3://${{ steps.tf.outputs.bucket }}/config.js \ | |
| --cache-control "no-cache,no-store,must-revalidate" | |
| - name: Invalidate CloudFront | |
| run: | | |
| aws cloudfront create-invalidation \ | |
| --distribution-id ${{ steps.tf.outputs.cf_id }} --paths "/*" | |
| # ============================================ | |
| # Deploy to Production | |
| # ============================================ | |
| deploy-production: | |
| name: Deploy to Production | |
| needs: [test-backend, test-frontend] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: production | |
| env: | |
| AWS_REGION: ca-central-1 | |
| TF_VERSION: "1.6.0" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install backend deps | |
| working-directory: backend | |
| run: pip install -r requirements.txt -t . | |
| - name: Terraform init | |
| working-directory: terraform | |
| run: | | |
| terraform init | |
| terraform workspace select prod || terraform workspace new prod | |
| - name: Terraform plan | |
| working-directory: terraform | |
| env: | |
| TF_VAR_ses_email: ${{ secrets.SES_EMAIL }} | |
| TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} | |
| TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} | |
| TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} | |
| TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} | |
| TF_VAR_environment: prod | |
| run: terraform plan -out=tfplan | |
| - name: Terraform apply | |
| working-directory: terraform | |
| env: | |
| TF_VAR_ses_email: ${{ secrets.SES_EMAIL }} | |
| TF_VAR_supabase_url: ${{ secrets.SUPABASE_URL }} | |
| TF_VAR_supabase_jwt_secret: ${{ secrets.SUPABASE_JWT_SECRET }} | |
| TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} | |
| TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERTIFICATE_ARN }} | |
| TF_VAR_environment: prod | |
| run: terraform apply -auto-approve tfplan | |
| - name: Get outputs | |
| id: tf | |
| working-directory: terraform | |
| run: | | |
| echo "bucket=$(terraform output -raw frontend_bucket)" >> $GITHUB_OUTPUT | |
| echo "url=$(terraform output -raw frontend_url)" >> $GITHUB_OUTPUT | |
| echo "cf_id=$(terraform output -raw cloudfront_distribution_id)" >> $GITHUB_OUTPUT | |
| echo "api=$(terraform output -raw api_gateway_url)" >> $GITHUB_OUTPUT | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Build frontend | |
| working-directory: frontend | |
| run: | | |
| npm ci | |
| npm run build | |
| - name: Inject runtime config | |
| run: | | |
| cat > frontend/dist/config.js << 'ENDOFCONFIG' | |
| window.APP_CONFIG = { | |
| API_URL: "${{ steps.tf.outputs.api }}", | |
| SUPABASE_URL: "${{ secrets.SUPABASE_URL }}", | |
| SUPABASE_ANON_KEY: "${{ secrets.SUPABASE_ANON_KEY }}" | |
| }; | |
| ENDOFCONFIG | |
| - name: Deploy to S3 | |
| run: | | |
| aws s3 sync frontend/dist s3://${{ steps.tf.outputs.bucket }} \ | |
| --delete --cache-control "max-age=31536000,public" \ | |
| --exclude "index.html" --exclude "config.js" | |
| aws s3 cp frontend/dist/index.html \ | |
| s3://${{ steps.tf.outputs.bucket }}/index.html \ | |
| --cache-control "no-cache,no-store,must-revalidate" | |
| aws s3 cp frontend/dist/config.js \ | |
| s3://${{ steps.tf.outputs.bucket }}/config.js \ | |
| --cache-control "no-cache,no-store,must-revalidate" | |
| - name: Invalidate CloudFront | |
| run: | | |
| aws cloudfront create-invalidation \ | |
| --distribution-id ${{ steps.tf.outputs.cf_id }} --paths "/*" |