diff --git a/.github/workflows/CheckCodeQuality.yml b/.github/workflows/CheckCodeQuality.yml new file mode 100644 index 0000000..b62dcfc --- /dev/null +++ b/.github/workflows/CheckCodeQuality.yml @@ -0,0 +1,140 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# # +# ==================================================================================================================== # +# Copyright 2025-2025 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: Code Quality Checking + +on: + workflow_call: + inputs: + ubuntu_image_version: + description: 'Ubuntu image version.' + required: false + default: '24.04' + type: string + python_version: + description: 'Python version.' + required: false + default: '3.13' + type: string + package_directory: + description: '.' + required: true + type: string + requirements: + description: '' + required: false + default: '-r requirements.txt' + type: string + artifact: + description: 'Name of the package artifact.' + required: true + type: string + +jobs: + Bandit: + name: 🚨 Security Scanning (Bandit) + runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v5 + with: + lfs: true + submodules: true + + - name: 🐍 Setup Python ${{ inputs.python_version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ inputs.python_version }} + + - name: ⚙ Install dependencies for running bandit + run: python -m pip install --disable-pip-version-check bandit + + - name: 👮 Bandit + if: inputs.artifact != '' + run: | + mkdir -p report/bandit + bandit -c pyproject.toml -r ${{ inputs.package_directory }} -f xml -o report/bandit/report.xml + + Radon: + name: ☢️ Metrics and Complexity + runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v5 + with: + lfs: true + submodules: true + + - name: 🐍 Setup Python ${{ inputs.python_version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ inputs.python_version }} + + - name: ⚙ Install dependencies for running radon + run: python -m pip install --disable-pip-version-check radon + + - name: Code Metrics +# if: inputs.artifact != '' + run: | + radon raw ${{ inputs.package_directory }} -s + + - name: Code Complexity +# if: inputs.artifact != '' + run: | + radon cc ${{ inputs.package_directory }} --total-average + + - name: Halstead Complexity Metrics +# if: inputs.artifact != '' + run: | + radon hal ${{ inputs.package_directory }} + + - name: Maintainability Index +# if: inputs.artifact != '' + run: | + radon mi ${{ inputs.package_directory }} -s + + PyLint: + name: 🩺 Linting + runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v5 + with: + lfs: true + submodules: true + + - name: 🐍 Setup Python ${{ inputs.python_version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ inputs.python_version }} + + - name: ⚙ Install dependencies for running PyLint + run: | + python -m pip install --disable-pip-version-check pylint + python -m pip install --disable-pip-version-check ${{ inputs.requirements }} + + - name: 🩺 PyLint +# if: inputs.artifact != '' + run: | + pylint ${{ inputs.package_directory }} diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index b1b1a4a..fd94427 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -198,6 +198,15 @@ jobs: junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_junit }} html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} + CodeQuality: + uses: pyTooling/Actions/.github/workflows/CheckCodeQuality.yml@dev + needs: + - UnitTestingParams + with: + python_version: ${{ needs.UnitTestingParams.outputs.python_version }} + package_directory: ${{ needs.UnitTestingParams.outputs.package_directory }} + artifact: CodeQuality + DocCoverage: uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@dev needs: diff --git a/.github/workflows/StaticApplicationSecurityTesting.yml b/.github/workflows/StaticApplicationSecurityTesting.yml new file mode 100644 index 0000000..4479b53 --- /dev/null +++ b/.github/workflows/StaticApplicationSecurityTesting.yml @@ -0,0 +1,74 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# # +# ==================================================================================================================== # +# Copyright 2025-2025 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: Security Testing (SAST) + +on: + workflow_call: + inputs: + ubuntu_image_version: + description: 'Ubuntu image version.' + required: false + default: '24.04' + type: string + python_version: + description: 'Python version.' + required: false + default: '3.13' + type: string +# requirements: +# description: 'Python dependencies to be installed through pip.' +# required: false +# default: 'bandit' +# type: string + package_directory: + description: '.' + required: true + type: string + artifact: + description: 'Name of the package artifact.' + required: true + type: string + +jobs: + Bandit: + name: 🚨 Security Scanning + runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v5 + with: + lfs: true + submodules: true + + - name: 🐍 Setup Python ${{ inputs.python_version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ inputs.python_version }} + + - name: ⚙ Install dependencies for packaging and release + run: python -m pip install --disable-pip-version-check bandit + + - name: 👮 Bandit + if: inputs.artifact != '' + run: | + bandit -c pyproject.toml -r ${{ inputs.package_directory }} -f xml -o report/bandit/report.xml diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 949b9c7..8cdf343 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -79,6 +79,15 @@ jobs: html_report: ${{ needs.ConfigParams.outputs.typing_report_html }} html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} + CodeQuality: + uses: pyTooling/Actions/.github/workflows/CheckCodeQuality.yml@dev + needs: + - UnitTestingParams + with: + python_version: ${{ needs.UnitTestingParams.outputs.python_version }} + package_directory: ${{ needs.UnitTestingParams.outputs.package_directory }} + artifact: CodeQuality + DocCoverage: uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@dev needs: diff --git a/.gitignore b/.gitignore index 9fdee07..b241e00 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ coverage.xml /report/unit /tests/*.github +# bandit +/report/bandit + # setuptools /build/**/*.* /dist/**/*.* diff --git a/.idea/Actions.iml b/.idea/Actions.iml index d8b3f6c..b80e16a 100644 --- a/.idea/Actions.iml +++ b/.idea/Actions.iml @@ -1,7 +1,13 @@ - + + + + + + + diff --git a/myFramework/Extension/__init__.py b/myFramework/Extension/__init__.py index 7afe407..285b68f 100644 --- a/myFramework/Extension/__init__.py +++ b/myFramework/Extension/__init__.py @@ -67,6 +67,14 @@ class Base: """ return self._value + def Add(self, value) -> None: + """ + Accumulate value to internal value. + + :param value: Value to accumulate. + """ + self._value += value + @export class Application(Base): @@ -81,6 +89,7 @@ class Application(Base): super().__init__() platform = Platform() + # pylint: disable=using-constant-test if platform.IsNativeLinux: self._value += 1 elif platform.IsNativeMacOS: diff --git a/myPackage/__init__.py b/myPackage/__init__.py index 2b2eff5..d065523 100644 --- a/myPackage/__init__.py +++ b/myPackage/__init__.py @@ -67,6 +67,14 @@ class Base: """ return self._value + def Add(self, value) -> None: + """ + Accumulate value to internal value. + + :param value: Value to accumulate. + """ + self._value += value + @export class Application(Base): @@ -81,6 +89,7 @@ class Application(Base): super().__init__() platform = Platform() + # pylint: disable=using-constant-test if platform.IsNativeLinux: self._value += 1 elif platform.IsNativeMacOS: diff --git a/pyproject.toml b/pyproject.toml index 8f7ecf1..6388d1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,22 @@ requires = [ ] build-backend = "setuptools.build_meta" -[tool.black] -line-length = 120 +[tool.pylint.format] +indent-string="\t" +max-line-length = 120 + +[tool.pylint.basic] +argument-naming-style = "camelCase" +attr-naming-style = "camelCase" +class-attribute-naming-style = "camelCase" +class-const-naming-style = "UPPER_CASE" +class-naming-style = "PascalCase" +const-naming-style = "UPPER_CASE" +function-naming-style = "camelCase" +inlinevar-naming-style = "camelCase" +method-naming-style = "PascalCase" +module-naming-style = "any" +variable-naming-style = "camelCase" [tool.mypy] packages = ["myPackage", "myFramework.Extension"]