diff --git a/.circleci/config.yml b/.circleci/config.yml index 15c40dc77..459faf1c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,84 +1,87 @@ -# Ruby CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-ruby/ for more details -# -version: 2 +version: 2.1 +orbs: + node: circleci/node@6.1.0 + defaults: &defaults working_directory: ~/build - docker: - # specify the version you desire here - - image: cimg/ruby:3.3.3-browsers - - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: cimg/postgres:15.3 - - image: cimg/redis:6.2.6 - environment: - - RAILS_LOG_TO_STDOUT: false - - COVERAGE: true - - LOG_LEVEL: warn - parallelism: 4 + machine: + image: ubuntu-2204:2024.05.1 resource_class: large + environment: + RAILS_LOG_TO_STDOUT: false + COVERAGE: true + LOG_LEVEL: warn + parallelism: 4 jobs: build: <<: *defaults steps: - checkout + - node/install: + node-version: '20.12' + - node/install-pnpm + - node/install-packages: + pkg-manager: pnpm + override-ci-command: pnpm i + - run: node --version + - run: pnpm --version - run: - name: Configure Bundler + name: Install System Dependencies command: | - echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV - source $BASH_ENV + sudo apt-get update + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ + libpq-dev \ + redis-server \ + postgresql \ + build-essential \ + git \ + curl \ + libssl-dev \ + zlib1g-dev \ + libreadline-dev \ + libyaml-dev \ + openjdk-11-jdk \ + jq \ + software-properties-common \ + ca-certificates \ + imagemagick \ + libxml2-dev \ + libxslt1-dev \ + file \ + g++ \ + gcc \ + autoconf \ + gnupg2 \ + patch \ + ruby-dev \ + liblzma-dev \ + libgmp-dev \ + libncurses5-dev \ + libffi-dev \ + libgdbm6 \ + libgdbm-dev \ + libvips + + - run: + name: Install RVM and Ruby 3.3.3 + command: | + sudo apt-get install -y gpg + gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB + \curl -sSL https://get.rvm.io | bash -s stable + echo 'source ~/.rvm/scripts/rvm' >> $BASH_ENV + source ~/.rvm/scripts/rvm + rvm install "3.3.3" + rvm use 3.3.3 --default gem install bundler - run: - name: Which bundler? - command: bundle -v - - - run: - name: Swap node versions + name: Install Application Dependencies command: | - set +e - wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" - nvm install v20 - echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV - echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV - - # Run bundler - # Load installed gems from cache if possible, bundle install then save cache - # Multiple caches are used to increase the chance of a cache hit - - - restore_cache: - keys: - - chatwoot-bundle-{{ .Environment.CACHE_VERSION }}-v20220524-{{ checksum "Gemfile.lock" }} - - - run: bundle install --frozen --path ~/.bundle - - save_cache: - paths: - - ~/.bundle - key: chatwoot-bundle-{{ .Environment.CACHE_VERSION }}-v20220524-{{ checksum "Gemfile.lock" }} - - # Only necessary if app uses webpacker or yarn in some other way - - restore_cache: - keys: - - chatwoot-yarn-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} - - chatwoot-yarn- - - - run: - name: yarn - command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn - - # Store yarn / webpacker cache - - save_cache: - key: chatwoot-yarn-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} - paths: - - ~/.cache/yarn + source ~/.rvm/scripts/rvm + bundle install + # pnpm install - run: name: Download cc-test-reporter @@ -86,12 +89,8 @@ jobs: mkdir -p ~/tmp curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ~/tmp/cc-test-reporter chmod +x ~/tmp/cc-test-reporter - - persist_to_workspace: - root: ~/tmp - paths: - - cc-test-reporter - # verify swagger specification + # Swagger verification - run: name: Verify swagger API specification command: | @@ -104,45 +103,62 @@ jobs: curl -L https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar > ~/tmp/openapi-generator-cli-6.3.0.jar java -jar ~/tmp/openapi-generator-cli-6.3.0.jar validate -i swagger/swagger.json - # Database setup - - run: bundle exec rake db:create - - run: bundle exec rake db:schema:load + # we remove the FRONTED_URL from the .env before running the tests + - run: + name: Database Setup and Configure Environment Variables + command: | + pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '') + sed -i "s/REPLACE_WITH_PASSWORD/${pg_pass}/g" ${PWD}/.circleci/setup_chatwoot.sql + chmod 644 ${PWD}/.circleci/setup_chatwoot.sql + mv ${PWD}/.circleci/setup_chatwoot.sql /tmp/ + sudo -i -u postgres psql -f /tmp/setup_chatwoot.sql + cp .env.example .env + sed -i '/^FRONTEND_URL/d' .env + sed -i -e '/REDIS_URL/ s/=.*/=redis:\/\/localhost:6379/' .env + sed -i -e '/POSTGRES_HOST/ s/=.*/=localhost/' .env + sed -i -e '/POSTGRES_USERNAME/ s/=.*/=chatwoot/' .env + sed -i -e "/POSTGRES_PASSWORD/ s/=.*/=$pg_pass/" .env + echo -en "\nINSTALLATION_ENV=circleci" >> ".env" + # Database setup + - run: + name: Run DB migrations + command: bundle exec rails db:chatwoot_prepare + + # Bundle audit - run: name: Bundle audit command: bundle exec bundle audit update && bundle exec bundle audit check -v + # Rubocop linting - run: name: Rubocop command: bundle exec rubocop - # - run: - # name: Brakeman - # command: bundle exec brakeman - + # ESLint linting - run: name: eslint - command: yarn run eslint + command: pnpm run eslint - # Run frontend tests - run: name: Run frontend tests command: | - mkdir -p ~/tmp/test-results/frontend_specs + mkdir -p ~/build/coverage/frontend ~/tmp/cc-test-reporter before-build - yarn test:coverage - - run: - name: Code Climate Test Coverage - command: | - ~/tmp/cc-test-reporter format-coverage -t lcov -o "coverage/codeclimate.frontend_$CIRCLE_NODE_INDEX.json" + pnpm run test:coverage - # Run rails tests + - run: + name: Code Climate Test Coverage (Frontend) + command: | + ~/tmp/cc-test-reporter format-coverage -t lcov -o "~/build/coverage/frontend/codeclimate.frontend_$CIRCLE_NODE_INDEX.json" + + # Run backend tests - run: name: Run backend tests command: | mkdir -p ~/tmp/test-results/rspec mkdir -p ~/tmp/test-artifacts - mkdir -p coverage + mkdir -p ~/build/coverage/backend ~/tmp/cc-test-reporter before-build TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings) bundle exec rspec --format progress \ @@ -150,54 +166,18 @@ jobs: --out ~/tmp/test-results/rspec.xml \ -- ${TESTFILES} no_output_timeout: 30m + - run: - name: Code Climate Test Coverage + name: Code Climate Test Coverage (Backend) command: | - ~/tmp/cc-test-reporter format-coverage -t simplecov -o "coverage/codeclimate.$CIRCLE_NODE_INDEX.json" + ~/tmp/cc-test-reporter format-coverage -t simplecov -o "~/build/coverage/backend/codeclimate.$CIRCLE_NODE_INDEX.json" + + - run: + name: List coverage directory contents + command: | + ls -R ~/build/coverage - persist_to_workspace: - root: coverage + root: ~/build paths: - - codeclimate.*.json - # collect reports - - store_test_results: - path: ~/tmp/test-results - - store_artifacts: - path: ~/tmp/test-artifacts - - store_artifacts: - path: log - - upload-coverage: - working_directory: ~/build - docker: - # specify the version you desire here - - image: circleci/ruby:3.0.2-node-browsers - environment: - - CC_TEST_REPORTER_ID: caf26a895e937974a90860cfadfded20891cfd1373a5aaafb3f67406ab9d433f - steps: - - attach_workspace: - at: ~/build - - run: - name: Download cc-test-reporter - command: | - mkdir -p ~/tmp - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ~/tmp/cc-test-reporter - chmod +x ~/tmp/cc-test-reporter - - persist_to_workspace: - root: ~/tmp - paths: - - cc-test-reporter - - run: - name: Upload coverage results to Code Climate - command: | - ~/tmp/cc-test-reporter sum-coverage --output - codeclimate.*.json | ~/tmp/cc-test-reporter upload-coverage --debug --input - - -workflows: - version: 2 - - commit: - jobs: - - build - - upload-coverage: - requires: - - build + - coverage diff --git a/.circleci/setup_chatwoot.sql b/.circleci/setup_chatwoot.sql new file mode 100644 index 000000000..4e5430f1d --- /dev/null +++ b/.circleci/setup_chatwoot.sql @@ -0,0 +1,11 @@ +CREATE USER chatwoot CREATEDB; +ALTER USER chatwoot PASSWORD 'REPLACE_WITH_PASSWORD'; +ALTER ROLE chatwoot SUPERUSER; + +UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1'; +DROP DATABASE template1; +CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UNICODE'; +UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1'; + +\c template1; +VACUUM FREEZE; diff --git a/.codeclimate.yml b/.codeclimate.yml index d8b8d985b..5e16262da 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -27,7 +27,8 @@ checks: threshold: 50 exclude_patterns: - 'spec/' - - '**/specs/' + - '**/specs/**/**' + - '**/spec/**/**' - 'db/*' - 'bin/**/*' - 'db/**/*' diff --git a/.eslintrc.js b/.eslintrc.js index cf4d1e7e1..a229133a2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,23 @@ module.exports = { - extends: ['airbnb-base/legacy', 'prettier', 'plugin:vue/vue3-recommended'], + extends: [ + 'airbnb-base/legacy', + 'prettier', + 'plugin:vue/vue3-recommended', + 'plugin:vitest-globals/recommended', + ], + overrides: [ + { + files: ['**/*.spec.{j,t}s?(x)'], + env: { + 'vitest-globals/env': true, + }, + }, + ], plugins: ['html', 'prettier'], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, rules: { 'prettier/prettier': ['error'], camelcase: 'off', @@ -206,5 +223,11 @@ module.exports = { globals: { bus: true, vi: true, + // beforeEach: true, + // afterEach: true, + // test: true, + // describe: true, + // it: true, + // expect: true, }, }; diff --git a/.github/workflows/frontend-fe.yml b/.github/workflows/frontend-fe.yml new file mode 100644 index 000000000..15bb6f5e9 --- /dev/null +++ b/.github/workflows/frontend-fe.yml @@ -0,0 +1,43 @@ +name: Frontend Lint & Test + +on: + push: + branches: + - develop + pull_request: + branches: + - develop + +jobs: + test: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@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: pnpm/action-setup@v4 + with: + version: 9.3.0 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install pnpm dependencies + run: pnpm install --frozen-lockfile + + - name: Run eslint + run: pnpm run eslint + + - name: Run frontend tests with coverage + run: | + mkdir -p coverage + pnpm run test:coverage diff --git a/.github/workflows/run_foss_spec.yml b/.github/workflows/run_foss_spec.yml index 9382ccbf6..6a018b314 100644 --- a/.github/workflows/run_foss_spec.yml +++ b/.github/workflows/run_foss_spec.yml @@ -21,7 +21,7 @@ jobs: image: postgres:15.3 env: POSTGRES_USER: postgres - POSTGRES_PASSWORD: "" + POSTGRES_PASSWORD: '' POSTGRES_DB: postgres POSTGRES_HOST_AUTH_METHOD: trust ports: @@ -41,46 +41,49 @@ jobs: options: --entrypoint redis-server steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - with: - version: 9 - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 9 + 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 # runs 'bundle install' and caches installed gems automatically + - uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' - - name: Install pnpm dependencies - run: pnpm i + - name: Install pnpm dependencies + run: pnpm i - - name: Strip enterprise code - run: | - rm -rf enterprise - rm -rf spec/enterprise + - name: Strip enterprise code + run: | + rm -rf enterprise + rm -rf spec/enterprise - - name: Create database - run: bundle exec rake db:create + - name: Create database + run: bundle exec rake db:create - - name: Seed database - run: bundle exec rake db:schema:load + - name: Seed database + run: bundle exec rake db:schema:load - # Run rails tests - - name: Run backend tests - run: | - bundle exec rspec --profile=10 --format documentation - env: - NODE_OPTIONS: --openssl-legacy-provider + - name: Run frontend tests + run: pnpm run test:coverage - - name: Upload rails log folder - uses: actions/upload-artifact@v4 - if: always() - with: - name: rails-log-folder - path: log + # Run rails tests + - name: Run backend tests + run: | + bundle exec rspec --profile=10 --format documentation + env: + NODE_OPTIONS: --openssl-legacy-provider + + - name: Upload rails log folder + uses: actions/upload-artifact@v4 + if: always() + with: + name: rails-log-folder + path: log diff --git a/app/javascript/dashboard/components/ModalHeader.vue b/app/javascript/dashboard/components/ModalHeader.vue index 63d361278..9e2330aa4 100644 --- a/app/javascript/dashboard/components/ModalHeader.vue +++ b/app/javascript/dashboard/components/ModalHeader.vue @@ -27,14 +27,14 @@ export default {
{{ headerContent }}
diff --git a/app/javascript/dashboard/components/layout/AvailabilityStatus.vue b/app/javascript/dashboard/components/layout/AvailabilityStatus.vue
index 4fce895b2..8bce09250 100644
--- a/app/javascript/dashboard/components/layout/AvailabilityStatus.vue
+++ b/app/javascript/dashboard/components/layout/AvailabilityStatus.vue
@@ -105,7 +105,7 @@ export default {
size="small"
:color-scheme="status.disabled ? '' : 'secondary'"
:variant="status.disabled ? 'smooth' : 'clear'"
- class-names="status-change--dropdown-button"
+ class="status-change--dropdown-button"
@click="changeAvailabilityStatus(status.value)"
>