Merged Code Coverage and Python 3.12

This commit is contained in:
Patrick Lehmann
2024-01-13 13:25:55 +01:00
committed by GitHub
45 changed files with 1372 additions and 364 deletions

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -85,7 +85,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job - name: 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.wheel }} name: ${{ inputs.wheel }}
path: install path: install
@@ -180,7 +180,7 @@ jobs:
- name: 🐍 Setup Python ${{ matrix.python }} - name: 🐍 Setup Python ${{ matrix.python }}
if: matrix.system != 'msys2' if: matrix.system != 'msys2'
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python }} python-version: ${{ matrix.python }}
@@ -222,7 +222,7 @@ jobs:
- name: 📤 Upload 'TestReportSummary.xml' artifact - name: 📤 Upload 'TestReportSummary.xml' artifact
if: inputs.artifact != '' if: inputs.artifact != ''
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.artifact }}-${{ matrix.system }}-${{ matrix.python }} name: ${{ inputs.artifact }}-${{ matrix.system }}-${{ matrix.python }}
path: ${{ inputs.tests_directory || '.' }}/TestReportSummary.xml path: ${{ inputs.tests_directory || '.' }}/TestReportSummary.xml

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -45,12 +45,14 @@ jobs:
- name: 🗑️ Delete package Artifacts - name: 🗑️ Delete package Artifacts
if: ${{ ! startsWith(github.ref, 'refs/tags') }} if: ${{ ! startsWith(github.ref, 'refs/tags') }}
uses: geekyeggo/delete-artifact@v2 uses: geekyeggo/delete-artifact@v4
with: with:
name: ${{ inputs.package }} name: ${{ inputs.package }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: 🗑️ Delete remaining Artifacts - name: 🗑️ Delete remaining Artifacts
if: ${{ inputs.remaining != '' }} if: ${{ inputs.remaining != '' }}
uses: geekyeggo/delete-artifact@v2 uses: geekyeggo/delete-artifact@v4
with: with:
name: ${{ inputs.remaining }} name: ${{ inputs.remaining }}
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -47,7 +47,7 @@ jobs:
- name: 📤 Upload 'documentation' artifacts - name: 📤 Upload 'documentation' artifacts
if: inputs.artifact != '' if: inputs.artifact != ''
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.artifact }} name: ${{ inputs.artifact }}
path: doc/_build/html path: doc/_build/html

View File

@@ -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 }}

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -70,7 +70,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🐍 Setup Python ${{ inputs.python_version }} - name: 🐍 Setup Python ${{ inputs.python_version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ inputs.python_version }} python-version: ${{ inputs.python_version }}
@@ -148,7 +148,7 @@ jobs:
- name: 📤 Upload 'Coverage Report' artifact - name: 📤 Upload 'Coverage Report' artifact
continue-on-error: true continue-on-error: true
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.artifact }} name: ${{ inputs.artifact }}
path: ${{ steps.getVariables.outputs.coverage_report_html_directory }} path: ${{ steps.getVariables.outputs.coverage_report_html_directory }}

View File

@@ -1,17 +1,9 @@
# ==================================================================================================================== # # ==================================================================================================================== #
# _____ _ _ _ _ _ #
# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / \ ___| |_(_) ___ _ __ ___ #
# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` | / _ \ / __| __| |/ _ \| '_ \/ __| #
# | |_) | |_| || | (_) | (_) | | | | | | (_| |_ / ___ \ (__| |_| | (_) | | | \__ \ #
# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)_/ \_\___|\__|_|\___/|_| |_|___/ #
# |_| |___/ |___/ #
# ==================================================================================================================== #
# Authors: # # Authors: #
# Patrick Lehmann # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -27,11 +19,37 @@
# # # #
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
# name: Intermediate Cleanup
"""Placeholder"""
__author__ = "Patrick Lehmann" on:
__email__ = "Paebbels@gmail.com" workflow_call:
__copyright__ = "2017-2022, Patrick Lehmann" inputs:
__license__ = "Apache License, Version 2.0" sqlite_coverage_artifacts_prefix:
__version__ = "0.4.4" description: 'Prefix for SQLite coverage artifacts'
__keywords__ = [] 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 }}

View File

