diff --git a/.github/workflows/render-preview-deploy.yml b/.github/workflows/render-preview-deploy.yml new file mode 100644 index 0000000000..0d99e0be43 --- /dev/null +++ b/.github/workflows/render-preview-deploy.yml @@ -0,0 +1,1040 @@ +name: Render review deploy +on: + pull_request_target: + types: [labeled, unlabeled, closed, synchronize, opened] + issue_comment: + types: [created, edited, deleted] +env: + PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} + BRANCH_NAME: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref_name }} + +permissions: + pull-requests: write + issues: write + +jobs: + +# Community Edition CE + create-ce-review-app-old: + if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'create-ce-review-app-old' || github.event.label.name == 'review-app') }} + runs-on: ubuntu-latest + + steps: + - name: Get PR details for issue_comment events + if: github.event_name == 'issue_comment' + uses: actions/github-script@v6 + with: + script: | + const pr = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + core.exportVariable('PR_NUMBER', pr.data.number); + core.exportVariable('BRANCH_NAME', pr.data.head.ref); + console.log(`✅ PR Number: ${pr.data.number}`); + console.log(`✅ Branch Name: ${pr.data.head.ref}`); + + - name: Sync repo + uses: actions/checkout@v3 + + - name: Check if Forked Repository + id: check_repo + run: | + if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then + echo "is_fork=true" >> $GITHUB_ENV + echo "FORKED_OWNER=${{ github.event.pull_request.head.repo.owner.login }}" >> $GITHUB_ENV + else + echo "is_fork=false" >> $GITHUB_ENV + fi + + - name: Set Repository URL + run: | + if [[ "$is_fork" == "true" ]]; then + echo "REPO_URL=https://github.com/${FORKED_OWNER}/ToolJet" >> $GITHUB_ENV + else + echo "REPO_URL=https://github.com/ToolJet/ToolJet" >> $GITHUB_ENV + fi + + - name: Fetch and Checkout Forked Branch + if: env.is_fork == 'true' + run: | + git fetch origin pull/${{ github.event.number }}/head:${{ env.BRANCH_NAME }} + git checkout ${{ env.BRANCH_NAME }} + + - name: Checkout Default Branch + if: env.is_fork == 'false' + uses: actions/checkout@v3 + + - name: Creating deployment for CE + id: create-ce-deployment + run: | + export RESPONSE=$(curl --request POST \ + --url https://api.render.com/v1/services \ + --header 'accept: application/json' \ + --header 'content-type: application/json' \ + --header 'Authorization: Bearer ${{ secrets.RENDER_API_KEY }}' \ + --data ' + { + "autoDeploy": "yes", + "branch": "${{ env.BRANCH_NAME }}", + "name": "ToolJet CE PR #${{ env.PR_NUMBER }}", + "notifyOnFail": "default", + "ownerId": "tea-caeo4bj19n072h3dddc0", + "repo": "'"$REPO_URL"'", + "slug": "tooljet-ce-pr-${{ env.PR_NUMBER }}", + "suspended": "not_suspended", + "suspenders": [], + "type": "web_service", + "envVars": [ + { + "key": "PG_HOST", + "value": "localhost" + }, + { + "key": "PG_PORT", + "value": "5432" + }, + { + "key": "PG_USER", + "value": "postgres" + }, + { + "key": "PG_PASS", + "value": "postgres" + }, + { + "key": "PG_DB", + "value": "${{ env.PR_NUMBER }}-ce" + }, + { + "key": "TOOLJET_DB", + "value": "${{ env.PR_NUMBER }}-ce-tjdb" + }, + { + "key": "TOOLJET_DB_HOST", + "value": "localhost" + }, + { + "key": "TOOLJET_DB_USER", + "value": "postgres" + }, + { + "key": "TOOLJET_DB_PASS", + "value": "postgres" + }, + { + "key": "TOOLJET_DB_PORT", + "value": "5432" + }, + { + "key": "PGRST_DB_PRE_CONFIG", + "value": "postgrest.pre_config" + }, + { + "key": "PGRST_DB_URI", + "value": "postgres://postgres:postgres@localhost/${{ env.PR_NUMBER }}-ce-tjdb" + }, + { + "key": "PGRST_HOST", + "value": "127.0.0.1:3000" + }, + { + "key": "PGRST_JWT_SECRET", + "value": "r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" + }, + { + "key": "PGRST_LOG_LEVEL", + "value": "info" + }, + { + "key": "PORT", + "value": "80" + }, + { + "key": "TOOLJET_HOST", + "value": "https://tooljet-ce-pr-${{ env.PR_NUMBER }}.onrender.com" + }, + { + "key": "DISABLE_TOOLJET_TELEMETRY", + "value": "true" + }, + { + "key": "SMTP_ADDRESS", + "value": "smtp.mailtrap.io" + }, + { + "key": "SMTP_DOMAIN", + "value": "smtp.mailtrap.io" + }, + { + "key": "SMTP_PORT", + "value": "2525" + }, + { + "key": "SMTP_USERNAME", + "value": "${{ secrets.RENDER_SMTP_USERNAME }}" + }, + { + "key": "SMTP_PASSWORD", + "value": "${{ secrets.RENDER_SMTP_PASSWORD }}" + }, + { + "key": "TOOLJET_MARKETPLACE_URL", + "value": "${{ secrets.MARKETPLACE_BUCKET }}" + } + ], + "serviceDetails": { + "disk": { + "name": "tooljet-ce-pr-${{ env.PR_NUMBER }}-postgresql", + "mountPath": "/var/lib/postgresql/13/main", + "sizeGB": 10 + }, + "env": "docker", + "envSpecificDetails": { + "dockerCommand": "", + "dockerContext": "./", + "dockerfilePath": "./docker/ce-preview.Dockerfile" + }, + "healthCheckPath": "/api/health", + "numInstances": 1, + "openPorts": [{ + "port": 80, + "protocol": "TCP" + }], + "plan": "standard", + "pullRequestPreviewsEnabled": "no", + "region": "oregon", + "url": "https://tooljet-ce-pr-${{ env.PR_NUMBER }}.onrender.com" + } + }') + + echo "response: $RESPONSE" + export SERVICE_ID=$(echo $RESPONSE | jq -r '.service.id') + echo "SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + + - name: Comment deployment URL + uses: actions/github-script@v5 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Community Edition:- \n Deployment: https://tooljet-ce-pr-${{ env.PR_NUMBER }}.onrender.com \n Dashboard: https://dashboard.render.com/web/${{ env.SERVICE_ID }}' + }) + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'create-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['active-ce-review-app-old'] + }) + + destroy-ce-review-app-old: + if: ${{ (github.event.action == 'labeled' && github.event.label.name == 'destroy-ce-review-app-old') || github.event.action == 'closed' }} + runs-on: ubuntu-latest + + steps: + - name: Delete service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request DELETE \ + --url https://api.render.com/v1/services/$SERVICE_ID \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'destroy-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'suspend-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'active-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + + suspend-ce-review-app-old: + if: ${{ github.event.action == 'labeled' && github.event.label.name == 'suspend-ce-review-app-old' }} + runs-on: ubuntu-latest + + steps: + - name: Suspend service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request POST \ + --url https://api.render.com/v1/services/$SERVICE_ID/suspend \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'active-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + resume-ce-review-app-old: + if: ${{ github.event.action == 'unlabeled' && github.event.label.name == 'suspend-ce-review-app-old' }} + runs-on: ubuntu-latest + + steps: + - name: Resume service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request POST \ + --url https://api.render.com/v1/services/$SERVICE_ID/resume \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['active-ce-review-app-old'] + }) + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'suspend-ce-review-app-old' + }) + } catch (e) { + console.log(e) + } + + + +# Enterprise Edition + + create-ee-review-app-old: + if: | + (github.event.action == 'labeled' && (github.event.label.name == 'create-ee-review-app-old' || github.event.label.name == 'create-ee-lts-review-app-old' || github.event.label.name == 'review-app-old')) || + (github.event.action == 'created' && (contains(github.event.comment.body, '/deploy-ee') || contains(github.event.comment.body, '/deploy-ee-lts'))) + runs-on: ubuntu-latest + + steps: + - name: Get PR details for issue_comment events + if: github.event_name == 'issue_comment' + uses: actions/github-script@v6 + with: + script: | + const pr = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + core.exportVariable('PR_NUMBER', pr.data.number); + core.exportVariable('BRANCH_NAME', pr.data.head.ref); + console.log(`✅ PR Number: ${pr.data.number}`); + console.log(`✅ Branch Name: ${pr.data.head.ref}`); + + - name: Sync repo + uses: actions/checkout@v3 + + - name: Check if Forked Repository + id: check_repo + run: | + if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then + echo "is_fork=true" >> $GITHUB_ENV + echo "FORKED_OWNER=${{ github.event.pull_request.head.repo.owner.login }}" >> $GITHUB_ENV + else + echo "is_fork=false" >> $GITHUB_ENV + fi + + - name: Set Repository URL + run: | + if [[ "$is_fork" == "true" ]]; then + echo "REPO_URL=https://github.com/${FORKED_OWNER}/ToolJet" >> $GITHUB_ENV + else + echo "REPO_URL=https://github.com/ToolJet/ToolJet" >> $GITHUB_ENV + fi + + - name: Fetch and Checkout Forked Branch + if: env.is_fork == 'true' + run: | + git fetch origin pull/${{ github.event.number }}/head:${{ env.BRANCH_NAME }} + git checkout ${{ env.BRANCH_NAME }} + + - name: Checkout Default Branch + if: env.is_fork == 'false' + uses: actions/checkout@v3 + + - name: Determine Dockerfile path + run: | + # Check if LTS deployment is requested via comment or label + if [[ "${{ github.event.action }}" == "labeled" && "${{ github.event.label.name }}" == "create-ee-lts-review-app-old" ]]; then + DOCKERFILE="./docker/LTS/ee/ee-preview.Dockerfile" + EDITION_TYPE="LTS" + echo "Using LTS EE Dockerfile (triggered by label)" + elif [[ "${{ github.event.action }}" == "created" && "${{ github.event.comment.body }}" == *"/deploy-ee-lts"* ]]; then + DOCKERFILE="./docker/LTS/ee/ee-preview.Dockerfile" + EDITION_TYPE="LTS" + echo "Using LTS EE Dockerfile (triggered by comment)" + else + DOCKERFILE="./docker/pre-release/ee/ee-preview.Dockerfile" + EDITION_TYPE="pre-release" + echo "Using pre-release EE Dockerfile" + fi + echo "Edition Type: $EDITION_TYPE" + echo "Selected Dockerfile: $DOCKERFILE" + echo "DOCKERFILE=$DOCKERFILE" >> $GITHUB_ENV + echo "EDITION_TYPE=$EDITION_TYPE" >> $GITHUB_ENV + + - name: Creating deployment for Enterprise Edition + id: create-ee-deployment + run: | + export RESPONSE=$(curl --request POST \ + --url https://api.render.com/v1/services \ + --header 'accept: application/json' \ + --header 'content-type: application/json' \ + --header 'Authorization: Bearer ${{ secrets.RENDER_API_KEY }}' \ + --data ' + { + "autoDeploy": "yes", + "branch": "${{ env.BRANCH_NAME }}", + "name": "ToolJet EE PR #${{ env.PR_NUMBER }}", + "notifyOnFail": "default", + "ownerId": "tea-caeo4bj19n072h3dddc0", + "repo": "'"$REPO_URL"'", + "slug": "tooljet-ee-pr-${{ env.PR_NUMBER }}", + "suspended": "not_suspended", + "suspenders": [], + "type": "web_service", + "envVars": [ + { + "key": "PG_HOST", + "value": "localhost" + }, + { + "key": "PG_PORT", + "value": "5432" + }, + { + "key": "PG_USER", + "value": "postgres" + }, + { + "key": "PG_PASS", + "value": "postgres" + }, + { + "key": "PG_DB", + "value": "${{ env.PR_NUMBER }}-ee" + }, + { + "key": "TOOLJET_DB", + "value": "${{ env.PR_NUMBER }}-ee-tjdb" + }, + { + "key": "TOOLJET_DB_HOST", + "value": "localhost" + }, + { + "key": "TOOLJET_DB_USER", + "value": "postgres" + }, + { + "key": "TOOLJET_DB_PASS", + "value": "postgres" + }, + { + "key": "TOOLJET_DB_PORT", + "value": "5432" + }, + { + "key": "PGRST_DB_PRE_CONFIG", + "value": "postgrest.pre_config" + }, + { + "key": "PGRST_DB_URI", + "value": "postgres://postgres:postgres@localhost/${{ env.PR_NUMBER }}-ee-tjdb" + }, + { + "key": "PGRST_HOST", + "value": "127.0.0.1:3000" + }, + { + "key": "PGRST_JWT_SECRET", + "value": "r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" + }, + { + "key": "PGRST_LOG_LEVEL", + "value": "info" + }, + { + "key": "PORT", + "value": "80" + }, + { + "key": "TOOLJET_HOST", + "value": "https://tooljet-ee-pr-${{ env.PR_NUMBER }}.onrender.com" + }, + { + "key": "DISABLE_TOOLJET_TELEMETRY", + "value": "true" + }, + { + "key": "SMTP_ADDRESS", + "value": "smtp.mailtrap.io" + }, + { + "key": "SMTP_DOMAIN", + "value": "smtp.mailtrap.io" + }, + { + "key": "SMTP_PORT", + "value": "2525" + }, + { + "key": "SMTP_USERNAME", + "value": "${{ secrets.RENDER_SMTP_USERNAME }}" + }, + { + "key": "SMTP_PASSWORD", + "value": "${{ secrets.RENDER_SMTP_PASSWORD }}" + }, + { + "key": "REDIS_HOST", + "value": "localhost" + }, + { + "key": "REDIS_PORT", + "value": "6379" + }, + { + "key": "REDIS_DB", + "value": "0" + }, + { + "key": "REDIS_TLS_ENABLED", + "value": "false" + }, + { + "key": "REDIS_PASSWORD", + "value": "" + }, + { + "key": "WORKER", + "value": "true" + }, + { + "key": "TOOLJET_MARKETPLACE_URL", + "value": "${{ secrets.MARKETPLACE_BUCKET }}" + }, + { + "key": "BRANCH_NAME", + "value": "${{ env.BRANCH_NAME }}" + }, + { + "key": "CUSTOM_GITHUB_TOKEN", + "value": "${{ secrets.CUSTOM_GITHUB_TOKEN }}" + }, + { + "key": "TOOLJET_WORKFLOW_SANDBOX_BYPASS", + "value": "true" + } + ], + "serviceDetails": { + "disk": { + "name": "tooljet-ee-pr-${{ env.PR_NUMBER }}-postgresql", + "mountPath": "/var/lib/postgresql/13/main", + "sizeGB": 10 + }, + "env": "docker", + "envSpecificDetails": { + "dockerCommand": "", + "dockerContext": "./", + "dockerfilePath": "'"$DOCKERFILE"'" + }, + "healthCheckPath": "/api/health", + "numInstances": 1, + "openPorts": [{ + "port": 80, + "protocol": "TCP" + }], + "plan": "pro", + "pullRequestPreviewsEnabled": "no", + "region": "oregon", + "url": "https://tooljet-ee-pr-${{ env.PR_NUMBER }}.onrender.com" + } + }') + + echo "response: $RESPONSE" + export SERVICE_ID=$(echo $RESPONSE | jq -r '.service.id') + echo "SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + + - name: Comment deployment URL + uses: actions/github-script@v5 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const editionType = '${{ env.EDITION_TYPE }}' === 'LTS' ? '(LTS)' : ''; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `Enterprise Edition ${editionType}: \n Deployment: https://tooljet-ee-pr-${{ env.PR_NUMBER }}.onrender.com \n Dashboard: https://dashboard.render.com/web/${{ env.SERVICE_ID }}` + }) + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'create-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'create-ee-lts-review-app-old' + }) + } catch (e) { + console.log(e) + } + + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['active-ee-review-app-old'] + }) + + destroy-ee-review-app-old: + if: ${{ (github.event.action == 'labeled' && github.event.label.name == 'destroy-ee-review-app-old') || github.event.action == 'closed' }} + runs-on: ubuntu-latest + + steps: + - name: Delete service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request DELETE \ + --url https://api.render.com/v1/services/$SERVICE_ID \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'destroy-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'suspend-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'active-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + + + suspend-ee-review-app-old: + if: ${{ github.event.action == 'labeled' && github.event.label.name == 'suspend-ee-review-app-old' }} + runs-on: ubuntu-latest + + steps: + - name: Suspend service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request POST \ + --url https://api.render.com/v1/services/$SERVICE_ID/suspend \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'active-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + resume-ee-review-app-old: + if: ${{ github.event.action == 'unlabeled' && github.event.label.name == 'suspend-ee-review-app-old' }} + runs-on: ubuntu-latest + + steps: + - name: Resume service + run: | + export SERVICE_ID=$(curl --request GET \ + --url 'https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${{ env.PR_NUMBER }}&limit=1' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' | \ + jq -r '.[0].service.id') + + curl --request POST \ + --url https://api.render.com/v1/services/$SERVICE_ID/resume \ + --header 'accept: application/json' \ + --header 'authorization: Bearer ${{ secrets.RENDER_API_KEY }}' + + - uses: actions/github-script@v6 + with: + script: | + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['active-ee-review-app-old'] + }) + + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'suspend-ee-review-app-old' + }) + } catch (e) { + console.log(e) + } + + + + redeploy-review-app: + if: ${{ github.event.action == 'synchronize' || github.event.action == 'opened' }} + runs-on: ubuntu-latest + steps: + - name: Get PR labels + id: get_labels + uses: actions/github-script@v6 + with: + script: | + const labels = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + return labels.data.map(l => l.name); + + - name: Redeploy CE review app if active + if: contains(steps.get_labels.outputs.result, 'active-ce-review-app-old') + id: redeploy_ce + env: + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + PR_NUMBER: ${{ github.event.number }} + run: | + SERVICE_ID=$(curl --request GET \ + --url "https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${PR_NUMBER}&limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY" | jq -r '.[0].service.id') + DEPLOY_RESPONSE=$(curl --request POST \ + --url "https://api.render.com/v1/services/$SERVICE_ID/deploys" \ + --header 'accept: application/json' \ + --header 'content-type: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY" \ + --data '{"clearCache":"clear"}') + DEPLOY_ID=$(echo $DEPLOY_RESPONSE | jq -r '.id') + echo "SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + echo "DEPLOY_ID=$DEPLOY_ID" >> $GITHUB_ENV + + + - name: Redeploy EE review app if active + if: contains(steps.get_labels.outputs.result, 'active-ee-review-app-old') + id: redeploy_ee + env: + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + PR_NUMBER: ${{ github.event.number }} + run: | + SERVICE_ID=$(curl --request GET \ + --url "https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${PR_NUMBER}&limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY" | jq -r '.[0].service.id') + DEPLOY_RESPONSE=$(curl --request POST \ + --url "https://api.render.com/v1/services/$SERVICE_ID/deploys" \ + --header 'accept: application/json' \ + --header 'content-type: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY" \ + --data '{"clearCache":"clear"}') + DEPLOY_ID=$(echo $DEPLOY_RESPONSE | jq -r '.id') + echo "SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + echo "DEPLOY_ID=$DEPLOY_ID" >> $GITHUB_ENV + + + render-bot-check-deployment: + runs-on: ubuntu-latest + if: github.event.action == 'labeled' && github.event.label.name == 'render-check-deployment' + steps: + - name: Get PR labels + id: get_labels + uses: actions/github-script@v6 + with: + script: | + const labels = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + return labels.data.map(l => l.name); + + - name: Fetch CE service and deploy ID + run: | + response=$(curl --silent --request GET \ + --url "https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${PR_NUMBER}&limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY") + + SERVICE_ID=$(echo "$response" | jq -r 'if type=="array" and length > 0 then .[0].service.id else empty end') + + if [[ -z "$SERVICE_ID" ]]; then + echo "No CE service found for PR #$PR_NUMBER. Skipping deployment ID fetch." + exit 0 + fi + + response_deploy=$(curl --silent --request GET \ + --url "https://api.render.com/v1/services/$SERVICE_ID/deploys?limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY") + + DEPLOY_ID=$(echo "$response_deploy" | jq -r 'if type=="array" and length > 0 then .[0].deploy.id else empty end') + + echo "CE_SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + echo "CE_DEPLOY_ID=$DEPLOY_ID" >> $GITHUB_ENV + env: + PR_NUMBER: ${{ env.PR_NUMBER }} + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + + - name: Comment CE deployment details + uses: actions/github-script@v6 + env: + PR_NUMBER: ${{ env.PR_NUMBER }} + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = process.env.PR_NUMBER; + const apiKey = process.env.RENDER_API_KEY; + + const ceServiceRes = await fetch(`https://api.render.com/v1/services?name=ToolJet%20CE%20PR%20%23${prNumber}&limit=1`, { + headers: { + 'accept': 'application/json', + 'authorization': `Bearer ${apiKey}` + } + }); + const ceServices = await ceServiceRes.json(); + const ceServiceId = ceServices[0]?.service?.id || null; + + let ceInfo = 'No active CE review app deployment found.'; + if (ceServiceId) { + const deployRes = await fetch(`https://api.render.com/v1/services/${ceServiceId}/deploys?limit=1`, { + headers: { + 'accept': 'application/json', + 'authorization': `Bearer ${apiKey}` + } + }); + const deployData = await deployRes.json(); + const deploy = deployData[0]?.deploy || {}; + const ceCommit = deploy.commit || {}; + const status = deploy.status || 'unknown'; + ceInfo = `### Community Edition\n- App: https://tooljet-ce-pr-${prNumber}.onrender.com\n- Dashboard: https://dashboard.render.com/web/${ceServiceId}\n- Commit: ${ceCommit.id || ''}\n- Message: ${ceCommit.message || ''}\n- Status: ${status}`; + } + + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: ceInfo + }); + + - name: Fetch EE service and deploy ID + run: | + response=$(curl --silent --request GET \ + --url "https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${PR_NUMBER}&limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY") + + SERVICE_ID=$(echo "$response" | jq -r 'if type=="array" and length > 0 then .[0].service.id else empty end') + + if [[ -z "$SERVICE_ID" ]]; then + echo "No EE service found for PR #$PR_NUMBER. Skipping deployment ID fetch." + exit 0 + fi + + response_deploy=$(curl --silent --request GET \ + --url "https://api.render.com/v1/services/$SERVICE_ID/deploys?limit=1" \ + --header 'accept: application/json' \ + --header "authorization: Bearer $RENDER_API_KEY") + + DEPLOY_ID=$(echo "$response_deploy" | jq -r 'if type=="array" and length > 0 then .[0].deploy.id else empty end') + + echo "EE_SERVICE_ID=$SERVICE_ID" >> $GITHUB_ENV + echo "EE_DEPLOY_ID=$DEPLOY_ID" >> $GITHUB_ENV + env: + PR_NUMBER: ${{ env.PR_NUMBER }} + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + + - name: Comment EE deployment details + uses: actions/github-script@v6 + env: + PR_NUMBER: ${{ env.PR_NUMBER }} + RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = process.env.PR_NUMBER; + const apiKey = process.env.RENDER_API_KEY; + + const eeServiceRes = await fetch(`https://api.render.com/v1/services?name=ToolJet%20EE%20PR%20%23${prNumber}&limit=1`, { + headers: { + 'accept': 'application/json', + 'authorization': `Bearer ${apiKey}` + } + }); + const eeServices = await eeServiceRes.json(); + const eeServiceId = eeServices[0]?.service?.id || null; + + let eeInfo = 'No active EE review app deployment found.'; + if (eeServiceId) { + const deployRes = await fetch(`https://api.render.com/v1/services/${eeServiceId}/deploys?limit=1`, { + headers: { + 'accept': 'application/json', + 'authorization': `Bearer ${apiKey}` + } + }); + const deployData = await deployRes.json(); + const deploy = deployData[0]?.deploy || {}; + const eeCommit = deploy.commit || {}; + const status = deploy.status || 'unknown'; + eeInfo = `### Enterprise Edition\n- App: https://tooljet-ee-pr-${prNumber}.onrender.com\n- Dashboard: https://dashboard.render.com/web/${eeServiceId}\n- Commit: ${eeCommit.id || ''}\n- Message: ${eeCommit.message || ''}\n- Status: ${status}`; + } + + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: eeInfo + }); + + - name: Remove label + if: contains(steps.get_labels.outputs.result, 'render-check-deployment') + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + try { + await github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'render-check-deployment' + }) + } catch (e) { + console.log(e) + } + \ No newline at end of file