From 7106c17311148ef2b35bdeafff040e86a3f02e2e Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 17 Sep 2024 08:46:18 -0400 Subject: [PATCH 01/34] refactor: execute integration tests outside LMS container --- action.yml | 159 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 50 deletions(-) diff --git a/action.yml b/action.yml index 76097f1..d453242 100644 --- a/action.yml +++ b/action.yml @@ -1,60 +1,119 @@ -name: Integration Test in Tutor -description: 'A Github action to test your plugin in Tutor (Open edX distribution)' +name: Open edX Plugin Integration Tests with Tutor +description: "A Github action to test your plugin in Tutor (Open edX distribution)" inputs: app_name: - description: 'Application name to test. E.g., eox-tenant.' + description: "Application name to test. E.g., eox-tenant." required: true tutor_version: - description: 'The tutor version matrix to use.' + description: "The tutor version matrix to use." required: true shell_file_to_run: - description: 'The path of the shell file to run the integration tests.' + description: "The path of the shell file to run the integration tests." + required: true + openedx_extra_pip_requeriments: + description: "Optional extra pip requirements to install in Open edX. E.g: 'package1==1.0 package2>=2.0'" + required: false + default: "" + python_version: + description: "The Python version to use for running the tests." + required: false + default: "3.11" + fixtures_file: + description: "Optional path to the plugin's fixtures file to load." required: false runs: - using: 'composite' + using: "composite" steps: - - name: Create a Virtual Environment - run: | - pip install virtualenv - virtualenv venv - shell: bash - - - name: Install Tutor - run: | - source venv/bin/activate - if [ "$INPUT_TUTOR_VERSION" = "nightly" ]; then - git clone --branch=nightly --depth=1 https://github.com/overhangio/tutor.git - chmod 777 tutor -R - pip install -e "./tutor[full]" - else - pip install "tutor$INPUT_TUTOR_VERSION" - fi - shell: bash - env: - INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} - - - name: Configure Tutor and Launch - run: | - source venv/bin/activate - TUTOR_ROOT="$(pwd)" tutor --version - TUTOR_ROOT="$(pwd)" tutor config save - TUTOR_ROOT="$(pwd)" tutor mounts add lms,cms,lms-worker,cms-worker:$(pwd)/$INPUT_APP:/openedx/$INPUT_APP - chmod 777 . -R - if [ "$INPUT_TUTOR_VERSION" = "nightly" ]; then - TUTOR_ROOT="$(pwd)" tutor images build openedx - fi - TUTOR_ROOT="$(pwd)" tutor local launch -I - shell: bash - env: - INPUT_APP: ${{ inputs.app_name }} - INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} - - - name: Run integration tests in lms - if: ${{ inputs.shell_file_to_run }} - run: | - source venv/bin/activate - TUTOR_ROOT="$(pwd)" tutor local run lms bash $INPUT_SHELL_FILE - shell: bash - env: - INPUT_SHELL_FILE: /openedx/${{ inputs.app_name }}/${{ inputs.shell_file_to_run }} + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python_version }} + + - name: Set Tutor environment variables + run: | + echo "LMS_HOST=local.edly.io" >> "$GITHUB_ENV" + echo "CMS_HOST=studio.local.edly.io" >> "$GITHUB_ENV" + echo "TUTOR_ROOT=$(pwd)" >> "$GITHUB_ENV" + echo "TUTOR_PLUGINS_ROOT=$(pwd)/plugins/" >> "$GITHUB_ENV" + shell: bash + + - name: Install and prepare Tutor + run: | + pip install "tutor${{ inputs.tutor_version }}" + tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST + chmod 777 . -R + tutor local launch -I + shell: bash + + - name: Configure Caddyfile and Open edX settings + run: | + mkdir -p plugins + cat << 'EOF' > plugins/patches.yml + + name: patches + patches: + caddyfile: | + {$default_site_port} { + import proxy "lms:8000" + } + openedx-cms-production-settings: | + ALLOWED_HOSTS = ["*"] + ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] + openedx-lms-production-settings: | + ALLOWED_HOSTS = ["*"] + ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] + EOF + tutor plugins enable patches + shell: bash + + - name: Install plugin and extra requirements + run: | + tutor local exec lms pip install ${{ inputs.app_name }} ${{ inputs.openedx_extra_pip_requeriments }} + tutor local exec cms pip install ${{ inputs.app_name }} ${{ inputs.openedx_extra_pip_requeriments }} + shell: bash + + - name: Run migrations + run: | + tutor local exec lms python manage.py lms migrate + tutor local exec cms python manage.py cms migrate + tutor local restart + shell: bash + + - name: Load inital data for the tests + if: ${{ inputs.fixtures_file }} + run: | + echo "Copying fixtures file to the LMS container" + tutor local exec lms mkdir -p /openedx/fixtures + tutor local dc cp ${{ inputs.fixtures_file }} lms:/openedx/fixtures/fixture.json + tutor local exec lms python manage.py lms loaddata /openedx/fixtures/fixture.json + shell: bash + + - name: Curl Heartbeat + run: | + echo "Curling LMS heartbeat" + status_code=$(curl -s -o /dev/null -w "%{http_code}" http://$LMS_HOST/heartbeat) + if [ "$status_code" -ne 200 ]; then + echo "Error: LMS Heartbeat endpoint returned status code $status_code" + exit 1 # Exit with non-zero code to fail the workflow + else + echo "Heartbeat endpoint returned status code 200" + fi + shell: bash + + - name: Run integration tests + if: ${{ inputs.shell_file_to_run }} + run: | + echo "Creating isolated venv to run the tests" + python -m venv .venv + if [ ! -d ".venv" ]; then + echo "Virtual environment creation failed" + exit 1 + fi + source .venv/bin/activate + chmod +x ./${{ inputs.shell_file_to_run }} + ./${{ inputs.shell_file_to_run }} + shell: bash From 2a6867482ca484726f103f8091f8ca0589c7edb7 Mon Sep 17 00:00:00 2001 From: magajh Date: Wed, 25 Sep 2024 08:03:06 -0400 Subject: [PATCH 02/34] feat: test Open edX imports --- action.yml | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index d453242..cf2fd82 100644 --- a/action.yml +++ b/action.yml @@ -21,12 +21,20 @@ inputs: fixtures_file: description: "Optional path to the plugin's fixtures file to load." required: false + openedx_imports_test_file_path: + description: "Path to the file that contains the test function for validating Open edX imports. This should be a Python file within your project." + required: false + openedx_imports_test_function_name: + description: "Name of the function in the specified file that executes the import tests for Open edX." + required: false runs: using: "composite" steps: - name: Checkout code uses: actions/checkout@v4 + with: + path: ${{ inputs.app_name }} - name: Set up Python uses: actions/setup-python@v5 @@ -70,10 +78,20 @@ runs: tutor plugins enable patches shell: bash - - name: Install plugin and extra requirements + - name: Install plugin as an editable package + if: ${{ inputs.fixtures_file }} + run: | + echo "Copying plugin to the LMS folder" + #tutor local exec lms mkdir -p /openedx/${{ inputs.app_name }} + tutor local dc cp "$GITHUB_WORKSPACE/${{ inputs.app_name }}" lms:/openedx/ + + tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ + shell: bash + + - name: Install extra requirements run: | - tutor local exec lms pip install ${{ inputs.app_name }} ${{ inputs.openedx_extra_pip_requeriments }} - tutor local exec cms pip install ${{ inputs.app_name }} ${{ inputs.openedx_extra_pip_requeriments }} + tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requeriments }} + tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requeriments }} shell: bash - name: Run migrations @@ -83,13 +101,43 @@ runs: tutor local restart shell: bash + - name: Test Open edX imports in plugin + if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} + run: | + echo "Running test function dynamically" + tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ + --env DJANGO_SETTINGS_MODULE=lms.envs.production \ + lms python -c " + import os + import django + import importlib.util + django.setup() + + # Path to the file where the test function is located + file_path = '/openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }}' + function_name = '${{ inputs.openedx_imports_test_function_name }}' + + # Load the module from the file path + spec = importlib.util.spec_from_file_location('test_module', file_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + # Get the function dynamically using getattr + func = getattr(module, function_name) + + # Execute the function + func() + " + shell: bash + - name: Load inital data for the tests if: ${{ inputs.fixtures_file }} run: | echo "Copying fixtures file to the LMS container" - tutor local exec lms mkdir -p /openedx/fixtures - tutor local dc cp ${{ inputs.fixtures_file }} lms:/openedx/fixtures/fixture.json - tutor local exec lms python manage.py lms loaddata /openedx/fixtures/fixture.json + #tutor local exec lms mkdir -p /openedx/fixtures + #tutor local dc cp ${{ inputs.fixtures_file }} lms:/openedx/fixtures/fixture.json + #tutor local exec lms python manage.py lms loaddata /openedx/fixtures/fixture.json + tutor local exec lms python manage.py lms loaddata /openedx/${{ inputs.app_name }}/${{ inputs.fixtures_file }} shell: bash - name: Curl Heartbeat @@ -114,6 +162,7 @@ runs: exit 1 fi source .venv/bin/activate + cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} shell: bash From f07b10b8ac4efbf77fb9cdb433f240dc31b4f11a Mon Sep 17 00:00:00 2001 From: magajh Date: Thu, 26 Sep 2024 21:23:11 -0400 Subject: [PATCH 03/34] fix: Test Open edX imports in plugin step --- action.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/action.yml b/action.yml index cf2fd82..27608f9 100644 --- a/action.yml +++ b/action.yml @@ -104,7 +104,7 @@ runs: - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} run: | - echo "Running test function dynamically" + echo "Running test for Open edX imports" tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ --env DJANGO_SETTINGS_MODULE=lms.envs.production \ lms python -c " @@ -113,7 +113,6 @@ runs: import importlib.util django.setup() - # Path to the file where the test function is located file_path = '/openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }}' function_name = '${{ inputs.openedx_imports_test_function_name }}' @@ -122,10 +121,7 @@ runs: module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) - # Get the function dynamically using getattr func = getattr(module, function_name) - - # Execute the function func() " shell: bash From 30ff6d30423ab9ba01bd7fa12c740f9abf41661a Mon Sep 17 00:00:00 2001 From: magajh Date: Thu, 26 Sep 2024 23:59:10 -0400 Subject: [PATCH 04/34] fix: remove venv check during Run integration tests step and remove unnecessary lines --- action.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/action.yml b/action.yml index 27608f9..33409f7 100644 --- a/action.yml +++ b/action.yml @@ -82,7 +82,6 @@ runs: if: ${{ inputs.fixtures_file }} run: | echo "Copying plugin to the LMS folder" - #tutor local exec lms mkdir -p /openedx/${{ inputs.app_name }} tutor local dc cp "$GITHUB_WORKSPACE/${{ inputs.app_name }}" lms:/openedx/ tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ @@ -130,9 +129,6 @@ runs: if: ${{ inputs.fixtures_file }} run: | echo "Copying fixtures file to the LMS container" - #tutor local exec lms mkdir -p /openedx/fixtures - #tutor local dc cp ${{ inputs.fixtures_file }} lms:/openedx/fixtures/fixture.json - #tutor local exec lms python manage.py lms loaddata /openedx/fixtures/fixture.json tutor local exec lms python manage.py lms loaddata /openedx/${{ inputs.app_name }}/${{ inputs.fixtures_file }} shell: bash @@ -153,10 +149,6 @@ runs: run: | echo "Creating isolated venv to run the tests" python -m venv .venv - if [ ! -d ".venv" ]; then - echo "Virtual environment creation failed" - exit 1 - fi source .venv/bin/activate cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} From 4d2b2db9534170fa3547c77b3054b7dc28753c5c Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 00:26:47 -0400 Subject: [PATCH 05/34] fix: use tutor mounts instead of copying files --- action.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 33409f7..9bca85d 100644 --- a/action.yml +++ b/action.yml @@ -78,11 +78,23 @@ runs: tutor plugins enable patches shell: bash + - name: Add mount for plugin + run: | + tutor mounts add "lms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" + tutor mounts add "cms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" + shell: bash + + - name: Restart Tutor services to apply mounts + run: | + tutor local stop + tutor local start -d + shell: bash + - name: Install plugin as an editable package if: ${{ inputs.fixtures_file }} run: | echo "Copying plugin to the LMS folder" - tutor local dc cp "$GITHUB_WORKSPACE/${{ inputs.app_name }}" lms:/openedx/ + #tutor local dc cp "$GITHUB_WORKSPACE/${{ inputs.app_name }}" lms:/openedx/ tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ shell: bash From 2d9fc92864a3d4387f19ca610d2773212e2e36c9 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 05:36:49 -0400 Subject: [PATCH 06/34] fix: use default python version --- action.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/action.yml b/action.yml index 9bca85d..230a88b 100644 --- a/action.yml +++ b/action.yml @@ -14,10 +14,6 @@ inputs: description: "Optional extra pip requirements to install in Open edX. E.g: 'package1==1.0 package2>=2.0'" required: false default: "" - python_version: - description: "The Python version to use for running the tests." - required: false - default: "3.11" fixtures_file: description: "Optional path to the plugin's fixtures file to load." required: false @@ -36,11 +32,6 @@ runs: with: path: ${{ inputs.app_name }} - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python_version }} - - name: Set Tutor environment variables run: | echo "LMS_HOST=local.edly.io" >> "$GITHUB_ENV" From 3524cdbc73533eb546a66e0ea81974634433d0a9 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 08:08:15 -0400 Subject: [PATCH 07/34] feat: import DEMO course and set ID in env --- action.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 230a88b..8304e44 100644 --- a/action.yml +++ b/action.yml @@ -84,9 +84,6 @@ runs: - name: Install plugin as an editable package if: ${{ inputs.fixtures_file }} run: | - echo "Copying plugin to the LMS folder" - #tutor local dc cp "$GITHUB_WORKSPACE/${{ inputs.app_name }}" lms:/openedx/ - tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ shell: bash @@ -103,6 +100,21 @@ runs: tutor local restart shell: bash + - name: Import Demo course + run: | + tutor local do importdemocourse + shell: bash + + - name: Set DEMO_COURSE_ID environment variable + run: | + #TODO: remove this once we stop supporting Tutor <18.0.0 + if [ "$INPUT_TUTOR_VERSION" = "<18.0.0" ]; then + echo "DEMO_COURSE_ID=course-v1:edX+DemoX+Demo_Course" >> $GITHUB_ENV + else + echo "DEMO_COURSE_ID=course-v1:OpenedX+DemoX+DemoCourse" >> $GITHUB_ENV + fi + shell: bash + - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} run: | @@ -153,6 +165,7 @@ runs: echo "Creating isolated venv to run the tests" python -m venv .venv source .venv/bin/activate + cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} From 595c5ca265210797c9dde07dea8e74fa60b125f5 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 08:28:46 -0400 Subject: [PATCH 08/34] feat: add support for tutor nightly --- action.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8304e44..ff829a3 100644 --- a/action.yml +++ b/action.yml @@ -42,11 +42,21 @@ runs: - name: Install and prepare Tutor run: | - pip install "tutor${{ inputs.tutor_version }}" + if [ "$INPUT_TUTOR_VERSION" = "nightly" ]; then + git clone --branch=nightly --depth=1 https://github.com/overhangio/tutor.git + pip install -e "./tutor[full]" + tutor config save + tutor images build openedx + else + pip install "tutor$INPUT_TUTOR_VERSION" + fi + tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST chmod 777 . -R tutor local launch -I shell: bash + env: + INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} - name: Configure Caddyfile and Open edX settings run: | From 835b020032da615f0c2be7649a91fdd070e942dd Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 08:55:26 -0400 Subject: [PATCH 09/34] fix: use different file for patches --- action.yml | 16 +--------------- patches.yml | 12 ++++++++++++ 2 files changed, 13 insertions(+), 15 deletions(-) create mode 100644 patches.yml diff --git a/action.yml b/action.yml index ff829a3..672459e 100644 --- a/action.yml +++ b/action.yml @@ -61,21 +61,7 @@ runs: - name: Configure Caddyfile and Open edX settings run: | mkdir -p plugins - cat << 'EOF' > plugins/patches.yml - - name: patches - patches: - caddyfile: | - {$default_site_port} { - import proxy "lms:8000" - } - openedx-cms-production-settings: | - ALLOWED_HOSTS = ["*"] - ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] - openedx-lms-production-settings: | - ALLOWED_HOSTS = ["*"] - ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] - EOF + cp $GITHUB_ACTION_PATH/patches.yml plugins/ tutor plugins enable patches shell: bash diff --git a/patches.yml b/patches.yml new file mode 100644 index 0000000..f7f23f2 --- /dev/null +++ b/patches.yml @@ -0,0 +1,12 @@ +name: patches +patches: + caddyfile: | + {$default_site_port} { + import proxy "lms:8000" + } + openedx-cms-production-settings: | + ALLOWED_HOSTS = ["*"] + ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] + openedx-lms-production-settings: | + ALLOWED_HOSTS = ["*"] + ALLOWED_AUTH_APPLICATIONS = ['cms-sso', 'cms-sso-dev'] From 8a20e98697f2167607b73ac735fe14b8bb805205 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 09:13:06 -0400 Subject: [PATCH 10/34] fix: add script to run open edx imports test --- action.yml | 22 +++++----------------- run_openedx_imports_test.py | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 run_openedx_imports_test.py diff --git a/action.yml b/action.yml index 672459e..52b89d2 100644 --- a/action.yml +++ b/action.yml @@ -114,26 +114,14 @@ runs: - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} run: | + cp $GITHUB_ACTION_PATH/run_openedx_imports_test.py $GITHUB_WORKSPACE/${{ inputs.app_name }}/ echo "Running test for Open edX imports" + tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ --env DJANGO_SETTINGS_MODULE=lms.envs.production \ - lms python -c " - import os - import django - import importlib.util - django.setup() - - file_path = '/openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }}' - function_name = '${{ inputs.openedx_imports_test_function_name }}' - - # Load the module from the file path - spec = importlib.util.spec_from_file_location('test_module', file_path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - - func = getattr(module, function_name) - func() - " + lms python /openedx/${{ inputs.app_name }}/run_openedx_imports_test.py \ + --test-file-path /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }} \ + --test-function-name '${{ inputs.openedx_imports_test_function_name }}' shell: bash - name: Load inital data for the tests diff --git a/run_openedx_imports_test.py b/run_openedx_imports_test.py new file mode 100644 index 0000000..60bf0e2 --- /dev/null +++ b/run_openedx_imports_test.py @@ -0,0 +1,27 @@ +import os +import django +import importlib.util +import argparse + +def main(): + parser = argparse.ArgumentParser(description='Run Open edX imports test.') + parser.add_argument('--test-file-path', required=True, help='Path to the test file.') + parser.add_argument('--test-function-name', required=True, help='Name of the test function to execute.') + + args = parser.parse_args() + + django.setup() + + file_path = args.test_file_path + function_name = args.test_function_name + + # Load the module from the file path + spec = importlib.util.spec_from_file_location('test_module', file_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + func = getattr(module, function_name) + func() + +if __name__ == '__main__': + main() From 01231ceacab1fb28bab6dee6cab919fb08c25e63 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 09:29:51 -0400 Subject: [PATCH 11/34] fix: typo and remove unnecessary conditional --- action.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/action.yml b/action.yml index 52b89d2..18be9f4 100644 --- a/action.yml +++ b/action.yml @@ -10,7 +10,7 @@ inputs: shell_file_to_run: description: "The path of the shell file to run the integration tests." required: true - openedx_extra_pip_requeriments: + openedx_extra_pip_requirements: description: "Optional extra pip requirements to install in Open edX. E.g: 'package1==1.0 package2>=2.0'" required: false default: "" @@ -78,15 +78,14 @@ runs: shell: bash - name: Install plugin as an editable package - if: ${{ inputs.fixtures_file }} run: | tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ shell: bash - name: Install extra requirements run: | - tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requeriments }} - tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requeriments }} + tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requirements }} + tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requirements }} shell: bash - name: Run migrations @@ -124,7 +123,7 @@ runs: --test-function-name '${{ inputs.openedx_imports_test_function_name }}' shell: bash - - name: Load inital data for the tests + - name: Load initial data for the tests if: ${{ inputs.fixtures_file }} run: | echo "Copying fixtures file to the LMS container" From 9fa255627394aa497b42f12ffa9bfb817c355aea Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 09:51:28 -0400 Subject: [PATCH 12/34] docs: update README --- README.md | 137 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c23f015..a105723 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# Integration Test in Tutor +# Open edX Plugin Integration Tests with Tutor -A Github action to test your Django Apps in Tutor (Open edX distribution). +A GitHub Action to test your Open edX plugin (Django app) in Tutor (Open edX distribution). This action automates the setup of a Tutor environment, installs your plugin, runs migrations, and executes your integration tests in an isolated environment. -## Example usage +## Example Usage -``` -name: Integration +```yaml +name: Integration Tests on: [pull_request] jobs: @@ -14,30 +14,139 @@ jobs: strategy: matrix: - tutor_version: ["<17.0.0", "==17.0.3", "<18.0.0"] + tutor_version: ["<17.0.0", "==17.0.3", "<18.0.0", "nightly"] steps: - - uses: actions/checkout@v4 + - name: Checkout Plugin Code + uses: actions/checkout@v4 with: - path: eox-hooks + path: my-plugin - - uses: eduNEXT/integration-test-in-tutor + - name: Run Integration Tests + uses: your-github-username/your-action-repo@v1 with: + app_name: "my-plugin" tutor_version: ${{ matrix.tutor_version }} - app_name: "eox-hooks" - shell_file_to_run: "eox_hooks/tests/tutor/integration.sh" + shell_file_to_run: "tests/integration.sh" + openedx_extra_pip_requirements: "package1==1.0 package2>=2.0" + fixtures_file: "fixtures/test_data.json" + openedx_imports_test_file_path: "tests/import_tests.py" + openedx_imports_test_function_name: "test_openedx_imports" ``` ## Inputs ### `app_name` -**Required** Application name to test. E.g., eox-tenant. +**Required** +The name of your plugin/application to test. This should match the directory name of your plugin. +*Example*: `"my-plugin"` ### `tutor_version` -**Required** The tutor version matrix to use. +**Required** +The version of Tutor to use. You can specify: + +- A specific version number (e.g., `"==17.0.3"`). +- A comparison operator with a version (e.g., `"<18.0.0"`). +- The string `"nightly"` to use the latest development version. + +**Special Note on Using `"nightly"`**: +When you specify `"nightly"` for `tutor_version`, the action will clone the latest code from Tutor's `nightly` branch. This allows you to test your plugin against the most recent changes in Tutor, which might not yet be released in a stable version. + +*Examples*: + +- `"==17.0.3"` +- `"<18.0.0"` +- `"nightly"` ### `shell_file_to_run` -(Optional) The path of the shell file to run the integration tests. +**Required** +The path to the shell script that runs your integration tests. This path is relative to your plugin directory. +*Example*: `"tests/integration.sh"` + +### `openedx_extra_pip_requirements` + +**Optional** +Extra pip requirements to install in Open edX. These are additional Python packages your plugin depends on. Provide them as a space-separated string. +*Default*: `""` (empty string) +*Example*: `"package1==1.0 package2>=2.0"` + +### `fixtures_file` + +**Optional** +The path to the fixtures file of your plugin to load initial data for the tests. This path is relative to your plugin directory. +*Example*: `"fixtures/test_data.json"` + +### `openedx_imports_test_file_path` + +**Optional** +The path to the Python file in your plugin that contains the test function for validating Open edX imports. This path is relative to your plugin directory. +*Example*: `"tests/import_tests.py"` + +### `openedx_imports_test_function_name` + +**Optional** +The name of the function in the specified file that executes the import tests for Open edX. +*Example*: `"test_openedx_imports"` + +## Description + +This GitHub Action automates the process of setting up a Tutor Open edX environment to test your plugin. It performs the following steps: + +1. **Checkout Plugin Code**: Checks out your plugin code into a directory specified by `app_name`. + +2. **Set Tutor Environment Variables**: Sets necessary environment variables for Tutor. + +3. **Install and Prepare Tutor**: Installs the specified version of Tutor and launches the Open edX platform. If `tutor_version` is set to `"nightly"`, the action clones the latest code from Tutor's `nightly` branch. + +4. **Configure Caddyfile and Open edX Settings**: Configures the Caddyfile and Open edX settings using `patches.yml`. + +5. **Add Mount for Plugin**: Mounts your plugin into the LMS and CMS containers. + +6. **Install Plugin as an Editable Package**: Installs your plugin in editable mode inside the LMS container. + +7. **Install Extra Requirements**: Installs any extra pip requirements specified in `openedx_extra_pip_requirements`. + +8. **Run Migrations**: Runs database migrations for both LMS and CMS and restarts Tutor services. + +9. **Import Demo Course**: Imports the Open edX demo course for testing purposes. + +10. **Set `DEMO_COURSE_ID` Environment Variable**: + Sets the `DEMO_COURSE_ID` environment variable based on the Tutor version. This variable allows you to refer to the demo course in your tests, which can be helpful when you need to interact with course content during testing. + + **Usage in Your Tests**: + In your test code, you can access the `DEMO_COURSE_ID` environment variable to get the identifier of the demo course. For example, in Python: + + ```python + import os + + DEMO_COURSE_ID = os.environ.get("DEMO_COURSE_ID") + # Use DEMO_COURSE_ID in your tests + ``` + + This ensures that your tests are compatible with different Tutor versions, as the demo course ID may vary between versions. + +11. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. + +12. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. + +13. **Check LMS Heartbeat**: Verifies that the LMS is running by hitting the heartbeat endpoint. + +14. **Run Integration Tests**: Creates a virtual environment and runs your integration tests using the specified shell script. + +## Notes + +- **Using the `"nightly"` Version of Tutor**: + The `"nightly"` option allows you to test your plugin against the latest development code of Tutor. This is useful for ensuring compatibility with upcoming features or changes. Be aware that the nightly version may be less stable and could introduce breaking changes. When using `"nightly"`, the action clones the Tutor repository from the `nightly` branch and builds the Docker images locally, which may increase the execution time of the workflow. + +- **Paths**: Ensure that the paths provided in the inputs are relative to your plugin directory. + +- **Optional Steps**: Steps involving `openedx_imports_test_file_path`, `openedx_imports_test_function_name`, and `fixtures_file` are optional and will only run if the corresponding inputs are provided. + +- **Tutor Versions**: Use the matrix strategy to test your plugin against multiple Tutor versions, including the nightly build. + +- **Dependencies**: If your integration tests require additional dependencies, specify them in `openedx_extra_pip_requirements` or handle them within your `shell_file_to_run`. + +- **Permissions**: Ensure your `shell_file_to_run` is executable. The action sets executable permissions before running it. From 36f50e798d0d1725d97048622ef0f709bc7a9ec4 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 09:55:14 -0400 Subject: [PATCH 13/34] fix: quality in python script --- run_openedx_imports_test.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/run_openedx_imports_test.py b/run_openedx_imports_test.py index 60bf0e2..c7e2a4c 100644 --- a/run_openedx_imports_test.py +++ b/run_openedx_imports_test.py @@ -1,21 +1,42 @@ +""" +This script runs a specified test function from a given test file to validate Open edX imports. + +Usage: + python run_openedx_imports_test.py --test-file-path --test-function-name + +The script dynamically loads a Python module from the specified file path and executes the given test function. +""" + +import argparse +import importlib.util import os + import django -import importlib.util -import argparse + def main(): + """ + Parses command-line arguments, sets up the Django environment, dynamically loads the specified test module, + and executes the given test function to validate Open edX imports. + + Args: + None + + Returns: + None + """ parser = argparse.ArgumentParser(description='Run Open edX imports test.') parser.add_argument('--test-file-path', required=True, help='Path to the test file.') parser.add_argument('--test-function-name', required=True, help='Name of the test function to execute.') args = parser.parse_args() + # Set up the Django environment to avoid AppNotReady errors django.setup() file_path = args.test_file_path function_name = args.test_function_name - # Load the module from the file path spec = importlib.util.spec_from_file_location('test_module', file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) @@ -23,5 +44,6 @@ def main(): func = getattr(module, function_name) func() + if __name__ == '__main__': main() From 46b9ca48b35a15e4121117f83f36921244a91566 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 10:07:07 -0400 Subject: [PATCH 14/34] fix: readme --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index a105723..488a994 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm Sets the `DEMO_COURSE_ID` environment variable based on the Tutor version. This variable allows you to refer to the demo course in your tests, which can be helpful when you need to interact with course content during testing. **Usage in Your Tests**: - In your test code, you can access the `DEMO_COURSE_ID` environment variable to get the identifier of the demo course. For example, in Python: + In your test code, you can access the `DEMO_COURSE_ID` environment variable to get the identifier of the demo course. For example: ```python import os @@ -126,8 +126,6 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm # Use DEMO_COURSE_ID in your tests ``` - This ensures that your tests are compatible with different Tutor versions, as the demo course ID may vary between versions. - 11. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. 12. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. From eb37a155437fb398ccbb989ec1e3160463638413 Mon Sep 17 00:00:00 2001 From: magajh Date: Fri, 27 Sep 2024 11:53:28 -0400 Subject: [PATCH 15/34] fix: change order of step set DEMO_COURSE_ID env variable --- README.md | 12 ++++++------ action.yml | 24 +++++++++++++----------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 488a994..579f9c0 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,12 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm 9. **Import Demo Course**: Imports the Open edX demo course for testing purposes. +10. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. + +11. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. + +12. **Check LMS Heartbeat**: Verifies that the LMS is running by hitting the heartbeat endpoint. + 10. **Set `DEMO_COURSE_ID` Environment Variable**: Sets the `DEMO_COURSE_ID` environment variable based on the Tutor version. This variable allows you to refer to the demo course in your tests, which can be helpful when you need to interact with course content during testing. @@ -126,12 +132,6 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm # Use DEMO_COURSE_ID in your tests ``` -11. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. - -12. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. - -13. **Check LMS Heartbeat**: Verifies that the LMS is running by hitting the heartbeat endpoint. - 14. **Run Integration Tests**: Creates a virtual environment and runs your integration tests using the specified shell script. ## Notes diff --git a/action.yml b/action.yml index 18be9f4..a5582b7 100644 --- a/action.yml +++ b/action.yml @@ -100,21 +100,11 @@ runs: tutor local do importdemocourse shell: bash - - name: Set DEMO_COURSE_ID environment variable - run: | - #TODO: remove this once we stop supporting Tutor <18.0.0 - if [ "$INPUT_TUTOR_VERSION" = "<18.0.0" ]; then - echo "DEMO_COURSE_ID=course-v1:edX+DemoX+Demo_Course" >> $GITHUB_ENV - else - echo "DEMO_COURSE_ID=course-v1:OpenedX+DemoX+DemoCourse" >> $GITHUB_ENV - fi - shell: bash - - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} run: | cp $GITHUB_ACTION_PATH/run_openedx_imports_test.py $GITHUB_WORKSPACE/${{ inputs.app_name }}/ - echo "Running test for Open edX imports" + echo "Running test for Open edX imports in plugin" tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ --env DJANGO_SETTINGS_MODULE=lms.envs.production \ @@ -142,6 +132,16 @@ runs: fi shell: bash + - name: Set DEMO_COURSE_ID environment variable + run: | + #TODO: remove this once we stop supporting Tutor <18.0.0 + if [ "${{ inputs.tutor_version }}" = "<18.0.0" ]; then + echo "DEMO_COURSE_ID=course-v1:edX+DemoX+Demo_Course" >> $GITHUB_ENV + else + echo "DEMO_COURSE_ID=course-v1:OpenedX+DemoX+DemoCourse" >> $GITHUB_ENV + fi + shell: bash + - name: Run integration tests if: ${{ inputs.shell_file_to_run }} run: | @@ -153,3 +153,5 @@ runs: chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} shell: bash + env: + DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} From c60d34ca201bb6171887ec247b5b73938f82ebc2 Mon Sep 17 00:00:00 2001 From: magajh Date: Sat, 28 Sep 2024 10:27:00 -0400 Subject: [PATCH 16/34] fix: support nightly --- action.yml | 61 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/action.yml b/action.yml index a5582b7..2f03c9d 100644 --- a/action.yml +++ b/action.yml @@ -1,8 +1,8 @@ name: Open edX Plugin Integration Tests with Tutor -description: "A Github action to test your plugin in Tutor (Open edX distribution)" +description: "A Github action to test your Open edX plugin in Tutor" inputs: app_name: - description: "Application name to test. E.g., eox-tenant." + description: "Open edX plugin or application name to test. E.g., eox-tenant." required: true tutor_version: description: "The tutor version matrix to use." @@ -32,6 +32,11 @@ runs: with: path: ${{ inputs.app_name }} + - name: Adjust permissions to execute Tutor commands + run: | + chmod 777 . -R + shell: bash + - name: Set Tutor environment variables run: | echo "LMS_HOST=local.edly.io" >> "$GITHUB_ENV" @@ -40,19 +45,26 @@ runs: echo "TUTOR_PLUGINS_ROOT=$(pwd)/plugins/" >> "$GITHUB_ENV" shell: bash + - name: Create virtualenvs + run: | + echo "Creating isolated venv for Tutor" + python -m venv .tutor_venv + echo "Creating isolated venv to run the integration tests" + python -m venv .tests_venv + shell: bash + - name: Install and prepare Tutor run: | + source .tutor_venv/bin/activate + if [ "$INPUT_TUTOR_VERSION" = "nightly" ]; then git clone --branch=nightly --depth=1 https://github.com/overhangio/tutor.git - pip install -e "./tutor[full]" - tutor config save - tutor images build openedx + pip install -e ./tutor else pip install "tutor$INPUT_TUTOR_VERSION" fi tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST - chmod 777 . -R tutor local launch -I shell: bash env: @@ -60,36 +72,49 @@ runs: - name: Configure Caddyfile and Open edX settings run: | + source .tutor_venv/bin/activate + mkdir -p plugins cp $GITHUB_ACTION_PATH/patches.yml plugins/ tutor plugins enable patches shell: bash - - name: Add mount for plugin + - name: Add mount for Open edX plugin run: | + source .tutor_venv/bin/activate + tutor mounts add "lms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" tutor mounts add "cms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" shell: bash - name: Restart Tutor services to apply mounts run: | - tutor local stop - tutor local start -d + source .tutor_venv/bin/activate + + tutor local stop lms cms + tutor local start -d lms cms shell: bash - - name: Install plugin as an editable package + - name: Install Open edX plugin as an editable package run: | + source .tutor_venv/bin/activate + tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ + tutor local exec cms pip install -e /openedx/${{ inputs.app_name }}/ shell: bash - name: Install extra requirements run: | + source .tutor_venv/bin/activate + tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requirements }} tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requirements }} shell: bash - - name: Run migrations + - name: Run migrations and restart services run: | + source .tutor_venv/bin/activate + tutor local exec lms python manage.py lms migrate tutor local exec cms python manage.py cms migrate tutor local restart @@ -97,12 +122,16 @@ runs: - name: Import Demo course run: | + source .tutor_venv/bin/activate + tutor local do importdemocourse shell: bash - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} run: | + source .tutor_venv/bin/activate + cp $GITHUB_ACTION_PATH/run_openedx_imports_test.py $GITHUB_WORKSPACE/${{ inputs.app_name }}/ echo "Running test for Open edX imports in plugin" @@ -116,6 +145,8 @@ runs: - name: Load initial data for the tests if: ${{ inputs.fixtures_file }} run: | + source .tutor_venv/bin/activate + echo "Copying fixtures file to the LMS container" tutor local exec lms python manage.py lms loaddata /openedx/${{ inputs.app_name }}/${{ inputs.fixtures_file }} shell: bash @@ -126,7 +157,7 @@ runs: status_code=$(curl -s -o /dev/null -w "%{http_code}" http://$LMS_HOST/heartbeat) if [ "$status_code" -ne 200 ]; then echo "Error: LMS Heartbeat endpoint returned status code $status_code" - exit 1 # Exit with non-zero code to fail the workflow + exit 1 else echo "Heartbeat endpoint returned status code 200" fi @@ -145,9 +176,7 @@ runs: - name: Run integration tests if: ${{ inputs.shell_file_to_run }} run: | - echo "Creating isolated venv to run the tests" - python -m venv .venv - source .venv/bin/activate + source .tests_venv/bin/activate cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} @@ -155,3 +184,5 @@ runs: shell: bash env: DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} + LMS_HOST: ${{ env.LMS_HOST }} + CMS_HOST: ${{ env.CMS_HOST }} From 89999f152330cbde98ee9afb9224b4f9807ba9d3 Mon Sep 17 00:00:00 2001 From: magajh Date: Mon, 30 Sep 2024 10:10:24 -0400 Subject: [PATCH 17/34] fix: update README --- README.md | 106 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 579f9c0..aeeba51 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Open edX Plugin Integration Tests with Tutor -A GitHub Action to test your Open edX plugin (Django app) in Tutor (Open edX distribution). This action automates the setup of a Tutor environment, installs your plugin, runs migrations, and executes your integration tests in an isolated environment. +A GitHub Action to test your Open edX plugin (Django app) within Tutor (Open edX distribution). This action automates the setup of a Tutor environment, installs your plugin, runs migrations, and executes your integration tests in an isolated environment. ## Example Usage @@ -17,20 +17,15 @@ jobs: tutor_version: ["<17.0.0", "==17.0.3", "<18.0.0", "nightly"] steps: - - name: Checkout Plugin Code - uses: actions/checkout@v4 - with: - path: my-plugin - - name: Run Integration Tests - uses: your-github-username/your-action-repo@v1 + uses: eduNEXT/integration-test-in-tutor@main with: - app_name: "my-plugin" + app_name: "eox-test" tutor_version: ${{ matrix.tutor_version }} shell_file_to_run: "tests/integration.sh" openedx_extra_pip_requirements: "package1==1.0 package2>=2.0" fixtures_file: "fixtures/test_data.json" - openedx_imports_test_file_path: "tests/import_tests.py" + openedx_imports_test_file_path: "tests/integration/import_tests.py" openedx_imports_test_function_name: "test_openedx_imports" ``` @@ -40,7 +35,7 @@ jobs: **Required** The name of your plugin/application to test. This should match the directory name of your plugin. -*Example*: `"my-plugin"` +*Example*: `"eox-tenant"` ### `tutor_version` @@ -51,9 +46,6 @@ The version of Tutor to use. You can specify: - A comparison operator with a version (e.g., `"<18.0.0"`). - The string `"nightly"` to use the latest development version. -**Special Note on Using `"nightly"`**: -When you specify `"nightly"` for `tutor_version`, the action will clone the latest code from Tutor's `nightly` branch. This allows you to test your plugin against the most recent changes in Tutor, which might not yet be released in a stable version. - *Examples*: - `"==17.0.3"` @@ -97,34 +89,44 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm 1. **Checkout Plugin Code**: Checks out your plugin code into a directory specified by `app_name`. -2. **Set Tutor Environment Variables**: Sets necessary environment variables for Tutor. +2. **Adjust Permissions**: Modifies file permissions to ensure that all files and directories are accessible, preventing permission-related errors during Tutor operations. -3. **Install and Prepare Tutor**: Installs the specified version of Tutor and launches the Open edX platform. If `tutor_version` is set to `"nightly"`, the action clones the latest code from Tutor's `nightly` branch. +3. **Set Tutor Environment Variables**: Sets necessary environment variables for Tutor. -4. **Configure Caddyfile and Open edX Settings**: Configures the Caddyfile and Open edX settings using `patches.yml`. +4. **Create Virtual Environments**: Creates isolated Python virtual environments for Tutor and running tests. -5. **Add Mount for Plugin**: Mounts your plugin into the LMS and CMS containers. +5. **Install and Prepare Tutor**: Installs the specified version of Tutor and launches the Open edX platform. + + - If `tutor_version` is set to `"nightly"`, clones the Tutor repository from the `nightly` branch. + - Saves Tutor configuration. + - Launches Tutor in interactive mode. -6. **Install Plugin as an Editable Package**: Installs your plugin in editable mode inside the LMS container. +6. **Configure Caddyfile and Open edX Settings**: Configures the web server and Open edX settings using Tutor plugins, to enable running integration tests from the plugin with multiple sites. -7. **Install Extra Requirements**: Installs any extra pip requirements specified in `openedx_extra_pip_requirements`. +7. **Add Mount for Plugin**: Mounts your plugin into the LMS and CMS containers. -8. **Run Migrations**: Runs database migrations for both LMS and CMS and restarts Tutor services. +8. **Restart Tutor Services**: Stops and starts Tutor services to apply the new mounts. -9. **Import Demo Course**: Imports the Open edX demo course for testing purposes. +9. **Install Open edX Plugin as an Editable Package**: Installs your plugin in editable mode inside both LMS and CMS containers. -10. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. +10. **Install Extra Requirements**: Installs any additional Python packages specified in `openedx_extra_pip_requirements`. -11. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. +11. **Run Migrations and Restart Services**: Applies database migrations and restarts Tutor services. -12. **Check LMS Heartbeat**: Verifies that the LMS is running by hitting the heartbeat endpoint. +12. **Import Demo Course**: Imports the Open edX demo course for testing purposes. -10. **Set `DEMO_COURSE_ID` Environment Variable**: - Sets the `DEMO_COURSE_ID` environment variable based on the Tutor version. This variable allows you to refer to the demo course in your tests, which can be helpful when you need to interact with course content during testing. +13. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. +14. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. + +15. **Check LMS Heartbeat**: Verifies that the LMS is running by hitting the heartbeat endpoint. + +16. **Set `DEMO_COURSE_ID` Environment Variable**: + Sets the `DEMO_COURSE_ID` environment variable based on the Tutor version. This variable allows you to refer to the demo course in your tests, which can be helpful when you need to interact with course content during testing. + **Usage in Your Tests**: In your test code, you can access the `DEMO_COURSE_ID` environment variable to get the identifier of the demo course. For example: - + ```python import os @@ -132,12 +134,12 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm # Use DEMO_COURSE_ID in your tests ``` -14. **Run Integration Tests**: Creates a virtual environment and runs your integration tests using the specified shell script. +17. **Run Integration Tests**: Activates the test virtual environment and runs your integration tests using the specified shell script. ## Notes - **Using the `"nightly"` Version of Tutor**: - The `"nightly"` option allows you to test your plugin against the latest development code of Tutor. This is useful for ensuring compatibility with upcoming features or changes. Be aware that the nightly version may be less stable and could introduce breaking changes. When using `"nightly"`, the action clones the Tutor repository from the `nightly` branch and builds the Docker images locally, which may increase the execution time of the workflow. + The `"nightly"` option allows you to test your plugin against the latest development code of Tutor. This is useful for ensuring compatibility with upcoming features or changes. Be aware that the nightly version may be less stable and could introduce breaking changes. When using `"nightly"`, the action clones the Tutor repository from the `nightly` branch and uses pre-built Tutor images that are published daily to Docker Hub. These images include the latest changes from the master branch at the time of the build. This approach significantly reduces the execution time and conserves the runner's resources by eliminating the overhead of building images during the workflow. - **Paths**: Ensure that the paths provided in the inputs are relative to your plugin directory. @@ -147,4 +149,48 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm - **Dependencies**: If your integration tests require additional dependencies, specify them in `openedx_extra_pip_requirements` or handle them within your `shell_file_to_run`. -- **Permissions**: Ensure your `shell_file_to_run` is executable. The action sets executable permissions before running it. +- **Maintaining Python Versions**: + + It's crucial to align the Python version in your virtual environments with the versions supported by the specified Tutor versions. Mismatched Python versions can lead to unexpected errors during Tutor operations and plugin integrations. + + If you need to specify a Python version different from the default provided by the runner, you can add a step before invoking the action to set the desired Python version. For example: + + ```yaml + - name: Set Up Python + uses: actions/setup-python@v4 + with: + python-version: '3.X' # Specify the required Python version here + + - name: Run Integration Tests + uses: eduNEXT/integration-test-in-tutor@mjh/run-integration-tests-outside-container + with: + ... + ``` + + If you're testing against multiple Tutor versions that require different Python versions, you can consider expanding your matrix to include Python versions. For example: + + ```yaml + strategy: + matrix: + include: + - tutor_version: '<18.0.0' + python_version: '3.8' + - tutor_version: '<19.0.0' + python_version: '3.9' + - tutor_version: 'nightly' + python_version: '3.10' + ``` + + Then, adjust the steps to use both `matrix.tutor_version` and `matrix.python_version`. + + ```yaml + steps: + - name: Set Up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} # Utilize matrix.python_version + ... + ``` + +## Contributing +Contributions are welcome! Please open an issue or submit a pull request for any enhancements or bug fixes. From 60b1640e31d9b443953a52d1c088469ecea00c75 Mon Sep 17 00:00:00 2001 From: Mariagabriela Jaimes Date: Mon, 30 Sep 2024 20:54:27 -0400 Subject: [PATCH 18/34] fix: recreate containers Co-authored-by: Bryann Valderrama <64033729+BryanttV@users.noreply.github.com> --- action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 2f03c9d..e802d67 100644 --- a/action.yml +++ b/action.yml @@ -87,11 +87,10 @@ runs: tutor mounts add "cms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" shell: bash - - name: Restart Tutor services to apply mounts + - name: Recreate containers to apply mounts run: | source .tutor_venv/bin/activate - tutor local stop lms cms tutor local start -d lms cms shell: bash From aa36a75e0c8015ab04f7b917618584f9bc65d0d7 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 09:33:32 -0400 Subject: [PATCH 19/34] fix: add default shell_file_to_run and restart only lms and cms serv --- action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index e802d67..c4d0662 100644 --- a/action.yml +++ b/action.yml @@ -10,6 +10,7 @@ inputs: shell_file_to_run: description: "The path of the shell file to run the integration tests." required: true + default: "scripts/execute_integration_tests.sh" openedx_extra_pip_requirements: description: "Optional extra pip requirements to install in Open edX. E.g: 'package1==1.0 package2>=2.0'" required: false @@ -116,7 +117,7 @@ runs: tutor local exec lms python manage.py lms migrate tutor local exec cms python manage.py cms migrate - tutor local restart + tutor local restart lms cms shell: bash - name: Import Demo course From d31d0e8b5893e98310bba11f492af1a7af98884b Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 09:36:52 -0400 Subject: [PATCH 20/34] fix: use default shell --- action.yml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/action.yml b/action.yml index c4d0662..4a6613e 100644 --- a/action.yml +++ b/action.yml @@ -27,6 +27,9 @@ inputs: runs: using: "composite" + defaults: + run: + shell: bash steps: - name: Checkout code uses: actions/checkout@v4 @@ -36,7 +39,6 @@ runs: - name: Adjust permissions to execute Tutor commands run: | chmod 777 . -R - shell: bash - name: Set Tutor environment variables run: | @@ -44,7 +46,6 @@ runs: echo "CMS_HOST=studio.local.edly.io" >> "$GITHUB_ENV" echo "TUTOR_ROOT=$(pwd)" >> "$GITHUB_ENV" echo "TUTOR_PLUGINS_ROOT=$(pwd)/plugins/" >> "$GITHUB_ENV" - shell: bash - name: Create virtualenvs run: | @@ -52,7 +53,6 @@ runs: python -m venv .tutor_venv echo "Creating isolated venv to run the integration tests" python -m venv .tests_venv - shell: bash - name: Install and prepare Tutor run: | @@ -67,7 +67,6 @@ runs: tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST tutor local launch -I - shell: bash env: INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} @@ -78,7 +77,6 @@ runs: mkdir -p plugins cp $GITHUB_ACTION_PATH/patches.yml plugins/ tutor plugins enable patches - shell: bash - name: Add mount for Open edX plugin run: | @@ -86,14 +84,12 @@ runs: tutor mounts add "lms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" tutor mounts add "cms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" - shell: bash - name: Recreate containers to apply mounts run: | source .tutor_venv/bin/activate tutor local start -d lms cms - shell: bash - name: Install Open edX plugin as an editable package run: | @@ -101,7 +97,6 @@ runs: tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ tutor local exec cms pip install -e /openedx/${{ inputs.app_name }}/ - shell: bash - name: Install extra requirements run: | @@ -109,7 +104,6 @@ runs: tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requirements }} tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requirements }} - shell: bash - name: Run migrations and restart services run: | @@ -118,14 +112,12 @@ runs: tutor local exec lms python manage.py lms migrate tutor local exec cms python manage.py cms migrate tutor local restart lms cms - shell: bash - name: Import Demo course run: | source .tutor_venv/bin/activate tutor local do importdemocourse - shell: bash - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} @@ -140,7 +132,6 @@ runs: lms python /openedx/${{ inputs.app_name }}/run_openedx_imports_test.py \ --test-file-path /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }} \ --test-function-name '${{ inputs.openedx_imports_test_function_name }}' - shell: bash - name: Load initial data for the tests if: ${{ inputs.fixtures_file }} @@ -149,7 +140,6 @@ runs: echo "Copying fixtures file to the LMS container" tutor local exec lms python manage.py lms loaddata /openedx/${{ inputs.app_name }}/${{ inputs.fixtures_file }} - shell: bash - name: Curl Heartbeat run: | @@ -161,7 +151,6 @@ runs: else echo "Heartbeat endpoint returned status code 200" fi - shell: bash - name: Set DEMO_COURSE_ID environment variable run: | @@ -171,7 +160,6 @@ runs: else echo "DEMO_COURSE_ID=course-v1:OpenedX+DemoX+DemoCourse" >> $GITHUB_ENV fi - shell: bash - name: Run integration tests if: ${{ inputs.shell_file_to_run }} @@ -181,7 +169,6 @@ runs: cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} - shell: bash env: DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} LMS_HOST: ${{ env.LMS_HOST }} From a55d2a1192fdb185a9c21e3ba855d98f46deea07 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 09:45:44 -0400 Subject: [PATCH 21/34] fix: move env in step --- action.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index 4a6613e..ac149e7 100644 --- a/action.yml +++ b/action.yml @@ -55,6 +55,8 @@ runs: python -m venv .tests_venv - name: Install and prepare Tutor + env: + INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} run: | source .tutor_venv/bin/activate @@ -67,8 +69,6 @@ runs: tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST tutor local launch -I - env: - INPUT_TUTOR_VERSION: ${{ inputs.tutor_version }} - name: Configure Caddyfile and Open edX settings run: | @@ -163,13 +163,13 @@ runs: - name: Run integration tests if: ${{ inputs.shell_file_to_run }} + env: + DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} + LMS_HOST: ${{ env.LMS_HOST }} + CMS_HOST: ${{ env.CMS_HOST }} run: | source .tests_venv/bin/activate cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} - env: - DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} - LMS_HOST: ${{ env.LMS_HOST }} - CMS_HOST: ${{ env.CMS_HOST }} From 9ec1377d2d184f2d0bd08afe6369bf480a8763c0 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 09:54:32 -0400 Subject: [PATCH 22/34] fix: use env var in Test Open edX imports in plugin step --- action.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index ac149e7..d5e9557 100644 --- a/action.yml +++ b/action.yml @@ -121,6 +121,9 @@ runs: - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} + env: + SCRIPT: /openedx/${{ inputs.app_name }}/run_openedx_imports_test.py + OPENEDX_IMPORTS_TEST_FILE_PATH: /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }} run: | source .tutor_venv/bin/activate @@ -129,8 +132,8 @@ runs: tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ --env DJANGO_SETTINGS_MODULE=lms.envs.production \ - lms python /openedx/${{ inputs.app_name }}/run_openedx_imports_test.py \ - --test-file-path /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }} \ + lms python $SCRIPT \ + --test-file-path $OPENEDX_IMPORTS_TEST_FILE_PATH \ --test-function-name '${{ inputs.openedx_imports_test_function_name }}' - name: Load initial data for the tests From da7bad800dcabc264d40012c49faefa81a3eb5d9 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 09:56:40 -0400 Subject: [PATCH 23/34] fix: readme --- README.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index aeeba51..5cbd2f5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ jobs: strategy: matrix: - tutor_version: ["<17.0.0", "==17.0.3", "<18.0.0", "nightly"] + tutor_version: ["<18.0.0", "==18.0.3", "<19.0.0", "nightly"] steps: - name: Run Integration Tests @@ -40,22 +40,20 @@ The name of your plugin/application to test. This should match the directory nam ### `tutor_version` **Required** -The version of Tutor to use. You can specify: +The version of Tutor where you want to run the integration tests. You can specify: -- A specific version number (e.g., `"==17.0.3"`). +- A specific version number (e.g., `"==18.0.3"`). - A comparison operator with a version (e.g., `"<18.0.0"`). - The string `"nightly"` to use the latest development version. -*Examples*: - -- `"==17.0.3"` -- `"<18.0.0"` -- `"nightly"` +> **Important:** +> This action is officially supported and tested with Tutor versions corresponding to the current and immediate previous Open edX releases, as well as the nightly build. Using other Tutor versions is not guaranteed to be supported. ### `shell_file_to_run` -**Required** -The path to the shell script that runs your integration tests. This path is relative to your plugin directory. +**Optional** +The path to the shell script that runs your integration tests. This path is relative to your plugin directory. +*Default*: `"scripts/execute_integration_tests.sh"` *Example*: `"tests/integration.sh"` ### `openedx_extra_pip_requirements` @@ -93,7 +91,7 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm 3. **Set Tutor Environment Variables**: Sets necessary environment variables for Tutor. -4. **Create Virtual Environments**: Creates isolated Python virtual environments for Tutor and running tests. +4. **Create Virtual Environments**: Creates isolated Python virtual environments for installing Tutor and for running the integration tests. 5. **Install and Prepare Tutor**: Installs the specified version of Tutor and launches the Open edX platform. From 536e492334f6539ceb46a3adcc6287d6fedbbec8 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 10:01:25 -0400 Subject: [PATCH 24/34] fix: remove unnecessary vars in last step --- action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/action.yml b/action.yml index d5e9557..602f60c 100644 --- a/action.yml +++ b/action.yml @@ -168,8 +168,6 @@ runs: if: ${{ inputs.shell_file_to_run }} env: DEMO_COURSE_ID: ${{ env.DEMO_COURSE_ID }} - LMS_HOST: ${{ env.LMS_HOST }} - CMS_HOST: ${{ env.CMS_HOST }} run: | source .tests_venv/bin/activate From e5d083699ee00b0cff3078769a0f4ce1f7c22348 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 10:27:57 -0400 Subject: [PATCH 25/34] revert: use default shell --- action.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 602f60c..cd98577 100644 --- a/action.yml +++ b/action.yml @@ -27,9 +27,6 @@ inputs: runs: using: "composite" - defaults: - run: - shell: bash steps: - name: Checkout code uses: actions/checkout@v4 @@ -39,6 +36,7 @@ runs: - name: Adjust permissions to execute Tutor commands run: | chmod 777 . -R + shell: bash - name: Set Tutor environment variables run: | @@ -46,6 +44,7 @@ runs: echo "CMS_HOST=studio.local.edly.io" >> "$GITHUB_ENV" echo "TUTOR_ROOT=$(pwd)" >> "$GITHUB_ENV" echo "TUTOR_PLUGINS_ROOT=$(pwd)/plugins/" >> "$GITHUB_ENV" + shell: bash - name: Create virtualenvs run: | @@ -53,6 +52,7 @@ runs: python -m venv .tutor_venv echo "Creating isolated venv to run the integration tests" python -m venv .tests_venv + shell: bash - name: Install and prepare Tutor env: @@ -69,6 +69,7 @@ runs: tutor config save --set LMS_HOST=$LMS_HOST --set CMS_HOST=$CMS_HOST tutor local launch -I + shell: bash - name: Configure Caddyfile and Open edX settings run: | @@ -77,6 +78,7 @@ runs: mkdir -p plugins cp $GITHUB_ACTION_PATH/patches.yml plugins/ tutor plugins enable patches + shell: bash - name: Add mount for Open edX plugin run: | @@ -84,12 +86,14 @@ runs: tutor mounts add "lms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" tutor mounts add "cms:$GITHUB_WORKSPACE/${{ inputs.app_name }}:/openedx/${{ inputs.app_name }}" + shell: bash - name: Recreate containers to apply mounts run: | source .tutor_venv/bin/activate tutor local start -d lms cms + shell: bash - name: Install Open edX plugin as an editable package run: | @@ -97,6 +101,7 @@ runs: tutor local exec lms pip install -e /openedx/${{ inputs.app_name }}/ tutor local exec cms pip install -e /openedx/${{ inputs.app_name }}/ + shell: bash - name: Install extra requirements run: | @@ -104,6 +109,7 @@ runs: tutor local exec lms pip install ${{ inputs.openedx_extra_pip_requirements }} tutor local exec cms pip install ${{ inputs.openedx_extra_pip_requirements }} + shell: bash - name: Run migrations and restart services run: | @@ -112,12 +118,14 @@ runs: tutor local exec lms python manage.py lms migrate tutor local exec cms python manage.py cms migrate tutor local restart lms cms + shell: bash - name: Import Demo course run: | source .tutor_venv/bin/activate tutor local do importdemocourse + shell: bash - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} @@ -135,6 +143,7 @@ runs: lms python $SCRIPT \ --test-file-path $OPENEDX_IMPORTS_TEST_FILE_PATH \ --test-function-name '${{ inputs.openedx_imports_test_function_name }}' + shell: bash - name: Load initial data for the tests if: ${{ inputs.fixtures_file }} @@ -143,6 +152,7 @@ runs: echo "Copying fixtures file to the LMS container" tutor local exec lms python manage.py lms loaddata /openedx/${{ inputs.app_name }}/${{ inputs.fixtures_file }} + shell: bash - name: Curl Heartbeat run: | @@ -154,6 +164,7 @@ runs: else echo "Heartbeat endpoint returned status code 200" fi + shell: bash - name: Set DEMO_COURSE_ID environment variable run: | @@ -163,6 +174,7 @@ runs: else echo "DEMO_COURSE_ID=course-v1:OpenedX+DemoX+DemoCourse" >> $GITHUB_ENV fi + shell: bash - name: Run integration tests if: ${{ inputs.shell_file_to_run }} @@ -174,3 +186,4 @@ runs: cd ${{ inputs.app_name }} chmod +x ./${{ inputs.shell_file_to_run }} ./${{ inputs.shell_file_to_run }} + shell: bash From 3cb8882e3fa058e944d8be898ccc4af7a47f8de0 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 10:35:57 -0400 Subject: [PATCH 26/34] test: set env vars --- action.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index cd98577..b41f8fb 100644 --- a/action.yml +++ b/action.yml @@ -40,10 +40,13 @@ runs: - name: Set Tutor environment variables run: | - echo "LMS_HOST=local.edly.io" >> "$GITHUB_ENV" - echo "CMS_HOST=studio.local.edly.io" >> "$GITHUB_ENV" - echo "TUTOR_ROOT=$(pwd)" >> "$GITHUB_ENV" - echo "TUTOR_PLUGINS_ROOT=$(pwd)/plugins/" >> "$GITHUB_ENV" + { + LMS_HOST=local.edly.io + CMS_HOST=studio.local.edly.io + TUTOR_ROOT=$(pwd) + TUTOR_PLUGINS_ROOT=$(pwd)/plugins/ + echo EOF + } >> "$GITHUB_ENV" shell: bash - name: Create virtualenvs From 839bffaf3eedf2bf3364188f848e7a0ab26e9e53 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 10:37:49 -0400 Subject: [PATCH 27/34] fix: use heredoc to set tutor vars --- action.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index b41f8fb..4f4fe7d 100644 --- a/action.yml +++ b/action.yml @@ -40,13 +40,12 @@ runs: - name: Set Tutor environment variables run: | - { - LMS_HOST=local.edly.io - CMS_HOST=studio.local.edly.io - TUTOR_ROOT=$(pwd) - TUTOR_PLUGINS_ROOT=$(pwd)/plugins/ - echo EOF - } >> "$GITHUB_ENV" + cat <> "$GITHUB_ENV" + LMS_HOST=local.edly.io + CMS_HOST=studio.local.edly.io + TUTOR_ROOT=$(pwd) + TUTOR_PLUGINS_ROOT=$(pwd)/plugins/ + EOF shell: bash - name: Create virtualenvs From 0e779846f39c6a350311d987a3bb720706666d8c Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 13:57:31 -0400 Subject: [PATCH 28/34] revert: start just LMS anc CMS services --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 4f4fe7d..94c5679 100644 --- a/action.yml +++ b/action.yml @@ -119,7 +119,7 @@ runs: tutor local exec lms python manage.py lms migrate tutor local exec cms python manage.py cms migrate - tutor local restart lms cms + tutor local restart shell: bash - name: Import Demo course From 4f1f1314a5decb6b0336e612ae5a368c65554459 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 14:07:06 -0400 Subject: [PATCH 29/34] docs: change description title for overview in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cbd2f5..ebb290f 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ The path to the Python file in your plugin that contains the test function for v The name of the function in the specified file that executes the import tests for Open edX. *Example*: `"test_openedx_imports"` -## Description +## Overview This GitHub Action automates the process of setting up a Tutor Open edX environment to test your plugin. It performs the following steps: From 77c39fa9313249cf974a4e3674dbd08453cdd604 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 14:31:11 -0400 Subject: [PATCH 30/34] test: remove Python path --- action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 94c5679..fe16c61 100644 --- a/action.yml +++ b/action.yml @@ -140,8 +140,7 @@ runs: cp $GITHUB_ACTION_PATH/run_openedx_imports_test.py $GITHUB_WORKSPACE/${{ inputs.app_name }}/ echo "Running test for Open edX imports in plugin" - tutor local exec --env PYTHONPATH=/openedx/${{ inputs.app_name }} \ - --env DJANGO_SETTINGS_MODULE=lms.envs.production \ + tutor local exec --env DJANGO_SETTINGS_MODULE=lms.envs.production \ lms python $SCRIPT \ --test-file-path $OPENEDX_IMPORTS_TEST_FILE_PATH \ --test-function-name '${{ inputs.openedx_imports_test_function_name }}' From 0dd8832babc2b55b1ced26eab4c61331535d338c Mon Sep 17 00:00:00 2001 From: Mariagabriela Jaimes Date: Tue, 1 Oct 2024 16:15:28 -0400 Subject: [PATCH 31/34] Update README.md Co-authored-by: Bryann Valderrama <64033729+BryanttV@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebb290f..36d0bf4 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ The version of Tutor where you want to run the integration tests. You can specif - A comparison operator with a version (e.g., `"<18.0.0"`). - The string `"nightly"` to use the latest development version. -> **Important:** +> [!IMPORTANT] > This action is officially supported and tested with Tutor versions corresponding to the current and immediate previous Open edX releases, as well as the nightly build. Using other Tutor versions is not guaranteed to be supported. ### `shell_file_to_run` From aba7551aa1af410cde11dd4cc3aa92dc88bd3e56 Mon Sep 17 00:00:00 2001 From: magajh Date: Tue, 1 Oct 2024 16:26:45 -0400 Subject: [PATCH 32/34] docs: use unorderd lists in readme --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 36d0bf4..82f3ee8 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,16 @@ jobs: **Required** The name of your plugin/application to test. This should match the directory name of your plugin. -*Example*: `"eox-tenant"` +* *Example*: `"eox-tenant"` ### `tutor_version` **Required** The version of Tutor where you want to run the integration tests. You can specify: -- A specific version number (e.g., `"==18.0.3"`). -- A comparison operator with a version (e.g., `"<18.0.0"`). -- The string `"nightly"` to use the latest development version. +* A specific version number (e.g., `"==18.0.3"`). +* A comparison operator with a version (e.g., `"<18.0.0"`). +* The string `"nightly"` to use the latest development version. > [!IMPORTANT] > This action is officially supported and tested with Tutor versions corresponding to the current and immediate previous Open edX releases, as well as the nightly build. Using other Tutor versions is not guaranteed to be supported. @@ -53,33 +53,33 @@ The version of Tutor where you want to run the integration tests. You can specif **Optional** The path to the shell script that runs your integration tests. This path is relative to your plugin directory. -*Default*: `"scripts/execute_integration_tests.sh"` -*Example*: `"tests/integration.sh"` +* *Default*: `"scripts/execute_integration_tests.sh"` +* *Example*: `"tests/integration.sh"` ### `openedx_extra_pip_requirements` **Optional** Extra pip requirements to install in Open edX. These are additional Python packages your plugin depends on. Provide them as a space-separated string. -*Default*: `""` (empty string) -*Example*: `"package1==1.0 package2>=2.0"` +* *Default*: `""` (empty string) +* *Example*: `"package1==1.0 package2>=2.0"` ### `fixtures_file` **Optional** The path to the fixtures file of your plugin to load initial data for the tests. This path is relative to your plugin directory. -*Example*: `"fixtures/test_data.json"` +* *Example*: `"fixtures/test_data.json"` ### `openedx_imports_test_file_path` **Optional** The path to the Python file in your plugin that contains the test function for validating Open edX imports. This path is relative to your plugin directory. -*Example*: `"tests/import_tests.py"` +* *Example*: `"tests/import_tests.py"` ### `openedx_imports_test_function_name` **Optional** The name of the function in the specified file that executes the import tests for Open edX. -*Example*: `"test_openedx_imports"` +* *Example*: `"test_openedx_imports"` ## Overview From 935eafedd0f2529a80e61e8087606af6793e5885 Mon Sep 17 00:00:00 2001 From: magajh Date: Wed, 2 Oct 2024 15:53:06 -0400 Subject: [PATCH 33/34] fix: run backend tests with pytest --- action.yml | 16 +++--------- run_openedx_imports_test.py | 49 ------------------------------------- 2 files changed, 3 insertions(+), 62 deletions(-) delete mode 100644 run_openedx_imports_test.py diff --git a/action.yml b/action.yml index fe16c61..e606d18 100644 --- a/action.yml +++ b/action.yml @@ -21,9 +21,6 @@ inputs: openedx_imports_test_file_path: description: "Path to the file that contains the test function for validating Open edX imports. This should be a Python file within your project." required: false - openedx_imports_test_function_name: - description: "Name of the function in the specified file that executes the import tests for Open edX." - required: false runs: using: "composite" @@ -131,19 +128,12 @@ runs: - name: Test Open edX imports in plugin if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} - env: - SCRIPT: /openedx/${{ inputs.app_name }}/run_openedx_imports_test.py - OPENEDX_IMPORTS_TEST_FILE_PATH: /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }} run: | source .tutor_venv/bin/activate - cp $GITHUB_ACTION_PATH/run_openedx_imports_test.py $GITHUB_WORKSPACE/${{ inputs.app_name }}/ - echo "Running test for Open edX imports in plugin" - - tutor local exec --env DJANGO_SETTINGS_MODULE=lms.envs.production \ - lms python $SCRIPT \ - --test-file-path $OPENEDX_IMPORTS_TEST_FILE_PATH \ - --test-function-name '${{ inputs.openedx_imports_test_function_name }}' + echo "Running test for Open edX imports in plugin with pytest" + tutor local exec lms bash -c "pip install pytest pytest-django" + tutor local exec lms bash -c "pytest -s --ds=lms.envs.tutor.test /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }}" shell: bash - name: Load initial data for the tests diff --git a/run_openedx_imports_test.py b/run_openedx_imports_test.py deleted file mode 100644 index c7e2a4c..0000000 --- a/run_openedx_imports_test.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -This script runs a specified test function from a given test file to validate Open edX imports. - -Usage: - python run_openedx_imports_test.py --test-file-path --test-function-name - -The script dynamically loads a Python module from the specified file path and executes the given test function. -""" - -import argparse -import importlib.util -import os - -import django - - -def main(): - """ - Parses command-line arguments, sets up the Django environment, dynamically loads the specified test module, - and executes the given test function to validate Open edX imports. - - Args: - None - - Returns: - None - """ - parser = argparse.ArgumentParser(description='Run Open edX imports test.') - parser.add_argument('--test-file-path', required=True, help='Path to the test file.') - parser.add_argument('--test-function-name', required=True, help='Name of the test function to execute.') - - args = parser.parse_args() - - # Set up the Django environment to avoid AppNotReady errors - django.setup() - - file_path = args.test_file_path - function_name = args.test_function_name - - spec = importlib.util.spec_from_file_location('test_module', file_path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - - func = getattr(module, function_name) - func() - - -if __name__ == '__main__': - main() From b27df97ce3d5df175ab23df99a21e9ad5f85c689 Mon Sep 17 00:00:00 2001 From: magajh Date: Thu, 3 Oct 2024 09:54:33 -0400 Subject: [PATCH 34/34] fix: update readme and workflow to remove openedx_imports_test_function_name input --- README.md | 15 ++++----------- action.yml | 3 +-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 82f3ee8..457e186 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,7 @@ jobs: shell_file_to_run: "tests/integration.sh" openedx_extra_pip_requirements: "package1==1.0 package2>=2.0" fixtures_file: "fixtures/test_data.json" - openedx_imports_test_file_path: "tests/integration/import_tests.py" - openedx_imports_test_function_name: "test_openedx_imports" + openedx_imports_test_file_path: "eox_test/edxapp_wrapper/test_backends.py" ``` ## Inputs @@ -73,13 +72,7 @@ The path to the fixtures file of your plugin to load initial data for the tests. **Optional** The path to the Python file in your plugin that contains the test function for validating Open edX imports. This path is relative to your plugin directory. -* *Example*: `"tests/import_tests.py"` - -### `openedx_imports_test_function_name` - -**Optional** -The name of the function in the specified file that executes the import tests for Open edX. -* *Example*: `"test_openedx_imports"` +* *Example*: `"eox_test/edxapp_wrapper/test_backends.py"` ## Overview @@ -113,7 +106,7 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm 12. **Import Demo Course**: Imports the Open edX demo course for testing purposes. -13. **Test Open edX Imports in Plugin** *(Optional)*: Runs a test function to validate Open edX imports in your plugin if `openedx_imports_test_file_path` and `openedx_imports_test_function_name` are provided. +13. **Test Open edX Imports in Plugin** *(Optional)*: Runs pytest to validate Open edX imports in your plugin if `openedx_imports_test_file_path` is provided. The only two dependencies installed to run these tests are `pytest` and `pytest-django`, so ensure that your import tests do not require any extra packages that are not in the plugin's base requirements. 14. **Load Initial Data for the Tests** *(Optional)*: Loads initial data from a fixtures file into the LMS if `fixtures_file` is provided. @@ -141,7 +134,7 @@ This GitHub Action automates the process of setting up a Tutor Open edX environm - **Paths**: Ensure that the paths provided in the inputs are relative to your plugin directory. -- **Optional Steps**: Steps involving `openedx_imports_test_file_path`, `openedx_imports_test_function_name`, and `fixtures_file` are optional and will only run if the corresponding inputs are provided. +- **Optional Steps**: Steps involving `openedx_imports_test_file_path` and `fixtures_file` are optional and will only run if the corresponding inputs are provided. - **Tutor Versions**: Use the matrix strategy to test your plugin against multiple Tutor versions, including the nightly build. diff --git a/action.yml b/action.yml index e606d18..17b0bdb 100644 --- a/action.yml +++ b/action.yml @@ -127,11 +127,10 @@ runs: shell: bash - name: Test Open edX imports in plugin - if: ${{ inputs.openedx_imports_test_file_path && inputs.openedx_imports_test_function_name }} + if: ${{ inputs.openedx_imports_test_file_path }} run: | source .tutor_venv/bin/activate - echo "Running test for Open edX imports in plugin with pytest" tutor local exec lms bash -c "pip install pytest pytest-django" tutor local exec lms bash -c "pytest -s --ds=lms.envs.tutor.test /openedx/${{ inputs.app_name }}/${{ inputs.openedx_imports_test_file_path }}" shell: bash