@@ -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

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,7 +28,7 @@ on:
python_version: python_version:
description: 'Python version.' description: 'Python version.'
required: false required: false
default: '3.11' default: '3.12'
type: string type: string
requirements: requirements:
description: 'Python dependencies to be installed through pip; if empty, use pyproject.toml through build.' description: 'Python dependencies to be installed through pip; if empty, use pyproject.toml through build.'
@@ -51,7 +51,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🐍 Setup Python ${{ inputs.python_version }} - name: 🐍 Setup Python ${{ inputs.python_version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ inputs.python_version }} python-version: ${{ inputs.python_version }}
@@ -98,7 +98,7 @@ jobs:
run: python setup.py bdist_wheel run: python setup.py bdist_wheel
- name: 📤 Upload wheel artifact - name: 📤 Upload wheel artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.artifact }} name: ${{ inputs.artifact }}
path: dist/ path: dist/

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -32,17 +32,17 @@ on:
python_version: python_version:
description: 'Python version.' description: 'Python version.'
required: false required: false
default: '3.11' default: '3.12'
type: string type: string
python_version_list: python_version_list:
description: 'Space separated list of Python versions to run tests with.' description: 'Space separated list of Python versions to run tests with.'
required: false required: false
default: '3.8 3.9 3.10 3.11' default: '3.8 3.9 3.10 3.11 3.12'
type: string type: string
system_list: system_list:
description: 'Space separated list of systems to run tests on.' description: 'Space separated list of systems to run tests on.'
required: false required: false
default: 'ubuntu windows mingw64 macos' default: 'ubuntu windows macos mingw64 ucrt64'
type: string type: string
include_list: include_list:
description: 'Space separated list of system:python items to be included into the list of test.' 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() exclude_list = "${{ inputs.exclude_list }}".strip()
disable_list = "${{ inputs.disable_list }}".strip() disable_list = "${{ inputs.disable_list }}".strip()
currentMSYS2Version = "3.10" currentMSYS2Version = "3.11"
currentAlphaVersion = "3.12" currentAlphaVersion = "3.13"
currentAlphaRelease = "3.12.0-alpha.1" currentAlphaRelease = "3.13.0-alpha.1"
if systems == "": if systems == "":
print("::error title=Parameter::system_list is empty.") print("::error title=Parameter::system_list is empty.")
@@ -131,8 +131,8 @@ jobs:
else: else:
disabled = [disable.strip() for disable in disable_list.split(" ")] disabled = [disable.strip() for disable in disable_list.split(" ")]
if "3.6" in versions: if "3.7" in versions:
print("::warning title=Deprecated::Support for Python 3.6 ended in 2021.12.23.") print("::warning title=Deprecated::Support for Python 3.7 ended in 2023.06.27.")
if "msys2" in systems: if "msys2" in systems:
print("::warning title=Deprecated::System 'msys2' will be replaced by 'mingw64'.") print("::warning title=Deprecated::System 'msys2' will be replaced by 'mingw64'.")
if currentAlphaVersion in versions: if currentAlphaVersion in versions:
@@ -143,16 +143,17 @@ jobs:
data = { data = {
# Python and PyPy versions supported by "setup-python" action # Python and PyPy versions supported by "setup-python" action
"python": { "python": {
"3.6": { "icon": "⚫", "until": "2021.12.23" },
"3.7": { "icon": "⚫", "until": "2023.06.27" }, "3.7": { "icon": "⚫", "until": "2023.06.27" },
"3.8": { "icon": "🔴", "until": "2024.10" }, "3.8": { "icon": "🔴", "until": "2024.10" },
"3.9": { "icon": "🟠", "until": "2025.10" }, "3.9": { "icon": "🟠", "until": "2025.10" },
"3.10": { "icon": "🟡", "until": "2026.10" }, "3.10": { "icon": "🟡", "until": "2026.10" },
"3.11": { "icon": "🟢", "until": "2027.10" }, "3.11": { "icon": "🟢", "until": "2027.10" },
"3.12": { "icon": "🟣", "until": "2028.10" }, "3.12": { "icon": "🟢", "until": "2028.10" },
"pypy-3.7": { "icon": "⟲🔴", "until": "????.??" }, # "3.13": { "icon": "🟣", "until": "2028.10" },
"pypy-3.8": { "icon": "⟲🟠", "until": "????.??" }, "pypy-3.7": { "icon": "⟲", "until": "????.??" },
"pypy-3.9": { "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 # Runner systems (runner images) supported by GitHub Actions
"sys": { "sys": {
@@ -211,6 +212,7 @@ jobs:
"sysicon": data["sys"][system]["icon"], "sysicon": data["sys"][system]["icon"],
"system": system, "system": system,
"runs-on": data["sys"][system]["runs-on"], "runs-on": data["sys"][system]["runs-on"],
"runtime": "native",
"shell": data["sys"][system]["shell"], "shell": data["sys"][system]["shell"],
"pyicon": data["python"][version]["icon"], "pyicon": data["python"][version]["icon"],
"python": currentAlphaRelease if version == currentAlphaVersion else version, "python": currentAlphaRelease if version == currentAlphaVersion else version,
@@ -232,16 +234,20 @@ jobs:
] ]
artifact_names = { artifact_names = {
"unittesting_xml": f"{name}-UnitTestReportSummary-XML", "unittesting_xml": f"{name}-UnitTestReportSummary-XML",
"perftesting_xml": f"{name}-PerformanceTestReportSummary-XML", "unittesting_html": f"{name}-UnitTestReportSummary-HTML",
"benchtesting_xml": f"{name}-BenchmarkTestReportSummary-XML", "perftesting_xml": f"{name}-PerformanceTestReportSummary-XML",
"apptesting_xml": f"{name}-ApplicationTestReportSummary-XML", "benchtesting_xml": f"{name}-BenchmarkTestReportSummary-XML",
"codecoverage_xml": f"{name}-CodeCoverage-XML", "apptesting_xml": f"{name}-ApplicationTestReportSummary-XML",
"codecoverage_html": f"{name}-CodeCoverage-HTML", "codecoverage_sqlite": f"{name}-CodeCoverage-SQLite",
"statictyping_html": f"{name}-StaticTyping-HTML", "codecoverage_xml": f"{name}-CodeCoverage-XML",
"package_all": f"{name}-Packages", "codecoverage_json": f"{name}-CodeCoverage-JSON",
"documentation_pdf": f"{name}-Documentation-PDF", "codecoverage_html": f"{name}-CodeCoverage-HTML",
"documentation_html": f"{name}-Documentation-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 # Deprecated structure

View File

@@ -1,10 +0,0 @@
#name: Pipeline
name: Documentation
on:
push:
workflow_dispatch:
jobs:
BuildTheDocs:
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@dev

View File

@@ -3,7 +3,7 @@
# Patrick Lehmann # # Patrick Lehmann #
# # # #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2020-2023 The pyTooling Authors # # Copyright 2020-2024 The pyTooling Authors #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -19,15 +19,35 @@
# # # #
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
name: Publish Unit Test Results name: Publish Code Coverage Results
on: on:
workflow_call: workflow_call:
inputs: inputs:
report_files: coverage_config:
description: 'Pattern of report files to upload. Can be a comma separated list.' description: 'Path to the .coveragerc file. Use pyproject.toml by default.'
required: false 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 type: string
secrets: secrets:
codacy_token: codacy_token:
@@ -35,8 +55,8 @@ on:
required: true required: true
jobs: jobs:
PublishTestResults: PublishCoverageResults:
name: 📊 Publish Test Results name: 📊 Publish Code Coverage Results
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: always() if: always()
@@ -45,10 +65,137 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download Artifacts - name: Download Artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
path: artifacts 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 - name: 📊 Publish code coverage at CodeCov
if: inputs.CodeCov == true if: inputs.CodeCov == true
continue-on-error: true continue-on-error: true

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,7 +28,7 @@ on:
python_version: python_version:
description: 'Python version.' description: 'Python version.'
required: false required: false
default: '3.11' default: '3.12'
type: string type: string
requirements: requirements:
description: 'Python dependencies to be installed through pip.' description: 'Python dependencies to be installed through pip.'
@@ -52,13 +52,13 @@ jobs:
steps: steps:
- name: 📥 Download artifacts '${{ inputs.artifact }}' from 'Package' job - name: 📥 Download artifacts '${{ inputs.artifact }}' from 'Package' job
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.artifact }} name: ${{ inputs.artifact }}
path: dist/ path: dist/
- name: 🐍 Setup Python ${{ inputs.python_version }} - name: 🐍 Setup Python ${{ inputs.python_version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ inputs.python_version }} python-version: ${{ inputs.python_version }}
@@ -78,6 +78,6 @@ jobs:
run: twine upload dist/*.whl run: twine upload dist/*.whl
- name: 🗑️ Delete packaging Artifacts - name: 🗑️ Delete packaging Artifacts
uses: geekyeggo/delete-artifact@v2 uses: geekyeggo/delete-artifact@v4
with: with:
name: ${{ inputs.artifact }} name: ${{ inputs.artifact }}

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -25,10 +25,10 @@ name: Publish Unit Test Results
on: on:
workflow_call: workflow_call:
inputs: inputs:
report_files: merged_junit_artifact:
description: 'Pattern of report files to upload. Can be a comma separated list.' description: 'Name of the merged JUnit Test Summary artifact.'
required: false required: false
default: 'artifacts/**/*.xml' default: ''
type: string type: string
jobs: jobs:
@@ -42,13 +42,48 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download Artifacts - name: Download Artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
path: artifacts 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 - name: 📊 Publish Unit Test Results
uses: dorny/test-reporter@v1 uses: dorny/test-reporter@v1
with: with:
name: Unit Test Results name: Unit Test Results
path: ${{ inputs.report_files }} path: junit/merged.xml
reporter: java-junit 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

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -51,21 +51,21 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 📥 Download artifacts '${{ inputs.doc }}' from 'BuildTheDocs' job - name: 📥 Download artifacts '${{ inputs.doc }}' from 'BuildTheDocs' job
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.doc }} name: ${{ inputs.doc }}
path: public path: public
- name: 📥 Download artifacts '${{ inputs.coverage }}' from 'Coverage' job - name: 📥 Download artifacts '${{ inputs.coverage }}' from 'Coverage' job
if: ${{ inputs.coverage != '' }} if: ${{ inputs.coverage != '' }}
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.coverage }} name: ${{ inputs.coverage }}
path: public/coverage path: public/coverage
- name: 📥 Download artifacts '${{ inputs.typing }}' from 'StaticTypeCheck' job - name: 📥 Download artifacts '${{ inputs.typing }}' from 'StaticTypeCheck' job
if: ${{ inputs.typing != '' }} if: ${{ inputs.typing != '' }}
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.typing }} name: ${{ inputs.typing }}
path: public/typing path: public/typing

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -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

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,7 +28,7 @@ on:
python_version: python_version:
description: 'Python version.' description: 'Python version.'
required: false required: false
default: '3.11' default: '3.12'
type: string type: string
requirements: requirements:
description: 'Python dependencies to be installed through pip.' description: 'Python dependencies to be installed through pip.'
@@ -70,7 +70,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🐍 Setup Python ${{ inputs.python_version }} - name: 🐍 Setup Python ${{ inputs.python_version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ inputs.python_version }} python-version: ${{ inputs.python_version }}
@@ -84,7 +84,7 @@ jobs:
- name: 📤 Upload 'Static Typing Report' HTML artifact - name: 📤 Upload 'Static Typing Report' HTML artifact
if: ${{ inputs.html_artifact != '' }} if: ${{ inputs.html_artifact != '' }}
continue-on-error: true continue-on-error: true
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.html_artifact }} name: ${{ inputs.html_artifact }}
path: ${{ inputs.html_report }} path: ${{ inputs.html_report }}
@@ -94,7 +94,7 @@ jobs:
- name: 📤 Upload 'Static Typing Report' JUnit artifact - name: 📤 Upload 'Static Typing Report' JUnit artifact
if: ${{ inputs.junit_artifact != '' }} if: ${{ inputs.junit_artifact != '' }}
continue-on-error: true continue-on-error: true
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.junit_artifact }} name: ${{ inputs.junit_artifact }}
path: ${{ inputs.junit_report }} path: ${{ inputs.junit_report }}

