diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml new file mode 100644 index 0000000000..c01e25a804 --- /dev/null +++ b/.github/actions/run-tests/action.yml @@ -0,0 +1,99 @@ +# evennia/run-tests + +# Use this action to run the Evennia test suite after database setup. +# This action handles Python setup, dependency installation, evennia initialization, +# and test execution with optional coverage. + +name: Run Evennia tests +description: "Sets up Python, installs dependencies, initializes Evennia, and runs the test suite." + +inputs: + python-version: + description: "Python version to use for testing." + required: true + testing-db: + description: "Database type being tested (sqlite3, mysql, postgresql)." + required: true + coverage-test: + description: "Whether to run tests with coverage (true/false)." + required: false + default: "false" + needs-mysql-package: + description: "Whether to install mysqlclient package (true/false)." + required: false + default: "false" + needs-postgres-package: + description: "Whether to install psycopg2-binary package (true/false)." + required: false + default: "false" + +runs: + using: "composite" + + steps: + - name: Set up Python ${{ inputs.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python-version }} + cache: pip + cache-dependency-path: | + pyproject.toml + + - name: Install package dependencies + run: | + python -m pip install --upgrade pip + pip install wheel + if [ "${{ inputs.needs-postgres-package }}" == "true" ]; then + pip install psycopg2-binary==2.9.5 # req by postgresql + fi + if [ "${{ inputs.needs-mysql-package }}" == "true" ]; then + pip install mysqlclient + fi + pip install coveralls + pip install tblib + pip install . + pip install .[extra] + shell: bash + + - name: Initialize evennia + run: | + evennia --init testing_mygame + cp .github/workflows/${{ inputs.testing-db }}_settings.py testing_mygame/server/conf/settings.py + cd testing_mygame + evennia migrate + evennia collectstatic --noinput + shell: bash + + # For non-coverage tests, run them in parallel. + - name: Run test suite + if: ${{ inputs.coverage-test != 'true' }} + working-directory: testing_mygame + run: | + evennia test --settings=settings --keepdb --timing evennia + shell: bash + + # OBS - it's important to not run the coverage tests with --parallel, it messes up the coverage + # calculation! + - name: Run test suite with coverage + if: ${{ inputs.coverage-test == 'true' }} + working-directory: testing_mygame + run: | + coverage run --rcfile=../pyproject.toml ../bin/unix/evennia test --settings=settings --timing evennia + coverage combine + coverage xml + coverage --version + coverage report | grep TOTAL + shell: bash + + # we only want to run coverall once, so we only do it for the designated matrix combination(s) + # it's also not critical if pushing to either service fails (happens for PRs since env is not + # available outside of the evennia org) + - name: Send data to Coveralls + if: ${{ inputs.coverage-test == 'true' && github.ref == 'refs/heads/main' }} + continue-on-error: true + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + working-directory: testing_mygame + run: | + coveralls + shell: bash diff --git a/.github/actions/setup-database/action.yml b/.github/actions/setup-database/action.yml index 47a0020d64..f3c8598849 100644 --- a/.github/actions/setup-database/action.yml +++ b/.github/actions/setup-database/action.yml @@ -19,59 +19,39 @@ runs: using: "composite" steps: - - name: Set up PostgreSQL server - if: ${{ inputs.database == 'postgresql' }} - uses: harmon758/postgresql-action@v1 - with: - postgresql version: "13" - postgresql db: "evennia" - postgresql user: "evennia" - postgresql password: "password" - - - name: Wait for PostgreSQL to activate + - name: Wait for PostgreSQL to be ready if: ${{ inputs.database == 'postgresql' }} run: | - while ! pg_isready -h 127.0.0.1 -q >/dev/null 2>&1 - do + # Wait for PostgreSQL service container to be healthy + until pg_isready -h localhost -U evennia -d evennia; do sleep 1 echo -n . done - echo + echo "PostgreSQL is ready" shell: bash + env: + PGPASSWORD: password - - name: Set up MySQL server - if: ${{ inputs.database == 'mysql' }} - uses: mirromutth/mysql-action@v1.1 - with: - host port: 3306 - # character set server: "utf8mb4" - # collation server: "utf8mb4_unicode_ci" - character set server: "utf8" - collation server: "utf8_general_ci" - mysql database: "evennia" - mysql user: "evennia" - mysql password: "password" - mysql root password: root_password - - - name: Wait for MySQL to activate + - name: Wait for MySQL to be ready if: ${{ inputs.database == 'mysql' }} run: | - while ! mysqladmin ping -h 127.0.0.1 -u root -proot_password -s >/dev/null 2>&1 - do + # Wait for MySQL service container to be healthy + until mysqladmin ping -h 127.0.0.1 -u root -proot_password --silent; do sleep 1 echo -n . done - echo + echo "MySQL is ready" shell: bash - name: Set up MySQL Privileges if: ${{ inputs.database == 'mysql' }} run: | - cat <- + --health-cmd="mysqladmin ping -h localhost" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + --character-set-server=utf8mb4 + --collation-server=utf8mb4_unicode_ci steps: - uses: actions/checkout@v4 - - name: Set up database (${{ matrix.TESTING_DB }}) + - name: Install MySQL client + run: | + sudo apt-get update + sudo apt-get install -y default-mysql-client + timeout-minutes: 2 + + - name: Set up database (mysql) uses: ./.github/actions/setup-database with: - database: ${{ matrix.TESTING_DB }} + database: mysql timeout-minutes: 5 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - name: Run tests + uses: ./.github/actions/run-tests with: python-version: ${{ matrix.python-version }} - cache: pip - cache-dependency-path: | - pyproject.toml + testing-db: mysql + coverage-test: "false" + needs-postgres-package: "false" + needs-mysql-package: "true" - - name: Install package dependencies - run: | - python -m pip install --upgrade pip - pip install wheel - pip install psycopg2-binary==2.9.5 # req by postgresql - pip install mysqlclient - pip install coveralls - pip install tblib - pip install . - pip install .[extra] + test-postgresql: + name: Test (PostgreSQL) + runs-on: ubuntu-latest - - name: Initialize evennia - run: | - evennia --init testing_mygame - cp .github/workflows/${{ matrix.TESTING_DB }}_settings.py testing_mygame/server/conf/settings.py - cd testing_mygame - evennia migrate - evennia collectstatic --noinput + strategy: + fail-fast: false + matrix: + python-version: ["3.11", "3.12", "3.13"] - # For non-coverage tests, run them in parallel. - - name: Run test suite - if: ${{ ! matrix.coverage-test }} - working-directory: testing_mygame - run: | - evennia test ${{ env.UNIT_TEST_SETTINGS }} evennia + timeout-minutes: 35 - # OBS - it's important to not run the coverage tests with --parallel, it messes up the coverage - # calculation! - - name: Run test suite with coverage - if: ${{ matrix.coverage-test }} - working-directory: testing_mygame - run: | - coverage run --rcfile=../pyproject.toml ../bin/unix/evennia test ${{ env.COVERAGE_TEST_SETTINGS }} evennia - coverage combine - coverage xml - coverage --version - coverage report | grep TOTAL - - # we only want to run coverall once, so we only do it for the designated matrix combination(s) - # it's also not critical if pushing to either service fails (happens for PRs since env is not - # available outside of the evennia org) - - name: Send data to Coveralls - if: ${{ matrix.coverage-test && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }} - continue-on-error: true + services: + postgres: + image: postgres:13 env: - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + POSTGRES_DB: evennia + POSTGRES_USER: evennia + POSTGRES_PASSWORD: password + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval=10s + --health-timeout=5s + --health-retries=5 + + steps: + - uses: actions/checkout@v4 + + - name: Install PostgreSQL client run: | - cd testing_mygame - coveralls + sudo apt-get update + sudo apt-get install -y postgresql-client + timeout-minutes: 2 + + - name: Set up database (postgresql) + uses: ./.github/actions/setup-database + with: + database: postgresql + timeout-minutes: 5 + + - name: Run tests + uses: ./.github/actions/run-tests + with: + python-version: ${{ matrix.python-version }} + testing-db: postgresql + coverage-test: "false" + needs-postgres-package: "true" + needs-mysql-package: "false" deploy: name: Deploy Docker Image - needs: test + needs: [test-sqlite, test-mysql, test-postgresql] runs-on: ubuntu-latest - if: ${{ github.repository == 'evennia/evennia' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }} + if: ${{ github.repository == 'evennia/evennia' && github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v3 diff --git a/evennia/contrib/utils/random_string_generator/random_string_generator.py b/evennia/contrib/utils/random_string_generator/random_string_generator.py index 708064caf8..867600c328 100644 --- a/evennia/contrib/utils/random_string_generator/random_string_generator.py +++ b/evennia/contrib/utils/random_string_generator/random_string_generator.py @@ -1,4 +1,4 @@ -""" +r""" Pseudo-random generator and registry Evennia contribution - Vincent Le Goff 2017