diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..10f37e6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,69 @@ +name: Release + +on: + push: + branches: [release] + workflow_dispatch: + branches: [release] + workflow_call: + inputs: + QT_DEPENDENCIES: + description: 'Set to true to install Qt dependencies (Linux)' + required: false + default: 'false' + type: string + +jobs: + run-tests: + uses: nxt-dev/nxt/.github/workflows/unittests.yml@release + with: + QT_DEPENDENCIES: ${{ inputs.QT_DEPENDENCIES }} + build-and-deploy-pypi: + needs: [run-tests] + runs-on: ubuntu-latest + env: + TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Checkout build graph (if needed) + if: github.repository != 'nxt-dev/nxt' + uses: actions/checkout@v4 + with: + repository: nxt-dev/nxt + ref: release + path: nxt + sparse-checkout: build + + + - name: Install Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Ensure PIP + run: python -m ensurepip --upgrade + + - name: Install nxt-core (if needed) + if: github.repository != 'nxt-dev/nxt' + run: | + pip install git+https://github.com/nxt-dev/nxt.git@release + + - name: Install this package and dependencies + run: | + pip install twine + pip install . + + - name: Set NXT_FILE_ROOTS (if needed) + if: github.repository != 'nxt-dev/nxt' + env: + # Thepackaging graph expects nxt to be cloned next to nxt_editor + # this is not possible in GHA so we abuse the file fall backs to + # trick it into working + NXT_FILE_ROOTS: '../docs/api_docs' + run: echo "NXT_FILE_ROOTS=$NXT_FILE_ROOTS" >> $GITHUB_ENV + + - name: Build package and upload + run: | + python -m nxt.cli -vv exec build/packaging.nxt -s /make_and_test_upload \ No newline at end of file diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml new file mode 100644 index 0000000..c23ed16 --- /dev/null +++ b/.github/workflows/unittests.yml @@ -0,0 +1,91 @@ +name: Unittests + +on: + workflow_dispatch: + branches-ignore: [release] + workflow_call: + inputs: + QT_DEPENDENCIES: + description: 'Set to true to install Qt dependencies (Linux)' + required: false + default: 'false' + type: string + pull_request: + branches-ignore: [release] + push: + branches-ignore: [release] + +jobs: + test-python: + env: + QT_DEPENDENCIES: ${{ inputs.QT_DEPENDENCIES }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + python-version: ['3.7', '3.8', '3.9', '3.10'] + fail-fast: true + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Determine nxt-core branch to use + run: | + if [ "${{ github.ref_name }}" = "release" ]; then + echo "NXT_CORE_BRANCH=release" >> $GITHUB_ENV + else + echo "NXT_CORE_BRANCH=dev" >> $GITHUB_ENV + fi + shell: bash + + - name: Install Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies (Ubuntu) + if: runner.os == 'Linux' && env.QT_DEPENDENCIES == 'true' + run: | + sudo apt-get update + sudo apt-get install -y \ + libxkbcommon-x11-0 \ + libxrender1 \ + libxext6 \ + libxcb1 \ + libxcb-icccm4 \ + libxcb-image0 \ + libxcb-keysyms1 \ + libxcb-randr0 \ + libxcb-render0 \ + libxcb-render-util0 \ + libxcb-shape0 \ + libxcb-shm0 \ + libxcb-sync1 \ + libxcb-xfixes0 \ + libxcb-xinerama0 \ + libxcb-xkb1 \ + libqt5x11extras5 \ + xvfb + + - name: Ensure PIP + run: python -m ensurepip --upgrade + + - name: Install nxt-core + if: github.repository != 'nxt-dev/nxt' + run: | + pip install git+https://github.com/nxt-dev/nxt.git@${{ env.NXT_CORE_BRANCH }} + + - name: Install this package + run: pip install . + + - name: Run tests with xvfb (Ubuntu + Qt) + if: runner.os == 'Linux' && env.QT_DEPENDENCIES == 'true' + run: | + Xvfb :99 -screen 0 1024x768x24 & + export DISPLAY=:99 + python -m nxt.cli test + + - name: Run Unittests from CLI + if: env.QT_DEPENDENCIES != 'true' + run: python -m nxt.cli test \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b6603eb..0000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: python -branches: - only: - - release - - dev -python: - - "3.9" - -before_install: - - | - if [ "$TRAVIS_BRANCH" = "dev" ] && [ "$TRAVIS_EVENT_TYPE" = "push" ]; then - echo "Push to dev, not running tests until PR" - exit 0 - else - echo "Doing the build" - fi - -install: - - cd .. - - pip install ./nxt - - pip install importlib-metadata - - pip install twine - -script: - - | - if [ "$TRAVIS_BRANCH" = "release" ] && [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then - python -m nxt.cli test - exit $? - fi - - | - if [ "$TRAVIS_BRANCH" = "release" ] && [ "$TRAVIS_EVENT_TYPE" = "push" ]; then - python -m nxt.cli exec nxt/build/packaging.nxt -s /make_and_upload - exit $? - fi \ No newline at end of file diff --git a/README.md b/README.md index f5abf05..a443cce 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,17 @@ +
+ +![Release Status](https://github.com/nxt-dev/nxt/actions/workflows/release.yml/badge.svg?branch=release) +![Dev Status](https://github.com/nxt-dev/nxt/actions/workflows/unittests.yml/badge.svg?branch=dev) # NXT Python Core +
+ + **nxt** (**/ɛn·ɛks·ti/**) is a general purpose code compositor designed for rigging, scene assembly, and automation. (node execution tree) [Installation/Usage](#installationusage) | [Docs](https://nxt-dev.github.io/) | [Contributing](CONTRIBUTING.md) | [Licensing](LICENSE) # Installation/Usage + **This repo is the nxt core, it does not come with a UI. If you're looking for the UI, please see [the nxt editor](https://github.com/nxt-dev/nxt_editor).** This package is designed for headless execution of graphs in a render farm or other headless environment. Only clone this repo if you're contributing to the NXT codebase. @@ -11,18 +19,21 @@ Only clone this repo if you're contributing to the NXT codebase.
#### Requirements + - Python >= [2.7.*](https://www.python.org/download/releases/2.7) <= [3.7.*](https://www.python.org/download/releases/3.7) - We strongly recommend using a Python [virtual environment](https://docs.python.org/3.7/tutorial/venv.html) *[Requirements for contributors](CONTRIBUTING.md#python-environment)* ### NXT Python Core + Our releases are hosted on [PyPi](https://pypi.org/project/nxt-editor/). **Install:** `pip install nxt-core` **Execute Graph:** + ```python import nxt nxt.execute_graph('path/to/graph.nxt') @@ -34,11 +45,6 @@ nxt.execute_graph('path/to/graph.nxt')
## Special Thanks -[Sunrise Productions](https://sunriseproductions.tv/) | [School of Visual Art and Design](https://www.southern.edu/visualartanddesign/) ---- - -| Release | Dev | -| :---: | :---: | -| [![Build Status](https://travis-ci.com/nxt-dev/nxt.svg?token=rBRbAJTv2rq1c8WVEwGs&branch=release)](https://travis-ci.com/nxt-dev/nxt) | [![Build Status](https://travis-ci.com/nxt-dev/nxt.svg?token=rBRbAJTv2rq1c8WVEwGs&branch=dev)](https://travis-ci.com/nxt-dev/nxt) | +[Sunrise Productions](https://sunriseproductions.tv/) | [School of Visual Art and Design](https://www.southern.edu/visualartanddesign/) diff --git a/build/packaging.nxt b/build/packaging.nxt index e6b6031..eed556e 100644 --- a/build/packaging.nxt +++ b/build/packaging.nxt @@ -7,16 +7,16 @@ "meta_data": { "positions": { "/make_and_test_upload": [ - -223, - 306 + 380.0, + 340.0 ], "/make_and_upload": [ - -221.61718055199395, - 65.0 + 400.0, + 100.0 ], "/make_package": [ - -223.0, - -153.0 + 380.0, + -120.0 ] } }, @@ -45,7 +45,7 @@ "import subprocess", "orig_cwd = os.getcwd()", "os.chdir('${repo_root}')", - "subprocess.call([sys.executable, '-m', 'twine' ,'upload', '--repository', 'testpypi', '${dest_dir}/*'])", + "subprocess.check_call([sys.executable, '-m', 'twine' ,'upload', '--repository', 'testpypi', '${dest_dir}/*'])", "os.chdir(orig_cwd)" ] }, diff --git a/nxt/nxt_log.py b/nxt/nxt_log.py index 1327939..fa995b7 100644 --- a/nxt/nxt_log.py +++ b/nxt/nxt_log.py @@ -20,6 +20,7 @@ # Internal from .constants import USER_DIR +LOG_DIR = os.path.join(tempfile.gettempdir(), 'nxt_logs') VERBOSE_ENV_VAR = 'NXT_VERBOSE' """Logging levels are as follows, with custom levels marked with * @@ -248,10 +249,9 @@ def get_new_session_log_filename(): :rtype: str """ logger = logging.getLogger(__name__) - log_dir = os.path.join(tempfile.gettempdir(), 'nxt_logs') try: - os.makedirs(log_dir) - os.chmod(log_dir, 0o777) + os.makedirs(LOG_DIR) + os.chmod(LOG_DIR, 0o777) except OSError as err: if err.errno is errno.EEXIST: logger.debug("Not creating logs directory because it exists.") @@ -259,7 +259,7 @@ def get_new_session_log_filename(): raise log_filename_template = "nxt_session_{time}.log" log_filename = log_filename_template.format(time=str(int(time.time()))) - return os.path.join(log_dir, log_filename) + return os.path.join(LOG_DIR, log_filename) def stop_session_log(filename): diff --git a/nxt/plugin_loader.py b/nxt/plugin_loader.py index 278fd02..836e8cf 100644 --- a/nxt/plugin_loader.py +++ b/nxt/plugin_loader.py @@ -1,6 +1,6 @@ # Built-in import os -import imp +import importlib.util import logging # Internal @@ -23,10 +23,11 @@ def load_plugins(): mod_name, _ = os.path.splitext(file_name) if mod_name in _nxt_loaded_plugin_module_names: continue - try: - found = imp.find_module(mod_name, [plugin_dir]) - except ImportError: + mod_path = os.path.join(plugin_dir, file_name) + spec = importlib.util.spec_from_file_location(mod_name, mod_path) + if not spec: continue - mod = imp.load_module(mod_name, *found) + mod = importlib.util.module_from_spec(spec) _nxt_loaded_plugin_module_names += [mod_name] _nxt_loaded_plugin_modules += [mod] + spec.loader.exec_module(mod) diff --git a/nxt/test/test_plugins.py b/nxt/test/test_plugins.py index b240a46..cf8386a 100644 --- a/nxt/test/test_plugins.py +++ b/nxt/test/test_plugins.py @@ -3,7 +3,7 @@ import os # Internal -from nxt.plugins.file_fallbacks import NXT_FILE_ROOTS +from nxt.plugins.file_fallbacks import NXT_FILE_ROOTS, ROOT_PATH_SEP from nxt.session import Session from nxt.stage import DATA_STATE @@ -218,7 +218,8 @@ def test_saved(self): print('Test in a saved file with an environment, path:: ' 'resolves to first real env root') test_root = os.path.dirname(my_dir) - os.environ[NXT_FILE_ROOTS] = 'a super fake root;' + test_root + test_roots = 'a super fake root' + ROOT_PATH_SEP + test_root + os.environ[NXT_FILE_ROOTS] = test_roots expected = os.path.join(test_root, self.test_filename).replace(os.sep, '/') found = test_stage.get_node_attr_value(test_node, test_attr, diff --git a/nxt/test/test_stage.py b/nxt/test/test_stage.py index df5d11d..db2f5d1 100644 --- a/nxt/test/test_stage.py +++ b/nxt/test/test_stage.py @@ -278,7 +278,7 @@ def test_inherit_attrs(self): self.assertIs(True, hasattr(runtime_child, 'parent')) print("Test that the local attr from the parent node is IS accessible" "from the EDITOR child node via `self`.") - self.assertEquals(True, hasattr(self.child_node, 'parent')) + self.assertEqual(True, hasattr(self.child_node, 'parent')) # Test that code is not inherited print("Test that child code is NOT inherited FROM the PARENT.") self.assertEqual(["# Code"], getattr(runtime_parent, diff --git a/nxt/version.json b/nxt/version.json index dc5a9cf..54b9793 100644 --- a/nxt/version.json +++ b/nxt/version.json @@ -1,7 +1,7 @@ { "API": { "MAJOR": 0, - "MINOR": 16, + "MINOR": 17, "PATCH": 0 }, "GRAPH": { diff --git a/setup.py b/setup.py index bb692d5..2ce3974 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ long_description_content_type="text/markdown", url="https://github.com/nxt-dev/nxt", packages=setuptools.find_packages(), - python_requires='>=2.7, <3.11', + python_requires='>=3.7, <3.11', entry_points={ 'console_scripts': [ 'nxt=nxt.cli:main',