View File

@@ -3,7 +3,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -20,7 +20,7 @@
# # # #
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
name: Unit Testing name: Unit Testing (Matrix)
on: on:
workflow_call: workflow_call:
@@ -54,16 +54,45 @@ on:
required: false required: false
default: 'unit' default: 'unit'
type: string 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." description: "Generate unit test report with junitxml and upload results as an artifact."
required: false required: false
default: '' default: ''
type: string 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: jobs:
UnitTesting: 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 }} runs-on: ${{ matrix.runs-on }}
strategy: strategy:
@@ -79,6 +108,12 @@ jobs:
- name: ⏬ Checkout repository - name: ⏬ Checkout repository
uses: actions/checkout@v4 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 - name: Compute pacman/pacboy packages
id: pacboy id: pacboy
if: matrix.system == 'msys2' if: matrix.system == 'msys2'
@@ -87,6 +122,9 @@ jobs:
from os import getenv from os import getenv
from pathlib import Path from pathlib import Path
from re import compile from re import compile
from sys import version
print(f"Python: {version}")
def loadRequirementsFile(requirementsFile: Path): def loadRequirementsFile(requirementsFile: Path):
requirements = [] requirements = []
@@ -111,28 +149,32 @@ jobs:
dependencies = [req.strip() for req in requirements.split(" ")] dependencies = [req.strip() for req in requirements.split(" ")]
packages = { packages = {
"pip": "python-pip:p",
"wheel": "python-wheel:p",
"coverage": "python-coverage:p", "coverage": "python-coverage:p",
"lxml": "python-lxml:p",
"ruamel.yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p",
"numpy": "python-numpy:p",
"igraph": "igraph:p", "igraph": "igraph:p",
"jinja2": "python-markupsafe:p",
"lxml": "python-lxml:p",
"numpy": "python-numpy: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 = { subPackages = {
"pyTooling": { "pytooling": {
"yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", "yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p",
} }
} }
regExp = compile(r"(?P<PackageName>[\w_\-\.]+)(?:\[(?P<SubPackages>(?:\w+)(?:,\w+)*)\])?(?:\s*(?P<Comperator>[<>=]+)\s*)(?P<Version>\d+(?:\.\d+)*)(?:-(?P<VersionExtension>\w+))?") regExp = compile(r"(?P<PackageName>[\w_\-\.]+)(?:\[(?P<SubPackages>(?:\w+)(?:\s*,\s*\w+)*)\])?(?:\s*(?P<Comperator>[<>~=]+)\s*)(?P<Version>\d+(?:\.\d+)*)(?:-(?P<VersionExtension>\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)}):") print(f"Processing dependencies ({len(dependencies)}):")
for dependency in dependencies: for dependency in dependencies:
print(f" {dependency}") print(f" {dependency}")
match = regExp.match(dependency) match = regExp.match(dependency.lower())
if not match: if not match:
print(f" Wrong format: {dependency}") print(f" Wrong format: {dependency}")
print(f"::error title=Identifying Pacboy Packages::Unrecognized dependency format '{dependency}'") print(f"::error title=Identifying Pacboy Packages::Unrecognized dependency format '{dependency}'")
@@ -169,14 +211,14 @@ jobs:
- name: 🐍 Setup Python ${{ matrix.python }} - name: 🐍 Setup Python ${{ matrix.python }}
if: matrix.system != 'msys2' if: matrix.system != 'msys2'
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ matrix.python }} python-version: ${{ matrix.python }}
- name: 🔧 Install wheel and pip dependencies (native) - name: 🔧 Install wheel,tomli and pip dependencies (native)
if: matrix.system != 'msys2' if: matrix.system != 'msys2'
run: | 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 }} python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
- name: 🔧 Install pip dependencies (MSYS2) - name: 🔧 Install pip dependencies (MSYS2)
@@ -188,33 +230,164 @@ jobs:
python -m pip install --disable-pip-version-check ${{ inputs.requirements }} python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
fi fi
- name: ☑ Run unit tests (Windows) - name: 🔁 Extract configurations from pyproject.toml
if: matrix.system == 'windows' id: getVariables
shell: python
run: | run: |
$env:ENVIRONMENT_NAME = "${{ matrix.envname }}" from os import getenv
$env:PYTHONPATH = (Get-Location).ToString() from pathlib import Path
cd "${{ inputs.tests_directory || '.' }}" from sys import version
$PYTEST_ARGS = if ("${{ inputs.artifact }}") { "--junitxml=TestReportSummary.xml" } else { "" } from textwrap import dedent
Write-Host "python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }}"
python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }} 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) - name: ☑ Run unit tests (Ubuntu/macOS)
if: matrix.system != 'windows' if: matrix.system != 'windows'
run: | run: |
export ENVIRONMENT_NAME="${{ matrix.envname }}" export ENVIRONMENT_NAME="${{ matrix.envname }}"
export PYTHONPATH=$(pwd) export PYTHONPATH=$(pwd)
ABSDIR=$(pwd)
cd "${{ inputs.tests_directory || '.' }}" # cd "${{ inputs.tests_directory || '.' }}"
[ -n '${{ inputs.coverage_config }}' ] && PYCOV_ARGS="--cov-config=${ABSDIR}/${{ inputs.coverage_config }}" || unset PYCOV_ARGS [ -n '${{ inputs.unittest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=report/unit/TestReportSummary.xml' || unset PYTEST_ARGS
[ -n '${{ inputs.artifact }}' ] && PYTEST_ARGS='--junitxml=TestReportSummary.xml' || unset PYTEST_ARGS if [ -n '${{ inputs.coverage_config }}' ]; then
echo "python -m pytest -rA $PYTEST_ARGS --color=yes ${{ inputs.unittest_directory }}" echo "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
python -m pytest -rA $PYTEST_ARGS --color=yes ${{ 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 - name: 📤 Upload 'TestReportSummary.xml' artifact
if: inputs.artifact != '' if: inputs.unittest_xml_artifact != ''
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ inputs.artifact }}-${{ matrix.system }}-${{ matrix.python }} name: ${{ inputs.unittest_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
path: ${{ inputs.tests_directory || '.' }}/TestReportSummary.xml 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.coverage_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
path: ${{ steps.getVariables.outputs.coverage_report_html_directory }}
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,7 +28,7 @@ on:
python_version: python_version:
description: 'Python version.' description: 'Python version.'
required: false required: false
default: '3.11' default: '3.12'
type: string type: string
jobs: jobs:
@@ -42,7 +42,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🐍 Setup Python - name: 🐍 Setup Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: ${{ inputs.python_version }} python-version: ${{ inputs.python_version }}

View File

@@ -25,7 +25,7 @@ jobs:
run: echo "${{ matrix.runs-on }}-${{ matrix.python }}" >> artifact.txt run: echo "${{ matrix.runs-on }}-${{ matrix.python }}" >> artifact.txt
- name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }} - name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-${{ matrix.system }}-${{ matrix.python }} name: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-${{ matrix.system }}-${{ matrix.python }}
path: artifact.txt path: artifact.txt
@@ -42,7 +42,7 @@ jobs:
run: echo "Package" >> package.txt run: echo "Package" >> package.txt
- name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }} - name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }} name: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
path: package.txt path: package.txt

