diff --git a/.github/labeler.yml b/.github/labeler.yml index badf6a1e12b..d85740169a9 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -23,3 +23,93 @@ examples: - changed-files: - any-glob-to-any-file: - "examples/**/*" + +# -- Labels based on PR title ------------------------------------------------ +'fix': + - head-branch: ['fix'] + +'enhancement': + - head-branch: ['feat'] + +# -- Documentation labels ---------------------------------------------------- +'docs': + - all: + - changed-files: + - any-glob-to-any-file: ['doc/source/**/*.rst'] + - all-globs-to-all-files: ['!doc/source/API/**/*.rst', '!doc/styles/**', '!doc/.vale.ini'] + +'docs:api': + - any: + - changed-files: + - any-glob-to-any-file: ['doc/source/API/**/*.rst'] + +'docs:examples': + - any: + - changed-files: + - any-glob-to-any-file: ['examples/**/*.py'] + +## -- Other labels ------------------------------------------------------------ +'code-style': + - any: + - changed-files: + - any-glob-to-any-file: ['.pre-commit-config.yaml', 'doc/.vale.ini'] + +'docker': + - any: + - changed-files: + - any-glob-to-any-file: ['docker/**'] + +'ci': + - any: + - changed-files: + - any-glob-to-any-file: ['.github/workflows/**'] + +'tests:unit': + - any: + - changed-files: + - any-glob-to-any-file: ['_unittest/**'] + +'tests:iron': + - any: + - changed-files: + - any-glob-to-any-file: ['_unittest_ironpython/**'] + +'tests:solvers': + - any: + - changed-files: + - any-glob-to-any-file: ['_unittest_solvers/**'] + +# HACK: the following labels are declared with the only purpose of avoiding the +# GitHub labeler bot to remove those. This is a known issue reported in the +# official action/labeler repo https://github.com/actions/labeler/issues/763 + +'ci:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + +'docs:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + +'tests:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + +'tests:unit:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + +'tests:iron:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + +'tests:solvers:skip': + - all: + - changed-files: + - all-globs-to-all-files: ['THIS-NEVER-MATCHES-A-FILE'] + diff --git a/.github/labels.yml b/.github/labels.yml index e1d868c2e23..e58d4c65451 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -1,35 +1,140 @@ -- name: bug - description: Something isn't working +# The labels declared in this file are the ones avialables +# https://github.com/ansys/pyaedt/labels + +# -- Defects and glitches labels---------------------------------------------- + +- name: 'bug' + description: Defects or glitches reported by users or developers color: d42a34 -- name: dependencies - description: Related with project dependencies - color: ffc0cb +- name: 'fix' + description: Pull requests related to resolving problems or errors + color: d42a34 + +# -- Style labels ------------------------------------------------------------ + +- name: 'style' + description: Improvements related to general project style + color: dcbeff + +- name: 'style:code' + description: Improvements related to code style + color: dcbeff + +- name: 'style:docs' + description: Improvements related to doc style + color: dcbeff + +- name: 'style:branch' + description: Verifies branch style is compliant with PyAnsys guidelines + color: dcbeff + +- name: 'style:skip' + description: Skip style runs in CI/CD + color: dcbeff + +# -- Tests labels ------------------------------------------------------------ + +- name: 'tests' + description: Related with improvements of the test suite + color: ffd8b1 + +- name: 'tests:smoke' + description: Related with improvements of the smoke test suite + color: ffd8b1 + +- name: 'tests:unit' + description: Related with improvements of the unit test suite + color: ffd8b1 + +- name: 'tests:iron' + description: Related with improvements of the IronPython test suite + color: ffd8b1 + +- name: 'tests:solvers' + description: Related with improvements of the solvers test suite + color: ffd8b1 + +- name: 'tests:skip' + description: Skip tests runs in CI/CD + color: ffd8b1 + +- name: 'tests:smoke:skip' + description: Skip smoke tests runs in CI/CD + color: ffd8b1 + +- name: 'tests:unit:skip' + description: Skip IronPython tests runs in CI/CD + color: ffd8b1 + +- name: 'tests:iron:skip' + description: Skip IronPython tests runs in CI/CD + color: ffd8b1 -- name: documentation - description: Improvements or additions to documentation +- name: 'tests:solvers:skip' + description: Skip IronPython tests runs in CI/CD + color: ffd8b1 + +# -- Documentation labels ---------------------------------------------------- + +- name: 'docs' + description: Issues related to documentation color: 0677ba -- name: enhancement - description: New features or code improvements - color: FFD827 +- name: 'docs:api' + description: Related to API documentation + color: 0677ba -- name: good first issue - description: Easy to solve for newcomers - color: 62ca50 +- name: 'docs:examples' + description: Related to documentation examples + color: 0677ba -- name: maintenance - description: Package and maintenance related - color: f78c37 +- name: 'docs:skip' + description: Skip documentation runs in CI/CD + color: 0677ba + +# -- Dependencies labels ----------------------------------------------------- + +- name: 'dependencies' + description: Related with project dependencies + color: fabed4 -- name: release +- name: 'dependencies:pyproject' + description: Related with project file dependencies + color: fabed4 + +- name: 'dependencies:ci' + description: Related with pipelines dependencies + color: fabed4 + +# -- CI/CD labels ------------------------------------------------------------ + +- name: 'ci' + description: Pipelines maintenance related + color: a9a9a9 + +- name: 'ci:skip' + description: Skip CI/CD runs + color: a9a9a9 + +# -- Other labels ------------------------------------------------------------ + +- name: 'release' description: Anything related to an incoming release color: ffffff -- name: testing - description: Anything related to testing - color: 5802B8 +- name: 'good first issue' + description: Issues suitable for newcomers or those with less experience + color: 62ca50 + +- name: 'enhancement' + description: General improvements to existing features + color: ffd827 + +- name: 'maintenance' + description: Generic maintenance related + color: f78c37 -- name: examples - description: Anything related to the examples - color: 3C2E5F +- name: 'docker' + description: Docker maintenance related + color: 000075 diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml deleted file mode 100644 index ebe924c3c71..00000000000 --- a/.github/workflows/ci_cd.yml +++ /dev/null @@ -1,577 +0,0 @@ -name: GitHub CI CD -on: - pull_request: - workflow_dispatch: - push: - tags: - - "*" - branches: - - main - -env: - ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }} - MAIN_PYTHON_VERSION: '3.10' - PACKAGE_NAME: 'PyAEDT' - DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' - MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }} - MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }} - MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }} - ON_CI: True - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - - pr-title: - if: github.event_name == 'pull_request' - name: Check the title of the pull request - runs-on: ubuntu-latest - steps: - - name: Check commit name - uses: ansys/actions/commit-style@v6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - use-upper-case: true - - # TODO: Update to ansys/actions/doc-style@v6 - doc-style: - name: Documentation style check - runs-on: ubuntu-latest - steps: - - name: Check documentation style - uses: ansys/actions/doc-style@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - vale-config: "doc/.vale.ini" - vale-version: "2.29.6" - - smoke-tests: - name: Build wheelhouse and smoke tests - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest] - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] - target: ['all', 'installer'] - exclude: - - python-version: '3.7' - target: 'installer' - steps: - - name: Build wheelhouse and perform smoke test - uses: ansys/actions/build-wheelhouse@v4 - with: - library-name: ${{ env.PACKAGE_NAME }} - operating-system: ${{ matrix.os }} - python-version: ${{ matrix.python-version }} - target: ${{ matrix.target }} - - - name: Import python package - run: | - python -c "import pyaedt; from pyaedt import __version__" - - # TODO: Update to ansys/actions/doc-build@v6 once we remove examples - doc-build: - name: Documentation build without examples - runs-on: ubuntu-latest - needs: [doc-style] - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Update pip - run: | - pip install --upgrade pip - - - name: Install pyaedt and documentation dependencies - run: | - pip install .[doc-no-examples] - - - name: Retrieve PyAEDT version - id: version - run: | - echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT - echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")" - - - name: Install doc build requirements - run: | - sudo apt update - sudo apt install graphviz texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra -y - - # TODO: Update this step once pyaedt-examples is ready - - name: Build HTML documentation without examples - run: | - make -C doc clean - make -C doc html-no-examples - - # Verify that sphinx generates no warnings - - name: Check for warnings - run: | - python doc/print_errors.py - - - name: Upload HTML documentation without examples artifact - uses: actions/upload-artifact@v3 - with: - name: documentation-no-examples-html - path: doc/_build/html - retention-days: 7 - - - name: Build PDF documentation without examples - run: | - make -C doc pdf-no-examples - - - name: Upload PDF documentation without examples artifact - uses: actions/upload-artifact@v3 - with: - name: documentation-no-examples-pdf - path: doc/_build/latex/PyAEDT-Documentation-*.pdf - retention-days: 7 - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - doc-build-with-examples: - name: Documentation build with examples - if: github.event_name == 'push' && contains(github.ref, 'refs/tags') - runs-on: [ self-hosted, Windows, pyaedt ] - needs: [doc-style] - timeout-minutes: 720 - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Create virtual environment - run: | - python -m venv .venv - .venv\Scripts\Activate.ps1 - python -m pip install pip -U - python -m pip install wheel setuptools -U - python -c "import sys; print(sys.executable)" - - - name: Install pyaedt and documentation dependencies - run: | - .venv\Scripts\Activate.ps1 - pip install .[doc] - - - name: Retrieve PyAEDT version - id: version - run: | - .venv\Scripts\Activate.ps1 - echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT - echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")" - - - name: Install CI dependencies (e.g. vtk-osmesa) - run: | - .venv\Scripts\Activate.ps1 - # Uninstall conflicting dependencies - pip uninstall --yes vtk - pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0 - - # TODO: Update this step once pyaedt-examples is ready - # NOTE: Use environment variable to keep the doctree and avoid redundant build for PDF pages - - name: Build HTML documentation with examples - env: - SPHINXBUILD_KEEP_DOCTREEDIR: "1" - run: | - .venv\Scripts\Activate.ps1 - .\doc\make.bat clean - .\doc\make.bat html - - # TODO: Keeping this commented as reminder of https://github.com/ansys/pyaedt/issues/4296 - # # Verify that sphinx generates no warnings - # - name: Check for warnings - # run: | - # .venv\Scripts\Activate.ps1 - # python doc/print_errors.py - - # Use environment variable to remove the doctree after the build of PDF pages - - name: Build PDF documentation with examples - env: - SPHINXBUILD_KEEP_DOCTREEDIR: "0" - run: | - .venv\Scripts\Activate.ps1 - .\doc\make.bat pdf - - - name: Add assets to HTML docs - run: | - zip -r documentation-html.zip ./doc/_build/html - mv documentation-html.zip ./doc/_build/html/_static/assets/download/ - cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf - - - name: Upload HTML documentation with examples artifact - uses: actions/upload-artifact@v3 - with: - name: documentation-html - path: doc/_build/html - retention-days: 7 - - - name: Upload PDF documentation without examples artifact - uses: actions/upload-artifact@v3 - with: - name: documentation-pdf - path: doc/_build/latex/PyAEDT-Documentation-*.pdf - retention-days: 7 - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - test-solvers-windows: - name: Testing solvers and coverage (Windows) - needs: [smoke-tests] - runs-on: [ self-hosted, Windows, pyaedt ] - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Create virtual environment - run: | - python -m venv .venv - .venv\Scripts\Activate.ps1 - python -m pip install pip -U - python -m pip install wheel setuptools -U - python -c "import sys; print(sys.executable)" - - - name: Install pyaedt and tests dependencies - run: | - .venv\Scripts\Activate.ps1 - pip install .[tests] - pip install pytest-azurepipelines - - - name: Install CI dependencies (e.g. vtk-osmesa) - run: | - .venv\Scripts\Activate.ps1 - # Uninstall conflicting dependencies - pip uninstall --yes vtk - pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0 - - - name: Run tests on _unittest_solvers - env: - PYTHONMALLOC: malloc - run: | - .venv\Scripts\Activate.ps1 - pytest --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest_solvers - - - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: codecov-system-solver-tests - file: ./coverage.xml - flags: system,solver - - - name: Upload pytest test results - uses: actions/upload-artifact@v3 - with: - name: pytest-solver-results - path: junit/test-results.xml - if: ${{ always() }} - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - # TODO: Si if we can use ansys/actions - test-solvers-linux: - name: Testing solvers and coverage (Linux) - needs: [smoke-tests] - runs-on: [ self-hosted, Linux, pyaedt ] - env: - ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64' - ANS_NODEPCHECK: '1' - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Create virtual environment - run: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - python -m venv .venv - source .venv/bin/activate - python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip -U - python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org wheel setuptools -U - python -c "import sys; print(sys.executable)" - - - name: Install pyaedt and tests dependencies - run: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - source .venv/bin/activate - pip install .[tests] - pip install pytest-azurepipelines - - - name: Run tests on _unittest_solvers - run: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - source .venv/bin/activate - pytest --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest_solvers - - - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: codecov-system-solver-tests - file: ./coverage.xml - flags: system,solver - - - name: Upload pytest test results - uses: actions/upload-artifact@v3 - with: - name: pytest-solver-results - path: junit/test-results.xml - if: ${{ always() }} - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - test-windows: - name: Testing and coverage (Windows) - needs: [smoke-tests] - runs-on: [ self-hosted, Windows, pyaedt ] - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Create virtual environment - run: | - python -m venv .venv - .venv\Scripts\Activate.ps1 - python -m pip install pip -U - python -m pip install wheel setuptools -U - python -c "import sys; print(sys.executable)" - - - name: Install pyaedt and tests dependencies - run: | - .venv\Scripts\Activate.ps1 - pip install .[tests] - pip install pytest-azurepipelines - - - name: Install CI dependencies (e.g. vtk-osmesa) - run: | - .venv\Scripts\Activate.ps1 - # Uninstall conflicting dependencies - pip uninstall --yes vtk - pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0 - - - name: Run tests on _unittest - uses: nick-fields/retry@v3 - env: - PYTHONMALLOC: malloc - with: - max_attempts: 2 - retry_on: error - timeout_minutes: 50 - command: | - .venv\Scripts\Activate.ps1 - pytest -n 4 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest - - - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: codecov-system-tests - file: ./coverage.xml - flags: system - - - name: Upload pytest test results - uses: actions/upload-artifact@v3 - with: - name: pytest-results - path: junit/test-results.xml - if: ${{ always() }} - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - # TODO: Si if we can use ansys/actions - test-linux: - name: Testing and coverage (Linux) - needs: [smoke-tests] - runs-on: [ self-hosted, Linux, pyaedt ] - env: - ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64' - ANS_NODEPCHECK: '1' - steps: - - name: Install Git and checkout project - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - - name: Create virtual environment - run: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - python -m venv .venv - source .venv/bin/activate - python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip -U - python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org wheel setuptools -U - python -c "import sys; print(sys.executable)" - - - name: Install pyaedt and tests dependencies - run: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - source .venv/bin/activate - pip install .[tests] - pip install pytest-azurepipelines - - - name: Install CI dependencies (e.g. vtk-osmesa) - run: | - source .venv/bin/activate - # Uninstall conflicting dependencies - pip uninstall --yes vtk - pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0 - - - name: Run tests on _unittest - uses: nick-fields/retry@v3 - with: - max_attempts: 2 - retry_on: error - timeout_minutes: 50 - command: | - export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH - source .venv/bin/activate - pytest -n 4 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest - - - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: codecov-system-solver-tests - file: ./coverage.xml - flags: system,solver - - - name: Upload pytest test results - uses: actions/upload-artifact@v3 - with: - name: pytest-solver-results - path: junit/test-results.xml - if: ${{ always() }} - -# # ================================================================================================= -# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv RUNNING ON SELF-HOSTED RUNNER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -# # ================================================================================================= - - test-ironpython-windows: - name: Testing IronPython and coverage (Windows) - needs: [smoke-tests] - runs-on: [ self-hosted, Windows, pyaedt ] - steps: - - uses: actions/checkout@v4 - - - name: Run Ironpython tests - timeout-minutes: 5 - run: | - $processA = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd' -PassThru - $processA.WaitForExit() - - - name: Get log content - run: | - get-content .\_unittest_ironpython\pyaedt_unit_test_ironpython.log - - - name: Check for errors - run: | - $test_errors_failures = Select-String -Path .\_unittest_ironpython\pyaedt_unit_test_ironpython.log -Pattern "TextTestResult errors=" - if ($test_errors_failures -ne $null) - { - exit 1 - } - - package: - name: Package library - needs: [test-windows, test-solvers-windows, test-ironpython-windows, test-linux, test-solvers-linux, doc-build] - runs-on: ubuntu-latest - steps: - - name: Build library source and wheel artifacts - uses: ansys/actions/build-library@v4 - with: - library-name: ${{ env.PACKAGE_NAME }} - python-version: ${{ env.MAIN_PYTHON_VERSION }} - - # TODO: Si if we can fix the PDF issue and leverage classic ansys/release-github - release: - name: Release project - if: github.event_name == 'push' && contains(github.ref, 'refs/tags') - needs: [package, doc-build-with-examples] - runs-on: ubuntu-latest - steps: - - name: Release to the public PyPI repository - uses: ansys/actions/release-pypi-public@v4 - with: - library-name: ${{ env.PACKAGE_NAME }} - twine-username: "__token__" - twine-token: ${{ secrets.PYPI_TOKEN }} - - - name: Release to GitHub - uses: ansys/actions/release-github@v4 - with: - library-name: ${{ env.PACKAGE_NAME }} - - upload-release-doc: - name: Upload release documentation - if: github.event_name == 'push' && contains(github.ref, 'refs/tags') - runs-on: ubuntu-latest - needs: [release] - steps: - - name: Deploy the stable documentation - uses: ansys/actions/doc-deploy-stable@v4 - with: - cname: ${{ env.DOCUMENTATION_CNAME }} - token: ${{ secrets.GITHUB_TOKEN }} - doc-artifact-name: 'documentation-html' - - doc-index-stable: - name: Deploy stable docs index - if: github.event_name == 'push' && contains(github.ref, 'refs/tags') - runs-on: ubuntu-latest - needs: upload-release-doc - steps: - - name: Install Git and clone project - uses: actions/checkout@v4 - - - name: Install the package requirements - run: pip install -e . - - - name: Get the version to PyMeilisearch - run: | - VERSION=$(python -c "from pyaedt import __version__; print('.'.join(__version__.split('.')[:2]))") - VERSION_MEILI=$(python -c "from pyaedt import __version__; print('-'.join(__version__.split('.')[:2]))") - echo "Calculated VERSION: $VERSION" - echo "Calculated VERSION_MEILI: $VERSION_MEILI" - echo "VERSION=$VERSION" >> $GITHUB_ENV - echo "VERSION_MEILI=$VERSION_MEILI" >> $GITHUB_ENV - - - name: Deploy the latest documentation index - uses: ansys/actions/doc-deploy-index@v4 - with: - cname: ${{ env.DOCUMENTATION_CNAME }}/version/${{ env.VERSION }} - index-name: pyaedt-v${{ env.VERSION_MEILI }} - host-url: ${{ env.MEILISEARCH_HOST_URL }} - api-key: ${{ env.MEILISEARCH_API_KEY }} - python-version: ${{ env.MAIN_PYTHON_VERSION }} diff --git a/.github/workflows/ci_cd_main.yml b/.github/workflows/ci_cd_main.yml new file mode 100644 index 00000000000..a112eb5f00f --- /dev/null +++ b/.github/workflows/ci_cd_main.yml @@ -0,0 +1,96 @@ +name: main +on: + push: + branches: + - main + +env: + MAIN_PYTHON_VERSION: '3.10' + DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' + ON_CI: True + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + # TODO: Update to ansys/actions/doc-build@v6 once we remove examples + # TODO: Allow conditional build of sections in docs via env vars + doc-build-without-examples: + name: "Docs without examples" + runs-on: ubuntu-latest + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'docs:skip') && + !contains(github.event.pull_request.labels.*.name, 'docs:examples') + needs: style + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + - name: "Setup Python" + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Install system dependencies" + run: | + sudo apt update + sudo apt install -y \ + texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra \ + graphviz + + - name: "Install project dependencies" + run: | + python pip install --upgrade pip + python pip install .[doc-no-examples] + + # TODO: Update this step once pyaedt-examples is ready + - name: "Build HTML documentation without examples" + run: | + make -C doc clean + make -C doc html-no-examples + + # Verify that sphinx generates no warnings + - name: Check for warnings + run: | + python doc/print_errors.py + + - name: "Upload HTML documentation without examples artifact" + uses: actions/upload-artifact@v3 + with: + name: documentation-no-examples-html + path: doc/_build/html + retention-days: 7 + + - name: "Download the nightly documentation" + uses: actions/checkout@v4 + with: + ref: "gh-pages" + path: "gh-pages" + + - name: "Include 'API' and 'Examples' sections from nightly build docs" + run: | + # Copy content pages of the 'Examples' sections + cp -r gh-pages/version/dev/examples doc/_build/html/examples + # Copy landing page to include links to previous sections + cp gh-pages/version/dev/index.html doc/_build/html/index.html + + - name: "Upload combined artifacts" + uses: actions/upload-artifact@v4 + with: + path: doc/_build/html + name: complete-documentation-html + + doc-deploy-dev: + name: "Deploy dev docs" + runs-on: ubuntu-latest + needs: doc-build + steps: + - uses: ansys/actions/doc-deploy-dev@v6 + with: + doc-artifact-name: "complete-documentation-html" + cname: ${{ env.DOCUMENTATION_CNAME }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci_cd_night.yml b/.github/workflows/ci_cd_night.yml new file mode 100644 index 00000000000..a0ded5a4c91 --- /dev/null +++ b/.github/workflows/ci_cd_night.yml @@ -0,0 +1,37 @@ +name: night +on: + schedule: # UTC at 0300 + - cron: '0 3 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + tests-smoke: + name: "Tests / Smoke / ${{ matrix.os }} / Python ${{ matrix.python-version}} / ${{ matrix.target }}" + runs-on: ${{ matrix.os }} + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'tests:skip') && + !contains(github.event.pull_request.labels.*.name, 'tests:smoke:skip') + needs: style + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + target: ['all', 'installer'] + exclude: + - python-version: '3.7' + target: 'installer' + steps: + - uses: ansys/actions/build-wheelhouse@v6 + with: + library-name: ${{ env.PACKAGE_NAME }} + operating-system: ${{ matrix.os }} + python-version: ${{ matrix.python-version }} + target: ${{ matrix.target }} + + diff --git a/.github/workflows/ci_cd_pr.yml b/.github/workflows/ci_cd_pr.yml new file mode 100644 index 00000000000..4724ddc94f7 --- /dev/null +++ b/.github/workflows/ci_cd_pr.yml @@ -0,0 +1,362 @@ +name: pull-request +on: + pull_request: + types: [opened, synchronize, reopened, labeled] + +env: + ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }} + MAIN_PYTHON_VERSION: '3.10' + PACKAGE_NAME: 'pyaedt' + DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' + MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }} + MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }} + MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }} + ON_CI: True + VTK_OSMESA_VERSION: '9.2.20230527.dev0' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + labeler: + name: "Labels" + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + github.event.type != 'labeled' + steps: + + - name: "Checkout repository" + uses: actions/checkout@v4 + + - name: "Sync labels" + uses: micnncim/action-label-syncer@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: "Label pull-request" + uses: actions/labeler@v5.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + style: + name: "Style checks" + runs-on: ubuntu-latest + needs: labeler + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'style:skip') + steps: + + - name: "Style of branch name" + if: | + !contains(github.event.pull_request.labels.*.name, 'style:branch') + uses: ansys/actions/branch-name-style@v6 + + - name: "Style of pull-request title" + if: | + !contains(github.event.pull_request.labels.*.name, 'style:branch') + uses: ansys/actions/commit-style@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + use-upper-case: true + + # INFO: 'Style of code' is performed by the pre-commit platform + + # TODO: Update to ansys/actions/doc-style@v6 + - name: "Style of doc" + if: | + !contains(github.event.pull_request.labels.*.name, 'style:docs') + uses: ansys/actions/doc-style@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + vale-config: "doc/.vale.ini" + vale-version: "2.29.6" + + # TODO: Update to ansys/actions/doc-build@v6 once we remove examples + # TODO: Allow conditional build of sections in docs via env vars + doc-build-without-examples: + name: "Docs without examples" + runs-on: ubuntu-latest + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'docs:skip') && + !contains(github.event.pull_request.labels.*.name, 'docs:examples') + needs: style + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + - name: "Setup Python" + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Install system dependencies" + run: | + sudo apt update + sudo apt install -y \ + texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra \ + graphviz + + - name: "Install project dependencies" + run: | + python -m pip install --upgrade pip + python -m pip install .[doc-no-examples] + + # TODO: Update this step once pyaedt-examples is ready + - name: "Build HTML documentation without examples" + run: | + make -C doc clean + make -C doc html-no-examples + + # Verify that sphinx generates no warnings + - name: Check for warnings + run: | + python doc/print_errors.py + + - name: "Upload HTML documentation without examples artifact" + uses: actions/upload-artifact@v3 + with: + name: documentation-no-examples-html + path: doc/_build/html + retention-days: 7 + + - name: "Build PDF documentation without examples" + run: | + make -C doc pdf-no-examples + + - name: "Upload PDF documentation without examples artifact" + uses: actions/upload-artifact@v3 + with: + name: documentation-no-examples-pdf + path: doc/_build/latex/PyAEDT-Documentation-*.pdf + retention-days: 7 + + tests-linux: + name: "Linux / Tests / ${{ matrix.tests.name }}" + needs: style + runs-on: [ self-hosted, Linux, pyaedt ] + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'tests:skip') + env: + ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64' + ANS_NODEPCHECK: '1' + strategy: + fail-fast: false + matrix: + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + - name: "Setup Python ${{ env.MAIN_PYTHON_VERSION }}" + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Create a virtual environment" + run: | + python -m venv .venv + source .venv/bin/activate + python -m pip install --upgrade \ + --trusted-host pypi.org \ + --trusted-host pypi.python.org \ + --trusted-host files.pythonhosted.org \ + pip + + - name: "Install tests dependencies" + run: | + source .venv/bin/activate + python -m pip install .[tests] pytest-azurepipelines + + - name: "Install graphics dependencies" + run: | + source .venv/bin/activate + python -m pip uninstall --yes vtk + python -m pip install --extra-index-url https://wheels.vtk.org \ + vtk-osmesa==${{ env.VTK_OSMESA_VERSION }} + + - name: "Run ${{ matrix.tests.label }} tests" + uses: nick-fields/retry@v3 + with: + max_attempts: 2 + retry_on: error + timeout_minutes: 50 + command: | + export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH + source .venv/bin/activate + + pytest ${{ matrix.tests.flags }} \ + --durations=50 -v \ + --cov=pyaedt --cov-report=xml --cov-report=html \ + --junitxml=junit/test-results.xml \ + ${{ matrix.tests.folder }} + + - name: "Upload ${{ matrix.tests.label }} tests coverage" + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + name: linux-${{ matrix.tests.label }}-tests-coverage + file: ./coverage.xml + flags: system,solver + + - name: "Upload ${{ matrix.tests.name }} tests results" + uses: actions/upload-artifact@v3 + if: ${{ always() }} + with: + name: linux-${{ matrix.tests.label }}-tests-results + path: junit/test-results.xml + + tests-windows: + name: "Windows / Tests / ${{ matrix.tests.name }}" + needs: style + runs-on: [ self-hosted, Windows, pyaedt ] + if: | + !contains(github.event.pull_request.labels.*.name, 'ci:skip') && + !contains(github.event.pull_request.labels.*.name, 'tests:skip') + strategy: + fail-fast: false + matrix: + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + - {name: "IronPython", label: "ironpython", folder: "_unittest_ironpython", flags: ""} + + tests-skip-units: + - contains(github.event.pull_request.labels.*.name, 'tests:units:skip') + + tests-skip-solvers: + - contains(github.event.pull_request.labels.*.name, 'tests:solvers:skip') + + tests-skip-ironpython: + - contains(github.event.pull_request.labels.*.name, 'tests:ironpython:skip') + + exclude: + + - tests-skip-units: true + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + + - tests-skip-solvers: true + tests: + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + + - tests-skip-ironpython: true + tests: + - {name: "IronPython", label: "ironpython", folder: "_unittest_ironpython", flags: ""} + + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + # IronPython tests + + - name: "Tests IronPython" + if: ${{ matrix.tests.label == 'ironpython' }} + timeout-minutes: 5 + run: | + $processA = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd' -PassThru + $processA.WaitForExit() + + - name: "Get logger content" + if: ${{ matrix.tests.label == 'ironpython' }} + run: | + get-content .\${{ matrix.tests.folder }}\pyaedt_unit_test_ironpython.log + + - name: "Check for errors" + if: ${{ matrix.tests.label == 'ironpython' }} + run: | + $test_errors_failures = Select-String -Path .\${{ matrix.tests.folder }}\pyaedt_unit_test_ironpython.log -Pattern "TextTestResult errors=" + if ($test_errors_failures -ne $null) + { + exit 1 + } + + # Solvers and units tests + + - name: "Setup Python ${{ env.MAIN_PYTHON_VERSION }}" + if: ${{ matrix.tests.label != 'ironpython' }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Create a virtual environment" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + python -m venv .venv + .venv\Scripts\Activate.ps1 + python -m pip install --upgrade ` + --trusted-host pypi.org ` + --trusted-host pypi.python.org ` + --trusted-host files.pythonhosted.org ` + pip + + - name: "Install tests dependencies" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + .venv\Scripts\Activate.ps1 + python -m pip install .[tests] pytest-azurepipelines + + - name: "Install graphics dependencies" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + .venv\Scripts\Activate.ps1 + python -m pip uninstall --yes vtk + python -m pip install --extra-index-url https://wheels.vtk.org ` + vtk-osmesa==${{ env.VTK_OSMESA_VERSION }} + + - name: "Run tests" + uses: nick-fields/retry@v3 + if: ${{ matrix.tests.label != 'ironpython' }} + env: + PYTHONMALLOC: malloc + with: + max_attempts: 2 + retry_on: error + timeout_minutes: 50 + command: | + .venv\Scripts\Activate.ps1 + + pytest ${{ matrix.tests.flags }} ` + --durations=50 -v ` + --cov=pyaedt --cov-report=xml --cov-report=html ` + --junitxml=junit/test-results.xml ` + ${{ matrix.tests.folder }} + + - name: "Upload ${{ matrix.tests.label }} tests coverage" + uses: codecov/codecov-action@v4 + if: ${{ matrix.tests.label != 'ironpython' }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + name: windows-${{ matrix.tests.label }}-tests-coverage + file: ./coverage.xml + flags: system + + - name: "Upload ${{ matrix.tests.name }} tests results" + uses: actions/upload-artifact@v3 + if: ${{ matrix.tests.label != 'ironpython' }} + with: + name: windows-${{ matrix.tests.label }}-tests-results + path: junit/test-results.xml + + build-library: + name: "Build library" + needs: [doc-build-without-examples, tests-linux, tests-windows] + runs-on: ubuntu-latest + steps: + - uses: ansys/actions/build-library@v6 + with: + library-name: ${{ env.PACKAGE_NAME }} + python-version: ${{ env.MAIN_PYTHON_VERSION }} diff --git a/.github/workflows/ci_cd_release.yml b/.github/workflows/ci_cd_release.yml new file mode 100644 index 00000000000..d8b14bb736e --- /dev/null +++ b/.github/workflows/ci_cd_release.yml @@ -0,0 +1,404 @@ +name: release +on: + push: + tags: + - "v*.*.*" + branches: + - "release/*.*" + +env: + ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }} + MAIN_PYTHON_VERSION: '3.10' + PACKAGE_NAME: 'pyaedt' + DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' + MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }} + MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }} + MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }} + ON_CI: True + VTK_OSMESA_VERSION: '9.2.20230527.dev0' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + style: + name: "Style checks" + runs-on: ubuntu-latest + steps: + + # TODO: Update to ansys/actions/doc-style@v6 + - name: "Style of doc" + uses: ansys/actions/doc-style@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + vale-config: "doc/.vale.ini" + vale-version: "2.29.6" + + doc-build: + name: Documentation build with examples + runs-on: [ self-hosted, Windows, pyaedt ] + timeout-minutes: 720 + needs: style + steps: + - name: Install Git and checkout project + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: Create virtual environment + run: | + python -m venv .venv + .venv\Scripts\Activate.ps1 + python -m pip install pip -U + python -m pip install wheel setuptools -U + python -c "import sys; print(sys.executable)" + + - name: Install pyaedt and documentation dependencies + run: | + .venv\Scripts\Activate.ps1 + pip install .[doc] + + - name: Retrieve PyAEDT version + id: version + run: | + .venv\Scripts\Activate.ps1 + echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT + echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")" + + - name: Install CI dependencies (e.g. vtk-osmesa) + run: | + .venv\Scripts\Activate.ps1 + # Uninstall conflicting dependencies + pip uninstall --yes vtk + pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0 + + # TODO: Update this step once pyaedt-examples is ready + # NOTE: Use environment variable to keep the doctree and avoid redundant build for PDF pages + - name: Build HTML documentation with examples + env: + SPHINXBUILD_KEEP_DOCTREEDIR: "1" + run: | + .venv\Scripts\Activate.ps1 + .\doc\make.bat clean + .\doc\make.bat html + + # TODO: Keeping this commented as reminder of https://github.com/ansys/pyaedt/issues/4296 + # # Verify that sphinx generates no warnings + # - name: Check for warnings + # run: | + # .venv\Scripts\Activate.ps1 + # python doc/print_errors.py + + # Use environment variable to remove the doctree after the build of PDF pages + - name: Build PDF documentation with examples + env: + SPHINXBUILD_KEEP_DOCTREEDIR: "0" + run: | + .venv\Scripts\Activate.ps1 + .\doc\make.bat pdf + + - name: Add assets to HTML docs + run: | + zip -r documentation-html.zip ./doc/_build/html + mv documentation-html.zip ./doc/_build/html/_static/assets/download/ + cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf + + - name: Upload HTML documentation with examples artifact + uses: actions/upload-artifact@v3 + with: + name: documentation-html + path: doc/_build/html + retention-days: 7 + + - name: Upload PDF documentation without examples artifact + uses: actions/upload-artifact@v3 + with: + name: documentation-pdf + path: doc/_build/latex/PyAEDT-Documentation-*.pdf + retention-days: 7 + + tests-linux: + name: "Linux / Tests / ${{ matrix.tests.name }}" + needs: style + runs-on: [ self-hosted, Linux, pyaedt ] + env: + ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64' + ANS_NODEPCHECK: '1' + strategy: + fail-fast: false + matrix: + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + - name: "Setup Python ${{ env.MAIN_PYTHON_VERSION }}" + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Create a virtual environment" + run: | + python -m venv .venv + source .venv/bin/activate + python -m pip install --upgrade \ + --trusted-host pypi.org \ + --trusted-host pypi.python.org \ + --trusted-host files.pythonhosted.org \ + pip + + - name: "Install tests dependencies" + run: | + source .venv/bin/activate + python -m pip install .[tests] pytest-azurepipelines + + - name: "Install graphics dependencies" + run: | + source .venv/bin/activate + python -m pip uninstall --yes vtk + python -m pip install --extra-index-url https://wheels.vtk.org \ + vtk-osmesa==${{ env.VTK_OSMESA_VERSION }} + + - name: "Run ${{ matrix.tests.label }} tests" + uses: nick-fields/retry@v3 + with: + max_attempts: 2 + retry_on: error + timeout_minutes: 50 + command: | + export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH + source .venv/bin/activate + + pytest ${{ matrix.tests.flags }} \ + --durations=50 -v \ + --cov=pyaedt --cov-report=xml --cov-report=html \ + --junitxml=junit/test-results.xml \ + ${{ matrix.tests.folder }} + + - name: "Upload ${{ matrix.tests.label }} tests coverage" + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + name: linux-${{ matrix.tests.label }}-tests-coverage + file: ./coverage.xml + flags: system,solver + + - name: "Upload ${{ matrix.tests.name }} tests results" + uses: actions/upload-artifact@v3 + if: ${{ always() }} + with: + name: linux-${{ matrix.tests.label }}-tests-results + path: junit/test-results.xml + + tests-windows: + name: "Windows / Tests / ${{ matrix.tests.name }}" + needs: style + runs-on: [ self-hosted, Windows, pyaedt ] + strategy: + fail-fast: false + matrix: + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + - {name: "IronPython", label: "ironpython", folder: "_unittest_ironpython", flags: ""} + + tests-skip-units: + - contains(github.event.pull_request.labels.*.name, 'tests:units:skip') + + tests-skip-solvers: + - contains(github.event.pull_request.labels.*.name, 'tests:solvers:skip') + + tests-skip-ironpython: + - contains(github.event.pull_request.labels.*.name, 'tests:ironpython:skip') + + exclude: + + - tests-skip-units: true + tests: + - {name: "Units", label: "units", folder: "_unittest", flags: "-n 4 --dist loadfile"} + + - tests-skip-solvers: true + tests: + - {name: "Solvers", label: "solvers", folder: "_unittest_solvers", flags: ""} + + - tests-skip-ironpython: true + tests: + - {name: "IronPython", label: "ironpython", folder: "_unittest_ironpython", flags: ""} + + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + # IronPython tests + + - name: "Tests IronPython" + if: ${{ matrix.tests.label == 'ironpython' }} + timeout-minutes: 5 + run: | + $processA = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd' -PassThru + $processA.WaitForExit() + + - name: "Get logger content" + if: ${{ matrix.tests.label == 'ironpython' }} + run: | + get-content .\${{ matrix.tests.folder }}\pyaedt_unit_test_ironpython.log + + - name: "Check for errors" + if: ${{ matrix.tests.label == 'ironpython' }} + run: | + $test_errors_failures = Select-String -Path .\${{ matrix.tests.folder }}\pyaedt_unit_test_ironpython.log -Pattern "TextTestResult errors=" + if ($test_errors_failures -ne $null) + { + exit 1 + } + + # Solvers and units tests + + - name: "Setup Python ${{ env.MAIN_PYTHON_VERSION }}" + if: ${{ matrix.tests.label != 'ironpython' }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Create a virtual environment" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + python -m venv .venv + .venv\Scripts\Activate.ps1 + python -m pip install --upgrade ` + --trusted-host pypi.org ` + --trusted-host pypi.python.org ` + --trusted-host files.pythonhosted.org ` + pip + + - name: "Install tests dependencies" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + .venv\Scripts\Activate.ps1 + python -m pip install .[tests] pytest-azurepipelines + + - name: "Install graphics dependencies" + if: ${{ matrix.tests.label != 'ironpython' }} + run: | + .venv\Scripts\Activate.ps1 + python -m pip uninstall --yes vtk + python -m pip install --extra-index-url https://wheels.vtk.org ` + vtk-osmesa==${{ env.VTK_OSMESA_VERSION }} + + - name: "Run tests" + uses: nick-fields/retry@v3 + if: ${{ matrix.tests.label != 'ironpython' }} + env: + PYTHONMALLOC: malloc + with: + max_attempts: 2 + retry_on: error + timeout_minutes: 50 + command: | + .venv\Scripts\Activate.ps1 + + pytest ${{ matrix.tests.flags }} ` + --durations=50 -v ` + --cov=pyaedt --cov-report=xml --cov-report=html ` + --junitxml=junit/test-results.xml ` + ${{ matrix.tests.folder }} + + - name: "Upload ${{ matrix.tests.label }} tests coverage" + uses: codecov/codecov-action@v4 + if: ${{ matrix.tests.label != 'ironpython' }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + name: windows-${{ matrix.tests.label }}-tests-coverage + file: ./coverage.xml + flags: system + + - name: "Upload ${{ matrix.tests.name }} tests results" + uses: actions/upload-artifact@v3 + if: ${{ matrix.tests.label != 'ironpython' }} + with: + name: windows-${{ matrix.tests.label }}-tests-results + path: junit/test-results.xml + + build-library: + name: "Build library" + needs: [doc-build, tests-linux, tests-windows] + runs-on: ubuntu-latest + steps: + - uses: ansys/actions/build-library@v6 + with: + library-name: ${{ env.PACKAGE_NAME }} + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + + # TODO: Si if we can fix the PDF issue and leverage classic ansys/release-github + release: + name: "Release project" + if: github.event_name == 'push' && contains(github.ref, 'refs/tags') + needs: [package, doc-build-with-examples] + runs-on: ubuntu-latest + steps: + + - name: "Release to the public PyPI repository" + uses: ansys/actions/release-pypi-public@v4 + with: + library-name: ${{ env.PACKAGE_NAME }} + twine-username: "__token__" + twine-token: ${{ secrets.PYPI_TOKEN }} + + - name: "Release to GitHub" + uses: ansys/actions/release-github@v4 + with: + library-name: ${{ env.PACKAGE_NAME }} + + doc-deploy-stable: + name: "Deploy stable docs" + if: github.event_name == 'push' && contains(github.ref, 'refs/tags') + runs-on: ubuntu-latest + needs: [release] + steps: + uses: ansys/actions/doc-deploy-stable@v6 + with: + cname: ${{ env.DOCUMENTATION_CNAME }} + token: ${{ secrets.GITHUB_TOKEN }} + doc-artifact-name: 'documentation-html' + + doc-deploy-index: + name: "Deploy stable docs index" + if: github.event_name == 'push' && contains(github.ref, 'refs/tags') + runs-on: ubuntu-latest + needs: upload-release-doc + steps: + + - name: "Checkout project" + uses: actions/checkout@v4 + + - name: "Install project dependencies" + run: | + python -m pip install -e . + + - name: "Get the version to PyMeilisearch" + run: | + VERSION=$(python -c "from pyaedt import __version__; print('.'.join(__version__.split('.')[:2]))") + VERSION_MEILI=$(python -c "from pyaedt import __version__; print('-'.join(__version__.split('.')[:2]))") + echo "Calculated VERSION: $VERSION" + echo "Calculated VERSION_MEILI: $VERSION_MEILI" + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "VERSION_MEILI=$VERSION_MEILI" >> $GITHUB_ENV + + - name: "Deploy the latest documentation index" + uses: ansys/actions/doc-deploy-index@v6 + with: + cname: ${{ env.DOCUMENTATION_CNAME }}/version/${{ env.VERSION }} + index-name: pyaedt-v${{ env.VERSION_MEILI }} + host-url: ${{ env.MEILISEARCH_HOST_URL }} + api-key: ${{ env.MEILISEARCH_API_KEY }} + python-version: ${{ env.MAIN_PYTHON_VERSION }} diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml deleted file mode 100644 index 596cace4c8f..00000000000 --- a/.github/workflows/label.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Labeler -on: - pull_request: - push: - branches: [ main ] - paths: - - '../labels.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - - label-syncer: - name: Syncer - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: micnncim/action-label-syncer@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - labeler: - name: Set labels - needs: [label-syncer] - permissions: - contents: read - pull-requests: write - runs-on: ubuntu-latest - steps: - - # Label based on modified files - - name: Label based on changed files - uses: actions/labeler@v5 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - - # Label based on branch name - - uses: actions-ecosystem/action-add-labels@v1 - if: | - startsWith(github.event.pull_request.head.ref, 'doc') || - startsWith(github.event.pull_request.head.ref, 'docs') - with: - labels: documentation - - - uses: actions-ecosystem/action-add-labels@v1 - if: | - startsWith(github.event.pull_request.head.ref, 'maint') || - startsWith(github.event.pull_request.head.ref, 'no-ci') || - startsWith(github.event.pull_request.head.ref, 'ci') - with: - labels: maintenance - - - uses: actions-ecosystem/action-add-labels@v1 - if: startsWith(github.event.pull_request.head.ref, 'feat') - with: - labels: | - enhancement - - - uses: actions-ecosystem/action-add-labels@v1 - if: | - startsWith(github.event.pull_request.head.ref, 'fix') || - startsWith(github.event.pull_request.head.ref, 'patch') - with: - labels: bug - - - uses: actions-ecosystem/action-add-labels@v1 - if: | - startsWith(github.event.pull_request.head.ref, 'test') - with: - labels: testing - - commenter: - runs-on: ubuntu-latest - steps: - - name: Suggest to add labels - uses: peter-evans/create-or-update-comment@v4 - # Execute only when no labels have been applied to the pull request - if: toJSON(github.event.pull_request.labels.*.name) == '{}' - with: - issue-number: ${{ github.event.pull_request.number }} - body: | - Please add one of the following labels to add this contribution to the Release Notes :point_down: - - [bug](https://github.com/ansys/pyaedt/pulls?q=label%3Abug+) - - [documentation](https://github.com/ansys/pyaedt/pulls?q=label%3Adocumentation+) - - [enhancement](https://github.com/ansys/pyaedt/pulls?q=label%3Aenhancement+) - - [good first issue](https://github.com/ansys/pyaedt/pulls?q=label%3Agood+first+issue) - - [maintenance](https://github.com/ansys/pyaedt/pulls?q=label%3Amaintenance+) - - [release](https://github.com/ansys/pyaedt/pulls?q=label%3Arelease+) - - [testing](https://github.com/ansys/pyaedt/pulls?q=label%Atesting+)