discourse/.github/workflows/tests.yml
Martin Brennan caef12344a
DEV: Debug
2025-02-26 15:53:33 +10:00

284 lines
11 KiB
YAML

name: Tests
on:
pull_request:
paths-ignore:
- ".github/workflows/migration-tests.yml"
- ".github/dependabot.yml"
- ".github/labeler.yml"
- "migrations/**"
push:
branches:
- main
- beta
- stable
paths-ignore:
- ".github/workflows/migration-tests.yml"
- ".github/dependabot.yml"
- ".github/labeler.yml"
- "migrations/**"
concurrency:
group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: github.event_name == 'pull_request' || github.repository != 'discourse/discourse-private-mirror'
name: ${{ matrix.target }} ${{ matrix.build_type }}${{ (matrix.target == 'core' && matrix.build_type == 'frontend' && format(' ({0})', matrix.browser)) || '' }} # Update fetch-job-id step if changing this
runs-on: ${{ (github.repository_owner == 'discourse' && 'debian-12') || 'ubuntu-latest' }}
permissions:
pull-requests: write
container: discourse/discourse_test:release
timeout-minutes: 20
env:
RAILS_ENV: test
DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS: ${{ (matrix.build_type == 'system' || matrix.build_type == 'backend') && '1' }}
MINIO_RUNNER_INSTALL_DIR: /home/discourse/.minio_runner
MINIO_RUNNER_LOG_LEVEL: DEBUG
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
TESTEM_FIREFOX_PATH: ${{ (matrix.browser == 'Firefox Evergreen') && '/opt/firefox-evergreen/firefox' }}
CAPYBARA_DEFAULT_MAX_WAIT_TIME: 10
CHEAP_SOURCE_MAPS: "1"
USES_PARALLEL_DATABASES: ${{ toJSON(matrix.build_type == 'backend' || matrix.build_type == 'system') }}
PGUSER: discourse
PGPASSWORD: discourse
strategy:
fail-fast: false
matrix:
build_type: [backend, frontend, system, annotations]
target: [core, plugins, themes]
browser: [Chrome]
exclude:
- build_type: annotations
target: plugins
- build_type: annotations
target: themes
- build_type: backend
target: themes
include:
- build_type: system
target: chat
- build_type: frontend
target: core
browser: Firefox Evergreen
- build_type: frontend
target: core
browser: Firefox ESR
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Get CPU cores
shell: bash
id: cpu-info
run: echo "cpu-cores=$(nproc)" >> $GITHUB_OUTPUT
- name: Install GitHub CLI
run: sudo apt-get install -y gh
- name: Set PARALLEL_TEST_PROCESSORS for system tests
if: matrix.build_type == 'system'
shell: bash
run: |
echo "PARALLEL_TEST_PROCESSORS=$(($(nproc) / 2))" >> $GITHUB_ENV
- name: Setup Specs
uses: ./.github/actions/test-setup
with:
uses_parallel_databases: ${{env.USES_PARALLEL_DATABASES}}
parallel_test_processors: ${{env.PARALLEL_TEST_PROCESSORS}}
build_type: ${{matrix.build_type}}
target: ${{matrix.target}}
browser: ${{matrix.browser}}
cpu_cores: ${{steps.cpu-info.outputs.cpu-cores}}
github_token: ${{secrets.GITHUB_TOKEN}}
- name: Core RSpec
if: matrix.build_type == 'backend' && matrix.target == 'core'
run: bin/turbo_rspec --use-runtime-info --verbose --format=documentation --profile=50
- name: Plugin RSpec
if: matrix.build_type == 'backend' && matrix.target == 'plugins'
run: bin/rake plugin:turbo_spec['*','--verbose --format=documentation --use-runtime-info --profile=50']
- name: Core QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'core'
run: QUNIT_WRITE_EXECUTION_FILE=1 bin/rake qunit:test
timeout-minutes: 30
- name: Plugin QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'plugins'
run: QUNIT_WRITE_EXECUTION_FILE=1 bin/rake plugin:qunit['*']
timeout-minutes: 30
- name: Theme QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'themes'
run: DISCOURSE_DEV_DB=discourse_test bin/rake themes:qunit_all_official
timeout-minutes: 10
- uses: actions/upload-artifact@v4
if: always() && matrix.build_type == 'frontend'
with:
name: ember-exam-execution-${{ matrix.target }}-${{ matrix.browser }}-frontend-${{ hashFiles('./app/assets/javascripts/discourse/test-execution-*.json') }}
path: ./app/assets/javascripts/discourse/test-execution-*.json
- name: Ember Build for System Tests
if: matrix.build_type == 'system'
run: bin/ember-cli --build
- name: Ensure latest minio binary installed for Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
run: bundle exec ruby script/install_minio_binaries.rb
- name: Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
env:
CHECKOUT_TIMEOUT: 10
run: RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error bin/turbo_rspec --use-runtime-info --profile=50 --verbose --format documentation spec/system
- name: Plugin System Tests
if: matrix.build_type == 'system' && matrix.target == 'plugins'
env:
CHECKOUT_TIMEOUT: 10
run: |
GLOBIGNORE="plugins/chat/*";
LOAD_PLUGINS=1 RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error bin/turbo_rspec --use-runtime-info --profile=50 --verbose --format documentation plugins/*/spec/system
shell: bash
timeout-minutes: 30
- name: Chat System Tests
if: matrix.build_type == 'system' && matrix.target == 'chat'
env:
CHECKOUT_TIMEOUT: 10
run: LOAD_PLUGINS=1 RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error bin/turbo_rspec --use-runtime-info --profile=50 --verbose --format documentation plugins/chat/spec/system
timeout-minutes: 30
- name: Theme System Tests
if: matrix.build_type == 'system' && matrix.target == 'themes'
env:
CHECKOUT_TIMEOUT: 10
run: |
RAILS_ENABLE_TEST_LOG=1 RAILS_TEST_LOG_LEVEL=error bin/turbo_rspec --profile=50 --verbose --format documentation tmp/themes/*/spec/system
shell: bash
timeout-minutes: 30
- name: Check for failed system test screenshots
id: check-failed-system-test-screenshots
if: always() && matrix.build_type == 'system'
run: |
if [ -d tmp/capybara ] && [ "$(ls -A tmp/capybara/)" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Upload failed system test screenshots
uses: actions/upload-artifact@v4
if: always() && steps.check-failed-system-test-screenshots.outputs.exists == 'true'
with:
name: failed-system-test-screenshots-${{ matrix.build_type }}-${{ matrix.target }}
path: tmp/capybara/failures_*.png
- name: Check for flaky tests report
id: check-flaky-spec-report
if: github.repository == 'discourse/discourse' && github.ref_name == 'main' && env.DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS == '1'
run: |
if [ -f tmp/turbo_rspec_flaky_tests.json ]; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Fetch Job ID
id: fetch-job-id
if: steps.check-flaky-spec-report.outputs.exists == 'true'
run: |
job_id=$(ruby script/get_github_workflow_run_job_id.rb ${{ github.run_id }} ${{ github.run_attempt }} '${{ matrix.target }} ${{ matrix.build_type }}${{ (matrix.target == 'core' && matrix.build_type == 'frontend' && format(' ({0})', matrix.browser)) || '' }}')
echo "job_id=$job_id" >> $GITHUB_OUTPUT
- name: Create flaky tests report artifact
if: steps.check-flaky-spec-report.outputs.exists == 'true'
run: cp tmp/turbo_rspec_flaky_tests.json tmp/turbo_rspec_flaky_tests-${{ matrix.build_type }}-${{ matrix.target }}-${{ steps.fetch-job-id.outputs.job_id }}.json
- name: Upload flaky tests report
uses: actions/upload-artifact@v4
if: steps.check-flaky-spec-report.outputs.exists == 'true'
with:
name: flaky-test-reports-${{ matrix.build_type }}-${{ matrix.target }}
path: tmp/turbo_rspec_flaky_tests-${{ matrix.build_type }}-${{ matrix.target }}-${{ steps.fetch-job-id.outputs.job_id }}.json
- name: Check Annotations
if: matrix.build_type == 'annotations'
run: |
bin/rake annotate:ensure_all_indexes
bin/annotate --models --model-dir app/models
if [ ! -z "$(git status --porcelain app/models/)" ]; then
echo "Core annotations are not up to date. To resolve, run:"
echo " bin/rake annotate:clean"
echo
echo "Or manually apply the diff printed below:"
echo "---------------------------------------------"
git -c color.ui=always diff app/models/
exit 1
fi
timeout-minutes: 30
- name: Save app state cache
shell: bash
run: |
CACHE_KEY="${{ runner.os }}-$(echo '${{ steps.cpu-info.outputs.cpu-cores }}' | sha256sum | cut -d' ' -f1)-$(echo '${{ hashFiles('.github/workflows/tests.yml') }}' | sha256sum | cut -d' ' -f1)-$(echo '${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}' | sha256sum | cut -d' ' -f1)-$(echo '${{ hashFiles('config/environments/test.rb') }}' | sha256sum | cut -d' ' -f1)-${{ env.USES_PARALLEL_DATABASES }}-${{ env.PARALLEL_TEST_PROCESSORS }}"
echo "Saving cache with key: $CACHE_KEY"
gh cache save tmp/app-cache --key "$CACHE_KEY"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Save turbo_rspec_runtime.log cache
if: matrix.build_type == 'backend' || matrix.build_type == 'system'
shell: bash
run: |
CACHE_KEY="rspec-runtime-${{ matrix.build_type }}-${{ matrix.target }}-${{ github.run_id }}"
echo "Saving cache with key: $CACHE_KEY"
gh cache save tmp/turbo_rspec_runtime.log --key "$CACHE_KEY"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
merge:
if: github.repository == 'discourse/discourse' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
needs: build
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: failed-system-test-screenshots
pattern: failed-system-test-screenshots-*
delete-merged: true
separate-directories: false
# Don't fail the job if there aren't any artifacts to merge.
continue-on-error: true
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: flaky-test-reports
pattern: flaky-test-reports-*
delete-merged: true
separate-directories: false
# Don't fail the job if there aren't any artifacts to merge.
continue-on-error: true