View File

@@ -9,18 +9,15 @@ jobs:
uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov
with: with:
name: pyDummy name: pyDummy
python_version_list: "3.11" python_version_list: "3.8 3.9 3.10 3.11 3.12 pypy-3.8 pypy-3.9 pypy-3.10"
# python_version_list: "3.7 3.8 pypy-3.8 3.9 pypy-3.9 3.10 3.11" disable_list: "windows:pypy-3.10"
exclude_list: "windows:pypy-3.8 windows:pypy-3.9"
# disable_list: "windows:3.11"
PlatformTestingParams: PlatformTestingParams:
uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov uses: pyTooling/Actions/.github/workflows/Parameters.yml@cov
with: with:
name: Platform name: Platform
python_version_list: "" 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: UnitTesting:
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov
@@ -28,7 +25,12 @@ jobs:
- UnitTestingParams - UnitTestingParams
with: with:
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }} 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: PlatformTesting:
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@cov
@@ -36,27 +38,24 @@ jobs:
- PlatformTestingParams - PlatformTestingParams
with: with:
jobs: ${{ needs.PlatformTestingParams.outputs.python_jobs }} jobs: ${{ needs.PlatformTestingParams.outputs.python_jobs }}
tests_directory: "" # tests_directory: ""
unittest_directory: tests/unit/Platform unittest_directory: platform
artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }} 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: # Coverage:
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@cov # uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@cov
needs: # needs:
- UnitTestingParams # - UnitTestingParams
with: # with:
python_version: ${{ needs.UnitTestingParams.outputs.python_version }} # python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} # artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
secrets: # secrets:
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} # codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
PublishCoverageResults:
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@cov
needs:
- UnitTesting
- Coverage
secrets:
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
StaticTypeCheck: StaticTypeCheck:
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@cov uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@cov
@@ -69,44 +68,38 @@ jobs:
html_report: 'htmlmypy' html_report: 'htmlmypy'
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
PublishCoverageResults:
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@cov
needs:
- UnitTestingParams
- UnitTesting
- 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 }}
PublishTestResults: PublishTestResults:
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@cov uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@cov
needs: needs:
- UnitTesting - UnitTesting
- PlatformTesting
Package: Package:
uses: pyTooling/Actions/.github/workflows/Package.yml@cov uses: pyTooling/Actions/.github/workflows/Package.yml@cov
needs: needs:
- UnitTestingParams - UnitTestingParams
- Coverage - UnitTesting
# - Coverage
- PlatformTesting - PlatformTesting
with: with:
python_version: ${{ needs.UnitTestingParams.outputs.python_version }} python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} 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
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: # VerifyDocs:
# uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@cov # uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@cov
# needs: # needs:
@@ -114,33 +107,60 @@ jobs:
# with: # with:
# python_version: ${{ needs.UnitTestingParams.outputs.python_version }} # python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
# BuildTheDocs: BuildTheDocs:
# uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@cov uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@cov
# needs: needs:
# - UnitTestingParams - UnitTestingParams
## - VerifyDocs # - VerifyDocs
# with: with:
# artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
PublishToGitHubPages: PublishToGitHubPages:
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@cov uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@cov
needs: needs:
- UnitTestingParams - UnitTestingParams
# - BuildTheDocs - BuildTheDocs
- Coverage # - Coverage
- PublishCoverageResults
- StaticTypeCheck - StaticTypeCheck
with: with:
doc: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }} doc: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
coverage: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} coverage: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
typing: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_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: ArtifactCleanUp:
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@cov uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@cov
needs: needs:
- UnitTestingParams - UnitTestingParams
- PlatformTestingParams
- UnitTesting - UnitTesting
- PlatformTesting - PlatformTesting
- Coverage # - Coverage
- StaticTypeCheck - StaticTypeCheck
# - BuildTheDocs # - BuildTheDocs
- PublishToGitHubPages - PublishToGitHubPages
@@ -150,6 +170,22 @@ jobs:
package: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} package: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
remaining: | remaining: |
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-* ${{ 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).codecoverage_html }}
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_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 }}-*

