name: CI on: pull_request: branches: - main merge_group: branches: - main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} env: COVERAGE: true RAILS_ENV: test NODE_ENV: test DATABASE_URL_TEST: postgres://postgres:postgres@localhost:5432/Forem_test DATABASE_NAME_TEST: Forem_test KNAPSACK_PRO_FIXED_QUEUE_SPLIT: true POSTGRES_PASSWORD: postgres KNAPSACK_PRO_LOG_LEVEL: info jobs: bundle_install: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: bundler-cache: true yarn_install: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Look up if node_module cache exist id: cache uses: actions/cache/restore@v3 with: lookup-only: true path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - name: Cache node_modules uses: actions/cache@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- if: steps.cache.outputs.cache-hit != 'true' - uses: actions/setup-node@v4 if: steps.cache.outputs.cache-hit != 'true' with: node-version-file: '.nvmrc' cache: yarn - run: yarn install --immutable if: steps.cache.outputs.cache-hit != 'true' precompile_assets: runs-on: ubuntu-latest env: E2E: true steps: - uses: actions/checkout@v4 - name: Look up if compiled assets exist uses: actions/cache@v3 id: precompiled-asset with: fail-on-cache-miss: false path: | public/assets tmp/cache/webpacker key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }} restore-keys: ${{ runner.os }}-compiled-assets-v3- - name: setup ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true if: steps.precompiled-asset.outputs.cache-hit != 'true' - name: Cache node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- if: steps.precompiled-asset.outputs.cache-hit != 'true' - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn if: steps.precompiled-asset.outputs.cache-hit != 'true' - run: yarn install --immutable if: steps.precompiled-asset.outputs.cache-hit != 'true' - run: bundle exec rails assets:precompile if: steps.precompiled-asset.outputs.cache-hit != 'true' audit: runs-on: ubuntu-latest needs: [bundle_install, yarn_install] steps: - uses: actions/checkout@v4 - name: setup ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - name: rubocop uses: reviewdog/action-rubocop@v2 with: rubocop_version: gemfile rubocop_extensions: rubocop-performance:gemfile rubocop-rails:gemfile rubocop-rspec:gemfile rubocop-capybara:gemfile reporter: github-pr-review # Default is github-pr-check - run: yarn lint:frontend - run: bundle exec bundle-audit check --update --ignore CVE-2023-26141 rspec: runs-on: ubuntu-latest needs: [bundle_install, yarn_install, precompile_assets] timeout-minutes: 20 env: KNAPSACK_PRO_CI_NODE_TOTAL: ${{ matrix.ci_node_total }} KNAPSACK_PRO_CI_NODE_INDEX: ${{ matrix.ci_node_index }} KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC }} services: postgres: image: postgres:13-alpine env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 redis: image: redis ports: - 6379:6379 strategy: fail-fast: false matrix: ci_node_total: [8] ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7] steps: - uses: actions/checkout@v4 - name: Restore compiled assets uses: actions/cache/restore@v3 with: fail-on-cache-miss: true path: | public/assets tmp/cache/webpacker key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }} restore-keys: ${{ runner.os }}-compiled-assets-v3- - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - name: setup ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true - run: bundle exec rails db:test:prepare - name: RSpec run: bin/knapsack_pro_rspec - name: Upload RSpec artifacts uses: actions/upload-artifact@v3 if: failure() with: name: rspec-artifacts path: tmp/capybara - name: Rename folder run: mv coverage/simplecov coverage/simplecov-${{ matrix.ci_node_index }} - name: Upload test coverage result uses: actions/upload-artifact@v3 with: name: coverage path: coverage/ - name: Upload test results to BuildPulse for flaky test detection if: '!cancelled()' # Run this step even when the tests fail. Skip if the workflow is cancelled. uses: Workshop64/buildpulse-action@master with: account: ${{ secrets.BUILDPULSE_ACCOUNT }} repository: ${{ secrets.BUILDPULSE_REPOSITORY }} path: tmp/rspec_final_results.xml key: ${{ secrets.BUILDPULSE_ACCESS_KEY_ID }} secret: ${{ secrets.BUILDPULSE_SECRET_ACCESS_KEY }} jest: runs-on: ubuntu-latest needs: [yarn_install] timeout-minutes: 20 steps: - uses: actions/checkout@v4 - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - run: yarn test --colors --ci --reporters="jest-junit" --reporters="default" - name: Upload test results to BuildPulse for flaky test detection if: '!cancelled()' # Run this step even when the tests fail. Skip if the workflow is cancelled. uses: Workshop64/buildpulse-action@master with: account: ${{ secrets.BUILDPULSE_ACCOUNT }} repository: ${{ secrets.BUILDPULSE_REPOSITORY }} path: junit.xml key: ${{ secrets.BUILDPULSE_ACCESS_KEY_ID }} secret: ${{ secrets.BUILDPULSE_SECRET_ACCESS_KEY }} - name: Upload test coverage result uses: actions/upload-artifact@v3 with: name: coverage path: coverage/ storybook: runs-on: ubuntu-latest needs: [yarn_install] timeout-minutes: 20 steps: - uses: actions/checkout@v4 - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - run: yarn build-storybook build_test: runs-on: ubuntu-latest needs: [bundle_install, yarn_install, precompile_assets] timeout-minutes: 20 env: RAILS_ENV: production NODE_ENV: production DATABASE_URL: postgres://postgres:postgres@localhost:5432/Forem_prod_test DATABASE_NAME: Forem_prod_test APP_PROTOCOL: http:// APP_DOMAIN: localhost:3000 HEROKU_APP_URL: practicaldev.herokuapp.com SECRET_KEY_BASE: dummydummydummy GITHUB_KEY: dummy GITHUB_SECRET: dummy services: postgres: image: postgres:13-alpine env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 redis: image: redis ports: - 6379:6379 steps: - uses: actions/checkout@v4 - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - name: setup ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true - run: bundle exec rails assets:precompile - run: RAILS_ENV=test bin/test-console-check cypress: runs-on: ubuntu-latest timeout-minutes: 20 needs: [bundle_install, yarn_install, precompile_assets] env: E2E: true services: postgres: image: postgres:13-alpine env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 redis: image: redis ports: - 6379:6379 strategy: fail-fast: false matrix: ci_node_total: [8] ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, non-seed] steps: - uses: actions/checkout@v4 - name: Restore compiled assets uses: actions/cache/restore@v3 with: fail-on-cache-miss: true path: | public/assets tmp/cache/webpacker key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }} restore-keys: ${{ runner.os }}-compiled-assets-v3- - name: Restore node_modules uses: actions/cache/restore@v3 with: path: node_modules key: ${{ runner.os }}-node-modules-v2-${{ hashFiles('**/yarn.lock') }} restore-keys: ${{ runner.os }}-node-modules-v2- - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn - name: setup ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true - run: bundle exec rails db:test:prepare - name: Cache cypress binary uses: actions/cache@v3 with: path: ~/.cache/Cypress key: ${{ runner.os }}-cypress-binary-${{ hashFiles('**/yarn.lock') }} - run: yarn cypress install - name: cypress env: CYPRESS_RAILS_HOST: localhost CYPRESS_RAILS_PORT: 3000 KNAPSACK_PRO_CI_NODE_TOTAL: ${{ matrix.ci_node_total }} KNAPSACK_PRO_CI_NODE_INDEX: ${{ matrix.ci_node_index }} KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS }} KNAPSACK_PRO_TEST_FILE_PATTERN: "cypress/e2e/seededFlows/**/*.spec.js" run: bin/knapsack_pro_cypress if: ${{ matrix.ci_node_index != 'non-seed' }} - name: cypress non-seed run: CREATOR_ONBOARDING_SEED_DATA=1 E2E_FOLDER=creatorOnboardingFlows E2E=true bin/rails cypress:run if: ${{ matrix.ci_node_index == 'non-seed' }} - name: Upload Cypress artifacts uses: actions/upload-artifact@v3 if: failure() with: name: cypress-artifacts path: | tmp/cypress_screenshots cypress/logs - name: Upload test results to BuildPulse for flaky test detection if: '!cancelled()' # Run this step even when the tests fail. Skip if the workflow is cancelled. uses: Workshop64/buildpulse-action@master with: account: ${{ secrets.BUILDPULSE_ACCOUNT }} repository: ${{ secrets.BUILDPULSE_REPOSITORY }} path: cypress/results key: ${{ secrets.BUILDPULSE_ACCESS_KEY_ID }} secret: ${{ secrets.BUILDPULSE_SECRET_ACCESS_KEY }} upload-coverage: runs-on: ubuntu-latest needs: [rspec, jest, cypress] steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v3 with: name: coverage - run: | mkdir coverage coverage/simplecov coverage/cypress mv simplecov-* coverage/simplecov mv jest coverage/jest - uses: Wandalen/wretry.action@master with: action: codecov/codecov-action@v3 with: | flags: ruby directory: coverage/simplecov fail_ci_if_error: ${{ github.ref != 'refs/heads/main' }} attempt_limit: 5 attempt_delay: 60000 - uses: Wandalen/wretry.action@master with: action: codecov/codecov-action@v3 with: | flags: jest, javascript directory: coverage/jest fail_ci_if_error: ${{ github.ref != 'refs/heads/main' }} attempt_limit: 5 attempt_delay: 60000 CI-status-report: runs-on: ubuntu-latest needs: [rspec, jest, cypress, build_test, audit, storybook] if: always() steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }}