diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 07a5ab57d2..9efeb82e16 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -48,35 +48,112 @@ jobs:
with:
extra_args: --all-files --color=always
+ build-wheel:
+ name: Build python wheel
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@v4
+ # update the version
+ - name: Get short commit SHA
+ run: |
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
+ SHA="${{ github.event.pull_request.head.sha }}"
+ else
+ SHA="${{ github.sha }}"
+ fi
+ echo "SHA=$(git rev-parse --short $SHA)" >> $GITHUB_ENV
+ - name: Get current version (MAJOR.MINOR.PATCH)
+ id: current-version
+ run: echo "current_version=$(grep -Po '(?<=__version__ = ")[\d\w.]+(?=")' rdmo/__init__.py)" >> $GITHUB_OUTPUT
+ - name: Generate new version (current version + SHA)
+ id: new-version
+ run: echo "new_version=${{ steps.current-version.outputs.current_version }}+$SHA" >> $GITHUB_OUTPUT
+ - name: Update version in rdmo/__init__.py
+ run: |
+ sed -i "s/__version__ = .*/__version__ = \"${{ steps.new-version.outputs.new_version }}\"/" rdmo/__init__.py
+ # build the webpack bundle
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 18
+ cache: npm
+ - run: npm install && npm run build:prod
+ # build the wheel
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+ cache: pip
+ - run: |
+ python -m pip install --upgrade pip pipx
+ pip --version
+ pipx --version
+ - name: Build the wheel
+ run: pipx run build
+ - name: Check the metadata
+ run: pipx run twine check --strict dist/*
+ - name: Install package from built wheel
+ run: python -m pip install --no-compile dist/rdmo*.whl # do not create __pycache__/*.pyc files
+ - name: Write info to step summary
+ run: |
+ {
+ echo -e "# ✓ Wheel successfully built (v${{ steps.new-version.outputs.new_version }})\n\n"
+ echo 'Information about installed wheel
'
+ echo -e "\n\`\`\`console"
+ echo "$ python -m pip show --files --verbose rdmo"
+ python -m pip show --files --verbose rdmo
+ echo -e "\`\`\`\n "
+ } >> $GITHUB_STEP_SUMMARY
+ - name: Upload wheel as artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: wheel
+ path: dist/rdmo*.whl
+ if-no-files-found: error
+ retention-days: 30
+
test:
+ name: "Test (Python: ${{ matrix.python-version }}, DB: ${{ matrix.db-backend }})" # TODO: add end-to-end to name
+ needs: build-wheel
runs-on: ubuntu-24.04
+ timeout-minutes: 45
strategy:
matrix:
python-version: ['3.8', '3.12']
db-backend: [mysql, postgres]
- name: "Test (Python: ${{ matrix.python-version }}, DB: ${{ matrix.db-backend }})"
- needs: lint
+ end-to-end: [false]
+ include:
+ - python-version: '3.12'
+ db-backend: postgres
+ end-to-end: true
steps:
+ - run: echo "true"
+ if: matrix.end-to-end
+ - run: echo "false"
+ if: matrix.end-to-end == false
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
+ - name: Download wheel
+ uses: actions/download-artifact@v4
+ with:
+ name: wheel
+ path: dist
- name: Install Dependencies
run: |
- sudo apt update
- sudo apt install --yes pandoc texlive-xetex librsvg2-bin
- python -m pip install --upgrade pip
+ sudo apt-get update && sudo apt-get install --yes pandoc texlive-xetex librsvg2-bin
pandoc --version
- - name: Install rdmo[mysql] and start mysql
+ python -m pip install --upgrade pip
+ python -m pip --version
+ - name: Install rdmo[mysql] from wheel and start mysql
run: |
- python -m pip install --editable .[ci,mysql]
+ python -m pip install "$(ls dist/*.whl)[ci,mysql]"
sudo systemctl start mysql.service
if: matrix.db-backend == 'mysql'
- - name: Install rdmo[postgres] and start postgresql
+ - name: Install rdmo[postgres] from wheel and start postgresql
run: |
- python -m pip install --editable .[ci,postgres]
+ python -m pip install "$(ls dist/*.whl)[ci,postgres]"
sudo systemctl start postgresql.service
pg_isready
sudo -u postgres psql --command="CREATE USER postgres_user PASSWORD 'postgres_password' CREATEDB"
@@ -89,33 +166,28 @@ jobs:
run: |
pytest rdmo/core/tests/test_package_status.py::test_package_json_and_pre_commit_versions_match \
--nomigrations --verbose
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
+ if: matrix.end-to-end
- name: Run Tests
run: |
pytest -p randomly -p no:cacheprovider --cov --reuse-db --numprocesses=auto --dist=loadscope
env:
GITHUB_DB_BACKEND: ${{ matrix.db-backend }}
+ if: matrix.end-to-end == false
- name: Upload coverage data to coveralls.io
uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63 # v2.3.0
with:
flag-name: '${{ matrix.db-backend }}: ${{ matrix.python-version }}'
parallel: true
+ if: matrix.end-to-end == false
# end-to-end tests
- - uses: actions/setup-node@v4
- with:
- node-version: 18
- cache: npm
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
- name: Install e2e tests dependencies
- run: |
- npm install
- npm run build:prod
- playwright install chromium
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
- - run: mkdir screenshots
+ run: python -m playwright install --with-deps chromium
+ if: matrix.end-to-end
- name: Run end-to-end tests
- run: pytest -p randomly -p no:cacheprovider --reuse-db --numprocesses=auto --dist=loadscope -m e2e --nomigrations
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
+ run: |
+ mkdir screenshots
+ pytest --nomigrations -m e2e
+ if: matrix.end-to-end
env:
DJANGO_DEBUG: True
GITHUB_DB_BACKEND: ${{ matrix.db-backend }}
@@ -123,7 +195,7 @@ jobs:
with:
name: screenshots
path: screenshots/*.png
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
+ if: matrix.end-to-end
coveralls:
name: Indicate completion to coveralls
@@ -136,63 +208,6 @@ jobs:
with:
parallel-finished: true
- build-wheel:
- name: Build python wheel
- needs: test
- runs-on: ubuntu-24.04
- steps:
- - uses: actions/checkout@v4
- - name: Get short commit SHA
- run: |
- if [ "${{ github.event_name }}" = "pull_request" ]; then
- SHA="${{ github.event.pull_request.head.sha }}"
- else
- SHA="${{ github.sha }}"
- fi
- echo "SHA=$(git rev-parse --short $SHA)" >> $GITHUB_ENV
- - name: Get current version (MAJOR.MINOR.PATCH)
- id: current-version
- run: echo "current_version=$(grep -Po '(?<=__version__ = ")[\d\w.]+(?=")' rdmo/__init__.py)" >> $GITHUB_OUTPUT
- - name: Generate new version (current version + SHA)
- id: new-version
- run: echo "new_version=${{ steps.current-version.outputs.current_version }}+$SHA" >> $GITHUB_OUTPUT
- - name: Update version in rdmo/__init__.py
- run: |
- sed -i "s/__version__ = .*/__version__ = \"${{ steps.new-version.outputs.new_version }}\"/" rdmo/__init__.py
- - uses: actions/setup-node@v4
- with:
- node-version: 18
- cache: npm
- - run: npm install
- - run: npm run build:prod
- - uses: actions/setup-python@v5
- with:
- python-version: '3.12'
- cache: pip
- - run: |
- python -m pip install --upgrade pip
- python -m pip install .[dev]
- - name: Build the wheel
- run: python -m build --wheel
- - name: Check metadata
- run: python -m twine check --strict dist/*
- - name: Install package from built wheel
- run: python -m pip install --force-reinstall dist/rdmo*.whl
- - name: Write info to step summary
- run: |
- echo -e "# ✓ Wheel successfully built (v${{ steps.new-version.outputs.new_version }})\n\n" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`console" >> $GITHUB_STEP_SUMMARY
- echo "$ python -m pip show rdmo" >> $GITHUB_STEP_SUMMARY
- python -m pip show rdmo >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- - name: Upload wheel as artifact
- uses: actions/upload-artifact@v4
- with:
- name: wheel
- path: dist/rdmo*.whl
- if-no-files-found: error
- retention-days: 30
-
dev-setup:
# Ref: structlog (MIT licensed)
name: "Test dev setup on ${{ matrix.os }}"
@@ -211,6 +226,7 @@ jobs:
dependencies:
name: Test installation of all dependencies
+ needs: build-wheel
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
@@ -218,12 +234,18 @@ jobs:
with:
python-version: "3.12"
cache: pip
+ - name: Download wheel
+ uses: actions/download-artifact@v4
+ with:
+ name: wheel
+ path: dist
- name: Install os requirements for python-ldap
- run: |
- sudo apt update
- sudo apt install --yes libldap2-dev libsasl2-dev
+ run: sudo apt-get update && sudo apt-get install --yes libldap2-dev libsasl2-dev
- run: python -m pip install --upgrade pip
- - run: python -m pip install .[allauth,ci,dev,gunicorn,ldap,mysql,postgres,pytest]
+ - name: Install rdmo wheel with all optional dependency groups
+ run: python -m pip install --no-compile "$(ls dist/*.whl)[allauth,ci,dev,gunicorn,ldap,mysql,postgres,pytest]"
+ - name: Verify installed packages have compatible dependencies
+ run: python -m pip check
- uses: actions/setup-node@v4
with:
node-version: 18
@@ -259,9 +281,9 @@ jobs:
if: always()
needs:
- lint
+ - build-wheel
- test
- coveralls
- - build-wheel
- dev-setup
- dependencies
runs-on: ubuntu-24.04
diff --git a/pyproject.toml b/pyproject.toml
index 44cae49a16..1f39b76036 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -207,6 +207,8 @@ filterwarnings = [
"ignore:'cgi' is deprecated and slated for removal in Python 3.13:DeprecationWarning",
"ignore:pkg_resources is deprecated as an API:DeprecationWarning",
+ "ignore:CoreAPI compatibility is deprecated and will be removed in DRF 3.17:rest_framework.RemovedInDRF317Warning",
+
# ignore warnings raised from within django itself
# django/core/files/storage/__init__.py
"ignore:django.core.files.storage.get_storage_class is deprecated:django.utils.deprecation.RemovedInDjango51Warning",
diff --git a/rdmo/management/tests/conftest.py b/rdmo/management/tests/conftest.py
index 79cbc2d4aa..ef25f965ab 100644
--- a/rdmo/management/tests/conftest.py
+++ b/rdmo/management/tests/conftest.py
@@ -1,7 +1,7 @@
import pytest
from django.core.management import call_command
-
+from django.conf import settings
from playwright.sync_api import BrowserType, Page, expect
from pytest_django.live_server_helper import LiveServer
@@ -18,32 +18,60 @@ def _e2e_tests_django_db_setup(django_db_setup, django_db_blocker, fixtures):
@pytest.fixture
-def base_url_page(live_server: LiveServer, browser: BrowserType) -> Page:
+def base_url_page(
+ django_user_model,
+ username,
+ live_server: LiveServer,
+ browser: BrowserType) -> Page:
"""Enable playwright to address URLs with base URL automatically prefixed."""
- context = browser.new_context(base_url=live_server.url)
- page = context.new_page()
+ # context = browser.new_context(base_url=live_server.url)
+ user = django_user_model.objects.get(username=username)
+ print(user)
+ page = browser.new_page()
yield page
- context.close()
+ # context.close()
-# helper function for logging in the user
-def login_user(page: Page, username: str, password: str) -> Page:
- page.goto("/account/login")
- page.get_by_label("Username").fill(username, timeout=5000)
- page.get_by_label("Password").fill(password)
- page.get_by_role("button", name="Login").click()
- page.goto("/management")
- return page
+# # helper function for logging in the user
+# def login_user(page: Page, username: str, password: str) -> Page:
+# page.goto("/account/login")
+# page.get_by_label("Username").fill(username, timeout=5000)
+# page.get_by_label("Password").fill(password)
+# page.get_by_role("button", name="Login").click()
+# page.goto("/management")
+# return page
-def logout_user(page: Page):
- page.goto("/account/logout")
- page.get_by_role("button", name="Logout").click()
- expect(page).to_have_url('/')
- return page
+# def logout_user(page: Page):
+# page.goto("/account/logout")
+# page.get_by_role("button", name="Logout").click()
+# expect(page).to_have_url('/')
+# return page
@pytest.fixture
-def logged_in_user(_e2e_tests_django_db_setup, base_url_page, username:str, password: str) -> Page:
+def logged_in_user(_e2e_tests_django_db_setup, django_user_model, base_url_page, client, username:str, password: str) -> Page:
"""Log in as admin user through Django login UI, returns logged in page for e2e tests."""
+
+ print()
+ user = django_user_model.objects.get(username=username)
+ print(user)
+ print(client)
+ client.force_login(user)
+ print(client.cookies)
+ session_cookie = client.cookies[settings.SESSION_COOKIE_NAME]
+ assert session_cookie
+ print(session_cookie)
+
+ # Inject the session Cookie to playwright browser:
+ cookie = {
+ 'name': session_cookie.key,
+ 'value': session_cookie.value,
+ # 'url': live_server_url,
+ }
+ print(cookie)
+
+ # page.context.add_cookies([cookie])
+
+
page = login_user(base_url_page, username, password)
yield page
logout_user(page)