4
.gitignore vendored
View File

@@ -24,8 +24,8 @@ coverage.xml
# Sphinx # Sphinx
doc/_build/ doc/_build/
doc/pyTooling/**/*.* doc/pyDummy/**/*.*
!doc/pyTooling/index.rst !doc/pyDummy/index.rst
# BuildTheDocs # BuildTheDocs
doc/_theme/**/*.* doc/_theme/**/*.*

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -44,31 +44,31 @@ Complex Example
The following instantiation example creates 3 jobs from the same template, but with differing input parameters. The 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 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 addition a list of excludes (marked as :deletion:`deletions`) and includes (marked as :addition:`additions`) is handed
over resulting in the following combinations: 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 🟡 | | 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.7 | windows:3.8 | windows:3.9 | windows:3.10 | | | | :deletion:`windows:pypy-3.8` | :deletion:`windows:pypy-3.9` | | 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.7 | ubuntu:3.8 | ubuntu:3.9 | ubuntu:3.10 | :addition:`ubuntu:3.11` | | | ubuntu:pypy-3.8 | ubuntu:pypy-3.9 | | 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.7 | macos:3.8 | macos:3.9 | macos:3.10 | :addition:`macos:3.11` | | | macos:pypy-3.8 | macos:pypy-3.9 | | 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 🟪 | | | | | | | | | | | MSYS 🟪 | | | | | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
| MinGW32 ⬛ | | | | | | | | | | | MinGW32 ⬛ | | | | | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
| MinGW64 🟦 | | | | mingw64:3.10 | | | | | | | MinGW64 🟦 | | | | mingw64:3.11 | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
| Clang32 🟫 | | | | | | | | | | | Clang32 🟫 | | | | | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
| Clang64 🟧 | | | | | | | | | | | Clang64 🟧 | | | | | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
| UCRT64 🟨 | | | | | | | | | | | UCRT64 🟨 | | | | | | | | | |
+------------+-------------+-------------+-------------+--------------+-------------------------+------------+-------------+------------------------------+------------------------------+ +------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
.. code-block:: yaml .. code-block:: yaml
@@ -84,22 +84,22 @@ over resulting in the following combinations:
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0 uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
with: with:
name: pyTooling name: pyTooling
python_version_list: "3.7 3.8 3.9 3.10 pypy-3.8 pypy-3.9" python_version_list: "3.8 3.9 3.10 3.11 pypy-3.9 pypy-3.10"
include_list: "ubuntu:3.11 macos:3.11" include_list: "ubuntu:3.12 macos:3.12"
exclude_list: "windows:pypy-3.8 windows:pypy-3.9" exclude_list: "windows:pypy-3.9 windows:pypy-3.10"
PerformanceTestingParams: PerformanceTestingParams:
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0 uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
with: with:
name: pyTooling name: pyTooling
python_version_list: "3.10 3.11" python_version_list: "3.11 3.12"
system_list: "ubuntu windows macos" system_list: "ubuntu windows macos"
PlatformTestingParams: PlatformTestingParams:
uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev
with: with:
name: pyTooling name: pyTooling
python_version_list: "3.10" python_version_list: "3.12"
system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64" system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64"
Parameters Parameters
@@ -125,7 +125,7 @@ python_version
+----------------+----------+----------+----------+ +----------------+----------+----------+----------+
| Parameter Name | Required | Type | Default | | 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. 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 python_version_list
=================== ===================
+----------------------+----------+----------+---------------------------+ +----------------------+----------+----------+----------------------------+
| Parameter Name | Required | Type | Default | | Parameter Name | Required | Type | Default |
+======================+==========+==========+===========================+ +======================+==========+==========+============================+
| python_version_list | optional | string | ``3.7 3.8 3.9 3.10 3.11`` | | 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. Space separated list of CPython versions and/or mypy version to run tests with.
**Possible values:** **Possible values:**
* ``3.6``, ``3.7``, ``3.8``, ``3.9``, ``3.10`` , ``3.11``, ``3.12`` * ``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.7``, ``pypy-3.8``, ``pypy-3.9``, ``pypy-3.10``
+------+-----------+------------------+-----------------------------------------+ +------+-----------+------------------+-----------------------------------------+
| Icon | Version | Maintained until | Comments | | 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 system_list
=========== ===========
+----------------+----------+----------+----------------------------------+ +----------------+----------+----------+-----------------------------------------+
| Parameter Name | Required | Type | Default | | Parameter Name | Required | Type | Default |
+================+==========+==========+==================================+ +================+==========+==========+=========================================+
| system_list | optional | string | ``ubuntu windows mingw64 macos`` | | system_list | optional | string | ``ubuntu windows macos mingw64 ucrt64`` |
+----------------+----------+----------+----------------------------------+ +----------------+----------+----------+-----------------------------------------+
Space separated list of systems to run tests on. 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) | | | 🧊 | 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 | | | | 🟪 | MSYS | | |
+------+-----------+------------------------------+-----------------------------------------------------------------+ +------+-----------+------------------------------+-----------------------------------------------------------------+
@@ -210,6 +212,7 @@ Space separated list of systems to run tests on.
| 🟨 | UCRT64 | | | | 🟨 | UCRT64 | | |
+------+-----------+------------------------------+-----------------------------------------------------------------+ +------+-----------+------------------------------+-----------------------------------------------------------------+
Source: `Images provided by GitHub <https://github.com/actions/runner-images>`__
include_list include_list
============ ============
@@ -370,6 +373,9 @@ A dictionary of artifact names sharing a common prefix.
The supported artifacts are: The supported artifacts are:
* ``unittesting_xml`` - UnitTesting XML summary report * ``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_xml`` - Code Coverage XML report
* ``codecoverage_html`` - Code Coverage HTML report * ``codecoverage_html`` - Code Coverage HTML report
* ``statictyping_html`` - Static Type Checking HTML report * ``statictyping_html`` - Static Type Checking HTML report

