# NOTE: Everything test in this file should be in `tools/test-all`. If there's a # reason not to run it there, it should be there as a comment # explaining why. name: Zulip CI on: [push, pull_request] defaults: run: shell: bash jobs: tests: strategy: fail-fast: false matrix: include: # This docker image was created by a generated Dockerfile at: # tools/ci/images/bionic/Dockerfile # Bionic ships with Python 3.6. - docker_image: zulip/ci:bionic name: Ubuntu 18.04 Bionic (Python 3.6, backend + frontend) os: bionic is_bionic: true include_frontend_tests: true # This docker image was created by a generated Dockerfile at: # tools/ci/images/focal/Dockerfile # Focal ships with Python 3.8.2. - docker_image: zulip/ci:focal name: Ubuntu 20.04 Focal (Python 3.8, backend) os: focal is_focal: true include_frontend_tests: false # This docker image was created by a generated Dockerfile at: # tools/ci/images/focal/Dockerfile # Bullseye ships with Python 3.9.2. - docker_image: zulip/ci:bullseye name: Debian 11 Bullseye (Python 3.9, backend) os: bullseye is_bullseye: true include_frontend_tests: false runs-on: ubuntu-latest name: ${{ matrix.name }} container: ${{ matrix.docker_image }} env: # GitHub Actions sets HOME to /github/home which causes # problem later in provison and frontend test that runs # tools/setup/postgresql-init-dev-db because of the .pgpass # location. PostgreSQL (psql) expects .pgpass to be at # /home/github/.pgpass and setting home to `/home/github/` # ensures it written there because we write it to ~/.pgpass. HOME: /home/github/ steps: - name: Add required permissions run: | # The checkout actions doesn't clone to ~/zulip or allow # us to use the path option to clone outside the current # /__w/zulip/zulip directory. Since this directory is owned # by root we need to change it's ownership to allow the # github user to clone the code here. # Note: /__w/ is a docker volume mounted to $GITHUB_WORKSPACE # which is /home/runner/work/. sudo chown -R github . # This is the GitHub Actions specific cache directory the # the current github user must be able to access for the # cache action to work. It is owned by root currently. sudo chmod -R 0777 /__w/_temp/ - uses: actions/checkout@v2 - name: Create cache directories run: | dirs=(/srv/zulip-{npm,venv,emoji}-cache) sudo mkdir -p "${dirs[@]}" sudo chown -R github "${dirs[@]}" - name: Restore node_modules cache uses: actions/cache@v2 with: path: /srv/zulip-npm-cache key: v1-yarn-deps-${{ matrix.os }}-${{ hashFiles('package.json') }}-${{ hashFiles('yarn.lock') }} restore-keys: v1-yarn-deps-${{ matrix.os }} - name: Restore python cache uses: actions/cache@v2 with: path: /srv/zulip-venv-cache key: v1-venv-${{ matrix.os }}-${{ hashFiles('requirements/dev.txt') }} restore-keys: v1-venv-${{ matrix.os }} - name: Restore emoji cache uses: actions/cache@v2 with: path: /srv/zulip-emoji-cache key: v1-emoji-${{ matrix.os }}-${{ hashFiles('tools/setup/emoji/emoji_map.json') }}-${{ hashFiles('tools/setup/emoji/build_emoji') }}-${{ hashFiles('tools/setup/emoji/emoji_setup_utils.py') }}-${{ hashFiles('tools/setup/emoji/emoji_names.py') }}-${{ hashFiles('package.json') }} restore-keys: v1-emoji-${{ matrix.os }} - name: Do Bionic hack if: ${{ matrix.is_bionic }} run: | # Temporary hack till `sudo service redis-server start` gets fixes in Bionic. See # https://chat.zulip.org/#narrow/stream/3-backend/topic/Ubuntu.20bionic.20CircleCI sudo sed -i '/^bind/s/bind.*/bind 0.0.0.0/' /etc/redis/redis.conf - name: Install dependencies run: | # This is the main setup job for the test suite ./tools/ci/setup-backend --skip-dev-db-build # Cleaning caches is mostly unnecessary in GitHub Actions, because # most builds don't get to write to the cache. # scripts/lib/clean-unused-caches --verbose --threshold 0 - name: Run tools test run: | source tools/ci/activate-venv ./tools/test-tools - name: Run backend lint run: | source tools/ci/activate-venv echo "Test suite is running under $(python --version)." ./tools/lint --groups=backend --skip=gitlint,mypy # gitlint disabled because flaky - name: Run frontend lint if: ${{ matrix.include_frontend_tests }} run: | source tools/ci/activate-venv ./tools/lint --groups=frontend --skip=gitlint # gitlint disabled because flaky - name: Run backend tests run: | source tools/ci/activate-venv ./tools/test-backend --coverage --include-webhooks --no-cov-cleanup --ban-console-output - name: Run mypy run: | source tools/ci/activate-venv # We run mypy after the backend tests so we get output from the # backend tests, which tend to uncover more serious problems, first. ./tools/run-mypy --version ./tools/run-mypy - name: Run miscellaneous tests run: | source tools/ci/activate-venv # Currently our compiled requirements files will differ for different python versions # so we will run test-locked-requirements only for Bionic. # ./tools/test-locked-requirements # ./tools/test-run-dev # https://github.com/zulip/zulip/pull/14233 # # This test has been persistently flaky at like 1% frequency, is slow, # and is for a very specific single feature, so we don't run it by default: # ./tools/test-queue-worker-reload ./tools/test-migrations ./tools/setup/optimize-svg --check ./tools/setup/generate_integration_bots_avatars.py --check-missing - name: Run documentation and api tests run: | source tools/ci/activate-venv # In CI, we only test links we control in test-documentation to avoid flakes ./tools/test-documentation --skip-external-links ./tools/test-help-documentation --skip-external-links ./tools/test-api - name: Run node tests if: ${{ matrix.include_frontend_tests }} run: | source tools/ci/activate-venv # Run the node tests first, since they're fast and deterministic ./tools/test-js-with-node --coverage - name: Check schemas if: ${{ matrix.include_frontend_tests }} run: | source tools/ci/activate-venv # Check that various schemas are consistent. (is fast) ./tools/check-schemas - name: Check capitalization of strings if: ${{ matrix.include_frontend_tests }} run: | source tools/ci/activate-venv ./manage.py makemessages --locale en PYTHONWARNINGS=ignore ./tools/check-capitalization --no-generate PYTHONWARNINGS=ignore ./tools/check-frontend-i18n --no-generate - name: Run puppeteer tests if: ${{ matrix.include_frontend_tests }} run: | source tools/ci/activate-venv ./tools/test-js-with-puppeteer - name: Check for untracked files run: | source tools/ci/activate-venv # This final check looks for untracked files that may have been # created by test-backend or provision. untracked="$(git ls-files --exclude-standard --others)" if [ -n "$untracked" ]; then printf >&2 "Error: untracked files:\n%s\n" "$untracked" exit 1 fi - name: Test locked requirements if: ${{ matrix.is_bionic }} run: | . /srv/zulip-py3-venv/bin/activate && \ ./tools/test-locked-requirements - name: Upload coverage reports # Only upload coverage when both frontend and backend # tests are ran. if: ${{ matrix.include_frontend_tests }} run: | # Codcov requires `.coverage` file to be stored in the # current working directory. mv ./var/.coverage ./.coverage . /srv/zulip-py3-venv/bin/activate || true pip install codecov && codecov || echo "Error in uploading coverage reports to codecov.io." - name: Store Puppeteer artifacts # Upload these on failure, as well if: ${{ always() && matrix.include_frontend_tests }} uses: actions/upload-artifact@v2 with: name: puppeteer path: ./var/puppeteer retention-days: 60 - name: Check development database build if: ${{ matrix.is_focal || matrix.is_bullseye }} run: ./tools/ci/setup-backend - name: Report status if: failure() env: ZULIP_BOT_KEY: ${{ secrets.ZULIP_BOT_KEY }} run: tools/ci/send-failure-message