diff --git a/.github/workflows/cloud-frontend-gcp.yml b/.github/workflows/cloud-frontend-gcp.yml new file mode 100644 index 0000000000..12deb9c653 --- /dev/null +++ b/.github/workflows/cloud-frontend-gcp.yml @@ -0,0 +1,133 @@ +name: Deploy to cloud frontend stage + +on: + workflow_dispatch: + inputs: + branch: + description: 'Git branch to deploy (must start with "lts-", e.g., lts-3.6)' + required: true + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: ✅ Check user authorization + run: | + allowed_user1=${{ secrets.ALLOWED_USER1_USERNAME }} + allowed_user2=${{ secrets.ALLOWED_USER2_USERNAME }} + allowed_user3=${{ secrets.ALLOWED_USER3_USERNAME }} + + if [[ "${{ github.actor }}" != "$allowed_user1" && \ + "${{ github.actor }}" != "$allowed_user2" && \ + "${{ github.actor }}" != "$allowed_user3" ]]; then + echo "❌ User '${{ github.actor }}' is not authorized to trigger this workflow." + exit 1 + else + echo "✅ User '${{ github.actor }}' is authorized." + fi + + - name: 📥 Manual Git checkout with submodules + run: | + set -e + + BRANCH="${{ github.event.inputs.branch }}" + REPO="https://x-access-token:${{ secrets.CUSTOM_GITHUB_TOKEN }}@github.com/${{ github.repository }}" + + git config --global url."https://x-access-token:${{ secrets.CUSTOM_GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/" + git config --global http.version HTTP/1.1 + git config --global http.postBuffer 524288000 + + echo "👉 Cloning $REPO (branch: $BRANCH)" + git clone --recurse-submodules --depth=1 --branch "$BRANCH" "$REPO" repo + cd repo + + echo "🔁 Updating submodules" + git submodule update --init --recursive + + echo "🔀 Attempting to checkout '$BRANCH' in each submodule and validating" + + BRANCH="$BRANCH" git submodule foreach --recursive bash -c ' + name="$sm_path" + echo "" + echo "Entering '\''$name'\''" + echo "↪ $name: trying to checkout branch '\''$BRANCH'\''" + + if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null; then + git fetch origin "$BRANCH:$BRANCH" || { + echo "❌ $name: fetch failed for $BRANCH" + exit 1 + } + + PREV=$(git rev-parse --short HEAD || echo "unknown") + git checkout "$BRANCH" || { + echo "❌ $name: checkout failed for $BRANCH" + exit 1 + } + + echo "Previous HEAD position was $PREV: $(git log -1 --pretty=%s || echo 'unknown')" + echo "✅ $name: checked out branch $BRANCH" + else + echo "⚠️ $name: branch '$BRANCH' not found on origin. Falling back to 'main'" + PREV=$(git rev-parse --short HEAD || echo "unknown") + git checkout main && git pull origin main || { + echo "❌ $name: fallback to main failed" + exit 1 + } + echo "Previous HEAD position was $PREV: $(git log -1 --pretty=%s || echo 'unknown')" + echo "✅ $name: now on branch main" + fi + + CURRENT=$(git rev-parse --abbrev-ref HEAD) + echo "🔎 $name: current branch = $CURRENT" + if [ "$CURRENT" != "$BRANCH" ] && [ "$CURRENT" != "main" ]; then + echo "❌ $name: unexpected branch state — wanted '$BRANCH' or fallback 'main', got '$CURRENT'" + exit 1 + fi + ' + + - name: 🧰 Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: 22.15.1 + + - name: 📦 Install dependencies + run: npm install + working-directory: repo + + - name: 🛠️ Build the project + run: npm run build:plugins:prod && npm run build:frontend + working-directory: repo + env: + GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_GOOGLE_MAPS_API_KEY }} + NODE_ENV: ${{ secrets.CLOUD_NODE_ENV }} + NODE_OPTIONS: ${{ secrets.CLOUD_NODE_OPTIONS }} + SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.CLOUD_SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CLOUD_SENTRY_PROJECT }} + SERVE_CLIENT: ${{ secrets.CLOUD_SERVE_CLIENT }} + SERVER_IP: ${{ secrets.CLOUD_SERVER_IP }} + TJDB_SQL_MODE_DISABLE: ${{ secrets.CLOUD_TJDB_SQL_MODE_DISABLE }} + TOOLJET_SERVER_URL: ${{ secrets.CLOUD_TOOLJET_SERVER_URL }} + TOOLJET_EDITION: cloud + WEBSITE_SIGNUP_URL: https://website-stage.tooljet.ai/ai-create-account + + - name: 🚀 Deploy to Netlify + run: | + npm install -g netlify-cli + netlify deploy --prod --dir=frontend/build --auth=$NETLIFY_AUTH_TOKEN --site=${{ secrets.CLOUD_NETLIFY_SITE_ID }} + working-directory: repo + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_GOOGLE_MAPS_API_KEY }} + NODE_ENV: ${{ secrets.CLOUD_NODE_ENV }} + NODE_OPTIONS: ${{ secrets.CLOUD_NODE_OPTIONS }} + SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.CLOUD_SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CLOUD_SENTRY_PROJECT }} + SERVE_CLIENT: ${{ secrets.CLOUD_SERVE_CLIENT }} + SERVER_IP: ${{ secrets.CLOUD_SERVER_IP }} + TJDB_SQL_MODE_DISABLE: ${{ secrets.CLOUD_TJDB_SQL_MODE_DISABLE }} + TOOLJET_SERVER_URL: ${{ secrets.CLOUD_TOOLJET_SERVER_URL }} + WEBSITE_SIGNUP_URL: https://website-stage.tooljet.ai/ai-create-account + TOOLJET_EDITION: cloud diff --git a/.github/workflows/cloud-frontend.yml b/.github/workflows/cloud-frontend.yml index 71e100c52d..35d13aaa40 100644 --- a/.github/workflows/cloud-frontend.yml +++ b/.github/workflows/cloud-frontend.yml @@ -99,35 +99,35 @@ jobs: run: npm run build:plugins:prod && npm run build:frontend working-directory: repo env: - GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_GOOGLE_MAPS_API_KEY }} + GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_PROD_CLOUD_GOOGLE_MAPS_API_KEY }} NODE_ENV: ${{ secrets.CLOUD_NODE_ENV }} NODE_OPTIONS: ${{ secrets.CLOUD_NODE_OPTIONS }} - SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_SENTRY_AUTH_TOKEN }} - SENTRY_ORG: ${{ secrets.CLOUD_SENTRY_ORG }} - SENTRY_PROJECT: ${{ secrets.CLOUD_SENTRY_PROJECT }} - SERVE_CLIENT: ${{ secrets.CLOUD_SERVE_CLIENT }} - SERVER_IP: ${{ secrets.CLOUD_SERVER_IP }} + SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_PROJECT }} + SERVE_CLIENT: ${{ secrets.CLOUD_PROD_CLOUD_SERVE_CLIENT }} + SERVER_IP: ${{ secrets.CLOUD_PROD_CLOUD_SERVER_IP }} TJDB_SQL_MODE_DISABLE: ${{ secrets.CLOUD_TJDB_SQL_MODE_DISABLE }} TOOLJET_SERVER_URL: ${{ secrets.CLOUD_TOOLJET_SERVER_URL }} + WEBSITE_SIGNUP_URL: https://tooljet.ai/ai-create-account TOOLJET_EDITION: cloud - WEBSITE_SIGNUP_URL: https://website-stage.tooljet.ai/ai-create-account - name: 🚀 Deploy to Netlify run: | npm install -g netlify-cli - netlify deploy --prod --dir=frontend/build --auth=$NETLIFY_AUTH_TOKEN --site=${{ secrets.CLOUD_NETLIFY_SITE_ID }} + netlify deploy --prod --dir=frontend/build --auth=$NETLIFY_AUTH_TOKEN --site=${{ secrets.CLOUD_PROD_NETLIFY_SITE_ID }} working-directory: repo env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} - GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_GOOGLE_MAPS_API_KEY }} + GOOGLE_MAPS_API_KEY: ${{ secrets.CLOUD_PROD_CLOUD_GOOGLE_MAPS_API_KEY }} NODE_ENV: ${{ secrets.CLOUD_NODE_ENV }} NODE_OPTIONS: ${{ secrets.CLOUD_NODE_OPTIONS }} - SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_SENTRY_AUTH_TOKEN }} - SENTRY_ORG: ${{ secrets.CLOUD_SENTRY_ORG }} - SENTRY_PROJECT: ${{ secrets.CLOUD_SENTRY_PROJECT }} - SERVE_CLIENT: ${{ secrets.CLOUD_SERVE_CLIENT }} - SERVER_IP: ${{ secrets.CLOUD_SERVER_IP }} + SENTRY_AUTH_TOKEN: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CLOUD_PROD_CLOUD_SENTRY_PROJECT }} + SERVE_CLIENT: ${{ secrets.CLOUD_PROD_CLOUD_SERVE_CLIENT }} + SERVER_IP: ${{ secrets.CLOUD_PROD_CLOUD_SERVER_IP }} TJDB_SQL_MODE_DISABLE: ${{ secrets.CLOUD_TJDB_SQL_MODE_DISABLE }} TOOLJET_SERVER_URL: ${{ secrets.CLOUD_TOOLJET_SERVER_URL }} - WEBSITE_SIGNUP_URL: https://website-stage.tooljet.ai/ai-create-account + WEBSITE_SIGNUP_URL: https://tooljet.ai/ai-create-account TOOLJET_EDITION: cloud diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 7afca64ea7..6702780e88 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -21,7 +21,7 @@ jobs: if: "contains(github.event.release.tag_name, '-ce-lts')" uses: actions/checkout@v2 with: - ref: refs/heads/lts-3.6 + ref: refs/heads/lts-3.16 # Create Docker Buildx builder with platform configuration - name: Set up Docker Buildx @@ -108,7 +108,7 @@ jobs: if: "contains(github.event.release.tag_name, '-ee-lts')" uses: actions/checkout@v2 with: - ref: refs/heads/lts-3.6 + ref: refs/heads/lts-3.16 # Create Docker Buildx builder with platform configuration - name: Set up Docker Buildx @@ -155,7 +155,7 @@ jobs: context: . build-args: | CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }} - BRANCH_NAME=lts-3.6 + BRANCH_NAME=lts-3.16 file: docker/ee/ee-production.Dockerfile push: true tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }} @@ -185,7 +185,7 @@ jobs: if: "contains(github.event.release.tag_name, '-cloud-lts')" uses: actions/checkout@v2 with: - ref: refs/heads/lts-3.6 + ref: refs/heads/lts-3.16 # Create Docker Buildx builder with platform configuration - name: Set up Docker Buildx @@ -215,7 +215,7 @@ jobs: context: . build-args: | CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }} - BRANCH_NAME=lts-3.6 + BRANCH_NAME=lts-3.16 file: docker/cloud/cloud-server.Dockerfile push: true tags: tooljet/saas:${{ github.event.release.tag_name }} @@ -247,11 +247,11 @@ jobs: with: ref: refs/heads/main - - name: Checkout code to lts-3.0 + - name: Checkout code to lts-3.16 if: contains(github.event.release.tag_name, '-ee-lts') uses: actions/checkout@v2 with: - ref: refs/heads/lts-3.0 + ref: refs/heads/lts-3.16 # Create Docker Buildx builder with platform configuration - name: Set up Docker Buildx diff --git a/.github/workflows/packer-build.yml b/.github/workflows/packer-build.yml index 7c1dfbb583..2397df3c52 100644 --- a/.github/workflows/packer-build.yml +++ b/.github/workflows/packer-build.yml @@ -16,11 +16,11 @@ jobs: name: packer-ee steps: - - name: Checkout code to lts-3.6 branch + - name: Checkout code to lts-3.16 branch if: contains(github.event.release.tag_name, '-ee-lts') uses: actions/checkout@v2 with: - ref: refs/heads/lts-3.6 + ref: refs/heads/lts-3.16 - name: Setting tag if: "${{ github.event.inputs.version != '' }}" diff --git a/frontend/ee b/frontend/ee index 3124bbc0be..01af83abcd 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 3124bbc0beb8c14d051804336ebe29e59a7ac3c9 +Subproject commit 01af83abcdb663c04088e215ff84f90d2bd33a62 diff --git a/server/data-migrations/1750927057649-AddAiGenerationFlagsInApp.ts b/server/data-migrations/1748331051836-AddAiGenerationFlagsInApp.ts similarity index 92% rename from server/data-migrations/1750927057649-AddAiGenerationFlagsInApp.ts rename to server/data-migrations/1748331051836-AddAiGenerationFlagsInApp.ts index 3205c9979b..2f55d6fbbe 100644 --- a/server/data-migrations/1750927057649-AddAiGenerationFlagsInApp.ts +++ b/server/data-migrations/1748331051836-AddAiGenerationFlagsInApp.ts @@ -1,7 +1,6 @@ -import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; - -export class AddAiGenerationFlagsInApp1750927057649 implements MigrationInterface { +import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'; +export class AddAiGenerationFlagsInApp1748331051836 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { // Add is_initialised_from_prompt column await queryRunner.addColumn( @@ -58,5 +57,4 @@ export class AddAiGenerationFlagsInApp1750927057649 implements MigrationInterfac await queryRunner.dropColumn('apps', 'app_generated_from_prompt'); await queryRunner.dropColumn('apps', 'is_initialised_from_prompt'); } - } diff --git a/server/data-migrations/1750927083207-AddArtifactsTable.ts b/server/data-migrations/1748542504137-AddArtifactsTable.ts similarity index 94% rename from server/data-migrations/1750927083207-AddArtifactsTable.ts rename to server/data-migrations/1748542504137-AddArtifactsTable.ts index 078c3412aa..2c66977be8 100644 --- a/server/data-migrations/1750927083207-AddArtifactsTable.ts +++ b/server/data-migrations/1748542504137-AddArtifactsTable.ts @@ -1,8 +1,7 @@ -import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm"; +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; -export class AddArtifactsTable1750927083207 implements MigrationInterface { - - public async up(queryRunner: QueryRunner): Promise { +export class AddArtifactsTable1748542504137 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { await queryRunner.createTable( new Table({ name: 'artifacts', diff --git a/server/ee b/server/ee index 39b3bebc8f..2f0948893f 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 39b3bebc8f352d0e078a0a91629652610ce7aa6b +Subproject commit 2f0948893fdea517479ba3cc2da421a06dff6a64