diff --git a/.github/workflows/ApplicationTesting.yml b/.github/workflows/ApplicationTesting.yml index e60c0966..c4830c6a 100644 --- a/.github/workflows/ApplicationTesting.yml +++ b/.github/workflows/ApplicationTesting.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -85,7 +85,7 @@ jobs: uses: actions/checkout@v4 - name: πŸ“₯ Download artifacts '${{ inputs.wheel }}' from 'Package' job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.wheel }} path: install @@ -180,7 +180,7 @@ jobs: - name: 🐍 Setup Python ${{ matrix.python }} if: matrix.system != 'msys2' - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} @@ -222,7 +222,7 @@ jobs: - name: πŸ“€ Upload 'TestReportSummary.xml' artifact if: inputs.artifact != '' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact }}-${{ matrix.system }}-${{ matrix.python }} path: ${{ inputs.tests_directory || '.' }}/TestReportSummary.xml diff --git a/.github/workflows/ArtifactCleanUp.yml b/.github/workflows/ArtifactCleanUp.yml index c252a118..24805777 100644 --- a/.github/workflows/ArtifactCleanUp.yml +++ b/.github/workflows/ArtifactCleanUp.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -45,12 +45,14 @@ jobs: - name: πŸ—‘οΈ Delete package Artifacts if: ${{ ! startsWith(github.ref, 'refs/tags') }} - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v4 with: name: ${{ inputs.package }} + token: ${{ secrets.GITHUB_TOKEN }} - name: πŸ—‘οΈ Delete remaining Artifacts if: ${{ inputs.remaining != '' }} - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v4 with: name: ${{ inputs.remaining }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/BuildTheDocs.yml b/.github/workflows/BuildTheDocs.yml index c2f1d6ed..44b13ea7 100644 --- a/.github/workflows/BuildTheDocs.yml +++ b/.github/workflows/BuildTheDocs.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -47,7 +47,7 @@ jobs: - name: πŸ“€ Upload 'documentation' artifacts if: inputs.artifact != '' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact }} path: doc/_build/html diff --git a/.github/workflows/CheckDocumentation.yml b/.github/workflows/CheckDocumentation.yml new file mode 100644 index 00000000..285516a9 --- /dev/null +++ b/.github/workflows/CheckDocumentation.yml @@ -0,0 +1,67 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# # +# ==================================================================================================================== # +# Copyright 2020-2024 The pyTooling Authors # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# SPDX-License-Identifier: Apache-2.0 # +# ==================================================================================================================== # +name: Check Documentation + +on: + workflow_call: + inputs: + python_version: + description: 'Python version.' + required: false + default: '3.12' + type: string + directory: + description: 'Source code directory to check.' + required: true + type: string +# fail_below: +# description: 'Minimum required documentation coverage level' +# required: false +# default: 75 +# type: string + +jobs: + DocCoverage: + name: πŸ‘€ Check documentation coverage + runs-on: ubuntu-latest + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v4 + + - name: 🐍 Setup Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: πŸ”§ Install wheel,tomli and pip dependencies (native) + run: | + python -m pip install --disable-pip-version-check -U docstr_coverage interrogate + + - name: Run 'interrogate' Documentation Coverage Check + continue-on-error: true + run: | + interrogate -c pyproject.toml + + - name: Run 'docstr_coverage' Documentation Coverage Check + continue-on-error: true + run: | + docstr_coverage -v ${{ inputs.directory }} diff --git a/.github/workflows/CoverageCollection.yml b/.github/workflows/CoverageCollection.yml index 9c3e4e38..2922e251 100644 --- a/.github/workflows/CoverageCollection.yml +++ b/.github/workflows/CoverageCollection.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -70,7 +70,7 @@ jobs: uses: actions/checkout@v4 - name: 🐍 Setup Python ${{ inputs.python_version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ inputs.python_version }} @@ -148,7 +148,7 @@ jobs: - name: πŸ“€ Upload 'Coverage Report' artifact continue-on-error: true - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact }} path: ${{ steps.getVariables.outputs.coverage_report_html_directory }} diff --git a/Actions/__init__.py b/.github/workflows/IntermediateCleanUp.yml similarity index 66% rename from Actions/__init__.py rename to .github/workflows/IntermediateCleanUp.yml index f8fa48a6..4699446f 100644 --- a/Actions/__init__.py +++ b/.github/workflows/IntermediateCleanUp.yml @@ -1,17 +1,9 @@ # ==================================================================================================================== # -# _____ _ _ _ _ _ # -# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / \ ___| |_(_) ___ _ __ ___ # -# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` | / _ \ / __| __| |/ _ \| '_ \/ __| # -# | |_) | |_| || | (_) | (_) | | | | | | (_| |_ / ___ \ (__| |_| | (_) | | | \__ \ # -# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)_/ \_\___|\__|_|\___/|_| |_|___/ # -# |_| |___/ |___/ # -# ==================================================================================================================== # # Authors: # # Patrick Lehmann # # # -# License: # # ==================================================================================================================== # -# Copyright 2017-2023 Patrick Lehmann - BΓΆtzingen, Germany # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -27,11 +19,37 @@ # # # SPDX-License-Identifier: Apache-2.0 # # ==================================================================================================================== # -# -"""Placeholder""" -__author__ = "Patrick Lehmann" -__email__ = "Paebbels@gmail.com" -__copyright__ = "2017-2022, Patrick Lehmann" -__license__ = "Apache License, Version 2.0" -__version__ = "0.4.4" -__keywords__ = [] +name: Intermediate Cleanup + +on: + workflow_call: + inputs: + sqlite_coverage_artifacts_prefix: + description: 'Prefix for SQLite coverage artifacts' + required: false + type: string + xml_unittest_artifacts_prefix: + description: 'Prefix for XML unittest artifacts' + required: false + type: string + +jobs: + IntermediateCleanUp: + name: πŸ—‘οΈ Intermediate Artifact Cleanup + runs-on: ubuntu-latest + steps: + - name: πŸ—‘οΈ Delete SQLite coverage artifacts from matrix jobs + uses: geekyeggo/delete-artifact@v4 + if: inputs.sqlite_coverage_artifacts_prefix != '' + continue-on-error: true + with: + name: ${{ inputs.sqlite_coverage_artifacts_prefix }}* + token: ${{ secrets.GITHUB_TOKEN }} + + - name: πŸ—‘οΈ Delete XML coverage artifacts from matrix jobs + uses: geekyeggo/delete-artifact@v4 + if: inputs.xml_unittest_artifacts_prefix != '' + continue-on-error: true + with: + name: ${{ inputs.xml_unittest_artifacts_prefix }}* + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/LaTeXDocumentation.yml b/.github/workflows/LaTeXDocumentation.yml new file mode 100644 index 00000000..0c4d3757 --- /dev/null +++ b/.github/workflows/LaTeXDocumentation.yml @@ -0,0 +1,66 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# # +# ==================================================================================================================== # +# Copyright 2020-2024 The pyTooling Authors # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# SPDX-License-Identifier: Apache-2.0 # +# ==================================================================================================================== # +name: LaTeX Documentation + +on: + workflow_call: + inputs: + document: + description: 'LaTeX root document without *.tex extension.' + required: true + type: string + latex_artifact: + description: 'Name of the LaTeX documentation artifact.' + required: false + default: '' + type: string + pdf_artifact: + description: 'Name of the PDF documentation artifact.' + required: false + default: '' + type: string + +jobs: + PDFDocumentation: + name: πŸ““ Converting LaTeX Documentation to PDF + runs-on: ubuntu-latest + steps: + - name: πŸ“₯ Download artifacts '${{ inputs.latex_artifact }}' from 'SphinxDocumentation' job + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.latex_artifact }} + path: latex + + - name: Compile LaTeX document + uses: xu-cheng/latex-action@master + with: + working_directory: latex + root_file: ${{ inputs.document }}.tex + + - name: πŸ“€ Upload 'PDF Documentation' artifact + uses: actions/upload-artifact@v4 + if: inputs.pdf_artifact != '' + with: + name: ${{ inputs.pdf_artifact }} + path: ${{ inputs.document }}.pdf + if-no-files-found: error + retention-days: 1 diff --git a/.github/workflows/Package.yml b/.github/workflows/Package.yml index 6ae3812a..5378fbc2 100644 --- a/.github/workflows/Package.yml +++ b/.github/workflows/Package.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -28,7 +28,7 @@ on: python_version: description: 'Python version.' required: false - default: '3.11' + default: '3.12' type: string requirements: description: 'Python dependencies to be installed through pip; if empty, use pyproject.toml through build.' @@ -51,7 +51,7 @@ jobs: uses: actions/checkout@v4 - name: 🐍 Setup Python ${{ inputs.python_version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ inputs.python_version }} @@ -98,7 +98,7 @@ jobs: run: python setup.py bdist_wheel - name: πŸ“€ Upload wheel artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact }} path: dist/ diff --git a/.github/workflows/Parameters.yml b/.github/workflows/Parameters.yml index 496d26d9..bc18f838 100644 --- a/.github/workflows/Parameters.yml +++ b/.github/workflows/Parameters.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -32,17 +32,17 @@ on: python_version: description: 'Python version.' required: false - default: '3.11' + default: '3.12' type: string python_version_list: description: 'Space separated list of Python versions to run tests with.' required: false - default: '3.8 3.9 3.10 3.11' + default: '3.8 3.9 3.10 3.11 3.12' type: string system_list: description: 'Space separated list of systems to run tests on.' required: false - default: 'ubuntu windows mingw64 macos' + default: 'ubuntu windows macos mingw64 ucrt64' type: string include_list: description: 'Space separated list of system:python items to be included into the list of test.' @@ -102,9 +102,9 @@ jobs: exclude_list = "${{ inputs.exclude_list }}".strip() disable_list = "${{ inputs.disable_list }}".strip() - currentMSYS2Version = "3.10" - currentAlphaVersion = "3.12" - currentAlphaRelease = "3.12.0-alpha.1" + currentMSYS2Version = "3.11" + currentAlphaVersion = "3.13" + currentAlphaRelease = "3.13.0-alpha.1" if systems == "": print("::error title=Parameter::system_list is empty.") @@ -131,8 +131,8 @@ jobs: else: disabled = [disable.strip() for disable in disable_list.split(" ")] - if "3.6" in versions: - print("::warning title=Deprecated::Support for Python 3.6 ended in 2021.12.23.") + if "3.7" in versions: + print("::warning title=Deprecated::Support for Python 3.7 ended in 2023.06.27.") if "msys2" in systems: print("::warning title=Deprecated::System 'msys2' will be replaced by 'mingw64'.") if currentAlphaVersion in versions: @@ -143,16 +143,17 @@ jobs: data = { # Python and PyPy versions supported by "setup-python" action "python": { - "3.6": { "icon": "⚫", "until": "2021.12.23" }, "3.7": { "icon": "⚫", "until": "2023.06.27" }, "3.8": { "icon": "πŸ”΄", "until": "2024.10" }, "3.9": { "icon": "🟠", "until": "2025.10" }, "3.10": { "icon": "🟑", "until": "2026.10" }, "3.11": { "icon": "🟒", "until": "2027.10" }, - "3.12": { "icon": "🟣", "until": "2028.10" }, - "pypy-3.7": { "icon": "βŸ²πŸ”΄", "until": "????.??" }, - "pypy-3.8": { "icon": "⟲🟠", "until": "????.??" }, - "pypy-3.9": { "icon": "⟲🟑", "until": "????.??" }, + "3.12": { "icon": "🟒", "until": "2028.10" }, + # "3.13": { "icon": "🟣", "until": "2028.10" }, + "pypy-3.7": { "icon": "⟲⚫", "until": "????.??" }, + "pypy-3.8": { "icon": "βŸ²πŸ”΄", "until": "????.??" }, + "pypy-3.9": { "icon": "⟲🟠", "until": "????.??" }, + "pypy-3.10": { "icon": "⟲🟑", "until": "????.??" }, }, # Runner systems (runner images) supported by GitHub Actions "sys": { @@ -211,6 +212,7 @@ jobs: "sysicon": data["sys"][system]["icon"], "system": system, "runs-on": data["sys"][system]["runs-on"], + "runtime": "native", "shell": data["sys"][system]["shell"], "pyicon": data["python"][version]["icon"], "python": currentAlphaRelease if version == currentAlphaVersion else version, @@ -232,16 +234,20 @@ jobs: ] artifact_names = { - "unittesting_xml": f"{name}-UnitTestReportSummary-XML", - "perftesting_xml": f"{name}-PerformanceTestReportSummary-XML", - "benchtesting_xml": f"{name}-BenchmarkTestReportSummary-XML", - "apptesting_xml": f"{name}-ApplicationTestReportSummary-XML", - "codecoverage_xml": f"{name}-CodeCoverage-XML", - "codecoverage_html": f"{name}-CodeCoverage-HTML", - "statictyping_html": f"{name}-StaticTyping-HTML", - "package_all": f"{name}-Packages", - "documentation_pdf": f"{name}-Documentation-PDF", - "documentation_html": f"{name}-Documentation-HTML", + "unittesting_xml": f"{name}-UnitTestReportSummary-XML", + "unittesting_html": f"{name}-UnitTestReportSummary-HTML", + "perftesting_xml": f"{name}-PerformanceTestReportSummary-XML", + "benchtesting_xml": f"{name}-BenchmarkTestReportSummary-XML", + "apptesting_xml": f"{name}-ApplicationTestReportSummary-XML", + "codecoverage_sqlite": f"{name}-CodeCoverage-SQLite", + "codecoverage_xml": f"{name}-CodeCoverage-XML", + "codecoverage_json": f"{name}-CodeCoverage-JSON", + "codecoverage_html": f"{name}-CodeCoverage-HTML", + "statictyping_html": f"{name}-StaticTyping-HTML", + "package_all": f"{name}-Packages", + "documentation_html": f"{name}-Documentation-HTML", + "documentation_latex": f"{name}-Documentation-LaTeX", + "documentation_pdf": f"{name}-Documentation-PDF", } # Deprecated structure diff --git a/.github/workflows/Pipeline.yml b/.github/workflows/Pipeline.yml deleted file mode 100644 index 77689117..00000000 --- a/.github/workflows/Pipeline.yml +++ /dev/null @@ -1,10 +0,0 @@ -#name: Pipeline -name: Documentation - -on: - push: - workflow_dispatch: - -jobs: - BuildTheDocs: - uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@dev diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 017da5f2..30031ff2 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -19,15 +19,35 @@ # # # SPDX-License-Identifier: Apache-2.0 # # ==================================================================================================================== # -name: Publish Unit Test Results +name: Publish Code Coverage Results on: workflow_call: inputs: - report_files: - description: 'Pattern of report files to upload. Can be a comma separated list.' + coverage_config: + description: 'Path to the .coveragerc file. Use pyproject.toml by default.' required: false - default: 'artifacts/**/*.xml' + default: 'pyproject.toml' + type: string + coverage_sqlite_artifact: + description: 'Name of the SQLite coverage artifact.' + required: false + default: '' + type: string + coverage_xml_artifact: + description: 'Name of the XML coverage artifact.' + required: false + default: '' + type: string + coverage_json_artifact: + description: 'Name of the JSON coverage artifact.' + required: false + default: '' + type: string + coverage_html_artifact: + description: 'Name of the HTML coverage artifact.' + required: false + default: '' type: string secrets: codacy_token: @@ -35,8 +55,8 @@ on: required: true jobs: - PublishTestResults: - name: πŸ“Š Publish Test Results + PublishCoverageResults: + name: πŸ“Š Publish Code Coverage Results runs-on: ubuntu-latest if: always() @@ -45,10 +65,137 @@ jobs: uses: actions/checkout@v4 - name: Download Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: artifacts + - name: πŸ”§ Install coverage and tomli + run: | + python -m pip install --disable-pip-version-check -U coverage[toml] tomli + + - name: πŸ” Extract configurations from pyproject.toml + id: getVariables + shell: python + run: | + from os import getenv + from pathlib import Path + from sys import version + from textwrap import dedent + + print(f"Python: {version}") + + from tomli import load as tomli_load + + htmlDirectory = Path("htmlcov") + xmlFile = Path("./coverage.xml") + jsonFile = Path("./coverage.json") + coverageRC = "${{ inputs.coverage_config }}".strip() + + # Read output paths from 'pyproject.toml' file + if coverageRC == "pyproject.toml": + pyProjectFile = Path("pyproject.toml") + if pyProjectFile.exists(): + with pyProjectFile.open("rb") as file: + pyProjectSettings = tomli_load(file) + + htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"]) + xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"]) + jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"]) + else: + print(f"File '{pyProjectFile}' not found and no '.coveragerc' file specified.") + + # Read output paths from '.coveragerc' file + elif len(coverageRC) > 0: + coverageRCFile = Path(coverageRC) + if coverageRCFile.exists(): + with coverageRCFile.open("rb") as file: + coverageRCSettings = tomli_load(file) + + htmlDirectory = Path(coverageRCSettings["html"]["directory"]) + xmlFile = Path(coverageRCSettings["xml"]["output"]) + jsonFile = Path(coverageRCSettings["json"]["output"]) + else: + print(f"File '{coverageRCFile}' not found.") + + # Write jobs to special file + github_output = Path(getenv("GITHUB_OUTPUT")) + print(f"GITHUB_OUTPUT: {github_output}") + with github_output.open("a+", encoding="utf-8") as f: + f.write(dedent(f"""\ + coverage_report_html_directory={htmlDirectory.as_posix()} + coverage_report_xml={xmlFile} + coverage_report_json={jsonFile} + """)) + + print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}") + + - name: Rename .coverage files and collect them all to coverage/ + run: | + mkdir -p coverage + find . -type f -path "*artifacts*SQLite*.coverage" -exec sh -c 'cp -v $0 "coverage/$(basename $0).$(basename $(dirname $0))"' {} ';' + tree -a coverage + + - name: Combine SQLite files (using Coverage.py) + run: coverage combine --data-file=.coverage coverage/ + + - name: Report code coverage + run: coverage report --rcfile=pyproject.toml --data-file=.coverage + + - name: Convert to XML format (Cobertura) + if: inputs.coverage_xml_artifact != '' + run: coverage xml --data-file=.coverage + + - name: Convert to JSON format + if: inputs.coverage_json_artifact != '' + run: coverage json --data-file=.coverage + + - name: Convert to HTML format + if: inputs.coverage_html_artifact != '' + run: | + coverage html --data-file=.coverage -d report/coverage/html + rm report/coverage/html/.gitignore + tree -a report/coverage/html + + - name: πŸ“€ Upload 'Coverage SQLite Database' artifact + if: inputs.coverage_sqlite_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_sqlite_artifact }} + path: .coverage + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage XML Report' artifact + if: inputs.coverage_xml_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_xml_artifact }} + path: ${{ steps.getVariables.outputs.coverage_report_xml }} + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage JSON Report' artifact + if: inputs.coverage_json_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_json_artifact }} + path: ${{ steps.getVariables.outputs.coverage_report_json }} + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage HTML Report' artifact + if: inputs.coverage_html_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_html_artifact }} + path: ${{ steps.getVariables.outputs.coverage_report_html_directory }} + if-no-files-found: error + retention-days: 1 + - name: πŸ“Š Publish code coverage at CodeCov if: inputs.CodeCov == true continue-on-error: true diff --git a/.github/workflows/PublishOnPyPI.yml b/.github/workflows/PublishOnPyPI.yml index 044575a8..4ec8ba81 100644 --- a/.github/workflows/PublishOnPyPI.yml +++ b/.github/workflows/PublishOnPyPI.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -28,7 +28,7 @@ on: python_version: description: 'Python version.' required: false - default: '3.11' + default: '3.12' type: string requirements: description: 'Python dependencies to be installed through pip.' @@ -52,13 +52,13 @@ jobs: steps: - name: πŸ“₯ Download artifacts '${{ inputs.artifact }}' from 'Package' job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.artifact }} path: dist/ - name: 🐍 Setup Python ${{ inputs.python_version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ inputs.python_version }} @@ -78,6 +78,6 @@ jobs: run: twine upload dist/*.whl - name: πŸ—‘οΈ Delete packaging Artifacts - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v4 with: name: ${{ inputs.artifact }} diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 35771dac..fd9391ad 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -25,10 +25,10 @@ name: Publish Unit Test Results on: workflow_call: inputs: - report_files: - description: 'Pattern of report files to upload. Can be a comma separated list.' + merged_junit_artifact: + description: 'Name of the merged JUnit Test Summary artifact.' required: false - default: 'artifacts/**/*.xml' + default: '' type: string jobs: @@ -42,13 +42,48 @@ jobs: uses: actions/checkout@v4 - name: Download Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: artifacts + - name: πŸ”§ Install junitparser + run: | + python -m pip install --disable-pip-version-check -U junitparser + + - name: Move JUnit files and collect them all to junit/ + run: | + mkdir -p junit + find . -type f -path "*artifacts*UnitTestReportSummary*.xml" -exec sh -c 'cp -v $0 "junit/$(basename $(dirname $0)).$(basename $0)"' {} ';' + tree -a junit + + - name: πŸ” Merge JUnit Unit Test Summaries + shell: python + run: | + from pathlib import Path + from junitparser import JUnitXml + + junitDirectory = Path("junit") + junitXml = None + for file in junitDirectory.iterdir(): + if junitXml is None: + junitXml = JUnitXml.fromfile(file) + else: + junitXml += JUnitXml.fromfile(file) + + junitXml.write(junitDirectory / "merged.xml") + - name: πŸ“Š Publish Unit Test Results uses: dorny/test-reporter@v1 with: name: Unit Test Results - path: ${{ inputs.report_files }} + path: junit/merged.xml reporter: java-junit + + - name: πŸ“€ Upload merged 'JUnit Test Summary' artifact + if: inputs.merged_junit_artifact != '' + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.merged_junit_artifact }} + path: junit/merged.xml + if-no-files-found: error + retention-days: 1 diff --git a/.github/workflows/PublishToGitHubPages.yml b/.github/workflows/PublishToGitHubPages.yml index 445a25c5..351eb02b 100644 --- a/.github/workflows/PublishToGitHubPages.yml +++ b/.github/workflows/PublishToGitHubPages.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -51,21 +51,21 @@ jobs: uses: actions/checkout@v4 - name: πŸ“₯ Download artifacts '${{ inputs.doc }}' from 'BuildTheDocs' job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.doc }} path: public - name: πŸ“₯ Download artifacts '${{ inputs.coverage }}' from 'Coverage' job if: ${{ inputs.coverage != '' }} - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.coverage }} path: public/coverage - name: πŸ“₯ Download artifacts '${{ inputs.typing }}' from 'StaticTypeCheck' job if: ${{ inputs.typing != '' }} - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: ${{ inputs.typing }} path: public/typing diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index f0fb2f78..cc3d4938 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # diff --git a/.github/workflows/SphinxDocumentation.yml b/.github/workflows/SphinxDocumentation.yml new file mode 100644 index 00000000..34f9d48e --- /dev/null +++ b/.github/workflows/SphinxDocumentation.yml @@ -0,0 +1,203 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# # +# ==================================================================================================================== # +# Copyright 2020-2024 The pyTooling Authors # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +# SPDX-License-Identifier: Apache-2.0 # +# ==================================================================================================================== # +name: Documentation + +on: + workflow_call: + inputs: + python_version: + description: 'Python version.' + required: false + default: '3.12' + type: string + requirements: + description: 'Python dependencies to be installed through pip.' + required: false + default: '-r doc/requirements.txt' + type: string + coverage_config: + description: 'Path to the .coveragerc file. Use pyproject.toml by default.' + required: false + default: 'pyproject.toml' + type: string + doc_directory: + description: 'Path to the directory containing documentation (Sphinx working directory).' + required: false + default: 'doc' + type: string + coverage_json_artifact: + description: 'Name of the coverage JSON artifact.' + required: false + default: '' + type: string + unittest_xml_artifact: + description: 'Name of the unittest XML artifact.' + required: false + default: '' + type: string + unittest_xml_directory: + description: 'Directory where unittest XML artifact is extracted.' + required: false + default: 'report/unit' + type: string + html_artifact: + description: 'Name of the HTML documentation artifact.' + required: false + default: '' + type: string + latex_artifact: + description: 'Name of the LaTeX documentation artifact.' + required: false + default: '' + type: string + +jobs: + Sphinx: + name: πŸ““ Documentation generation using Sphinx and Python ${{ inputs.python_version }} + runs-on: ubuntu-latest + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v4 + + - name: πŸ”§ Install graphviz + run: sudo apt-get install -y --no-install-recommends graphviz + + - name: 🐍 Setup Python ${{ inputs.python_version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python_version }} + + - name: πŸ”§ Install wheel,tomli and pip dependencies (native) + run: | + python -m pip install --disable-pip-version-check -U wheel tomli + python -m pip install --disable-pip-version-check ${{ inputs.requirements }} + + - name: πŸ” Extract configurations from pyproject.toml + id: getVariables + shell: python + run: | + from os import getenv + from pathlib import Path + from sys import version + from textwrap import dedent + + print(f"Python: {version}") + + from tomli import load as tomli_load + + htmlDirectory = Path("htmlcov") + xmlFile = Path("./coverage.xml") + jsonFile = Path("./coverage.json") + coverageRC = "${{ inputs.coverage_config }}".strip() + + # Read output paths from 'pyproject.toml' file + if coverageRC == "pyproject.toml": + pyProjectFile = Path("pyproject.toml") + if pyProjectFile.exists(): + with pyProjectFile.open("rb") as file: + pyProjectSettings = tomli_load(file) + + htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"]) + xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"]) + jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"]) + else: + print(f"File '{pyProjectFile}' not found and no '.coveragerc' file specified.") + + # Read output paths from '.coveragerc' file + elif len(coverageRC) > 0: + coverageRCFile = Path(coverageRC) + if coverageRCFile.exists(): + with coverageRCFile.open("rb") as file: + coverageRCSettings = tomli_load(file) + + htmlDirectory = Path(coverageRCSettings["html"]["directory"]) + xmlFile = Path(coverageRCSettings["xml"]["output"]) + jsonFile = Path(coverageRCSettings["json"]["output"]) + else: + print(f"File '{coverageRCFile}' not found.") + + # Write jobs to special file + github_output = Path(getenv("GITHUB_OUTPUT")) + print(f"GITHUB_OUTPUT: {github_output}") + with github_output.open("a+", encoding="utf-8") as f: + f.write(dedent(f"""\ + coverage_report_html_directory={htmlDirectory.as_posix()} + coverage_report_xml_directory={xmlFile.parent.as_posix()} + coverage_report_xml={xmlFile.as_posix()} + coverage_report_json_directory={jsonFile.parent.as_posix()} + coverage_report_json={jsonFile.as_posix()} + """)) + + print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}") + + - name: πŸ“₯ Download artifacts '${{ inputs.unittest_xml_artifact }}' from 'Unittesting' job + if: inputs.unittest_xml_artifact != '' + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.unittest_xml_artifact }} + path: ${{ inputs.unittest_xml_directory }} + + - name: πŸ“₯ Download artifacts '${{ inputs.coverage_json_artifact }}' from 'PublishCoverageResults' job + if: inputs.coverage_json_artifact != '' + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.coverage_json_artifact }} + path: ${{ steps.getVariables.outputs.coverage_report_json_directory }} + + - name: β˜‘ Generate HTML documentation + if: inputs.html_artifact != '' + run: | + export PYTHONPATH=$(pwd) + + cd "${{ inputs.doc_directory || '.' }}" + sphinx-build -v -n -b html -d _build/doctrees -j $(nproc) -w _build/html.log . _build/html + + - name: β˜‘ Generate LaTeX documentation + if: inputs.latex_artifact != '' +# continue-on-error: true + run: | + export PYTHONPATH=$(pwd) + + cd "${{ inputs.doc_directory || '.' }}" + sphinx-build -v -n -b latex -d _build/doctrees -j $(nproc) -w _build/latex.log . _build/latex +# --builder html --doctree-dir _build/doctrees --verbose --fresh-env --write-all --nitpicky --warning-file _build/html.log . _build/html + + - name: πŸ“€ Upload 'HTML Documentation' artifact + if: inputs.html_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.html_artifact }} + path: ${{ inputs.doc_directory }}/_build/html + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'LaTeX Documentation' artifact + if: inputs.latex_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.latex_artifact }} + path: ${{ inputs.doc_directory }}/_build/latex + if-no-files-found: error + retention-days: 1 diff --git a/.github/workflows/StaticTypeCheck.yml b/.github/workflows/StaticTypeCheck.yml index 18af69ed..eef16f3e 100644 --- a/.github/workflows/StaticTypeCheck.yml +++ b/.github/workflows/StaticTypeCheck.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -28,7 +28,7 @@ on: python_version: description: 'Python version.' required: false - default: '3.11' + default: '3.12' type: string requirements: description: 'Python dependencies to be installed through pip.' @@ -70,7 +70,7 @@ jobs: uses: actions/checkout@v4 - name: 🐍 Setup Python ${{ inputs.python_version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ inputs.python_version }} @@ -84,7 +84,7 @@ jobs: - name: πŸ“€ Upload 'Static Typing Report' HTML artifact if: ${{ inputs.html_artifact != '' }} continue-on-error: true - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.html_artifact }} path: ${{ inputs.html_report }} @@ -94,7 +94,7 @@ jobs: - name: πŸ“€ Upload 'Static Typing Report' JUnit artifact if: ${{ inputs.junit_artifact != '' }} continue-on-error: true - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.junit_artifact }} path: ${{ inputs.junit_report }} diff --git a/.github/workflows/TestReleaser.yml b/.github/workflows/TestReleaser.yml index 70f46b4d..5ee5787b 100644 --- a/.github/workflows/TestReleaser.yml +++ b/.github/workflows/TestReleaser.yml @@ -3,7 +3,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # diff --git a/.github/workflows/UnitTesting.yml b/.github/workflows/UnitTesting.yml index 18e91d2a..99eecf85 100644 --- a/.github/workflows/UnitTesting.yml +++ b/.github/workflows/UnitTesting.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -20,7 +20,7 @@ # # # SPDX-License-Identifier: Apache-2.0 # # ==================================================================================================================== # -name: Unit Testing +name: Unit Testing (Matrix) on: workflow_call: @@ -54,16 +54,45 @@ on: required: false default: 'unit' type: string - artifact: + coverage_config: + description: 'Path to the .coveragerc file. Use pyproject.toml by default.' + required: false + default: 'pyproject.toml' + type: string + unittest_xml_artifact: + description: "Generate unit test report with junitxml and upload results as an artifact." + required: false + default: '' + type: string + unittest_html_artifact: description: "Generate unit test report with junitxml and upload results as an artifact." required: false default: '' type: string + coverage_sqlite_artifact: + description: 'Name of the SQLite coverage artifact.' + required: false + default: '' + type: string + coverage_xml_artifact: + description: 'Name of the XML coverage artifact.' + required: false + default: '' + type: string + coverage_json_artifact: + description: 'Name of the JSON coverage artifact.' + required: false + default: '' + type: string + coverage_html_artifact: + description: 'Name of the HTML coverage artifact.' + required: false + default: '' + type: string jobs: - UnitTesting: - name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Unit Tests using Python ${{ matrix.python }} + name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Unit Tests - Python ${{ matrix.python }} runs-on: ${{ matrix.runs-on }} strategy: @@ -79,6 +108,12 @@ jobs: - name: ⏬ Checkout repository uses: actions/checkout@v4 + - name: πŸ”§ Install dependencies (system Python for Python shell) + if: matrix.system == 'msys2' + shell: pwsh + run: | + py -3.9 -m pip install --disable-pip-version-check -U tomli + - name: Compute pacman/pacboy packages id: pacboy if: matrix.system == 'msys2' @@ -87,6 +122,9 @@ jobs: from os import getenv from pathlib import Path from re import compile + from sys import version + + print(f"Python: {version}") def loadRequirementsFile(requirementsFile: Path): requirements = [] @@ -111,28 +149,32 @@ jobs: dependencies = [req.strip() for req in requirements.split(" ")] packages = { - "pip": "python-pip:p", - "wheel": "python-wheel:p", "coverage": "python-coverage:p", + "igraph": "igraph:p", + "jinja2": "python-markupsafe:p", "lxml": "python-lxml:p", - "ruamel.yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", "numpy": "python-numpy:p", - "igraph": "igraph:p", + "markupsafe": "python-markupsafe:p", + "pip": "python-pip:p", + "ruamel.yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", + "sphinx": "python-markupsafe:p", + "tomli": "python-tomli:p", + "wheel": "python-wheel:p", } subPackages = { - "pyTooling": { + "pytooling": { "yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", } } - regExp = compile(r"(?P[\w_\-\.]+)(?:\[(?P(?:\w+)(?:,\w+)*)\])?(?:\s*(?P[<>=]+)\s*)(?P\d+(?:\.\d+)*)(?:-(?P\w+))?") + regExp = compile(r"(?P[\w_\-\.]+)(?:\[(?P(?:\w+)(?:\s*,\s*\w+)*)\])?(?:\s*(?P[<>~=]+)\s*)(?P\d+(?:\.\d+)*)(?:-(?P\w+))?") - pacboyPackages = set(("python-pip:p", "python-wheel:p")) + pacboyPackages = set(("python-pip:p", "python-wheel:p", "python-tomli:p")) print(f"Processing dependencies ({len(dependencies)}):") for dependency in dependencies: print(f" {dependency}") - match = regExp.match(dependency) + match = regExp.match(dependency.lower()) if not match: print(f" Wrong format: {dependency}") print(f"::error title=Identifying Pacboy Packages::Unrecognized dependency format '{dependency}'") @@ -169,14 +211,14 @@ jobs: - name: 🐍 Setup Python ${{ matrix.python }} if: matrix.system != 'msys2' - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - - name: πŸ”§ Install wheel and pip dependencies (native) + - name: πŸ”§ Install wheel,tomli and pip dependencies (native) if: matrix.system != 'msys2' run: | - python -m pip install --disable-pip-version-check -U wheel + python -m pip install --disable-pip-version-check -U wheel tomli python -m pip install --disable-pip-version-check ${{ inputs.requirements }} - name: πŸ”§ Install pip dependencies (MSYS2) @@ -188,33 +230,164 @@ jobs: python -m pip install --disable-pip-version-check ${{ inputs.requirements }} fi - - name: β˜‘ Run unit tests (Windows) - if: matrix.system == 'windows' + - name: πŸ” Extract configurations from pyproject.toml + id: getVariables + shell: python run: | - $env:ENVIRONMENT_NAME = "${{ matrix.envname }}" - $env:PYTHONPATH = (Get-Location).ToString() - cd "${{ inputs.tests_directory || '.' }}" - $PYTEST_ARGS = if ("${{ inputs.artifact }}") { "--junitxml=TestReportSummary.xml" } else { "" } - Write-Host "python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }}" - python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }} + from os import getenv + from pathlib import Path + from sys import version + from textwrap import dedent + + print(f"Python: {version}") + + from tomli import load as tomli_load + + htmlDirectory = Path("htmlcov") + xmlFile = Path("./coverage.xml") + jsonFile = Path("./coverage.json") + coverageRC = "${{ inputs.coverage_config }}".strip() + + # Read output paths from 'pyproject.toml' file + if coverageRC == "pyproject.toml": + pyProjectFile = Path("pyproject.toml") + if pyProjectFile.exists(): + with pyProjectFile.open("rb") as file: + pyProjectSettings = tomli_load(file) + + htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"]) + xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"]) + jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"]) + else: + print(f"File '{pyProjectFile}' not found and no '.coveragerc' file specified.") + + # Read output paths from '.coveragerc' file + elif len(coverageRC) > 0: + coverageRCFile = Path(coverageRC) + if coverageRCFile.exists(): + with coverageRCFile.open("rb") as file: + coverageRCSettings = tomli_load(file) + + htmlDirectory = Path(coverageRCSettings["html"]["directory"]) + xmlFile = Path(coverageRCSettings["xml"]["output"]) + jsonFile = Path(coverageRCSettings["json"]["output"]) + else: + print(f"File '{coverageRCFile}' not found.") + + # Write jobs to special file + github_output = Path(getenv("GITHUB_OUTPUT")) + print(f"GITHUB_OUTPUT: {github_output}") + with github_output.open("a+", encoding="utf-8") as f: + f.write(dedent(f"""\ + unittest_report_html_directory={htmlDirectory} + coverage_report_html_directory={htmlDirectory.as_posix()} + coverage_report_xml={xmlFile} + coverage_report_json={jsonFile} + """)) + + print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}") - name: β˜‘ Run unit tests (Ubuntu/macOS) if: matrix.system != 'windows' run: | export ENVIRONMENT_NAME="${{ matrix.envname }}" export PYTHONPATH=$(pwd) - ABSDIR=$(pwd) - cd "${{ inputs.tests_directory || '.' }}" - [ -n '${{ inputs.coverage_config }}' ] && PYCOV_ARGS="--cov-config=${ABSDIR}/${{ inputs.coverage_config }}" || unset PYCOV_ARGS - [ -n '${{ inputs.artifact }}' ] && PYTEST_ARGS='--junitxml=TestReportSummary.xml' || unset PYTEST_ARGS - echo "python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }}" - python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }} + + # cd "${{ inputs.tests_directory || '.' }}" + [ -n '${{ inputs.unittest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=report/unit/TestReportSummary.xml' || unset PYTEST_ARGS + if [ -n '${{ inputs.coverage_config }}' ]; then + echo "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}" + coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }} + else + echo "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}" + python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }} + fi + + - name: β˜‘ Run unit tests (Windows) + if: matrix.system == 'windows' + run: | + $env:ENVIRONMENT_NAME = "${{ matrix.envname }}" + $env:PYTHONPATH = (Get-Location).ToString() + + # cd "${{ inputs.tests_directory || '.' }}" + $PYTEST_ARGS = if ("${{ inputs.unittest_xml_artifact }}") { "--junitxml=report/unit/TestReportSummary.xml" } else { "" } + if ("${{ inputs.coverage_config }}") { + Write-Host "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}" + coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }} + } else { + Write-Host "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}" + python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }} + } + + - name: Convert to XML format (Cobertura) + if: inputs.coverage_xml_artifact != '' + run: coverage xml --data-file=.coverage + + - name: Convert to JSON format + if: inputs.coverage_json_artifact != '' + run: coverage json --data-file=.coverage + + - name: Convert to HTML format + if: inputs.coverage_html_artifact != '' + run: | + coverage html --data-file=.coverage -d ${{ steps.getVariables.outputs.coverage_report_html_directory }} + rm ${{ steps.getVariables.outputs.coverage_report_html_directory }}/.gitignore - name: πŸ“€ Upload 'TestReportSummary.xml' artifact - if: inputs.artifact != '' - uses: actions/upload-artifact@v3 + if: inputs.unittest_xml_artifact != '' + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.unittest_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} + path: report/unit/TestReportSummary.xml + if-no-files-found: error + retention-days: 1 + +# - name: πŸ“€ Upload 'Unit Tests HTML Report' artifact +# if: inputs.unittest_html_artifact != '' +# continue-on-error: true +# uses: actions/upload-artifact@v4 +# with: +# name: ${{ inputs.unittest_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} +# path: ${{ steps.getVariables.outputs.unittest_report_html_directory }} +# if-no-files-found: error +# retention-days: 1 + + - name: πŸ“€ Upload 'Coverage SQLite Database' artifact + if: inputs.coverage_sqlite_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_sqlite_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} + path: .coverage + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage XML Report' artifact + if: inputs.coverage_xml_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} + path: ${{ steps.getVariables.outputs.coverage_report_xml }} + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage JSON Report' artifact + if: inputs.coverage_json_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.coverage_json_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} + path: ${{ steps.getVariables.outputs.coverage_report_json }} + if-no-files-found: error + retention-days: 1 + + - name: πŸ“€ Upload 'Coverage HTML Report' artifact + if: inputs.coverage_html_artifact != '' + continue-on-error: true + uses: actions/upload-artifact@v4 with: - name: ${{ inputs.artifact }}-${{ matrix.system }}-${{ matrix.python }} - path: ${{ inputs.tests_directory || '.' }}/TestReportSummary.xml + name: ${{ inputs.coverage_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }} + path: ${{ steps.getVariables.outputs.coverage_report_html_directory }} if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/VerifyDocs.yml b/.github/workflows/VerifyDocs.yml index 1c4c47fb..5866d847 100644 --- a/.github/workflows/VerifyDocs.yml +++ b/.github/workflows/VerifyDocs.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # @@ -28,7 +28,7 @@ on: python_version: description: 'Python version.' required: false - default: '3.11' + default: '3.12' type: string jobs: @@ -42,7 +42,7 @@ jobs: uses: actions/checkout@v4 - name: 🐍 Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ inputs.python_version }} diff --git a/.github/workflows/_Checking_ArtifactCleanup.yml b/.github/workflows/_Checking_ArtifactCleanup.yml index f620c334..f9b58ce0 100644 --- a/.github/workflows/_Checking_ArtifactCleanup.yml +++ b/.github/workflows/_Checking_ArtifactCleanup.yml @@ -25,7 +25,7 @@ jobs: run: echo "${{ matrix.runs-on }}-${{ matrix.python }}" >> artifact.txt - name: πŸ“€ Upload artifact for ${{ matrix.system }}-${{ matrix.python }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-${{ matrix.system }}-${{ matrix.python }} path: artifact.txt @@ -42,7 +42,7 @@ jobs: run: echo "Package" >> package.txt - name: πŸ“€ Upload artifact for ${{ matrix.system }}-${{ matrix.python }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }} path: package.txt diff --git a/.github/workflows/_Checking_Pipeline.yml b/.github/workflows/_Checking_Pipeline.yml index 98be0056..872243a6 100644 --- a/.github/workflows/_Checking_Pipeline.yml +++ b/.github/workflows/_Checking_Pipeline.yml @@ -9,18 +9,15 @@ jobs: uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov with: name: pyDummy - python_version_list: "3.11" -# python_version_list: "3.7 3.8 pypy-3.8 3.9 pypy-3.9 3.10 3.11" - exclude_list: "windows:pypy-3.8 windows:pypy-3.9" -# disable_list: "windows:3.11" + python_version_list: "3.8 3.9 3.10 3.11 3.12 pypy-3.8 pypy-3.9 pypy-3.10" + disable_list: "windows:pypy-3.10" PlatformTestingParams: uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov with: name: Platform python_version_list: "" - system_list: "ubuntu" -# system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64" + system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64" UnitTesting: uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov @@ -28,7 +25,12 @@ jobs: - UnitTestingParams with: jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }} - artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} + unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} + unittest_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }} +# coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }} +# coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }} +# coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }} +# coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} PlatformTesting: uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov @@ -36,76 +38,67 @@ jobs: - PlatformTestingParams with: jobs: ${{ needs.PlatformTestingParams.outputs.python_jobs }} - tests_directory: "" - unittest_directory: tests/unit/Platform - artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }} +# tests_directory: "" + unittest_directory: platform + unittest_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }} + unittest_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_html }} + coverage_sqlite_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_sqlite }} + coverage_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_xml }} + coverage_json_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_json }} + coverage_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_html }} + +# Coverage: +# uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@cov +# needs: +# - UnitTestingParams +# with: +# python_version: ${{ needs.UnitTestingParams.outputs.python_version }} +# artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} +# secrets: +# codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} - Coverage: - uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@cov + StaticTypeCheck: + uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@cov needs: - UnitTestingParams with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} - secrets: - codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} + commands: | + mypy --html-report htmlmypy -p pyDummy + html_report: 'htmlmypy' + html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} PublishCoverageResults: uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@cov needs: + - UnitTestingParams - UnitTesting - - Coverage + - PlatformTesting +# - Coverage + with: + coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }} + coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }} + coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }} + coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} secrets: codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} - StaticTypeCheck: - uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@cov - needs: - - UnitTestingParams - with: - python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - commands: | - mypy --html-report htmlmypy -p pyDummy - html_report: 'htmlmypy' - html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} - PublishTestResults: uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@cov needs: - UnitTesting + - PlatformTesting Package: uses: pyTooling/Actions/.github/workflows/Package.yml@cov needs: - UnitTestingParams - - Coverage - - PlatformTesting - with: - python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} - - Release: - uses: pyTooling/Actions/.github/workflows/Release.yml@cov - if: startsWith(github.ref, 'refs/tags') - needs: - UnitTesting - - Coverage - - StaticTypeCheck - - Package - - PublishOnPyPI: - uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@cov - if: startsWith(github.ref, 'refs/tags') - needs: - - UnitTestingParams - - Release - - Package +# - Coverage + - PlatformTesting with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - requirements: -r dist/requirements.txt artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} - secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} # VerifyDocs: # uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@cov @@ -114,33 +107,60 @@ jobs: # with: # python_version: ${{ needs.UnitTestingParams.outputs.python_version }} -# BuildTheDocs: -# uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@cov -# needs: -# - UnitTestingParams -## - VerifyDocs -# with: -# artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} + BuildTheDocs: + uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@cov + needs: + - UnitTestingParams +# - VerifyDocs + with: + artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} PublishToGitHubPages: uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@cov needs: - UnitTestingParams -# - BuildTheDocs - - Coverage + - BuildTheDocs +# - Coverage + - PublishCoverageResults - StaticTypeCheck with: doc: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} coverage: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} typing: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} + ReleasePage: + uses: pyTooling/Actions/.github/workflows/Release.yml@cov + if: startsWith(github.ref, 'refs/tags') + needs: + - UnitTesting + - PlatformTesting +# - Coverage +# - StaticTypeCheck + - Package + - PublishToGitHubPages + + PublishOnPyPI: + uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@cov + if: startsWith(github.ref, 'refs/tags') + needs: + - UnitTestingParams + - ReleasePage +# - Package + with: + python_version: ${{ needs.UnitTestingParams.outputs.python_version }} + requirements: -r dist/requirements.txt + artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + ArtifactCleanUp: uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@cov needs: - UnitTestingParams + - PlatformTestingParams - UnitTesting - PlatformTesting - - Coverage +# - Coverage - StaticTypeCheck # - BuildTheDocs - PublishToGitHubPages @@ -150,6 +170,22 @@ jobs: package: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} remaining: | ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}-* + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }} + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }} + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }} + ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }} ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }}-* + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_html }}-* + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_sqlite }}-* + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_xml }}-* + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_json }}-* + ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_html }}-* diff --git a/.gitignore b/.gitignore index b4feb0ea..7ab3de6d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,8 @@ coverage.xml # Sphinx doc/_build/ -doc/pyTooling/**/*.* -!doc/pyTooling/index.rst +doc/pyDummy/**/*.* +!doc/pyDummy/index.rst # BuildTheDocs doc/_theme/**/*.* diff --git a/ExamplePipeline.yml b/ExamplePipeline.yml index 04cde1c7..15c08c05 100644 --- a/ExamplePipeline.yml +++ b/ExamplePipeline.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2023 The pyTooling Authors # +# Copyright 2020-2024 The pyTooling Authors # # # # Licensed under the Apache License, Version 2.0 (the "License"); # # you may not use this file except in compliance with the License. # diff --git a/doc/JobTemplate/Parameters.rst b/doc/JobTemplate/Parameters.rst index fe9bcd82..f7ace30d 100644 --- a/doc/JobTemplate/Parameters.rst +++ b/doc/JobTemplate/Parameters.rst @@ -44,31 +44,31 @@ Complex Example The following instantiation example creates 3 jobs from the same template, but with differing input parameters. The first job `UnitTestingParams` might be used to create a job matrix of unit tests. It creates the cross of default -systems (Windows, Ubuntu, MacOS, MinGW64) and the given list of Python versions including some mypy versions. In +systems (Windows, Ubuntu, MacOS, MinGW64, UCRT64) and the given list of Python versions including some mypy versions. In addition a list of excludes (marked as :deletion:`deletions`) and includes (marked as :addition:`additions`) is handed over resulting in the following combinations: -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| Version | 3.7 πŸ”΄ | 3.8 🟠 | 3.9 🟑 | 3.10 🟒 | 3.11 🟒 | 3.12.a1 🟣 | pypy-3.7 πŸ”΄ | pypy-3.8 🟠 | pypy-3.9 🟑 | -+============+=============+=============+=============+==============+=========================+============+=============+==============================+==============================+ -| Windows 🧊 | windows:3.7 | windows:3.8 | windows:3.9 | windows:3.10 | | | | :deletion:`windows:pypy-3.8` | :deletion:`windows:pypy-3.9` | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| Ubuntu 🐧 | ubuntu:3.7 | ubuntu:3.8 | ubuntu:3.9 | ubuntu:3.10 | :addition:`ubuntu:3.11` | | | ubuntu:pypy-3.8 | ubuntu:pypy-3.9 | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| MacOS 🍎 | macos:3.7 | macos:3.8 | macos:3.9 | macos:3.10 | :addition:`macos:3.11` | | | macos:pypy-3.8 | macos:pypy-3.9 | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| MSYS πŸŸͺ | | | | | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| MinGW32 ⬛ | | | | | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| MinGW64 🟦 | | | | mingw64:3.10 | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| Clang32 🟫 | | | | | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| Clang64 🟧 | | | | | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ -| UCRT64 🟨 | | | | | | | | | | -+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| Version | 3.8 πŸ”΄ | 3.9 🟠 | 3.10 🟑 | 3.11 🟒 | 3.12 🟒 | 3.13.a1 🟣 | pypy-3.8 πŸ”΄ | pypy-3.9 🟠 | pypy-3.10 🟑 | ++============+=============+=============+==============+==============+=========================+============+=============+==============================+===============================+ +| Windows 🧊 | windows:3.8 | windows:3.9 | windows:3.10 | windows:3.11 | | | | :deletion:`windows:pypy-3.9` | :deletion:`windows:pypy-3.10` | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| Ubuntu 🐧 | ubuntu:3.8 | ubuntu:3.9 | ubuntu:3.10 | ubuntu:3.11 | :addition:`ubuntu:3.12` | | | ubuntu:pypy-3.9 | ubuntu:pypy-3.10 | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| MacOS 🍎 | macos:3.8 | macos:3.9 | macos:3.10 | macos:3.11 | :addition:`macos:3.12` | | | macos:pypy-3.9 | macos:pypy-3.10 | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| MSYS πŸŸͺ | | | | | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| MinGW32 ⬛ | | | | | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| MinGW64 🟦 | | | | mingw64:3.11 | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| Clang32 🟫 | | | | | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| Clang64 🟧 | | | | | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ +| UCRT64 🟨 | | | | | | | | | | ++------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+ .. code-block:: yaml @@ -84,22 +84,22 @@ over resulting in the following combinations: uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0 with: name: pyTooling - python_version_list: "3.7 3.8 3.9 3.10 pypy-3.8 pypy-3.9" - include_list: "ubuntu:3.11 macos:3.11" - exclude_list: "windows:pypy-3.8 windows:pypy-3.9" + python_version_list: "3.8 3.9 3.10 3.11 pypy-3.9 pypy-3.10" + include_list: "ubuntu:3.12 macos:3.12" + exclude_list: "windows:pypy-3.9 windows:pypy-3.10" PerformanceTestingParams: uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0 with: name: pyTooling - python_version_list: "3.10 3.11" + python_version_list: "3.11 3.12" system_list: "ubuntu windows macos" PlatformTestingParams: uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev with: name: pyTooling - python_version_list: "3.10" + python_version_list: "3.12" system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64" Parameters @@ -125,7 +125,7 @@ python_version +----------------+----------+----------+----------+ | Parameter Name | Required | Type | Default | +================+==========+==========+==========+ -| python_version | optional | string | ``3.11`` | +| python_version | optional | string | ``3.12`` | +----------------+----------+----------+----------+ Python version to be used for all jobs requiring a single Python version. @@ -134,52 +134,54 @@ Python version to be used for all jobs requiring a single Python version. python_version_list =================== -+----------------------+----------+----------+---------------------------+ -| Parameter Name | Required | Type | Default | -+======================+==========+==========+===========================+ -| python_version_list | optional | string | ``3.7 3.8 3.9 3.10 3.11`` | -+----------------------+----------+----------+---------------------------+ ++----------------------+----------+----------+----------------------------+ +| Parameter Name | Required | Type | Default | ++======================+==========+==========+============================+ +| python_version_list | optional | string | ``3.8 3.9 3.10 3.11 3.12`` | ++----------------------+----------+----------+-------------------------- -+ Space separated list of CPython versions and/or mypy version to run tests with. **Possible values:** -* ``3.6``, ``3.7``, ``3.8``, ``3.9``, ``3.10`` , ``3.11``, ``3.12`` -* ``pypy-3.7``, ``pypy-3.8``, ``pypy-3.9`` +* ``3.7``, ``3.8``, ``3.9``, ``3.10`` , ``3.11``, ``3.12``, ``3.13`` +* ``pypy-3.7``, ``pypy-3.8``, ``pypy-3.9``, ``pypy-3.10`` +------+-----------+------------------+-----------------------------------------+ | Icon | Version | Maintained until | Comments | +======+===========+==================+=========================================+ -| ⚫ | 3.6 | 2021.12.23 | :red:`outdated` | +| ⚫ | 3.7 | 2023.06.27 | :red:`outdated` | +------+-----------+------------------+-----------------------------------------+ -| πŸ”΄ | 3.7 | 2023.06.27 | | +| πŸ”΄ | 3.8 | 2024.10 | | +------+-----------+------------------+-----------------------------------------+ -| 🟠 | 3.8 | 2024.10 | | +| 🟠 | 3.9 | 2025.10 | | +------+-----------+------------------+-----------------------------------------+ -| 🟑 | 3.9 | 2025.10 | | +| 🟑 | 3.10 | 2026.10 | | +------+-----------+------------------+-----------------------------------------+ -| 🟒 | 3.10 | 2026.10 | | +| 🟒 | 3.11 | 2027.10 | | +------+-----------+------------------+-----------------------------------------+ -| 🟒 | 3.11 | 2027.10 | :green:`latest` | +| 🟒 | 3.12 | 2028.10 | :green:`latest` | +------+-----------+------------------+-----------------------------------------+ -| 🟣 | 3.12 | 2028.10 | Python 3.12 alpha (or RC) will be used. | +| 🟣 | 3.13 | 2029.10 | Python 3.13 alpha (or RC) will be used. | +------+-----------+------------------+-----------------------------------------+ -| βŸ²πŸ”΄ | pypy-3.7 | ????.?? | | +| ⟲⚫ | pypy-3.7 | ????.?? | | +------+-----------+------------------+-----------------------------------------+ -| ⟲🟠 | pypy-3.8 | ????.?? | | +| βŸ²πŸ”΄ | pypy-3.8 | ????.?? | | +------+-----------+------------------+-----------------------------------------+ -| ⟲🟑 | pypy-3.9 | ????.?? | | +| ⟲🟠 | pypy-3.9 | ????.?? | | ++------+-----------+------------------+-----------------------------------------+ +| ⟲🟑 | pypy-3.10 | ????.?? | | +------+-----------+------------------+-----------------------------------------+ system_list =========== -+----------------+----------+----------+----------------------------------+ -| Parameter Name | Required | Type | Default | -+================+==========+==========+==================================+ -| system_list | optional | string | ``ubuntu windows mingw64 macos`` | -+----------------+----------+----------+----------------------------------+ ++----------------+----------+----------+-----------------------------------------+ +| Parameter Name | Required | Type | Default | ++================+==========+==========+=========================================+ +| system_list | optional | string | ``ubuntu windows macos mingw64 ucrt64`` | ++----------------+----------+----------+-----------------------------------------+ Space separated list of systems to run tests on. @@ -193,9 +195,9 @@ Space separated list of systems to run tests on. +======+===========+==============================+=================================================================+ | 🧊 | Windows | Windows Server 2022 (latest) | | +------+-----------+------------------------------+-----------------------------------------------------------------+ -| 🐧 | Ubuntu | Ubuntu 20.04 (LTS) (latest) | While this marked latest, Ubuntu 22.02 LTS is already provided. | +| 🐧 | Ubuntu | Ubuntu 22.04 (LTS) (latest) | | +------+-----------+------------------------------+-----------------------------------------------------------------+ -| 🍎 | MacOS | macOS Big Sur 11 (latest) | While this marked latest, macOS Monterey 12 is already provided.| +| 🍎 | MacOS | macOS Monterey 12 (latest) | While this marked latest, macOS Ventura 13 is already provided. | +------+-----------+------------------------------+-----------------------------------------------------------------+ | πŸŸͺ | MSYS | | | +------+-----------+------------------------------+-----------------------------------------------------------------+ @@ -210,6 +212,7 @@ Space separated list of systems to run tests on. | 🟨 | UCRT64 | | | +------+-----------+------------------------------+-----------------------------------------------------------------+ +Source: `Images provided by GitHub `__ include_list ============ @@ -370,6 +373,9 @@ A dictionary of artifact names sharing a common prefix. The supported artifacts are: * ``unittesting_xml`` - UnitTesting XML summary report +* ``unittesting_html`` - UnitTesting HTML summary report +* ``codecoverage_sqlite`` - Code Coverage internal database (SQLite) +* ``codecoverage_json`` - Code Coverage JSON report * ``codecoverage_xml`` - Code Coverage XML report * ``codecoverage_html`` - Code Coverage HTML report * ``statictyping_html`` - Static Type Checking HTML report diff --git a/doc/_templates/autoapi/module.rst b/doc/_templates/autoapi/module.rst new file mode 100644 index 00000000..4dded81f --- /dev/null +++ b/doc/_templates/autoapi/module.rst @@ -0,0 +1,160 @@ +.. # Template modified by Patrick Lehmann + * removed automodule on top, because private members are activated for autodoc (no doubled documentation). + * Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels. + +{{ '=' * node.name|length }} +{{ node.name }} +{{ '=' * node.name|length }} + +.. automodule:: {{ node.name }} + +{##} +{%- block modules -%} +{%- if subnodes %} + +**Submodules** + +.. toctree:: + :maxdepth: 1 +{% for item in subnodes %} + {{ item.name }} +{%- endfor %} +{##} +{%- endif -%} +{%- endblock -%} +{##} +.. currentmodule:: {{ node.name }} +{##} + +{%- if node.variables %} + +**Variables** + +{% for item, obj in node.variables.items() -%} +- :py:data:`{{ item }}` + {#{ obj|summary }#} +{% endfor -%} +{%- endif -%} + +{%- if node.functions %} + +**Functions** + +{% for item, obj in node.functions.items() -%} +- :py:func:`{{ item }}`: + {{ obj|summary }} + +{% endfor -%} +{%- endif -%} + +{%- if node.exceptions %} + +**Exceptions** + +{% for item, obj in node.exceptions.items() -%} +- :py:exc:`{{ item }}`: + {{ obj|summary }} + +{% endfor -%} +{%- endif -%} + +{%- if node.classes %} + +**Classes** + +{% for item, obj in node.classes.items() -%} +- :py:class:`{{ item }}`: + {{ obj|summary }} + +{% endfor -%} +{%- endif -%} + +{%- block variables -%} +{%- if node.variables %} + +--------------------- + +**Variables** + +{#% for item, obj in node.variables.items() -%} +- :py:data:`{{ item }}` +{% endfor -%#} + +{% for item, obj in node.variables.items() %} +.. autodata:: {{ item }} + :annotation: + + .. code-block:: text + + {{ obj|pprint|indent(6) }} +{##} +{%- endfor -%} +{%- endif -%} +{%- endblock -%} + +{%- block functions -%} +{%- if node.functions %} + +--------------------- + +**Functions** + +{% for item in node.functions %} +.. autofunction:: {{ item }} +{##} +{%- endfor -%} +{%- endif -%} +{%- endblock -%} + +{%- block exceptions -%} +{%- if node.exceptions %} + +--------------------- + +**Exceptions** + +{#% for item, obj in node.exceptions.items() -%} +- :py:exc:`{{ item }}`: + {{ obj|summary }} + +{% endfor -%#} + +{% for item in node.exceptions %} +.. autoexception:: {{ item }} + + .. rubric:: Inheritance + .. inheritance-diagram:: {{ item }} + :parts: 1 +{##} +{%- endfor -%} +{%- endif -%} +{%- endblock -%} + +{%- block classes -%} +{%- if node.classes %} + +--------------------- + +**Classes** + +{#% for item, obj in node.classes.items() -%} +- :py:class:`{{ item }}`: + {{ obj|summary }} + +{% endfor -%#} + +{% for item in node.classes %} +.. autoclass:: {{ item }} + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: {{ item }} + :parts: 1 +{##} +{%- endfor -%} +{%- endif -%} +{%- endblock -%} diff --git a/doc/_templates/autoapi/package.rst b/doc/_templates/autoapi/package.rst new file mode 100644 index 00000000..9cc9fbdc --- /dev/null +++ b/doc/_templates/autoapi/package.rst @@ -0,0 +1,14 @@ +.. # Template created by Patrick Lehmann + +Python Class Reference +###################### + +Reference of all packages and modules: + +.. automodule:: {{ node.name }} + +.. toctree:: + :maxdepth: 1 +{% for item in subnodes %} + {{ item.name }} +{%- endfor %} diff --git a/doc/conf.py b/doc/conf.py index 9daaa066..40b56fe7 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -13,7 +13,7 @@ sys_path.insert(0, abspath(".")) sys_path.insert(0, abspath("..")) -#sys_path.insert(0, abspath("../pyTooling")) +sys_path.insert(0, abspath("../pyDummy")) sys_path.insert(0, abspath("_extensions")) @@ -25,7 +25,7 @@ # built documents. project = "Actions" -packageInformationFile = Path(f"../{project}/__init__.py") +packageInformationFile = Path(f"../pyDummy/__init__.py") versionInformation = extractVersionInformation(packageInformationFile) author = versionInformation.Author @@ -173,9 +173,11 @@ # ============================================================================== extensions = [ # Standard Sphinx extensions + "sphinx.ext.autodoc", "sphinx.ext.coverage", "sphinx.ext.extlinks", "sphinx.ext.intersphinx", + "sphinx.ext.inheritance_diagram", "sphinx.ext.todo", "sphinx.ext.graphviz", "sphinx.ext.mathjax", @@ -185,6 +187,9 @@ "sphinxcontrib.mermaid", # Other extensions "sphinx_fontawesome", + "sphinx_autodoc_typehints", + "sphinx_inline_tabs", + "autoapi.sphinx", ] @@ -216,11 +221,11 @@ # Sphinx.Ext.ExtLinks # ============================================================================== extlinks = { - "gh": ("https://GitHub.com/%s", "gh:"), - "ghissue": ("https://GitHub.com/pyTooling/Actions/issues/%s", "issue #"), - "ghpull": ("https://GitHub.com/pyTooling/Actions/pull/%s", "pull request #"), - "ghsrc": ("https://GitHub.com/pyTooling/Actions/blob/main/%s", None), - "wiki": ("https://en.wikipedia.org/wiki/%s", None), + "gh": ("https://GitHub.com/%s", "gh:%s"), + "ghissue": ("https://GitHub.com/pyTooling/Actions/issues/%s", "issue #%s"), + "ghpull": ("https://GitHub.com/pyTooling/Actions/pull/%s", "pull request #%s"), + "ghsrc": ("https://GitHub.com/pyTooling/Actions/blob/main/%s", None), + "wiki": ("https://en.wikipedia.org/wiki/%s", None), } @@ -239,6 +244,18 @@ mermaid_verbose = True +# ============================================================================== +# Sphinx.Ext.Inheritance_Diagram +# ============================================================================== +inheritance_node_attrs = { +# "shape": "ellipse", +# "fontsize": 14, +# "height": 0.75, + "color": "dodgerblue1", + "style": "filled" +} + + # ============================================================================== # Sphinx.Ext.ToDo # ============================================================================== @@ -251,3 +268,15 @@ # Sphinx.Ext.Coverage # ============================================================================== coverage_show_missing_items = True + + +# ============================================================================== +# AutoAPI.Sphinx +# ============================================================================== +autoapi_modules = { + "pyDummy": { + "template": "module", + "output": "pyDummy", + "override": True + } +} diff --git a/doc/coverage/index.rst b/doc/coverage/index.rst new file mode 100644 index 00000000..719080f0 --- /dev/null +++ b/doc/coverage/index.rst @@ -0,0 +1,4 @@ +Code Coverage Report +#################### + +*Placeholder for the Coverage report generated with* ``pytest`` *and* ``coverage``. diff --git a/doc/index.rst b/doc/index.rst index 9601fe1a..59cfb84c 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -122,14 +122,6 @@ License The accompanying documentation is licensed under **Creative Commons - Attribution 4.0 (CC-BY 4.0)**. ------------------------------------- - -.. |docdate| date:: %b %d, %Y - %H:%M - -.. only:: html - - This document was generated on |docdate|. - .. toctree:: :caption: Introduction :hidden: @@ -171,6 +163,19 @@ License JobTemplate/Release JobTemplate/ArtifactCleanUp +.. raw:: latex + + \part{pyDummy Example} + +.. toctree:: + :caption: pyDummy Example + :hidden: + + pyDummy/pyDummy + Unittest Report ➚ + Coverage Report ➚ + Static Type Check Report ➚ + .. raw:: latex \part{Appendix} diff --git a/doc/pyDummy/.gitempty b/doc/pyDummy/.gitempty new file mode 100644 index 00000000..e69de29b diff --git a/doc/requirements.txt b/doc/requirements.txt index 6a638b56..fbe0ef52 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -3,7 +3,8 @@ pyTooling >= 5.0.0, < 6.0 # Enforce latest version on ReadTheDocs -sphinx >=5.3, < 6.0 +sphinx >= 7.1, < 8.0 +docutils >= 0.18.0, < 0.19.0 # Sphinx Extenstions #sphinx.ext.coverage @@ -12,12 +13,8 @@ sphinxcontrib-mermaid>=0.9.2 #sphinxcontrib-seqdiag>=0.8.5 #sphinxcontrib-textstyle>=0.2.1 #sphinxcontrib-spelling>=2.2.0 -autoapi -sphinx_fontawesome>=0.0.6 -sphinx_autodoc_typehints>=1.19.5 +autoapi >= 2.0.1 +sphinx_fontawesome >= 0.0.6 +sphinx-inline-tabs >= 2023.4.21 +sphinx_autodoc_typehints >= 1.24.0 # changelog>=0.3.5 - -# BuildTheDocs Extensions (mostly patched Sphinx extensions) - -# For pyTooling.Configuration.YAML documentation -ruamel.yaml>=0.17 diff --git a/doc/typing/index.rst b/doc/typing/index.rst new file mode 100644 index 00000000..3a22a255 --- /dev/null +++ b/doc/typing/index.rst @@ -0,0 +1,8 @@ +Static Type Checking Report +########################### + +*Placeholder for the Static Type Checking report generated with* ``mypy``. + +.. #raw:: html + +