/ .github / workflows / budibase_ci.yml
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