160
doc/_templates/autoapi/module.rst vendored Normal file
View File

@@ -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 -%}

14
doc/_templates/autoapi/package.rst vendored Normal file
View File

@@ -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 %}

View File

@@ -13,7 +13,7 @@ ROOT = Path(__file__).resolve().parent
sys_path.insert(0, abspath(".")) sys_path.insert(0, abspath("."))
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")) sys_path.insert(0, abspath("_extensions"))
@@ -25,7 +25,7 @@ sys_path.insert(0, abspath("_extensions"))
# built documents. # built documents.
project = "Actions" project = "Actions"
packageInformationFile = Path(f"../{project}/__init__.py") packageInformationFile = Path(f"../pyDummy/__init__.py")
versionInformation = extractVersionInformation(packageInformationFile) versionInformation = extractVersionInformation(packageInformationFile)
author = versionInformation.Author author = versionInformation.Author
@@ -173,9 +173,11 @@ latex_documents = [
# ============================================================================== # ==============================================================================
extensions = [ extensions = [
# Standard Sphinx extensions # Standard Sphinx extensions
"sphinx.ext.autodoc",
"sphinx.ext.coverage", "sphinx.ext.coverage",
"sphinx.ext.extlinks", "sphinx.ext.extlinks",
"sphinx.ext.intersphinx", "sphinx.ext.intersphinx",
"sphinx.ext.inheritance_diagram",
"sphinx.ext.todo", "sphinx.ext.todo",
"sphinx.ext.graphviz", "sphinx.ext.graphviz",
"sphinx.ext.mathjax", "sphinx.ext.mathjax",
@@ -185,6 +187,9 @@ extensions = [
"sphinxcontrib.mermaid", "sphinxcontrib.mermaid",
# Other extensions # Other extensions
"sphinx_fontawesome", "sphinx_fontawesome",
"sphinx_autodoc_typehints",
"sphinx_inline_tabs",
"autoapi.sphinx",
] ]
@@ -216,11 +221,11 @@ autodoc_typehints = "both"
# Sphinx.Ext.ExtLinks # Sphinx.Ext.ExtLinks
# ============================================================================== # ==============================================================================
extlinks = { extlinks = {
"gh": ("https://GitHub.com/%s", "gh:"), "gh": ("https://GitHub.com/%s", "gh:%s"),
"ghissue": ("https://GitHub.com/pyTooling/Actions/issues/%s", "issue #"), "ghissue": ("https://GitHub.com/pyTooling/Actions/issues/%s", "issue #%s"),
"ghpull": ("https://GitHub.com/pyTooling/Actions/pull/%s", "pull request #"), "ghpull": ("https://GitHub.com/pyTooling/Actions/pull/%s", "pull request #%s"),
"ghsrc": ("https://GitHub.com/pyTooling/Actions/blob/main/%s", None), "ghsrc": ("https://GitHub.com/pyTooling/Actions/blob/main/%s", None),
"wiki": ("https://en.wikipedia.org/wiki/%s", None), "wiki": ("https://en.wikipedia.org/wiki/%s", None),
} }
@@ -239,6 +244,18 @@ mermaid_params = [
mermaid_verbose = True mermaid_verbose = True
# ==============================================================================
# Sphinx.Ext.Inheritance_Diagram
# ==============================================================================
inheritance_node_attrs = {
# "shape": "ellipse",
# "fontsize": 14,
# "height": 0.75,
"color": "dodgerblue1",
"style": "filled"
}
# ============================================================================== # ==============================================================================
# Sphinx.Ext.ToDo # Sphinx.Ext.ToDo
# ============================================================================== # ==============================================================================
@@ -251,3 +268,15 @@ todo_link_only = True
# Sphinx.Ext.Coverage # Sphinx.Ext.Coverage
# ============================================================================== # ==============================================================================
coverage_show_missing_items = True coverage_show_missing_items = True
# ==============================================================================
# AutoAPI.Sphinx
# ==============================================================================
autoapi_modules = {
"pyDummy": {
"template": "module",
"output": "pyDummy",
"override": True
}
}

4
doc/coverage/index.rst Normal file
View File

@@ -0,0 +1,4 @@
Code Coverage Report
####################
*Placeholder for the Coverage report generated with* ``pytest`` *and* ``coverage``.

View File

@@ -122,14 +122,6 @@ License
The accompanying documentation is licensed under **Creative Commons - Attribution 4.0 (CC-BY 4.0)**. 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:: .. toctree::
:caption: Introduction :caption: Introduction
:hidden: :hidden:
@@ -171,6 +163,19 @@ License
JobTemplate/Release JobTemplate/Release
JobTemplate/ArtifactCleanUp JobTemplate/ArtifactCleanUp
.. raw:: latex
\part{pyDummy Example}
.. toctree::
:caption: pyDummy Example
:hidden:
pyDummy/pyDummy
Unittest Report ➚ <unittests/index>
Coverage Report ➚ <coverage/index>
Static Type Check Report ➚ <typing/index>
.. raw:: latex .. raw:: latex
\part{Appendix} \part{Appendix}

0
doc/pyDummy/.gitempty Normal file
View File

View File

@@ -3,7 +3,8 @@
pyTooling >= 5.0.0, < 6.0 pyTooling >= 5.0.0, < 6.0
# Enforce latest version on ReadTheDocs # 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 Extenstions
#sphinx.ext.coverage #sphinx.ext.coverage
@@ -12,12 +13,8 @@ sphinxcontrib-mermaid>=0.9.2
#sphinxcontrib-seqdiag>=0.8.5 #sphinxcontrib-seqdiag>=0.8.5
#sphinxcontrib-textstyle>=0.2.1 #sphinxcontrib-textstyle>=0.2.1
#sphinxcontrib-spelling>=2.2.0 #sphinxcontrib-spelling>=2.2.0
autoapi autoapi >= 2.0.1
sphinx_fontawesome>=0.0.6 sphinx_fontawesome >= 0.0.6
sphinx_autodoc_typehints>=1.19.5 sphinx-inline-tabs >= 2023.4.21
sphinx_autodoc_typehints >= 1.24.0
# changelog>=0.3.5 # changelog>=0.3.5
# BuildTheDocs Extensions (mostly patched Sphinx extensions)
# For pyTooling.Configuration.YAML documentation
ruamel.yaml>=0.17

8
doc/typing/index.rst Normal file
View File

@@ -0,0 +1,8 @@
Static Type Checking Report
###########################
*Placeholder for the Static Type Checking report generated with* ``mypy``.
.. #raw:: html
<iframe src="../../../../report/typing/index.html" width="100%" height="500px" style="border:none;"/>

4
doc/unittests/index.rst Normal file
View File

@@ -0,0 +1,4 @@
UnitTest Report
###############
*Placeholder for the unittest report generated with* ``pytest``.

View File

@@ -11,7 +11,7 @@
# # # #
# License: # # License: #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Bötzingen, Germany # # Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,24 +28,74 @@
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
# #
"""
A module for a set of dummy classes.
"""
__author__ = "Patrick Lehmann" __author__ = "Patrick Lehmann"
__email__ = "Paebbels@gmail.com" __email__ = "Paebbels@gmail.com"
__copyright__ = "2017-2023, Patrick Lehmann" __copyright__ = "2017-2024, Patrick Lehmann"
__license__ = "Apache License, Version 2.0" __license__ = "Apache License, Version 2.0"
__version__ = "0.1.0" __version__ = "0.4.4"
__keywords__ = ["dummy"] __keywords__ = ["GitHub Actions"]
__issue_tracker__ = "https://GitHub.com/pyTooling/Actions/issues" __issue_tracker__ = "https://GitHub.com/pyTooling/Actions/issues"
from pyTooling.Decorators import export from pyTooling.Decorators import export, readonly
from pyTooling.Platform import Platform
@export @export
class Application: class Base:
_value: int """
A base-class for dummy applications.
"""
_value: int #: An internal value.
def __init__(self) -> None: def __init__(self) -> None:
self._value = 1 """
Initializes the base-class.
"""
self._value = 0
@property @readonly
def Value(self) -> int: def Value(self) -> int:
"""
Read-only property to return the internal value.
:return: Internal value.
"""
return self._value return self._value
@export
class Application(Base):
"""
A dummy application for demonstration purposes.
"""
def __init__(self) -> None:
"""
Initializes the dummy application.
"""
super().__init__()
platform = Platform()
if platform.IsNativeLinux:
self._value += 1
elif platform.IsNativeMacOS:
self._value += 2
elif platform.IsNativeWindows:
self._value += 3
elif platform.IsMSYSOnWindows:
self._value += 11
elif platform.IsMinGW32OnWindows:
self._value += 12
elif platform.IsMinGW64OnWindows:
self._value += 13
elif platform.IsUCRT64OnWindows:
self._value += 14
elif platform.IsClang32OnWindows:
self._value += 15
elif platform.IsClang64OnWindows:
self._value += 16

View File

@@ -11,7 +11,7 @@ line-length = 120
[tool.mypy] [tool.mypy]
files = ["pyDummy"] files = ["pyDummy"]
python_version = "3.11" python_version = "3.12"
#ignore_missing_imports = true #ignore_missing_imports = true
strict = true strict = true
pretty = true pretty = true
@@ -32,10 +32,14 @@ filterwarnings = [
[tool.coverage.run] [tool.coverage.run]
branch = true branch = true
relative_files = true
omit = [ omit = [
"*site-packages*", "*site-packages*",
"setup.py", "setup.py",
"tests/*" "tests/benchmark/*",
"tests/performance/*",
"tests/platform/*",
"tests/unit/*"
] ]
[tool.coverage.report] [tool.coverage.report]

View File

@@ -3,7 +3,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -3,7 +3,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -5,7 +5,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #

View File

@@ -11,7 +11,7 @@
# # # #
# License: # # License: #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Bötzingen, Germany # # Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -38,7 +38,8 @@ packageName = "pyDummy"
packageDirectory = packageName packageDirectory = packageName
packageInformationFile = Path(f"{packageDirectory}/__init__.py") packageInformationFile = Path(f"{packageDirectory}/__init__.py")
setup(**DescribePythonPackageHostedOnGitHub( # setup(**
DescribePythonPackageHostedOnGitHub(
packageName=packageName, packageName=packageName,
description="pyDummy is a test package to verify GitHub actions for Python projects.", description="pyDummy is a test package to verify GitHub actions for Python projects.",
gitHubNamespace=gitHubNamespace, gitHubNamespace=gitHubNamespace,
@@ -47,4 +48,5 @@ setup(**DescribePythonPackageHostedOnGitHub(
dataFiles={ dataFiles={
packageName: ["py.typed"] packageName: ["py.typed"]
} }
)) )
# )

View File

@@ -11,7 +11,7 @@
# # # #
# License: # # License: #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Bötzingen, Germany # # Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,12 +28,12 @@
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
# #
"""Unit tests for TBD.""" from unittest import TestCase
from os import getenv as os_getenv
from pytest import mark
from unittest import TestCase
from pyTooling.Platform import Platform from pytest import mark
from pyTooling.Common import CurrentPlatform
from pyDummy import Application
if __name__ == "__main__": # pragma: no cover if __name__ == "__main__": # pragma: no cover
@@ -42,75 +42,57 @@ if __name__ == "__main__": # pragma: no cover
exit(1) exit(1)
class AnyPlatform(TestCase): class PlatformTesting(TestCase):
expected = os_getenv("ENVIRONMENT_NAME", default="Windows (x86-64)") @mark.skipif(not CurrentPlatform.IsNativeLinux, reason="Skipped, if current platform isn't native Linux.")
def test_ApplicationOnNativeLinux(self):
app = Application()
@mark.skipif(os_getenv("ENVIRONMENT_NAME", "skip") == "skip", reason="Skipped when environment variable 'ENVIRONMENT_NAME' isn't set.") self.assertEqual(1, app.Value)
def test_PlatformString(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsNativeMacOS, reason="Skipped, if current platform isn't native macOS.")
print(platform) def test_ApplicationOnNativeMacOS(self):
app = Application()
@mark.skipif("Linux (x86-64)" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_NativeLinux' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(2, app.Value)
def test_NativeLinux(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsNativeWindows, reason="Skipped, if current platform isn't native Windows.")
print(platform) def test_ApplicationOnNativeWindows(self):
app = Application()
@mark.skipif("MacOS (x86-64)" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_NativeMacOS' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(3, app.Value)
def test_NativeMacOS(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsMSYSOnWindows, reason="Skipped, if current platform isn't MSYS on Windows.")
print(platform) def test_ApplicationOnMSYS2OnWindows(self):
app = Application()
@mark.skipif("Windows (x86-64)" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_NativeWindows' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(11, app.Value)
def test_NativeWindows(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsMinGW32OnWindows, reason="Skipped, if current platform isn't MinGW32 on Windows.")
print(platform) def test_ApplicationOnMinGW32OnWindows(self):
app = Application()
@mark.skipif("Windows+MSYS2 (x86-64) - MSYS" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_MSYS' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(12, app.Value)
def test_MSYS(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsMinGW64OnWindows, reason="Skipped, if current platform isn't MinGW64 on Windows.")
print(platform) def test_ApplicationOnMinGW64OnWindows(self):
app = Application()
@mark.skipif("Windows+MSYS2 (x86-64) - MinGW32" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_MinGW32' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(13, app.Value)
def test_MinGW32(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsUCRT64OnWindows, reason="Skipped, if current platform isn't UCRT64 on Windows.")
print(platform) def test_ApplicationOnURTC64OnWindows(self):
app = Application()
@mark.skipif("Windows+MSYS2 (x86-64) - MinGW64" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_MinGW64' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(14, app.Value)
def test_MinGW64(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsClang32OnWindows, reason="Skipped, if current platform isn't Clang32 on Windows.")
print(platform) def test_ApplicationOnClang32OnWindows(self):
app = Application()
@mark.skipif("Windows+MSYS2 (x86-64) - UCRT64" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_UCRT64' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(15, app.Value)
def test_UCRT64(self) -> None:
platform = Platform()
print() @mark.skipif(not CurrentPlatform.IsClang64OnWindows, reason="Skipped, if current platform isn't Clang64 on Windows.")
print(platform) def test_ApplicationOnClang64OnWindows(self):
app = Application()
@mark.skipif("Windows+MSYS2 (x86-64) - Clang32" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_Clang32' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}") self.assertEqual(16, app.Value)
def test_Clang32(self) -> None:
platform = Platform()
print()
print(platform)
@mark.skipif("Windows+MSYS2 (x86-64) - Clang64" != os_getenv("ENVIRONMENT_NAME", "skip"), reason=f"Skipped 'test_Clang64' when environment variable 'ENVIRONMENT_NAME' doesn't match. {os_getenv('ENVIRONMENT_NAME', 'skip')}")
def test_Clang64(self) -> None:
platform = Platform()
print()
print(platform)

View File

@@ -1,13 +1,13 @@
-r ../requirements.txt -r ../requirements.txt
# Coverage collection # Coverage collection
Coverage >= 7.3 Coverage >= 7.4
# Test Runner # Test Runner
pytest >= 7.4.0 pytest >= 7.4.0
pytest-cov >= 4.1.0 pytest-cov >= 4.1.0
# Static Type Checking # Static Type Checking
mypy >= 1.5.0 mypy >= 1.8.0
typing_extensions >= 4.7.1 typing_extensions >= 4.9.0
lxml>=4.9 lxml >= 5.0

View File

@@ -11,7 +11,7 @@
# # # #
# License: # # License: #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Bötzingen, Germany # # Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -37,4 +37,4 @@ class Instantiation(TestCase):
def test_Application(self): def test_Application(self):
app = Application() app = Application()
self.assertEqual(1, app.Value) self.assertGreater(app.Value, 0)

View File

@@ -11,7 +11,7 @@
# # # #
# License: # # License: #
# ==================================================================================================================== # # ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Bötzingen, Germany # # Copyright 2017-2024 Patrick Lehmann - Bötzingen, Germany #
# # # #
# Licensed under the Apache License, Version 2.0 (the "License"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #
@@ -28,4 +28,4 @@
# SPDX-License-Identifier: Apache-2.0 # # SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== # # ==================================================================================================================== #
# #
"""Test code for pyTooling.""" """Test code for pyDummy."""

View File

@@ -4,7 +4,7 @@
# Unai Martinez-Corral # # 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"); # # Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. # # you may not use this file except in compliance with the License. #