budibase_ci.yml
1 name: Budibase CI 2 3 on: 4 # Trigger the workflow on push or pull request, 5 # but only for the master branch 6 push: 7 branches: 8 - master 9 pull_request: 10 workflow_dispatch: 11 workflow_call: 12 inputs: 13 run_as_oss: 14 type: boolean 15 required: false 16 description: Force running checks as if it was an OSS contributor 17 default: false 18 19 permissions: 20 contents: read 21 22 env: 23 BRANCH: ${{ github.event.pull_request.head.ref }} 24 BASE_BRANCH: ${{ github.event.pull_request.base.ref}} 25 NX_BASE_BRANCH: origin/${{ github.base_ref }} 26 ONLY_AFFECTED_TASKS: ${{ github.event_name == 'pull_request' }} 27 HUSKY: 0 28 29 jobs: 30 install-deps: 31 runs-on: ubuntu-24.04 32 concurrency: 33 group: ${{ github.workflow }}-install-deps-${{ github.event.pull_request.number || github.ref }} 34 cancel-in-progress: true 35 steps: 36 - name: Checkout repo 37 uses: actions/checkout@v6 38 39 - name: Use Node.js 22.x 40 uses: actions/setup-node@v6 41 with: 42 node-version: 22.x 43 44 - name: Restore hoisted node_modules cache 45 id: hoisted-modules-cache-restore 46 uses: actions/cache/restore@v5 47 with: 48 path: | 49 node_modules 50 packages/*/node_modules 51 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 52 53 - name: Install dependencies 54 if: steps.hoisted-modules-cache-restore.outputs.cache-hit != 'true' 55 run: yarn --frozen-lockfile 56 57 - name: Save hoisted node_modules cache 58 if: steps.hoisted-modules-cache-restore.outputs.cache-hit != 'true' 59 uses: actions/cache/save@v5 60 with: 61 path: | 62 node_modules 63 packages/*/node_modules 64 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 65 66 lint: 67 runs-on: ubuntu-24.04 68 concurrency: 69 group: ${{ github.workflow }}-lint-${{ github.event.pull_request.number || github.ref }} 70 cancel-in-progress: true 71 needs: install-deps 72 steps: 73 - name: Checkout repo 74 uses: actions/checkout@v6 75 76 - name: Use Node.js 22.x 77 uses: actions/setup-node@v6 78 with: 79 node-version: 22.x 80 - name: Restore hoisted node_modules cache 81 uses: actions/cache/restore@v5 82 with: 83 path: | 84 node_modules 85 packages/*/node_modules 86 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 87 fail-on-cache-miss: true 88 - run: yarn lint 89 90 litellm-version-sync: 91 runs-on: ubuntu-24.04 92 concurrency: 93 group: ${{ github.workflow }}-litellm-version-sync-${{ github.event.pull_request.number || github.ref }} 94 cancel-in-progress: true 95 steps: 96 - name: Checkout repo 97 uses: actions/checkout@v6 98 99 - name: Use Node.js 22.x 100 uses: actions/setup-node@v6 101 with: 102 node-version: 22.x 103 104 - name: Verify LiteLLM versions are synchronized 105 run: yarn check:litellm-version 106 107 build: 108 runs-on: ubuntu-24.04 109 concurrency: 110 group: ${{ github.workflow }}-build-${{ github.event.pull_request.number || github.ref }} 111 cancel-in-progress: true 112 needs: 113 - install-deps 114 - compute-affected-jobs 115 if: needs.compute-affected-jobs.outputs.run_build == 'true' 116 steps: 117 - name: Checkout repo 118 uses: actions/checkout@v6 119 with: 120 fetch-depth: 2 121 122 - name: Fetch base branch for affected tasks 123 if: env.ONLY_AFFECTED_TASKS == 'true' 124 run: git fetch --no-tags --depth=1 origin ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} 125 126 - name: Use Node.js 22.x 127 uses: actions/setup-node@v6 128 with: 129 node-version: 22.x 130 - name: Restore hoisted node_modules cache 131 uses: actions/cache/restore@v5 132 with: 133 path: | 134 node_modules 135 packages/*/node_modules 136 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 137 fail-on-cache-miss: true 138 139 # Run build all the projects 140 - name: Build 141 run: yarn build 142 # Check the types of the projects built via esbuild 143 - name: Check types 144 run: | 145 if ${{ env.ONLY_AFFECTED_TASKS }}; then 146 yarn check:types --since=${{ env.NX_BASE_BRANCH }} 147 else 148 yarn check:types 149 fi 150 151 missing-deps: 152 runs-on: ubuntu-24.04 153 concurrency: 154 group: ${{ github.workflow }}-missing-deps-${{ github.event.pull_request.number || github.ref }} 155 cancel-in-progress: true 156 needs: install-deps 157 steps: 158 - name: Checkout repo 159 uses: actions/checkout@v6 160 161 - name: Use Node.js 22.x 162 uses: actions/setup-node@v6 163 with: 164 node-version: 22.x 165 166 - name: Restore hoisted node_modules cache 167 uses: actions/cache/restore@v5 168 with: 169 path: | 170 node_modules 171 packages/*/node_modules 172 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 173 fail-on-cache-miss: true 174 175 - name: Check missing deps 176 run: yarn check:missing-deps 177 178 helm-lint: 179 runs-on: ubuntu-24.04 180 concurrency: 181 group: ${{ github.workflow }}-helm-lint-${{ github.event.pull_request.number || github.ref }} 182 cancel-in-progress: true 183 steps: 184 - name: Checkout repo 185 uses: actions/checkout@v6 186 187 - name: Use Node.js 22.x 188 uses: azure/setup-helm@v3 189 - run: cd charts/budibase && helm lint . 190 191 test-libraries: 192 runs-on: ubuntu-24.04 193 concurrency: 194 group: ${{ github.workflow }}-test-libraries-${{ github.event.pull_request.number || github.ref }} 195 cancel-in-progress: true 196 needs: 197 - install-deps 198 - compute-affected-jobs 199 if: needs.compute-affected-jobs.outputs.run_test_libraries == 'true' 200 steps: 201 - name: Checkout repo 202 uses: actions/checkout@v6 203 with: 204 fetch-depth: 2 205 206 - name: Fetch base branch for affected tasks 207 if: env.ONLY_AFFECTED_TASKS == 'true' 208 run: git fetch --no-tags --depth=1 origin ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} 209 210 - name: Use Node.js 22.x 211 uses: actions/setup-node@v6 212 with: 213 node-version: 22.x 214 - name: Pull testcontainers images 215 run: | 216 docker pull testcontainers/ryuk:0.5.1 & 217 docker pull budibase/couchdb:v3.3.3-sqs-v2.1.1 & 218 docker pull redis & 219 220 wait $(jobs -p) 221 222 - name: Restore hoisted node_modules cache 223 uses: actions/cache/restore@v5 224 with: 225 path: | 226 node_modules 227 packages/*/node_modules 228 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 229 fail-on-cache-miss: true 230 231 - name: Test 232 run: | 233 if ${{ env.ONLY_AFFECTED_TASKS }}; then 234 yarn test -- --ignore=@budibase/worker --ignore=@budibase/server --ignore=@budibase/builder --ignore=@budibase/upgrade-tests --ignore=@budibase/client --ignore=@budibase/frontend-core --no-prefix --since=${{ env.NX_BASE_BRANCH }} -- --reporters=default --reporters=github-actions 235 yarn test -- --scope=@budibase/builder --scope=@budibase/client --scope=@budibase/frontend-core --since=${{ env.NX_BASE_BRANCH }} 236 else 237 yarn test -- --ignore=@budibase/worker --ignore=@budibase/server --ignore=@budibase/builder --ignore=@budibase/upgrade-tests --ignore=@budibase/client --ignore=@budibase/frontend-core --no-prefix -- --reporters=default --reporters=github-actions 238 yarn test -- --scope=@budibase/builder --scope=@budibase/client --scope=@budibase/frontend-core --no-prefix 239 fi 240 241 compute-affected-jobs: 242 name: Compute affected jobs 243 runs-on: ubuntu-24.04 244 concurrency: 245 group: ${{ github.workflow }}-compute-affected-jobs-${{ github.event.pull_request.number || github.ref }} 246 cancel-in-progress: true 247 needs: install-deps 248 outputs: 249 run_build: ${{ steps.affected.outputs.run_build }} 250 run_test_libraries: ${{ steps.affected.outputs.run_test_libraries }} 251 run_worker_tests: ${{ steps.affected.outputs.run_worker_tests }} 252 run_server_tests: ${{ steps.affected.outputs.run_server_tests }} 253 steps: 254 - name: Checkout repo 255 uses: actions/checkout@v6 256 with: 257 fetch-depth: 2 258 259 - name: Fetch base branch for affected tasks 260 if: env.ONLY_AFFECTED_TASKS == 'true' 261 run: git fetch --no-tags --depth=1 origin ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} 262 263 - name: Use Node.js 22.x 264 uses: actions/setup-node@v6 265 with: 266 node-version: 22.x 267 - name: Restore hoisted node_modules cache 268 uses: actions/cache/restore@v5 269 with: 270 path: | 271 node_modules 272 packages/*/node_modules 273 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 274 fail-on-cache-miss: true 275 276 - name: Check affected tests 277 id: affected 278 run: | 279 # Defaults for non-PR workflows. 280 RUN_BUILD="true" 281 RUN_TEST_LIBRARIES="true" 282 # This gates whole package test jobs (worker/server) based on Nx affected projects. 283 # Example: if a PR changes only FE projects, server/worker test jobs are skipped. 284 RUN_WORKER_TESTS="true" 285 RUN_SERVER_TESTS="true" 286 287 if ${{ env.ONLY_AFFECTED_TASKS }}; then 288 AFFECTED_BUILD=$(yarn --silent nx show projects --affected -t build --base=${{ env.NX_BASE_BRANCH }}) 289 if [ -z "$AFFECTED_BUILD" ]; then 290 RUN_BUILD="false" 291 fi 292 293 AFFECTED_LIBRARY_TESTS=$(yarn --silent nx show projects --affected -t test --base=${{ env.NX_BASE_BRANCH }} --exclude='@budibase/server,@budibase/worker,@budibase/upgrade-tests') 294 if [ -z "$AFFECTED_LIBRARY_TESTS" ]; then 295 RUN_TEST_LIBRARIES="false" 296 fi 297 298 AFFECTED_WORKER=$(yarn --silent nx show projects --affected -t test --base=${{ env.NX_BASE_BRANCH }} -p @budibase/worker) 299 if [ -z "$AFFECTED_WORKER" ]; then 300 RUN_WORKER_TESTS="false" 301 fi 302 303 AFFECTED_SERVER=$(yarn --silent nx show projects --affected -t test --base=${{ env.NX_BASE_BRANCH }} -p @budibase/server) 304 if [ -z "$AFFECTED_SERVER" ]; then 305 RUN_SERVER_TESTS="false" 306 fi 307 fi 308 309 echo "run_build=$RUN_BUILD" >> $GITHUB_OUTPUT 310 echo "run_test_libraries=$RUN_TEST_LIBRARIES" >> $GITHUB_OUTPUT 311 echo "run_worker_tests=$RUN_WORKER_TESTS" >> $GITHUB_OUTPUT 312 echo "run_server_tests=$RUN_SERVER_TESTS" >> $GITHUB_OUTPUT 313 echo "run_build=$RUN_BUILD" 314 echo "run_test_libraries=$RUN_TEST_LIBRARIES" 315 echo "run_worker_tests=$RUN_WORKER_TESTS" 316 echo "run_server_tests=$RUN_SERVER_TESTS" 317 318 test-worker: 319 runs-on: ubuntu-24.04 320 concurrency: 321 group: ${{ github.workflow }}-test-worker-${{ github.event.pull_request.number || github.ref }} 322 cancel-in-progress: true 323 needs: 324 - install-deps 325 - compute-affected-jobs 326 steps: 327 - name: Skip worker tests 328 if: needs.compute-affected-jobs.outputs.run_worker_tests != 'true' 329 run: echo "Skipping worker tests because @budibase/worker is not affected." 330 331 - name: Checkout repo 332 if: needs.compute-affected-jobs.outputs.run_worker_tests == 'true' 333 uses: actions/checkout@v6 334 335 - name: Use Node.js 22.x 336 if: needs.compute-affected-jobs.outputs.run_worker_tests == 'true' 337 uses: actions/setup-node@v6 338 with: 339 node-version: 22.x 340 - name: Restore hoisted node_modules cache 341 if: needs.compute-affected-jobs.outputs.run_worker_tests == 'true' 342 uses: actions/cache/restore@v5 343 with: 344 path: | 345 node_modules 346 packages/*/node_modules 347 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 348 fail-on-cache-miss: true 349 - name: Test worker 350 if: needs.compute-affected-jobs.outputs.run_worker_tests == 'true' 351 run: | 352 cd packages/worker 353 yarn test --reporters=default --reporters=github-actions 354 355 test-server: 356 runs-on: ubuntu-24.04 357 concurrency: 358 group: ${{ github.workflow }}-test-server-${{ matrix.datasource }}-${{ matrix.shard_index }}-${{ github.event.pull_request.number || github.ref }} 359 cancel-in-progress: false 360 needs: 361 - install-deps 362 - compute-affected-jobs 363 strategy: 364 fail-fast: false 365 matrix: 366 include: 367 # Use uneven sharding to balance runtime across datasources. 368 # Oracle and non-datasource ("none") suites are slower, so they use more shards. 369 - datasource: mssql 370 shard_index: 1 371 shard_total: 1 372 - datasource: mysql 373 shard_index: 1 374 shard_total: 1 375 - datasource: postgres 376 shard_index: 1 377 shard_total: 1 378 - datasource: postgres_legacy 379 shard_index: 1 380 shard_total: 1 381 - datasource: mongodb 382 shard_index: 1 383 shard_total: 1 384 - datasource: mariadb 385 shard_index: 1 386 shard_total: 1 387 - datasource: elasticsearch 388 shard_index: 1 389 shard_total: 1 390 - datasource: dynamodb 391 shard_index: 1 392 shard_total: 1 393 - datasource: sqs 394 shard_index: 1 395 shard_total: 2 396 - datasource: sqs 397 shard_index: 2 398 shard_total: 2 399 - datasource: none 400 shard_index: 1 401 shard_total: 3 402 - datasource: none 403 shard_index: 2 404 shard_total: 3 405 - datasource: none 406 shard_index: 3 407 shard_total: 3 408 - datasource: oracle 409 shard_index: 1 410 shard_total: 4 411 - datasource: oracle 412 shard_index: 2 413 shard_total: 4 414 - datasource: oracle 415 shard_index: 3 416 shard_total: 4 417 - datasource: oracle 418 shard_index: 4 419 shard_total: 4 420 steps: 421 - name: Skip server tests 422 if: needs.compute-affected-jobs.outputs.run_server_tests != 'true' 423 run: echo "Skipping server tests because @budibase/server is not affected." 424 425 - name: Checkout repo 426 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 427 uses: actions/checkout@v6 428 429 - name: Use Node.js 22.x 430 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 431 uses: actions/setup-node@v6 432 with: 433 node-version: 22.x 434 435 - name: Restore hoisted node_modules cache 436 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 437 uses: actions/cache/restore@v5 438 with: 439 path: | 440 node_modules 441 packages/*/node_modules 442 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 443 fail-on-cache-miss: true 444 445 - name: Load dotenv 446 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 447 id: dotenv 448 uses: falti/dotenv-action@v1.2.0 449 with: 450 path: ./packages/server/images-sha.env 451 452 - name: Pull testcontainers images 453 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 454 run: | 455 if [ "${{ matrix.datasource }}" == "mssql" ]; then 456 docker pull mcr.microsoft.com/mssql/server@${{ steps.dotenv.outputs.MSSQL_SHA }} 457 elif [ "${{ matrix.datasource }}" == "mysql" ]; then 458 docker pull mysql@${{ steps.dotenv.outputs.MYSQL_SHA }} 459 elif [ "${{ matrix.datasource }}" == "postgres" ]; then 460 docker pull postgres@${{ steps.dotenv.outputs.POSTGRES_SHA }} 461 elif [ "${{ matrix.datasource }}" == "mongodb" ]; then 462 docker pull mongo@${{ steps.dotenv.outputs.MONGODB_SHA }} 463 elif [ "${{ matrix.datasource }}" == "mariadb" ]; then 464 docker pull mariadb@${{ steps.dotenv.outputs.MARIADB_SHA }} 465 elif [ "${{ matrix.datasource }}" == "oracle" ]; then 466 docker pull budibase/oracle-database:23.2-slim-faststart 467 elif [ "${{ matrix.datasource }}" == "postgres_legacy" ]; then 468 docker pull postgres:9.5.25 469 elif [ "${{ matrix.datasource }}" == "elasticsearch" ]; then 470 docker pull elasticsearch@${{ steps.dotenv.outputs.ELASTICSEARCH_SHA }} 471 elif [ "${{ matrix.datasource }}" == "dynamodb" ]; then 472 docker pull amazon/dynamodb-local@${{ steps.dotenv.outputs.DYNAMODB_SHA }} 473 elif [ "${{ matrix.datasource }}" == "none" ]; then 474 docker pull ${{ steps.dotenv.outputs.KEYCLOAK_IMAGE }} & 475 fi 476 docker pull minio/minio & 477 docker pull redis & 478 docker pull testcontainers/ryuk:0.5.1 & 479 docker pull budibase/couchdb:v3.3.3-sqs-v2.1.1 & 480 481 wait $(jobs -p) 482 483 - name: Build client library - necessary for component tests 484 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' && matrix.datasource == 'none' 485 run: yarn build:client 486 487 - name: Test server 488 if: needs.compute-affected-jobs.outputs.run_server_tests == 'true' 489 env: 490 DATASOURCE: ${{ matrix.datasource }} 491 JEST_SHARD_INDEX: ${{ matrix.shard_index }} 492 JEST_SHARD_TOTAL: ${{ matrix.shard_total }} 493 JEST_MAX_WORKERS: 4 494 # DEBUG: testcontainers* 495 run: | 496 FILTER="./src/tests/filters/datasource-tests.js" 497 if [ "${{ matrix.datasource }}" == "none" ]; then 498 FILTER="./src/tests/filters/non-datasource-tests.js" 499 fi 500 501 SHARD_ARG="" 502 if [ "$JEST_SHARD_TOTAL" -gt "1" ]; then 503 SHARD_ARG="--shard=$JEST_SHARD_INDEX/$JEST_SHARD_TOTAL" 504 echo "Running shard $JEST_SHARD_INDEX/$JEST_SHARD_TOTAL for datasource '$DATASOURCE'" 505 fi 506 507 cd packages/server 508 yarn test --filter $FILTER --reporters=default --reporters=github-actions $SHARD_ARG 509 510 check-lockfile: 511 runs-on: ubuntu-24.04 512 concurrency: 513 group: ${{ github.workflow }}-check-lockfile-${{ github.event.pull_request.number || github.ref }} 514 cancel-in-progress: true 515 needs: install-deps 516 if: inputs.run_as_oss != true && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase') 517 steps: 518 - name: Checkout repo 519 uses: actions/checkout@v6 520 521 - name: Use Node.js 22.x 522 uses: actions/setup-node@v6 523 with: 524 node-version: 22.x 525 - name: Restore hoisted node_modules cache 526 uses: actions/cache/restore@v5 527 with: 528 path: | 529 node_modules 530 packages/*/node_modules 531 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 532 fail-on-cache-miss: true 533 - run: yarn install 534 - name: Check for yarn.lock changes 535 run: | 536 if [[ $(git status --porcelain) == *"yarn.lock"* ]]; then 537 echo "yarn.lock file needs to be modified. Please update it locally and commit the changes." 538 exit 1 539 else 540 echo "yarn.lock file is unchanged." 541 fi 542 543 check-openapi-specs: 544 runs-on: ubuntu-24.04 545 concurrency: 546 group: ${{ github.workflow }}-check-openapi-specs-${{ github.event.pull_request.number || github.ref }} 547 cancel-in-progress: true 548 needs: install-deps 549 steps: 550 - name: Checkout repo 551 uses: actions/checkout@v6 552 553 - name: Use Node.js 22.x 554 uses: actions/setup-node@v6 555 with: 556 node-version: 22.x 557 - name: Restore hoisted node_modules cache 558 uses: actions/cache/restore@v5 559 with: 560 path: | 561 node_modules 562 packages/*/node_modules 563 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 564 fail-on-cache-miss: true 565 566 - name: Generate OpenAPI specs 567 run: yarn build:specs 568 569 - name: Check for uncommitted changes 570 run: | 571 if [[ -n $(git status --porcelain packages/server) ]]; then 572 echo "OpenAPI specs are not up to date. Please run 'yarn build:specs' and commit the changes." 573 git status --porcelain packages/server 574 git diff packages/server 575 exit 1 576 else 577 echo "OpenAPI specs are up to date." 578 fi 579 580 build-database-image: 581 runs-on: ubuntu-24.04 582 concurrency: 583 group: ${{ github.workflow }}-build-database-image-${{ github.event.pull_request.number || github.ref }} 584 cancel-in-progress: true 585 steps: 586 - name: Checkout repo 587 uses: actions/checkout@v6 588 589 - name: Set up Docker Buildx 590 uses: docker/setup-buildx-action@v3 591 592 - name: Build budibase/database image 593 uses: docker/build-push-action@v5 594 with: 595 context: hosting/couchdb 596 push: false 597 load: true 598 tags: budibase/database:ci-test 599 cache-from: type=gha 600 cache-to: type=gha,mode=max 601 602 check-client-build-size: 603 runs-on: ubuntu-24.04 604 concurrency: 605 group: ${{ github.workflow }}-check-client-build-size-${{ github.event.pull_request.number || github.ref }} 606 cancel-in-progress: true 607 needs: install-deps 608 steps: 609 - name: Checkout repo 610 uses: actions/checkout@v6 611 612 - name: Use Node.js 22.x 613 uses: actions/setup-node@v6 614 with: 615 node-version: 22.x 616 - name: Restore hoisted node_modules cache 617 uses: actions/cache/restore@v5 618 with: 619 path: | 620 node_modules 621 packages/*/node_modules 622 key: ${{ runner.os }}-node22-hoisted-node-modules-${{ hashFiles('yarn.lock') }} 623 fail-on-cache-miss: true 624 625 - name: Build client library 626 run: yarn build:client 627 628 - name: Check client build size 629 run: | 630 CLIENT_FILE="packages/client/dist/budibase-client.js" 631 if [ ! -f "$CLIENT_FILE" ]; then 632 echo "Error: Client build file not found at $CLIENT_FILE" 633 exit 1 634 fi 635 636 SIZE_BYTES=$(stat -c%s "$CLIENT_FILE") 637 SIZE_MB=$(awk "BEGIN {printf \"%.2f\", $SIZE_BYTES / 1024 / 1024}") 638 MAX_SIZE_BYTES=$((8 * 1024 * 1024)) 639 640 echo "Client build size: ${SIZE_MB}MB" 641 echo "Maximum allowed size: 8MB" 642 643 if [ $SIZE_BYTES -gt $MAX_SIZE_BYTES ]; then 644 echo "Client build size (${SIZE_MB}MB) exceeds maximum allowed size (8MB)" 645 exit 1 646 else 647 echo "Client build size (${SIZE_MB}MB) is within acceptable limits" 648 fi