name: Run Chatwoot CE spec permissions: contents: read on: push: branches: - develop - master pull_request: workflow_dispatch: jobs: # Separate linting jobs for faster feedback lint-backend: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: bundler-cache: true - name: Run Rubocop run: bundle exec rubocop --parallel # Backend tests with parallelization backend-tests: runs-on: [self-hosted, oracle-arm] strategy: fail-fast: false max-parallel: 8 matrix: ci_node_total: [16] ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] env: POSTGRES_HOST: localhost RAILS_ENV: test steps: - uses: actions/checkout@v4 - name: Start services run: | docker run -d --name pg-${{ matrix.ci_node_index }}-${{ github.run_id }} \ -e POSTGRES_PASSWORD= -e POSTGRES_DB=postgres -e POSTGRES_HOST_AUTH_METHOD=trust \ -p ${{ 5432 + matrix.ci_node_index }}:5432 \ pgvector/pgvector:pg16 --mount type=tmpfs,destination=/var/lib/postgresql/data docker run -d --name redis-${{ matrix.ci_node_index }}-${{ github.run_id }} \ -p ${{ 6379 + matrix.ci_node_index }}:6379 \ redis:alpine - uses: pnpm/action-setup@v4 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - uses: ruby/setup-ruby@v1 with: bundler-cache: true - uses: actions/setup-node@v4 with: node-version: 23 cache: 'pnpm' - name: Install pnpm dependencies run: pnpm i - name: Strip enterprise code run: | rm -rf enterprise rm -rf spec/enterprise - name: Wait for services run: | echo "Waiting for services to be ready..." attempt=0 until pg_isready -h localhost -p $POSTGRES_PORT || [ $attempt -eq 5 ]; do sleep 2 attempt=$((attempt + 1)) done sleep 2 - name: Set up database run: | psql -U postgres -h localhost -p $POSTGRES_PORT -c "CREATE ROLE root LOGIN SUPERUSER;" psql -U postgres -h localhost -p $POSTGRES_PORT -c "CREATE DATABASE chatwoot_dev OWNER root;" env: PGPASSWORD: '' - name: Create database run: bundle exec rake db:create - name: Seed database run: bundle exec rake db:schema:load - name: Run migrations run: bundle exec rake db:migrate - name: Run backend tests (parallelized) run: | # Get all spec files and split them using round-robin distribution # This ensures slow tests are distributed evenly across all nodes SPEC_FILES=($(find spec -name '*_spec.rb' | sort)) TESTS="" for i in "${!SPEC_FILES[@]}"; do # Assign spec to this node if: index % total == node_index if [ $(( i % ${{ matrix.ci_node_total }} )) -eq ${{ matrix.ci_node_index }} ]; then TESTS="$TESTS ${SPEC_FILES[$i]}" fi done if [ -n "$TESTS" ]; then bundle exec rspec --profile=10 --format progress --format json --out tmp/rspec_results.json $TESTS fi env: NODE_OPTIONS: --openssl-legacy-provider - name: Upload test results uses: actions/upload-artifact@v4 if: always() with: name: rspec-results-${{ matrix.ci_node_index }} path: tmp/rspec_results.json - name: Upload rails log folder uses: actions/upload-artifact@v4 if: failure() with: name: rails-log-folder-${{ matrix.ci_node_index }} path: log - name: Stop services if: always() run: | docker stop $PG_CONTAINER_NAME || true docker rm $PG_CONTAINER_NAME || true docker stop $RD_CONTAINER_NAME || true docker rm $RD_CONTAINER_NAME || true