diff --git a/.github/scripts/generate_db_name.sh b/.github/scripts/generate_db_name.sh deleted file mode 100644 index 7125962..0000000 --- a/.github/scripts/generate_db_name.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# Get the branch name from the first argument -RAW_BRANCH=$1 - -# 1. Lowercase -# 2. Replace any non-alphanumeric with - -# 3. Trim leading/trailing - -# 4. Collapse multiple -- to single - -SAFE_NAME=$(echo "$RAW_BRANCH" \ - | tr '[:upper:]' '[:lower:]' \ - | sed 's/[^a-z0-9]/-/g' \ - | sed 's/--*/-/g' \ - | sed 's/^-//;s/-$//') - -# Ensure it starts with a letter (Turso requirement) -if [[ -z "$SAFE_NAME" || "$SAFE_NAME" =~ ^[0-9] ]]; then - SAFE_NAME="br-$SAFE_NAME" -fi - -# Output the result for GitHub Actions -echo "$SAFE_NAME" diff --git a/.github/workflows/database_cleanup.yml b/.github/workflows/database_cleanup.yml index ef31a71..f7a9e26 100644 --- a/.github/workflows/database_cleanup.yml +++ b/.github/workflows/database_cleanup.yml @@ -1,42 +1,37 @@ name: Cleanup Database Branch on: - delete: - branches-ignore: - - main - - dev + pull_request: + types: + - closed workflow_dispatch: + inputs: + pr_number: + description: "Pull Request Number" + required: false + type: number jobs: cleanup_database: - if: ${{ github.event.ref_type == 'branch' }} runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - # Checkout the main branch to retrieve the scripts - ref: main - - name: Install Turso CLI run: | curl -sSfL https://get.tur.so/install.sh | bash echo "$HOME/.turso" >> $GITHUB_PATH - - name: Generate Safe DB Name + - name: Get DB Name run: | - # Make the script executable, might not be necessary - chmod +x .github/scripts/generate_db_name.sh - - # Get the deleted branch name - RAW_REF="${{ github.event.ref }}" - CLEAN_REF="${RAW_REF#refs/heads/}" - - # Generate the safe branch name and store it in an environment variable - BRANCH_NAME=$(.github/scripts/generate_db_name.sh "$CLEAN_REF") - echo "SAFE_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + PR_NUM="${{ github.event.inputs.pr_number || github.event.pull_request.number }}" + if [ -z "$PR_NUM" ]; then + echo "No PR number provided" + exit 1 + fi + DB_NAME="pr-$PR_NUM" + echo "DB_NAME=$DB_NAME" >> $GITHUB_ENV - name: Destroy Turso Database env: TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }} + DB_NAME: ${{ env.DB_NAME }} run: | - turso db destroy ${{env.SAFE_BRANCH_NAME}} --yes || echo "Database already gone" + turso db destroy "$DB_NAME" --yes || echo "Database already gone or never existed" diff --git a/.github/workflows/dev_deploy.yml b/.github/workflows/dev_deploy.yml new file mode 100644 index 0000000..9ebd46d --- /dev/null +++ b/.github/workflows/dev_deploy.yml @@ -0,0 +1,40 @@ +name: Make Development Deployment + +on: + push: + branches: + - dev + workflow_dispatch: + +concurrency: + group: deployment-dev + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - run: npm ci + + - name: Push schema changes to database + env: + TURSO_DATABASE_URL: ${{ secrets.DEV_DB_URL }} + TURSO_AUTH_TOKEN: ${{ secrets.DEV_DB_TOKEN }} + run: | + npx drizzle-kit push + + - name: Make Development Deployment + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + run: | + npx vercel deploy --target preview --yes --token ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/pr_preview.yml b/.github/workflows/pr_preview.yml new file mode 100644 index 0000000..ac6d38a --- /dev/null +++ b/.github/workflows/pr_preview.yml @@ -0,0 +1,136 @@ +name: Make Pull Request Preview Deployment +on: + pull_request: + types: + - opened + - reopened + - synchronize + workflow_dispatch: + inputs: + pr_number: + description: "Pull Request Number" + required: false + type: number + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + pull-requests: write + contents: read + +jobs: + deploy: + environment: Preview + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - run: npm ci + + - name: Install Turso CLI + run: | + curl -sSfL https://get.tur.so/install.sh | bash + echo "$HOME/.turso" >> $GITHUB_PATH + + - name: Generate DB Name + run: | + PR_NUM="${{ github.event.inputs.pr_number || github.event.pull_request.number }}" + if [ -z "$PR_NUM" ]; then + echo "Error: No PR number found. If running manually, please provide the PR number input." + exit 1 + fi + echo "PR_NUM=$PR_NUM" >> $GITHUB_ENV + echo "SAFE_BRANCH_NAME=pr-${PR_NUM}" >> $GITHUB_ENV + + - name: Provision Turso Database + env: + TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }} + run: | + # Create a branch from the dev database with the generated safe name + turso db create ${{ env.SAFE_BRANCH_NAME }} --from-db dev || true + + - name: Get Database Credentials + env: + TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }} + run: | + DB_URL=$(turso db show ${{ env.SAFE_BRANCH_NAME }} --url) + DB_TOKEN=$(turso db tokens create ${{ env.SAFE_BRANCH_NAME }}) + + # Mask database credentials + echo "::add-mask::$DB_URL" + echo "::add-mask::$DB_TOKEN" + + # Add the database credentials to the environment variables + echo "DB_URL=$DB_URL" >> $GITHUB_ENV + echo "DB_TOKEN=$DB_TOKEN" >> $GITHUB_ENV + + - name: Sync schema to database + env: + TURSO_DATABASE_URL: ${{ env.DB_URL }} + TURSO_AUTH_TOKEN: ${{ env.DB_TOKEN }} + run: | + # Push changes to the created database + npx drizzle-kit push + + - name: Make Preview Deployment + id: vercel-deployment + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + run: | + # Make a preview deployment with the created database + DEPLOYMENT_URL=$(npx vercel deploy --target preview --token ${{ secrets.VERCEL_TOKEN }} \ + --build-env TURSO_DATABASE_URL=${{ env.DB_URL }} \ + --build-env TURSO_AUTH_TOKEN=${{ env.DB_TOKEN }} \ + --env TURSO_DATABASE_URL=${{ env.DB_URL }} \ + --env TURSO_AUTH_TOKEN=${{ env.DB_TOKEN }} \ + --yes --logs) + + echo "DEPLOYMENT_URL=$DEPLOYMENT_URL" >> $GITHUB_ENV + + - name: Comment on PR + if: always() + uses: actions/github-script@v8 + env: + DEPLOYMENT_URL: ${{ env.DEPLOYMENT_URL }} + DEPLOY_STATUS: ${{ steps.vercel-deployment.outcome }} + RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + PR_NUM: ${{ env.PR_NUM }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const {DEPLOYMENT_URL, DEPLOY_STATUS, RUN_URL} = process.env; + const status = DEPLOY_STATUS === "success" ? "✅ Ready" : "❌ Failed to deploy"; + + const body = `### 🚀 Preview Deployment: + - **Vercel Deployment:** ${DEPLOYMENT_URL ? `[View Deployment](${DEPLOYMENT_URL})` : "N/A"} + - **Status:** ${status} + - **Workflow Logs:** [View Run](${RUN_URL})`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: Number(PR_NUM), + }); + + const existingComment = comments.find(comment => comment.body.includes('### 🚀 Preview Deployment')); + const payload = { + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }; + + if (existingComment) { + await github.rest.issues.updateComment({...payload, comment_id: existingComment.id}) + } else { + await github.rest.issues.createComment({...payload, issue_number: Number(PR_NUM)}) + } diff --git a/.github/workflows/preview_deploy.yml b/.github/workflows/preview_deploy.yml deleted file mode 100644 index de80d5c..0000000 --- a/.github/workflows/preview_deploy.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Preview Deployment -on: - push: - branches-ignore: - - main - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "npm" - - - run: npm ci - - - name: Install Turso CLI - run: | - curl -sSfL https://get.tur.so/install.sh | bash - echo "$HOME/.turso" >> $GITHUB_PATH - - - name: Generate Safe DB Name - run: | - # Make the script executable, might not be necessary - chmod +x .github/scripts/generate_db_name.sh - - # Generate the safe branch name and store it in an environment variable - BRANCH_NAME=$(.github/scripts/generate_db_name.sh "${{ github.ref_name }}") - echo "SAFE_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV - - - name: Provision Turso Database - if: github.ref_name != 'dev' - env: - TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }} - run: | - # Create a branch from the dev database with the generated safe name - turso db create ${{ env.SAFE_BRANCH_NAME }} --from-db dev || true - - - name: Get Database Credentials - env: - TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }} - run: | - DB_URL=$(turso db show ${{ env.SAFE_BRANCH_NAME }} --url) - DB_TOKEN=$(turso db tokens create ${{ env.SAFE_BRANCH_NAME }}) - - # Mask database credentials - echo "::add-mask::$DB_URL" - echo "::add-mask::$DB_TOKEN" - - # Add the database credentials to the environment variables - echo "DB_URL=$DB_URL" >> $GITHUB_ENV - echo "DB_TOKEN=$DB_TOKEN" >> $GITHUB_ENV - - - name: Sync schema to database - env: - TURSO_DATABASE_URL: ${{ env.DB_URL }} - TURSO_AUTH_TOKEN: ${{ env.DB_TOKEN }} - run: | - # Push changes to the created database - npx drizzle-kit push - - - name: Make Preview Deployment - env: - VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} - VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} - VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} - run: | - # Make a preview deployment with the created database - npx vercel deploy --target preview --token ${{ secrets.VERCEL_TOKEN }} \ - --build-env TURSO_DATABASE_URL=${{ env.DB_URL }} \ - --build-env TURSO_AUTH_TOKEN=${{ env.DB_TOKEN }} \ - --env TURSO_DATABASE_URL=${{ env.DB_URL }} \ - --env TURSO_AUTH_TOKEN=${{ env.DB_TOKEN }} \ - --yes