discourse/.github/workflows/tests.yml
David Taylor a6b680f4fe
DEV: Fix GitHub CI permissions issues (#20069)
The `git` version in our discourse_test docker image was recently updated to include a permissions check before running any git commands. For this to pass, the owner of the discourse directory needs to match the user running any git commands.

Under GitHub actions, by default the working directory is created with uid=1000 as the owner. We run all our tests as `root`, so this mismatch causes git to raise the permissions error. We can't switch to run the entire workflow as the `discourse (uid=1000)` user because our discourse_test image is not configured to allow `discourse` access to postgres/redis directories. For now, this commit updates the working directory's owner to match the user running the workflow.
2023-01-30 15:39:43 +00:00

277 lines
9.2 KiB
YAML

name: Tests
on:
pull_request:
push:
branches:
- main
- beta
- stable
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 == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: ${{ matrix.target }} ${{ matrix.build_type }} ${{ matrix.ruby }}
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.2') && '-ruby-3.2.0' || '' }}
timeout-minutes: 20
env:
DISCOURSE_HOSTNAME: www.example.com
RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
RAILS_ENV: test
PGUSER: discourse
PGPASSWORD: discourse
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
CAPBYARA_DEFAULT_MAX_WAIT_TIME: 4
strategy:
fail-fast: false
matrix:
build_type: [backend, frontend, system, annotations]
target: [core, plugins]
ruby: ['3.1']
exclude:
- build_type: annotations
target: plugins
- build_type: frontend
target: core # Handled by core_frontend_tests job (below)
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Start redis
run: |
redis-server /etc/redis/redis.conf &
- name: Start Postgres
run: |
chown -R postgres /var/run/postgresql
sudo -E -u postgres script/start_test_db.rb
sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';"
- name: Bundler cache
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-gem-
- name: Setup gems
run: |
gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' Gemfile.lock)
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Yarn install
run: yarn install
- name: Checkout official plugins
if: matrix.target == 'plugins'
run: bin/rake plugin:install_all_official
- name: Pull compatible versions of plugins
if: matrix.target == 'plugins'
run: bin/rake plugin:pull_compatible_all
- name: Fetch app state cache
uses: actions/cache@v3
id: app-cache
with:
path: tmp/app-cache
key: >- # postgres version, hash of migrations, "parallel?"
${{ runner.os }}-
${{ hashFiles('.github/workflows/tests.yml') }}-
${{ matrix.postgres }}-
${{ hashFiles('db/**/*', 'plugins/**/db/**/*') }}-
${{ env.USES_PARALLEL_DATABASES }}
- name: Restore database from cache
if: steps.app-cache.outputs.cache-hit == 'true'
run: psql -f tmp/app-cache/cache.sql postgres
- name: Restore uploads from cache
if: steps.app-cache.outputs.cache-hit == 'true'
run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads
- name: Create and migrate database
if: steps.app-cache.outputs.cache-hit != 'true'
run: |
bin/rake db:create
bin/rake db:migrate
- name: Create and migrate parallel databases
if: >-
env.USES_PARALLEL_DATABASES == 'true' &&
steps.app-cache.outputs.cache-hit != 'true'
run: |
bin/rake parallel:create
bin/rake parallel:migrate
- name: Dump database for cache
if: steps.app-cache.outputs.cache-hit != 'true'
run: mkdir -p tmp/app-cache && pg_dumpall > tmp/app-cache/cache.sql
- name: Dump uploads for cache
if: steps.app-cache.outputs.cache-hit != 'true'
run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads
- name: Fetch turbo_rspec_runtime.log cache
uses: actions/cache@v3
id: test-runtime-cache
if: matrix.build_type == 'backend' && matrix.target == 'core'
with:
path: tmp/turbo_rspec_runtime.log
key: rspec-runtime-backend-core
- name: Core RSpec
if: matrix.build_type == 'backend' && matrix.target == 'core'
run: bin/turbo_rspec --verbose
- name: Plugin RSpec
if: matrix.build_type == 'backend' && matrix.target == 'plugins'
run: bin/rake plugin:turbo_spec
- name: Plugin QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'plugins'
run: QUNIT_PARALLEL=3 bin/rake plugin:qunit['*','1200000']
timeout-minutes: 30
- name: Ember Build for System Tests
if: matrix.build_type == 'system'
run: bin/ember-cli --build
- name: Setup Webdriver
if: matrix.build_type == 'system'
run: bin/rails runner "require 'webdrivers'; Webdrivers::Chromedriver.update"
- name: Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
run: PARALLEL_TEST_PROCESSORS=1 bin/turbo_rspec --verbose spec/system
- name: Plugin System Tests
if: matrix.build_type == 'system' && matrix.target == 'plugins'
run: LOAD_PLUGINS=1 PARALLEL_TEST_PROCESSORS=1 bin/turbo_rspec --verbose plugins/*/spec/system
- name: Upload failed system test screenshots
uses: actions/upload-artifact@v3
if: matrix.build_type == 'system' && failure()
with:
name: failed-system-test-screenshots
path: tmp/capybara/*.png
- 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
core_frontend_tests:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: core frontend (${{ matrix.browser }})
runs-on: ubuntu-20.04-8core
container:
image: discourse/discourse_test:slim-browsers
options: --user discourse
timeout-minutes: 35
strategy:
fail-fast: false
matrix:
browser: ["Chrome", "Firefox ESR", "Firefox Evergreen"]
env:
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
TESTEM_FIREFOX_PATH: ${{ (matrix.browser == 'Firefox Evergreen') && '/opt/firefox-evergreen/firefox' }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Yarn install
working-directory: ./app/assets/javascripts/discourse
run: yarn install
- name: Ember Build
working-directory: ./app/assets/javascripts/discourse
run: |
mkdir /tmp/emberbuild
yarn ember build --environment=test -o /tmp/emberbuild
- name: Core QUnit
working-directory: ./app/assets/javascripts/discourse
run: yarn ember exam --path /tmp/emberbuild --load-balance --parallel=5 --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random
timeout-minutes: 15
- uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: ember-exam-execution-${{matrix.browser}}
path: ./app/assets/javascripts/discourse/test-execution-*.json