From 27d45b9766b9afa551ea54c7ebda404b8d3d8b3d Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 18 Apr 2025 13:06:36 +0200 Subject: [PATCH 01/27] Bumped version of pyDummy. --- pyDummy/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyDummy/__init__.py b/pyDummy/__init__.py index c453bd0..636ed39 100644 --- a/pyDummy/__init__.py +++ b/pyDummy/__init__.py @@ -36,7 +36,7 @@ __author__ = "Patrick Lehmann" __email__ = "Paebbels@gmail.com" __copyright__ = "2017-2025, Patrick Lehmann" __license__ = "Apache License, Version 2.0" -__version__ = "0.4.4" +__version__ = "0.4.5" __keywords__ = ["GitHub Actions"] __issue_tracker__ = "https://GitHub.com/pyTooling/Actions/issues" From f10daa2e2cb32bfce5ff319a7590eb4498cbd6bc Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 20 Apr 2025 19:22:08 +0200 Subject: [PATCH 02/27] Allow setting a pipeline startup delay. --- .github/workflows/CompletePipeline.yml | 10 ++++------ .github/workflows/Parameters.yml | 11 +++++++++++ doc/coverage/index.rst | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 0355118..d0f862a 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -138,10 +138,10 @@ jobs: package_name: ${{ inputs.package_name }} python_version: ${{ inputs.unittest_python_version }} python_version_list: ${{ inputs.unittest_python_version_list }} - system_list: ${{ inputs.unittest_system_list }} - include_list: ${{ inputs.unittest_include_list }} - exclude_list: ${{ inputs.unittest_exclude_list }} - disable_list: ${{ inputs.unittest_disable_list }} + system_list: ${{ inputs.unittest_system_list }} + include_list: ${{ inputs.unittest_include_list }} + exclude_list: ${{ inputs.unittest_exclude_list }} + disable_list: ${{ inputs.unittest_disable_list }} AppTestingParams: uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev @@ -242,13 +242,11 @@ jobs: - UnitTestingParams - UnitTesting with: - additional_merge_args: '-d "--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit"' testsuite-summary-name: ${{ inputs.package_name }} merged_junit_filename: ${{ needs.ConfigParams.outputs.unittest_merged_report_xml_filename }} merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} dorny: ${{ inputs.dorny }} codecov: ${{ inputs.codecov }} - secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/Parameters.yml b/.github/workflows/Parameters.yml index 2e82729..a9a387f 100644 --- a/.github/workflows/Parameters.yml +++ b/.github/workflows/Parameters.yml @@ -95,6 +95,11 @@ on: required: false default: 'macos-14' type: string + pipeline-delay: + description: 'Slow down this job, to delay the startup of the GitHub Action pipline.' + required: false + default: 0 + type: number outputs: python_version: @@ -121,6 +126,12 @@ jobs: params: ${{ steps.params.outputs.params }} steps: + - name: Generate a startup delay of ${{ inputs.pipeline-delay }} seconds + id: delay + if: inputs.pipeline-delay >= 0 + run: | + sleep ${{ inputs.pipeline-delay }} + - name: Generate 'params' and 'python_jobs' id: params shell: python diff --git a/doc/coverage/index.rst b/doc/coverage/index.rst index ef8d044..02fd732 100644 --- a/doc/coverage/index.rst +++ b/doc/coverage/index.rst @@ -4,4 +4,4 @@ Code Coverage Report Code coverage report generated with `pytest `__ and `Coverage.py `__. .. #report:code-coverage:: - :packageid: src + :reportid: src From aaf283515bd99b9a3be7f2d60c1b07777a2e08b0 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 21 Apr 2025 13:09:12 +0200 Subject: [PATCH 03/27] Fixed typos. --- .github/workflows/CompletePipeline.yml | 2 +- .github/workflows/Parameters.yml | 2 +- .github/workflows/_Checking_JobTemplates.yml | 6 +++--- doc/requirements.txt | 2 +- pyproject.toml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index d0f862a..40948dd 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -180,7 +180,7 @@ jobs: commands: | ${{ needs.ConfigParams.outputs.mypy_prepare_command }} mypy --html-report report/typing -p ${{ needs.ConfigParams.outputs.package_fullname }} - html_report: 'report/typing' + html_report: 'report/typing' html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} DocCoverage: diff --git a/.github/workflows/Parameters.yml b/.github/workflows/Parameters.yml index a9a387f..41874ea 100644 --- a/.github/workflows/Parameters.yml +++ b/.github/workflows/Parameters.yml @@ -131,7 +131,7 @@ jobs: if: inputs.pipeline-delay >= 0 run: | sleep ${{ inputs.pipeline-delay }} - + - name: Generate 'params' and 'python_jobs' id: params shell: python diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 8995492..06e8fd5 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -69,8 +69,8 @@ jobs: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} commands: | ${{ needs.ConfigParams.outputs.mypy_prepare_command }} - mypy --html-report htmlmypy -p ${{ needs.ConfigParams.outputs.package_fullname }} - html_report: 'htmlmypy' + mypy --html-report report/typing -p ${{ needs.ConfigParams.outputs.package_fullname }} + html_report: 'report/typing' html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} DocCoverage: @@ -80,7 +80,7 @@ jobs: - UnitTestingParams with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - directory : ${{ needs.ConfigParams.outputs.package_directors }} + directory : ${{ needs.ConfigParams.outputs.package_directory }} # fail_below: 70 Package: diff --git a/doc/requirements.txt b/doc/requirements.txt index c2de896..cab4a5a 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -16,4 +16,4 @@ autoapi >= 2.0.1 sphinx_design ~= 0.6.1 sphinx-copybutton >= 0.5.2 sphinx_autodoc_typehints ~= 3.1 -sphinx_reports ~= 0.7 +sphinx_reports ~= 0.9 diff --git a/pyproject.toml b/pyproject.toml index 6d28fca..eba19e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] requires = [ - "setuptools ~= 78.1", + "setuptools ~= 79.0", "wheel ~= 0.45", "pyTooling ~= 8.4" ] From 8e94b774dae6939b55421c5c24e5df438dc2a8d2 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 00:17:59 +0200 Subject: [PATCH 04/27] Bumped copyright year. --- .github/workflows/ApplicationTesting.yml | 2 +- .github/workflows/ArtifactCleanUp.yml | 2 +- .github/workflows/BuildTheDocs.yml | 2 +- .github/workflows/CheckDocumentation.yml | 2 +- .github/workflows/CompletePipeline.yml | 2 +- .github/workflows/CoverageCollection.yml | 2 +- .github/workflows/ExtractConfiguration.yml | 2 +- .github/workflows/IntermediateCleanUp.yml | 2 +- .github/workflows/LaTeXDocumentation.yml | 2 +- .github/workflows/NightlyRelease.yml | 2 +- .github/workflows/Package.yml | 2 +- .github/workflows/Parameters.yml | 2 +- .github/workflows/PublishCoverageResults.yml | 2 +- .github/workflows/PublishOnPyPI.yml | 2 +- .github/workflows/PublishTestResults.yml | 2 +- .github/workflows/PublishToGitHubPages.yml | 2 +- .github/workflows/Release.yml | 3 +-- .github/workflows/SphinxDocumentation.yml | 2 +- .github/workflows/StaticTypeCheck.yml | 2 +- .github/workflows/UnitTesting.yml | 2 +- .github/workflows/VerifyDocs.yml | 2 +- releaser/action.yml | 2 +- releaser/composite/action.yml | 2 +- with-post-step/action.yml | 2 +- 24 files changed, 24 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ApplicationTesting.yml b/.github/workflows/ApplicationTesting.yml index b8b15b0..3090f55 100644 --- a/.github/workflows/ApplicationTesting.yml +++ b/.github/workflows/ApplicationTesting.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/ArtifactCleanUp.yml b/.github/workflows/ArtifactCleanUp.yml index b19e833..f082e0b 100644 --- a/.github/workflows/ArtifactCleanUp.yml +++ b/.github/workflows/ArtifactCleanUp.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/BuildTheDocs.yml b/.github/workflows/BuildTheDocs.yml index dcf8782..0cb92d9 100644 --- a/.github/workflows/BuildTheDocs.yml +++ b/.github/workflows/BuildTheDocs.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/CheckDocumentation.yml b/.github/workflows/CheckDocumentation.yml index 21e1bd8..81d967c 100644 --- a/.github/workflows/CheckDocumentation.yml +++ b/.github/workflows/CheckDocumentation.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 40948dd..d2f968a 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/CoverageCollection.yml b/.github/workflows/CoverageCollection.yml index a9df9dc..e8f37d5 100644 --- a/.github/workflows/CoverageCollection.yml +++ b/.github/workflows/CoverageCollection.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/ExtractConfiguration.yml b/.github/workflows/ExtractConfiguration.yml index 29e9379..7acff81 100644 --- a/.github/workflows/ExtractConfiguration.yml +++ b/.github/workflows/ExtractConfiguration.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/IntermediateCleanUp.yml b/.github/workflows/IntermediateCleanUp.yml index 1ba9295..b3ca6e7 100644 --- a/.github/workflows/IntermediateCleanUp.yml +++ b/.github/workflows/IntermediateCleanUp.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/LaTeXDocumentation.yml b/.github/workflows/LaTeXDocumentation.yml index 9027bc2..c197b49 100644 --- a/.github/workflows/LaTeXDocumentation.yml +++ b/.github/workflows/LaTeXDocumentation.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/NightlyRelease.yml b/.github/workflows/NightlyRelease.yml index 260fb8b..769990d 100644 --- a/.github/workflows/NightlyRelease.yml +++ b/.github/workflows/NightlyRelease.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/Package.yml b/.github/workflows/Package.yml index a3618d4..950969b 100644 --- a/.github/workflows/Package.yml +++ b/.github/workflows/Package.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/Parameters.yml b/.github/workflows/Parameters.yml index 41874ea..d3d2c0b 100644 --- a/.github/workflows/Parameters.yml +++ b/.github/workflows/Parameters.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index bafa84a..73b03ed 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/PublishOnPyPI.yml b/.github/workflows/PublishOnPyPI.yml index 0eb3735..f5e976c 100644 --- a/.github/workflows/PublishOnPyPI.yml +++ b/.github/workflows/PublishOnPyPI.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index de1a450..41b21ac 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/PublishToGitHubPages.yml b/.github/workflows/PublishToGitHubPages.yml index 020aefa..ca7e165 100644 --- a/.github/workflows/PublishToGitHubPages.yml +++ b/.github/workflows/PublishToGitHubPages.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 1dea8d1..936e90a 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -1,10 +1,9 @@ # ==================================================================================================================== # # Authors: # # Patrick Lehmann # -# Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/SphinxDocumentation.yml b/.github/workflows/SphinxDocumentation.yml index 3cf2089..d61c5e2 100644 --- a/.github/workflows/SphinxDocumentation.yml +++ b/.github/workflows/SphinxDocumentation.yml @@ -3,7 +3,7 @@ # Patrick Lehmann # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/StaticTypeCheck.yml b/.github/workflows/StaticTypeCheck.yml index 02571fb..5bb6217 100644 --- a/.github/workflows/StaticTypeCheck.yml +++ b/.github/workflows/StaticTypeCheck.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/UnitTesting.yml b/.github/workflows/UnitTesting.yml index eaf2f56..7bab324 100644 --- a/.github/workflows/UnitTesting.yml +++ b/.github/workflows/UnitTesting.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/.github/workflows/VerifyDocs.yml b/.github/workflows/VerifyDocs.yml index dad2d53..bb53f87 100644 --- a/.github/workflows/VerifyDocs.yml +++ b/.github/workflows/VerifyDocs.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/releaser/action.yml b/releaser/action.yml index d36d012..62068a4 100644 --- a/releaser/action.yml +++ b/releaser/action.yml @@ -3,7 +3,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/releaser/composite/action.yml b/releaser/composite/action.yml index bc1f180..3f4e638 100644 --- a/releaser/composite/action.yml +++ b/releaser/composite/action.yml @@ -3,7 +3,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # diff --git a/with-post-step/action.yml b/with-post-step/action.yml index 69c2a6e..bd9337a 100644 --- a/with-post-step/action.yml +++ b/with-post-step/action.yml @@ -4,7 +4,7 @@ # Unai Martinez-Corral # # # # ==================================================================================================================== # -# Copyright 2020-2024 The pyTooling Authors # +# Copyright 2020-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. # From a1309f9f425483aa6c05059b67703bddc8cf8176 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 00:18:51 +0200 Subject: [PATCH 05/27] Improved printf usage. --- .github/workflows/BuildTheDocs.yml | 2 +- .github/workflows/CheckDocumentation.yml | 2 +- .github/workflows/CoverageCollection.yml | 2 +- .github/workflows/NightlyRelease.yml | 22 +++++++++++----------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/BuildTheDocs.yml b/.github/workflows/BuildTheDocs.yml index 0cb92d9..391d22c 100644 --- a/.github/workflows/BuildTheDocs.yml +++ b/.github/workflows/BuildTheDocs.yml @@ -38,7 +38,7 @@ jobs: steps: - name: '❗ Deprecation message' - run: printf "%s\n" "::warning title=Deprecated::'BuildTheDocs.yml' is not maintained anymore. Please switch to 'SphinxDocumentation.yml', 'LaTeXDocumentation.yml' and 'ExtractConfiguration.yml'." + run: printf "::warning title=%s::%s\n" "Deprecated" "'BuildTheDocs.yml' is not maintained anymore. Please switch to 'SphinxDocumentation.yml', 'LaTeXDocumentation.yml' and 'ExtractConfiguration.yml'." - name: ⏬ Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/CheckDocumentation.yml b/.github/workflows/CheckDocumentation.yml index 81d967c..2eef1f2 100644 --- a/.github/workflows/CheckDocumentation.yml +++ b/.github/workflows/CheckDocumentation.yml @@ -64,7 +64,7 @@ jobs: - name: Run 'interrogate' Documentation Coverage Check continue-on-error: true run: | - interrogate -c pyproject.toml --fail-under=${{ inputs.fail_under }} && printf "%s\n" "::error title=interrogate::Insufficient documentation quality (goal: ${{ inputs.fail_under }})" + interrogate -c pyproject.toml --fail-under=${{ inputs.fail_under }} && printf "::error title=%s::%s\n" "interrogate" "Insufficient documentation quality (goal: ${{ inputs.fail_under }})" - name: Run 'docstr_coverage' Documentation Coverage Check continue-on-error: true diff --git a/.github/workflows/CoverageCollection.yml b/.github/workflows/CoverageCollection.yml index e8f37d5..e6cdde2 100644 --- a/.github/workflows/CoverageCollection.yml +++ b/.github/workflows/CoverageCollection.yml @@ -72,7 +72,7 @@ jobs: steps: - name: '❗ Deprecation message' - run: printf "%s\n" "::warning title=Deprecated::'CoverageCollection.yml' is not maintained anymore. Please switch to 'UnitTesting.yml', 'PublishCoverageResults.yml' and 'PublishTestResults.yml'." + run: printf "::warning title=%s::%s\n" "Deprecated" "'CoverageCollection.yml' is not maintained anymore. Please switch to 'UnitTesting.yml', 'PublishCoverageResults.yml' and 'PublishTestResults.yml'." - name: ⏬ Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/NightlyRelease.yml b/.github/workflows/NightlyRelease.yml index 769990d..3a8ebcd 100644 --- a/.github/workflows/NightlyRelease.yml +++ b/.github/workflows/NightlyRelease.yml @@ -130,7 +130,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=InternalError::Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'." + printf "::error title=%s::%s\n" "InternalError" "Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'." exit 1 fi @@ -190,7 +190,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=InternalError::Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'." + printf "::error title=%s::%s\n" "InternalError" "Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'." exit 1 fi @@ -289,7 +289,7 @@ jobs: printf " %s" "Checked asset for duplicates ... " if [[ -n "${assetFilenames[$asset]}" ]]; then printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" - printf "%s\n" "::error title=DuplicateAsset::Asset '${asset}' from artifact '${artifact}' was already uploaded to release '${{ inputs.nightly_name }}'." + printf "::error title=%s::%s\n" "DuplicateAsset" "Asset '${asset}' from artifact '${artifact}' was already uploaded to release '${{ inputs.nightly_name }}'." ERRORS=$((ERRORS + 1)) continue else @@ -309,7 +309,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't download artifact '${artifact}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=ArtifactNotFound::Couldn't download artifact '${artifact}'." + printf "::error title=%s::%s\n" "ArtifactNotFound" "Couldn't download artifact '${artifact}'." ERRORS=$((ERRORS + 1)) continue fi @@ -361,7 +361,7 @@ jobs: else printf " %s\n" "Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to zip file '${asset}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=CompressionError::Couldn't compress '${artifact}' to zip file '${asset}'." + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to zip file '${asset}'." ERRORS=$((ERRORS + 1)) continue fi @@ -390,7 +390,7 @@ jobs: else printf " %s\n" "Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to tgz file '${asset}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=CompressionError::Couldn't compress '${artifact}' to tgz file '${asset}'." + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to tgz file '${asset}'." ERRORS=$((ERRORS + 1)) continue fi @@ -419,7 +419,7 @@ jobs: else printf " %s\n" "Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to zst file '${asset}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=CompressionError::Couldn't compress '${artifact}' to zst file '${asset}'." + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to zst file '${asset}'." ERRORS=$((ERRORS + 1)) continue fi @@ -429,7 +429,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't find asset '${asset}' in artifact '${artifact}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=FileNotFound::Couldn't find asset '${asset}' in artifact '${artifact}'." + printf "::error title=%s::%s\n" "FileNotFound" "Couldn't find asset '${asset}' in artifact '${artifact}'." ERRORS=$((ERRORS + 1)) continue fi @@ -469,7 +469,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=UploadError::Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'." + printf "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'." ERRORS=$((ERRORS + 1)) continue fi @@ -492,7 +492,7 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't upload asset '${{ inputs.inventory-json }}' to release '${{ inputs.nightly_name }}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=UploadError::Couldn't upload asset '${{ inputs.inventory-json }}' to release '${{ inputs.nightly_name }}'." + printf "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${{ inputs.inventory-json }}' to release '${{ inputs.nightly_name }}'." ERRORS=$((ERRORS + 1)) continue fi @@ -526,5 +526,5 @@ jobs: else printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}" printf " %s\n" "${ANSI_LIGHT_RED}Couldn't remove draft-state from release '${{ inputs.nightly_name }}'.${ANSI_NOCOLOR}" - printf "%s\n" "::error title=ReleasePage::Couldn't remove draft-state from release '${{ inputs.nightly_name }}'." + printf "::error title=%s::%s\n" "ReleasePage" "Couldn't remove draft-state from release '${{ inputs.nightly_name }}'." fi From 70f5fe1fc83cae83e9ff45e22f4db64ae872ec28 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 00:19:49 +0200 Subject: [PATCH 06/27] Added default values to secrets in case a service demanding a secret isn't used. --- .github/workflows/CompletePipeline.yml | 3 +++ .github/workflows/CoverageCollection.yml | 1 + .github/workflows/PublishCoverageResults.yml | 2 ++ .github/workflows/PublishOnPyPI.yml | 1 + .github/workflows/PublishTestResults.yml | 1 + 5 files changed, 8 insertions(+) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index d2f968a..72c80cb 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -117,12 +117,15 @@ on: PYPI_TOKEN: description: "Token for pushing releases to PyPI." required: false + default: unset CODECOV_TOKEN: description: "Token for pushing coverage and unittest results to Codecov." required: false + default: unset CODACY_PROJECT_TOKEN: description: "Token for pushing coverage results to Codacy." required: false + default: unset jobs: ConfigParams: diff --git a/.github/workflows/CoverageCollection.yml b/.github/workflows/CoverageCollection.yml index e6cdde2..badf637 100644 --- a/.github/workflows/CoverageCollection.yml +++ b/.github/workflows/CoverageCollection.yml @@ -63,6 +63,7 @@ on: codacy_token: description: 'Token to push result to codacy.' required: true + default: unset jobs: diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 73b03ed..940bb5f 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -97,9 +97,11 @@ on: CODECOV_TOKEN: description: 'Token to push result to Codecov.' required: true + default: unset CODACY_TOKEN: description: 'Token to push result to Codacy.' required: true + default: unset jobs: PublishCoverageResults: diff --git a/.github/workflows/PublishOnPyPI.yml b/.github/workflows/PublishOnPyPI.yml index f5e976c..fa74349 100644 --- a/.github/workflows/PublishOnPyPI.yml +++ b/.github/workflows/PublishOnPyPI.yml @@ -48,6 +48,7 @@ on: PYPI_TOKEN: description: "Token for pushing releases to PyPI" required: false + default: unset jobs: diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 41b21ac..733a7cc 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -78,6 +78,7 @@ on: CODECOV_TOKEN: description: 'Token to push result to Codecov.' required: true + default: unset jobs: PublishTestResults: From 8d0c46d6b5837598524f48557e209857e55e66f5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 00:20:10 +0200 Subject: [PATCH 07/27] Added new Prepare job template. --- .github/workflows/Prepare.yml | 308 ++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 .github/workflows/Prepare.yml diff --git a/.github/workflows/Prepare.yml b/.github/workflows/Prepare.yml new file mode 100644 index 0000000..9e3337e --- /dev/null +++ b/.github/workflows/Prepare.yml @@ -0,0 +1,308 @@ +name: Prepare Variables + +on: + workflow_call: + inputs: + ubuntu_image: + description: 'Name of the Ubuntu image.' + required: false + default: 'ubuntu-24.04' + type: string + main_branch: + description: 'Name of the branch containing releases.' + required: false + default: 'main' + type: string + development_branch: + description: 'Name of the development branch containing features.' + required: false + default: 'dev' + type: string + release_branch: + description: 'Name of the branch containing releases.' + required: false + default: 'main' + type: string + tag_pattern: + description: 'Name of the branch containing releases.' + required: false + default: '(v|r)?[0-9]+(\.[0-9]+){0,2}(-(dev|alpha|beta|rc)([0-9]*))?' + type: string + + outputs: + on_main_branch: + description: "" + value: ${{ jobs.Prepare.outputs.on_main_branch }} + on_dev_branch: + description: "" + value: ${{ jobs.Prepare.outputs.on_dev_branch }} + on_release_branch: + description: "" + value: ${{ jobs.Prepare.outputs.on_release_branch }} + is_regular_commit: + description: "" + value: ${{ jobs.Prepare.outputs.is_regular_commit }} + is_merge_commit: + description: "" + value: ${{ jobs.Prepare.outputs.is_merge_commit }} + is_release_commit: + description: "" + value: ${{ jobs.Prepare.outputs.is_release_commit }} + ref_kind: + description: "" + value: ${{ jobs.Prepare.outputs.ref_kind }} + branch: + description: "" + value: ${{ jobs.Prepare.outputs.branch }} + tag: + description: "" + value: ${{ jobs.Prepare.outputs.tag }} + version: + description: "" + value: ${{ jobs.Prepare.outputs.version }} + pr_title: + description: "" + value: ${{ jobs.Prepare.outputs.pr_title }} + pr_number: + description: "" + value: ${{ jobs.Prepare.outputs.pr_number }} +# pr_mergedby: +# description: "" +# value: ${{ jobs.Prepare.outputs.pr_mergedby }} +# pr_mergedat: +# description: "" +# value: ${{ jobs.Prepare.outputs.pr_mergedat }} + +jobs: + Prepare: + name: Extract Information + runs-on: ubuntu-24.04 + outputs: + on_main_branch: ${{ steps.Classify.outputs.on_main_branch }} + on_dev_branch: ${{ steps.Classify.outputs.on_dev_branch }} + on_release_branch: ${{ steps.Classify.outputs.on_release_branch }} + is_regular_commit: ${{ steps.Classify.outputs.is_regular_commit }} + is_merge_commit: ${{ steps.Classify.outputs.is_merge_commit }} + is_release_commit: ${{ steps.Classify.outputs.is_release_commit }} + ref_kind: ${{ steps.Classify.outputs.ref_kind }} + branch: ${{ steps.Classify.outputs.branch }} + tag: ${{ steps.Classify.outputs.tag }} + version: ${{ steps.Classify.outputs.version || steps.FindPullRequest.outputs.pr_version }} +# release_version: ${{ steps.FindPullRequest.outputs.release_version }} + pr_title: ${{ steps.FindPullRequest.outputs.pr_title }} + pr_number: ${{ steps.FindPullRequest.outputs.pr_number }} + + steps: + - name: ⏬ Checkout repository + uses: actions/checkout@v4 + with: + # The command 'git describe' (used for version) needs the history. + fetch-depth: 0 + + - name: 🖉 GitHub context information + run: | + printf "%s\n" "github.event_name: ${{ github.event_name }}" + printf "%s\n" "github.actor: ${{ github.actor }}" + printf "%s\n" "github.ref: ${{ github.ref }}" + printf "%s\n" "github.base_ref: ${{ github.base_ref }}" + printf "%s\n" "github.head_ref: ${{ github.head_ref }}" + printf "%s\n" "github.sha: ${{ github.sha }}" + + - name: 🖉 Classify commit + id: Classify + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' + + ref="${{ github.ref }}" + on_main_branch="false" + on_dev_branch="false" + on_release_branch="false" + is_regular_commit="false" + is_merge_commit="false" + is_release_commit="false" + ref_kind="unknown" + branch="" + tag="" + version="" + + if [[ "${ref:0:11}" == "refs/heads/" ]]; then + ref_kind="branch" + branch="${ref:11}" + + printf "Commit check:\n" + + if [[ "${branch}" == "${{ inputs.main_branch }}" ]]; then + on_main_branch="true" + + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then + is_regular_commit="true" + printf " ${ANSI_LIGHT_YELLOW}regular " + else + is_merge_commit="true" + printf " ${ANSI_LIGHT_GREEN}merge " + fi + printf "commit${ANSI_NOCOLOR} on main branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.main_branch }}" + fi + + if [[ "${branch}" == "${{ inputs.development_branch }}" ]]; then + on_dev_branch="true" + + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then + is_regular_commit="true" + printf " ${ANSI_LIGHT_YELLOW}regular " + else + is_merge_commit="true" + printf " ${ANSI_LIGHT_GREEN}merge " + fi + printf "commit${ANSI_NOCOLOR} on development branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.development_branch }}" + fi + + if [[ "${branch}" == "${{ inputs.release_branch }}" ]]; then + on_release_branch="true" + + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then + is_regular_commit="true" + printf " ${ANSI_LIGHT_YELLOW}regular " + else + is_release_commit="true" + printf " ${ANSI_LIGHT_GREEN}release " + fi + printf "commit${ANSI_NOCOLOR} on release branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.release_branch }}" + fi + elif [[ "${ref:0:10}" == "refs/tags/" ]]; then + ref_kind="tag" + tag="${ref:10}" + + printf "Tag check:\n" + + printf " Check if tag is on release branch '%s' ... " "${{ inputs.release_branch }}" + git branch --remotes --contains $(git rev-parse --verify "tags/${tag}~0") | grep "origin/${{ inputs.release_branch }}" > /dev/null + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "${ANSI_LIGHT_RED}Tag '%s' isn't on branch '%s'.${ANSI_NOCOLOR}\n" "${tag}" "${{ inputs.release_branch }}" + printf "::error title=TagCheck::Tag '%s' isn't on branch '%s'.\n" "${tag}" "${{ inputs.release_branch }}" + exit 1 + fi + + TAG_PATTERN='^${{ inputs.tag_pattern }}$' + printf " Check tag name against regexp '%s' ... " "${TAG_PATTERN}" + if [[ "${tag}" =~ $TAG_PATTERN ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + version="${tag}" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "${ANSI_LIGHT_RED}Tag name '%s' doesn't conform to regexp '%s'.${ANSI_NOCOLOR}\n" "${tag}" "${TAG_PATTERN}" + printf "::error title=RexExpCheck::Tag name '%s' doesn't conform to regexp '%s'.\n" "${tag}" "${TAG_PATTERN}" + exit 1 + fi + else + printf "${ANSI_LIGHT_RED}Unknown Git reference '%s'.${ANSI_NOCOLOR}\n" "${{ github.ref }}" + printf "::error title=Classify Commit::Unknown Git reference '%s'.\n" "${{ github.ref }}" + exit 1 + fi + + tee --append "${GITHUB_OUTPUT}" < %s\n" "${{ github.ref }}^2" "${FATHER_SHA}" + exit 1 + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + fi + + printf "Search Pull Request to '%s' and branch containing SHA %s ... " "${{ inputs.release_branch }}" "${FATHER_SHA}" + PULL_REQUESTS=$(gh pr list --base "${{ inputs.release_branch }}" --search "${FATHER_SHA}" --state "merged" --json "title,number,mergedBy,mergedAt") + if [[ $? -ne 0 || "${PULL_REQUESTS}" == "" ]]; then + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "${ANSI_LIGHT_RED}Couldn't find a merged Pull Request to '%s'. -> %s${ANSI_NOCOLOR}\n" "${{ inputs.release_branch }}" "${PULL_REQUESTS}" + printf "::error title=PullRequest::Couldn't find a merged Pull Request to '%s'. -> %s\n" "${{ inputs.release_branch }}" "${PULL_REQUESTS}" + exit 1 + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + + PR_TITLE="$( printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].title")" + PR_NUMBER="$( printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].number")" + PR_MERGED_BY="$(printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].mergedBy.login")" + PR_MERGED_AT="$(printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].mergedAt")" + + printf "${ANSI_LIGHT_BLUE}Found Pull Request:${ANSI_NOCOLOR}\n" + printf " %s\n" "Title: ${PR_TITLE}" + printf " %s\n" "Number: ${PR_NUMBER}" + printf " %s\n" "MergedBy: ${PR_MERGED_BY}" + printf " %s\n" "MergedAt: ${PR_MERGED_AT} ($(date -d"${PR_MERGED_AT}" '+%d.%m.%Y - %H:%M:%S'))" + fi + + TAG_PATTERN='^${{ inputs.tag_pattern }}$' + printf "Check Pull Request title against regexp '%s' ... " "${TAG_PATTERN}" + if [[ "${PR_TITLE}" =~ $TAG_PATTERN ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + RELEASE_VERSION="${PR_TITLE}" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "${ANSI_LIGHT_RED}Pull Request title '%s' doesn't conform to regexp '%s'.${ANSI_NOCOLOR}\n" "${PR_TITLE}" "${TAG_PATTERN}" + printf "::error title=RexExpCheck::Pull Request title '%s' doesn't conform to regexp '%s'.\n" "${PR_TITLE}" "${TAG_PATTERN}" + exit 1 + fi + + printf "Release tag: ${ANSI_LIGHT_GREEN}%s${ANSI_NOCOLOR}\n" "${RELEASE_VERSION}" + tee --append "${GITHUB_OUTPUT}" < Date: Sat, 26 Apr 2025 00:20:29 +0200 Subject: [PATCH 08/27] Reworked Release job template. --- .github/workflows/CompletePipeline.yml | 3 - .github/workflows/CoverageCollection.yml | 1 - .github/workflows/PublishCoverageResults.yml | 2 - .github/workflows/PublishOnPyPI.yml | 1 - .github/workflows/PublishTestResults.yml | 1 - .github/workflows/Release.yml | 797 +++++++++++++++++-- 6 files changed, 751 insertions(+), 54 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 72c80cb..d2f968a 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -117,15 +117,12 @@ on: PYPI_TOKEN: description: "Token for pushing releases to PyPI." required: false - default: unset CODECOV_TOKEN: description: "Token for pushing coverage and unittest results to Codecov." required: false - default: unset CODACY_PROJECT_TOKEN: description: "Token for pushing coverage results to Codacy." required: false - default: unset jobs: ConfigParams: diff --git a/.github/workflows/CoverageCollection.yml b/.github/workflows/CoverageCollection.yml index badf637..e6cdde2 100644 --- a/.github/workflows/CoverageCollection.yml +++ b/.github/workflows/CoverageCollection.yml @@ -63,7 +63,6 @@ on: codacy_token: description: 'Token to push result to codacy.' required: true - default: unset jobs: diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 940bb5f..73b03ed 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -97,11 +97,9 @@ on: CODECOV_TOKEN: description: 'Token to push result to Codecov.' required: true - default: unset CODACY_TOKEN: description: 'Token to push result to Codacy.' required: true - default: unset jobs: PublishCoverageResults: diff --git a/.github/workflows/PublishOnPyPI.yml b/.github/workflows/PublishOnPyPI.yml index fa74349..f5e976c 100644 --- a/.github/workflows/PublishOnPyPI.yml +++ b/.github/workflows/PublishOnPyPI.yml @@ -48,7 +48,6 @@ on: PYPI_TOKEN: description: "Token for pushing releases to PyPI" required: false - default: unset jobs: diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 733a7cc..41b21ac 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -78,7 +78,6 @@ on: CODECOV_TOKEN: description: 'Token to push result to Codecov.' required: true - default: unset jobs: PublishTestResults: diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 936e90a..3585bbe 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -24,69 +24,774 @@ name: Release on: workflow_call: inputs: - ubuntu_image_version: - description: 'Ubuntu image version.' + ubuntu_image: + description: 'Name of the Ubuntu image.' required: false - default: '24.04' + default: 'ubuntu-24.04' type: string + release_branch: + description: 'Name of the branch containing releases.' + required: false + default: 'main' + type: string + mode: + description: 'Release mode: nightly or release.' + required: false + default: 'release' + type: string + tag: + description: 'Name of the release (tag).' + required: false + default: '' + type: string + title: + description: 'Title of the release.' + required: false + default: '' + type: string + description: + description: 'Multi-line description of the release.' + required: false + default: 'Release of artifacts from latest CI pipeline.' + type: string + description_file: + description: 'Description of the release from a Markdown file.' + required: false + default: '' + type: string + description_footer: + description: 'Footer line(s) in every release.' + required: false + default: | + + -------- + Published from [%%gh_workflow%%](%%gh_server%%/%%gh_owner_repo%%/actions/runs/%%gh_runid%%) workflow triggered by %%gh_actor%% on %%datetime%%. + + This automatic release was created by [pyTooling/Actions](http://github.com/pyTooling/Actions)::Release.yml + type: string + draft: + description: 'Specify if this is a draft.' + required: false + default: false + type: boolean + prerelease: + description: 'Specify if this is a pre-release.' + required: false + default: false + type: boolean + latest: + description: 'Specify if this is the latest release.' + required: false + default: false + type: boolean + replacements: + description: 'Multi-line string containing search=replace patterns.' + required: false + default: '' + type: string + assets: + description: 'Multi-line string containing artifact:file:title asset descriptions.' + required: true + type: string + inventory-json: + type: string + required: false + default: '' + inventory-version: + type: string + required: false + default: '' + inventory-categories: + type: string + required: false + default: '' + tarball-name: + type: string + required: false + default: '__pyTooling_upload_artifact__.tar' + can-fail: + type: boolean + required: false + default: false + outputs: + release-page: + description: "URL to the release page." + value: ${{ jobs.Release.outputs.release-page }} jobs: Release: - name: 📝 Create 'Release Page' on GitHub - runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" + name: 📝 Create or Update Release Page on GitHub + runs-on: ${{ inputs.ubuntu_image }} + continue-on-error: ${{ inputs.can-fail }} + permissions: + contents: write + actions: write +# attestations: write + outputs: + release-page: ${{ steps.removeDraft.outputs.release_page }} steps: - - name: 🔁 Extract Git tag from GITHUB_REF - id: getVariables - run: | - GIT_TAG=${GITHUB_REF#refs/*/} - RELEASE_VERSION=${GIT_TAG#v} - RELEASE_DATETIME="$(date --utc '+%d.%m.%Y - %H:%M:%S')" - # write to step outputs - printf "%s\n" "gitTag=${GIT_TAG}" >> $GITHUB_OUTPUT - printf "%s\n" "version=${RELEASE_VERSION}" >> $GITHUB_OUTPUT - printf "%s\n" "datetime=${RELEASE_DATETIME}" >> $GITHUB_OUTPUT - - - name: 📑 Create Release Page - uses: actions/create-release@v1 - id: createReleasePage - env: - GITHUB_TOKEN: ${{ github.token }} + - name: ⏬ Checkout repository + uses: actions/checkout@v4 with: - tag_name: ${{ steps.getVariables.outputs.gitTag }} -# release_name: ${{ steps.getVariables.outputs.gitTag }} - body: | - **Automated Release created on: ${{ steps.getVariables.outputs.datetime }}** + # The command 'git describe' (used for version) needs the history. + fetch-depth: 0 - # New Features + - name: 🔧 Install zstd + run: sudo apt-get install -y --no-install-recommends zstd - * tbd - * tbd + - name: 📑 Prepare + id: prepare + run: | + set +e - # Changes + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' - * tbd - * tbd + printf "Release mode: ${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "${{ inputs.mode }}" + case "${{ inputs.mode }}" in + "release") + ;; + "nightly") + printf "→ Allow deletion and recreation of existing release pages for rolling releases (nightly releases)\n" + ;; + *) + printf "Unknown mode '%s'\n" "${{ inputs.mode }}" + printf "::error title=%s::%s\n" "InternalError" "Unknown mode '${{ inputs.mode }}'." + exit 1 + esac - # Bug Fixes + - name: 📑 Delete (old) Release Page + id: deleteReleasePage + if: inputs.mode == 'nightly' + run: | + set +e - * tbd - * tbd + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' - # Documentation + export GH_TOKEN=${{ github.token }} - * tbd - * tbd + printf "Deleting release '%s' ... " "${{ inputs.tag }}" + message="$(gh release delete ${{ inputs.tag }} --yes 2>&1)" + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + elif [[ "${message}" == "release not found" ]]; then + printf "${ANSI_LIGHT_YELLOW}[NOT FOUND]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't delete release '%s' -> Error: '%s'.${ANSI_NOCOLOR}\n" "${{ inputs.tag }}" "${message}" + printf "::error title=%s::%s\n" "InternalError" "Couldn't delete release '${{ inputs.tag }}' -> Error: '${message}'." + exit 1 + fi - # Unit Tests + - name: 📑 Assemble Release Notes + id: createReleaseNotes + run: | + set +e - * tbd - * tbd + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' - ---------- - # Related Issues and Pull-Requests + export GH_TOKEN=${{ github.token }} - * tbd - * tbd - draft: true - prerelease: false + # Save release description (from parameter in a file) + cat <<'EOF' > __DESCRIPTION__.md + ${{ inputs.description }} + EOF + + # Save release footer (from parameter in a file) + cat <<'EOF' > __FOOTER__.md + ${{ inputs.description_footer }} + EOF + + # Download Markdown from PullRequest + # Readout second parent's SHA + # Search PR with that SHA + # Load description of that PR + printf "Read second parent of current SHA (%s) ... " "${{ github.ref }}" + FATHER_SHA=$(git rev-parse ${{ github.ref }}^2 -- 2> /dev/null) + if [[ $? -ne 0 || "{FATHER_SHA}" == "" ]]; then + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "→ ${ANSI_LIGHT_YELLOW}Skipped readout of pull request description. This is not a merge commit.${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + + printf "Search Pull Request to '%s' and branch containing SHA %s ... " "${{ inputs.release_branch }}" "${FATHER_SHA}" + PULL_REQUESTS=$(gh pr list --base "${{ inputs.release_branch }}" --search "${FATHER_SHA}" --state "merged" --json "title,number,mergedBy,mergedAt,body") + if [[ $? -ne 0 || "${PULL_REQUESTS}" == "" ]]; then + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "${ANSI_LIGHT_RED}Couldn't find a merged Pull Request to '%s'. -> %s${ANSI_NOCOLOR}\n" "${{ inputs.release_branch }}" "${PULL_REQUESTS}" + printf "::error title=PullRequest::Couldn't find a merged Pull Request to '%s'. -> %s\n" "${{ inputs.release_branch }}" "${PULL_REQUESTS}" + exit 1 + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + + PR_TITLE="$( printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].title")" + PR_NUMBER="$( printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].number")" + PR_BODY="$( printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].body")" + PR_MERGED_BY="$(printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].mergedBy.login")" + PR_MERGED_AT="$(printf "%s\n" "${PULL_REQUESTS}" | jq --raw-output ".[0].mergedAt")" + + printf "Found Pull Request:\n" + printf " %s\n" "Title: ${PR_TITLE}" + printf " %s\n" "Number: ${PR_NUMBER}" + printf " %s\n" "MergedBy: ${PR_MERGED_BY}" + printf " %s\n" "MergedAt: ${PR_MERGED_AT} ($(date -d"${PR_MERGED_AT}" '+%d.%m.%Y - %H:%M:%S'))" + fi + + echo "${PR_BODY}" > __PULLREQUEST__.md + fi + + # Check if a release description file should be used and exists. + if [[ "${{ inputs.description_file }}" != "" ]]; then + if [[ ! -f "${{ inputs.description_file }}" ]]; then + printf "${ANSI_LIGHT_RED}Release description file '%s' not found.${ANSI_NOCOLOR}\n" "${{ inputs.description_file }}" + printf "::error title=%s::%s\n" "FileNotFound" "Release description file '${{ inputs.description_file }}' not found." + exit 1 + elif [[ -s "${{ inputs.description_file }}" ]]; then + printf "Use '%s' as main release description.\n" "${{ inputs.description_file }}" + cp -v "${{ inputs.description_file }}" __NOTES__.md + else + printf "${ANSI_LIGHT_RED}Release description file '%s' is empty.${ANSI_NOCOLOR}\n" "${{ inputs.description_file }}" + printf "::error title=%s::%s\n" "FileNotFound" "Release description file '${{ inputs.description_file }}' is empty." + exit 1 + fi + # Check if the main release description is provided by a template parameter + elif [[ -s __DESCRIPTION__.md ]]; then + printf "Use '__DESCRIPTION__.md' as main release description.\n" + mv -v __DESCRIPTION__.md __NOTES__.md + # Check if the pull request serves as the main release description text. + elif [[ -s __PULLREQUEST__.md ]]; then + printf "Use '__PULLREQUEST__.md' as main release description.\n" + mv -v __PULLREQUEST__.md __NOTES__.md + else + printf "${ANSI_LIGHT_RED}No release description specified (file, parameter, PR text).${ANSI_NOCOLOR}\n" + printf "::error title=%s::%s\n" "MissingDescription" "No release description specified (file, parameter, PR text)." + exit 1 + fi + + # Read release notes main file for placeholder substitution + NOTES=$(<__NOTES__.md) + + # Inline description + if [[ -s __DESCRIPTION__.md ]]; then + NOTES="${NOTES//%%DESCRIPTION%%/$(<__DESCRIPTION__.md)}" + fi + + # Inline PullRequest and increase headline levels + if [[ -s __PULLREQUEST__.md ]]; then + while [[ "${NOTES}" =~ %%(PULLREQUEST(\+[0-3])?)%% ]]; do + case "${BASH_REMATCH[1]}" in + "PULLREQUEST+0" | "PULLREQUEST") + NOTES="${NOTES//${BASH_REMATCH[0]}/$(<__PULLREQUEST__.md)}" + ;; + "PULLREQUEST+1") + NOTES="${NOTES//${BASH_REMATCH[0]}/$(cat __PULLREQUEST__.md | sed -E 's/^(#+) /\1# /gm;t')}" + ;; + "PULLREQUEST+2") + NOTES="${NOTES//${BASH_REMATCH[0]}/$(cat __PULLREQUEST__.md | sed -E 's/^(#+) /\1### /gm;t')}" + ;; + "PULLREQUEST+3") + NOTES="${NOTES//${BASH_REMATCH[0]}/$(cat __PULLREQUEST__.md | sed -E 's/^(#+) /\1### /gm;t')}" + ;; + esac + done + fi + + # inline Footer + if [[ -s __FOOTER__.md ]]; then + NOTES="${NOTES//%%FOOTER%%/$(<__FOOTER__.md)}" + fi + + # Apply replacements + while IFS=$'\r\n' read -r patternLine; do + # skip empty lines + [[ "$patternLine" == "" ]] && continue + + pattern="%${patternLine%%=*}%" + replacement="${patternLine#*=}" + NOTES="${NOTES//$pattern/$replacement}" + done <<<'${{ inputs.replacements }}' + + # Workarounds for stupid GitHub variables + owner_repo="${{ github.repository }}" + repo=${owner_repo##*/} + + # Replace special identifiers + NOTES="${NOTES//%%gh_server%%/${{ github.server_url }}}" + NOTES="${NOTES//%%gh_workflow_name%%/${{ github.workflow }}}" + NOTES="${NOTES//%%gh_owner%%/${{ github.repository_owner }}}" + NOTES="${NOTES//%%gh_repo%%/${repo}}" + NOTES="${NOTES//%%gh_owner_repo%%/${{ github.repository_owner }}}" + #NOTES="${NOTES//%%gh_pages%%/https://${{ github.repository_owner }}.github.io/${repo}/}" + NOTES="${NOTES//%%gh_runid%%/${{ github.run_id }}}" + NOTES="${NOTES//%%gh_actor%%/${{ github.actor }}}" + NOTES="${NOTES//%%gh_sha%%/${{ github.sha }}}" + NOTES="${NOTES//%%date%%/$(date '+%Y-%m-%d')}" + NOTES="${NOTES//%%time%%/$(date '+%H:%M:%S %Z')}" + NOTES="${NOTES//%%datetime%%/$(date '+%Y-%m-%d %H:%M:%S %Z')}" + + # Write final release notes to file + echo "${NOTES}" > __NOTES__.md + + # Display partial contents for debugging + if [[ -s __DESCRIPTION__.md ]]; then + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__DESCRIPTION__.md' ...." + cat __DESCRIPTION__.md + printf "::endgroup::\n" + else + printf "${ANSI_LIGHT_YELLOW}No '__DESCRIPTION__.md' found.${ANSI_NOCOLOR}\n" + fi + if [[ -s __PULLREQUEST__.md ]]; then + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__PULLREQUEST__.md' ...." + cat __PULLREQUEST__.md + printf "::endgroup::\n" + else + printf "${ANSI_LIGHT_YELLOW}No '__PULLREQUEST__.md' found.${ANSI_NOCOLOR}\n" + fi + if [[ -s __FOOTER__.md ]]; then + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__FOOTER__.md' ...." + cat __FOOTER__.md + printf "::endgroup::\n" + else + printf "${ANSI_LIGHT_YELLOW}No '__FOOTER__.md' found.${ANSI_NOCOLOR}\n" + fi + + # Print final release notes + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__NOTES__.md' ...." + cat __NOTES__.md + printf "::endgroup::\n" + + - name: 📑 Create new Release Page + id: createReleasePage + if: inputs.mode == 'release' + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' + + export GH_TOKEN=${{ github.token }} + + if [[ "${{ inputs.prerelease }}" == "true" ]]; then + addPreRelease="--prerelease" + fi + + if [[ "${{ inputs.latest }}" == "false" ]]; then + addLatest="--latest=false" + fi + + if [[ "${{ inputs.title }}" != "" ]]; then + addTitle=("--title" "${{ inputs.title }}") + fi + + if [[ -s __NOTES__.md ]]; then + addNotes=("--notes-file" "__NOTES__.md") + fi + + printf "Creating release '%s' ... " "${{ inputs.tag }}" + message="$(gh release create "${{ inputs.tag }}" --verify-tag --draft $addPreRelease $addLatest "${addTitle[@]}" "${addNotes[@]}" 2>&1)" + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + printf " Release page: %s\n" "${message}" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't create release '%s' -> Error: '%s'.${ANSI_NOCOLOR}\n" "${{ inputs.tag }}" "${message}" + printf "::error title=%s::%s\n" "InternalError" "Couldn't create release '${{ inputs.tag }}' -> Error: '${message}'." + exit 1 + fi + + - name: 📑 Recreate Release Page + id: recreateReleasePage + if: inputs.mode == 'nightly' + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' + + export GH_TOKEN=${{ github.token }} + + addDraft="--draft" + if [[ "${{ inputs.prerelease }}" == "true" ]]; then + addPreRelease="--prerelease" + fi + + if [[ "${{ inputs.latest }}" == "false" ]]; then + addLatest="--latest=false" + fi + + if [[ "${{ inputs.title }}" != "" ]]; then + addTitle=("--title" "${{ inputs.title }}") + fi + + if [[ -s __NOTES__.md ]]; then + addNotes=("--notes-file" "__NOTES__.md") + fi + + printf "Creating release '%s' ... " "${{ inputs.tag }}" + message="$(gh release create "${{ inputs.tag }}" --verify-tag --draft $addPreRelease $addLatest "${addTitle[@]}" "${addNotes[@]}" 2>&1)" + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + printf " Release page: %s\n" "${message}" + else + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't recreate release '%s' -> Error: '%s'.${ANSI_NOCOLOR}\n" "${{ inputs.tag }}" "${message}" + printf "::error title=%s::%s\n" "InternalError" "Couldn't recreate release '${{ inputs.tag }}' -> Error: '${message}'." + exit 1 + fi + + - name: 📥 Download artifacts and upload as assets + id: uploadAssets + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_LIGHT_YELLOW=$'\x1b[93m' + ANSI_LIGHT_BLUE=$'\x1b[94m' + ANSI_NOCOLOR=$'\x1b[0m' + + export GH_TOKEN=${{ github.token }} + + Replace() { + line="$1" + while IFS=$'\r\n' read -r patternLine; do + # skip empty lines + [[ "$patternLine" == "" ]] && continue + + pattern="${patternLine%%=*}" + replacement="${patternLine#*=}" + line="${line//"%$pattern%"/"$replacement"}" + done <<<'${{ inputs.replacements }}' + printf "%s\n" "$line" + } + + # Create JSON inventory + if [[ "${{ inputs.inventory-json }}" != "" ]]; then + VERSION="1.0" + + # Split categories by ',' into a Bash array. + # See https://stackoverflow.com/a/45201229/3719459 + if [[ "${{ inputs.inventory-categories }}" != "" ]]; then + readarray -td, inventoryCategories <<<"${{ inputs.inventory-categories }}," + unset 'inventoryCategories[-1]' + declare -p inventoryCategories + else + inventoryCategories="" + fi + + jsonInventory=$(jq -c -n \ + --arg version "${VERSION}" \ + --arg date "$(date +"%Y-%m-%dT%H-%M-%S%:z")" \ + --argjson jsonMeta "$(jq -c -n \ + --arg tag "${{ inputs.tag }}" \ + --arg version "${{ inputs.inventory-version }}" \ + --arg hash "${{ github.sha }}" \ + --arg repo "${{ github.server_url }}/${{ github.repository }}" \ + --arg release "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ inputs.tag }}" \ + --argjson categories "$(jq -c -n \ + '$ARGS.positional' \ + --args "${inventoryCategories[@]}" \ + )" \ + '{"tag": $tag, "version": $version, "git-hash": $hash, "repository-url": $repo, "release-url": $release, "categories": $categories}' \ + )" \ + '{"version": 1.0, "timestamp": $date, "meta": $jsonMeta, "files": {}}' + ) + fi + + ERRORS=0 + # A dictionary of 0/1 to avoid duplicate downloads + declare -A downloadedArtifacts + # A dictionary to check for duplicate asset files in release + declare -A assetFilenames + while IFS=$'\r\n' read -r assetLine; do + if [[ "${assetLine}" == "" || "${assetLine:0:1}" == "#" ]]; then + continue + fi + + # split assetLine colon separated triple: artifact:asset:title + artifact="${assetLine%%:*}" + assetLine="${assetLine#*:}" + asset="${assetLine%%:*}" + assetLine="${assetLine#*:}" + if [[ "${{ inputs.inventory-json }}" == "" ]]; then + categories="" + title="${assetLine##*:}" + else + categories="${assetLine%%:*}" + title="${assetLine##*:}" + fi + + # remove leading whitespace + asset="${asset#"${asset%%[![:space:]]*}"}" + categories="${categories#"${categories%%[![:space:]]*}"}" + title="${title#"${title%%[![:space:]]*}"}" + + # apply replacements + asset="$(Replace "${asset}")" + title="$(Replace "${title}")" + + printf "Publish asset '%s' from artifact '%s' with title '%s'\n" "${asset}" "${artifact}" "${title}" + printf " Checked asset for duplicates ... " + if [[ -n "${assetFilenames[$asset]}" ]]; then + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf "::error title=%s::%s\n" "DuplicateAsset" "Asset '${asset}' from artifact '${artifact}' was already uploaded to release '${{ inputs.tag }}'." + ERRORS=$((ERRORS + 1)) + continue + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + assetFilenames[$asset]=1 + fi + + # Download artifact by artifact name + if [[ -n "${downloadedArtifacts[$artifact]}" ]]; then + printf " downloading '%s' ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}\n" "${artifact}" + else + echo " downloading '${artifact}' ... " + printf " gh run download $GITHUB_RUN_ID --dir \"%s\" --name \"%s\" " "${artifact}" "${artifact}" + gh run download $GITHUB_RUN_ID --dir "${artifact}" --name "${artifact}" + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't download artifact '%s'.${ANSI_NOCOLOR}\n" "${artifact}" + printf "::error title=%s::%s\n" "ArtifactNotFound" "Couldn't download artifact '${artifact}'." + ERRORS=$((ERRORS + 1)) + continue + fi + downloadedArtifacts[$artifact]=1 + + printf " Checking for embedded tarball ... " + if [[ -f "${artifact}/${{ inputs.tarball-name }}" ]]; then + printf "${ANSI_LIGHT_GREEN}[FOUND]${ANSI_NOCOLOR}\n" + + pushd "${artifact}" > /dev/null + + printf " Extracting embedded tarball ... " + tar -xf "${{ inputs.tarball-name }}" + if [[ $? -ne 0 ]]; then + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + fi + + printf " Removing temporary tarball ... " + rm -f "${{ inputs.tarball-name }}" + if [[ $? -ne 0 ]]; then + printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + fi + + popd > /dev/null + else + printf "${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}\n" + fi + fi + + # Check if artifact should be compressed (zip, tgz) or if asset was part of the downloaded artifact. + printf " checking asset '%s' ... " "${artifact}/${asset}" + if [[ "${asset}" == !*.zip ]]; then + printf "${ANSI_LIGHT_GREEN}[ZIP]${ANSI_NOCOLOR}\n" + asset="${asset##*!}" + printf "::group:: %s\n" "Compressing artifact '${artifact}' to '${asset}' ..." + ( + cd "${artifact}" && \ + zip -r "../${asset}" * + ) + retCode=$? + printf "::endgroup::\n" + if [[ $retCode -eq 0 ]]; then + printf " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + uploadFile="${asset}" + else + printf " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't compress '%s' to zip file '%s'.${ANSI_NOCOLOR}\n" "${artifact}" "${asset}" + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to zip file '${asset}'." + ERRORS=$((ERRORS + 1)) + continue + fi + elif [[ "${asset}" == !*.tgz || "${asset}" == !*.tar.gz || "${asset}" == \$*.tgz || "${asset}" == \$*.tar.gz ]]; then + printf "${ANSI_LIGHT_GREEN}[TAR/GZ]${ANSI_NOCOLOR}\n" + + if [[ "${asset:0:1}" == "\$" ]]; then + asset="${asset##*$}" + dirName="${asset%.*}" + printf " Compressing artifact '%s' to '%s' ...\n" "${artifact}" "${asset}" + tar -c --gzip --owner=0 --group=0 --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" . + retCode=$? + else + asset="${asset##*!}" + printf " Compressing artifact '%s' to '%s' ...\n" "${artifact}" "${asset}" + ( + cd "${artifact}" && \ + tar -c --gzip --owner=0 --group=0 --file="../${asset}" * + ) + retCode=$? + fi + + if [[ $retCode -eq 0 ]]; then + printf " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + uploadFile="${asset}" + else + printf " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't compress '%s' to tgz file '%s'.${ANSI_NOCOLOR}\n" "${artifact}" "${asset}" + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to tgz file '${asset}'." + ERRORS=$((ERRORS + 1)) + continue + fi + elif [[ "${asset}" == !*.tzst || "${asset}" == !*.tar.zst || "${asset}" == \$*.tzst || "${asset}" == \$*.tar.zst ]]; then + printf "${ANSI_LIGHT_GREEN}[ZST]${ANSI_NOCOLOR}\n" + + if [[ "${asset:0:1}" == "\$" ]]; then + asset="${asset##*$}" + dirName="${asset%.*}" + printf " Compressing artifact '%s' to '%s' ...\n" "${artifact}" "${asset}" + tar -c --zstd --owner=0 --group=0 --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" . + retCode=$? + else + asset="${asset##*!}" + printf " Compressing artifact '%s' to '%s' ...\n" "${artifact}" "${asset}" + ( + cd "${artifact}" && \ + tar -c --zstd --owner=0 --group=0 --file="../${asset}" * + ) + retCode=$? + fi + + if [[ $retCode -eq 0 ]]; then + printf " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + uploadFile="${asset}" + else + printf " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't compress '%s' to zst file '%s'.${ANSI_NOCOLOR}\n" "${artifact}" "${asset}" + printf "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to zst file '${asset}'." + ERRORS=$((ERRORS + 1)) + continue + fi + elif [[ -e "${artifact}/${asset}" ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + uploadFile="${artifact}/${asset}" + else + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't find asset '%s' in artifact '%s'.${ANSI_NOCOLOR}\n" "${asset}" "${artifact}" + printf "::error title=%s::%s\n" "FileNotFound" "Couldn't find asset '${asset}' in artifact '${artifact}'." + ERRORS=$((ERRORS + 1)) + continue + fi + + # Add asset to JSON inventory + if [[ "${{ inputs.inventory-json }}" != "" ]]; then + if [[ "${categories}" != "${title}" ]]; then + printf " adding file '%s' with '%s' to JSON inventory ...\n" "${uploadFile#*/}" "${categories//;/ → }" + category="" + jsonEntry=$(jq -c -n \ + --arg title "${title}" \ + --arg file "${uploadFile#*/}" \ + '{"file": $file, "title": $title}' \ + ) + + while [[ "${categories}" != "${category}" ]]; do + category="${categories##*,}" + categories="${categories%,*}" + jsonEntry=$(jq -c -n --arg cat "${category}" --argjson value "${jsonEntry}" '{$cat: $value}') + done + + jsonInventory=$(jq -c -n \ + --argjson inventory "${jsonInventory}" \ + --argjson file "${jsonEntry}" \ + '$inventory * {"files": $file}' \ + ) + else + printf " adding file '%s' to JSON inventory ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}\n" "${uploadFile#*/}" + fi + fi + + # Upload asset to existing release page + printf " uploading asset '%s' from '%s' with title '%s' ... " "${asset}" "${uploadFile}" "${title}" + gh release upload ${{ inputs.tag }} "${uploadFile}#${title}" --clobber + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't upload asset '%s' from '%s' to release '%s'.${ANSI_NOCOLOR}\n" "${asset}" "${uploadFile}" "${{ inputs.tag }}" + printf "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.tag }}'." + ERRORS=$((ERRORS + 1)) + continue + fi + done <<<'${{ inputs.assets }}' + + if [[ "${{ inputs.inventory-json }}" != "" ]]; then + inventoryTitle="Release Inventory (JSON)" + + printf "Publish asset '%s' with title '%s'\n" "${{ inputs.inventory-json }}" "${inventoryTitle}" + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Writing JSON inventory to '${{ inputs.inventory-json }}' ...." + printf "%s\n" "$(jq -n --argjson inventory "${jsonInventory}" '$inventory')" > "${{ inputs.inventory-json }}" + cat "${{ inputs.inventory-json }}" + printf "::endgroup::\n" + + # Upload inventory asset to existing release page + printf " uploading asset '%s' title '%s' ... " "${{ inputs.inventory-json }}" "${inventoryTitle}" + gh release upload ${{ inputs.tag }} "${{ inputs.inventory-json }}#${inventoryTitle}" --clobber + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + else + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't upload asset '%s' to release '%s'.${ANSI_NOCOLOR}\n" "${{ inputs.inventory-json }}" "${{ inputs.tag }}" + printf "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${{ inputs.inventory-json }}' to release '${{ inputs.tag }}'." + ERRORS=$((ERRORS + 1)) + continue + fi + fi + + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Inspecting downloaded artifacts ..." + tree -pash -L 3 . + printf "::endgroup::\n" + + if [[ $ERRORS -ne 0 ]]; then + printf "${ANSI_LIGHT_RED}%s errors detected in previous steps.${ANSI_NOCOLOR}\n" "${ERRORS}" + exit 1 + fi + + - name: 📑 Remove draft state from Release Page + id: removeDraft + if: ${{ ! inputs.draft }} + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_NOCOLOR=$'\x1b[0m' + + export GH_TOKEN=${{ github.token }} + + # Remove draft-state from release page + printf "Remove draft-state from release '%s' ... " "${title}" + releasePage=$(gh release edit --draft=false "${{ inputs.tag }}") + if [[ $? -eq 0 ]]; then + printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + printf " Release page: %s\n" "${releasePage}" + + printf "release_page=%s\n" "${releasePage}" >> "${GITHUB_OUTPUT}" + else + printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n" + printf " ${ANSI_LIGHT_RED}Couldn't remove draft-state from release '%s'.${ANSI_NOCOLOR}\n" "${{ inputs.tag }}" + printf "::error title=%s::%s\n" "ReleasePage" "Couldn't remove draft-state from release '${{ inputs.tag }}'." + fi From 12389ac0f0fe9a46379c23014271e048ab2d4e16 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 15:00:18 +0200 Subject: [PATCH 09/27] Test new job templates. --- .github/workflows/CompletePipeline.yml | 16 +++- .../workflows/{Prepare.yml => PrepareJob.yml} | 0 .../{Release.yml => PublishReleaseNotes.yml} | 0 .github/workflows/TagReleaseCommit.yml | 84 +++++++++++++++++++ .github/workflows/_Checking_JobTemplates.yml | 37 ++++++-- README.md | 2 +- 6 files changed, 131 insertions(+), 8 deletions(-) rename .github/workflows/{Prepare.yml => PrepareJob.yml} (100%) rename .github/workflows/{Release.yml => PublishReleaseNotes.yml} (100%) create mode 100644 .github/workflows/TagReleaseCommit.yml diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index d2f968a..7ec64de 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -125,6 +125,9 @@ on: required: false jobs: + Prepare: + uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@dev + ConfigParams: uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@dev with: @@ -309,12 +312,21 @@ jobs: typing: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} ReleasePage: - uses: pyTooling/Actions/.github/workflows/Release.yml@dev + uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@dev if: startsWith(github.ref, 'refs/tags') needs: - - Package + - Prepare + - UnitTesting # - AppTesting +# - StaticTypeCheck + - Package - PublishToGitHubPages + secrets: inherit + permissions: + contents: write + actions: write + with: + tag: ${{ needs.Prepare.outputs.version }} PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev diff --git a/.github/workflows/Prepare.yml b/.github/workflows/PrepareJob.yml similarity index 100% rename from .github/workflows/Prepare.yml rename to .github/workflows/PrepareJob.yml diff --git a/.github/workflows/Release.yml b/.github/workflows/PublishReleaseNotes.yml similarity index 100% rename from .github/workflows/Release.yml rename to .github/workflows/PublishReleaseNotes.yml diff --git a/.github/workflows/TagReleaseCommit.yml b/.github/workflows/TagReleaseCommit.yml new file mode 100644 index 0000000..4aa28d3 --- /dev/null +++ b/.github/workflows/TagReleaseCommit.yml @@ -0,0 +1,84 @@ +# ==================================================================================================================== # +# Authors: # +# Patrick Lehmann # +# Unai Martinez-Corral # +# # +# ==================================================================================================================== # +# Copyright 2020-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: Auto Tag + +on: + workflow_call: + inputs: + ubuntu_image: + description: 'Name of the Ubuntu image.' + required: false + default: 'ubuntu-24.04' + type: string + version: + description: 'Version used as tag name.' + required: true + type: string + auto_tag: + description: 'Automatically add and push a tag.' + required: true + type: string + workflow: + description: 'Workflow to start after adding a tag.' + required: false + default: 'Pipeline.yml' + type: string + +jobs: + AutoTag: + name: "🏷 Create tag '${{ inputs.version}}' on GitHub" + runs-on: ${{ inputs.ubuntu_image }} + if: inputs.auto_tag == 'true' + +# if: github.ref == 'refs/heads/${{ inputs.release_branch }}' + + permissions: + contents: write # required for tag creation + actions: write # required to start a new pipeline + + steps: + - name: 🏷 Create release tag '${{ steps.FindPullRequest.outputs.version }}' + uses: actions/github-script@v7 + id: createReleaseTag +# if: inputs.auto_tag == 'true' + with: + script: | + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ inputs.version }}', + sha: context.sha + }) + + - name: Trigger Workflow + uses: actions/github-script@v7 + id: runReleaseTag +# if: inputs.auto_tag == 'true' + with: + script: | + github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: '${{ inputs.workflow }}', + ref: '${{ inputs.version }}' + }) diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 06e8fd5..e726dfe 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -5,6 +5,9 @@ on: workflow_dispatch: jobs: + Prepare: + uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@dev + ConfigParams: uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@dev with: @@ -185,19 +188,43 @@ jobs: - PublishCoverageResults - StaticTypeCheck 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 }} - 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@dev - if: startsWith(github.ref, 'refs/tags') + TriggerTaggedRelease: + uses: pyTooling/Actions/.github/workflows/TagReleaseCommit.yml@dev needs: + - Prepare - UnitTesting - PlatformTesting # - StaticTypeCheck - Package - PublishToGitHubPages + permissions: + contents: write # required for create tag + actions: write # required for trigger workflow + with: + version: ${{ needs.Prepare.outputs.version }} + auto_tag: ${{ needs.Prepare.outputs.is_release_commit }} + secrets: inherit + + ReleasePage: + uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@dev + if: startsWith(github.ref, 'refs/tags') + needs: + - Prepare + - UnitTesting + - PlatformTesting +# - StaticTypeCheck + - Package + - PublishToGitHubPages + secrets: inherit + permissions: + contents: write + actions: write + with: + tag: ${{ needs.Prepare.outputs.version }} PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev diff --git a/README.md b/README.md index 499e97c..ec7dc16 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ As shown in the screenshots above, the expected order is: [**NightlyRelease**](.github/workflows/NightlyRelease.yml): publish GitHub Release. - [**Release**](.github/workflows/Release.yml): publish GitHub Release. + [**PublishReleaseNotes**](.github/workflows/PublishReleaseNotes.yml): publish GitHub Release. - **Documentation:** [**SphinxDocumentation**](.github/workflows/PublishCoverageResults.yml): create HTML and LaTeX documentation using Sphinx. From 1b6454ba91f8e5413d1f2b70b1a623ff4f2c38a3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 16:43:35 +0200 Subject: [PATCH 10/27] Allow no assets. --- .github/workflows/PublishReleaseNotes.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/PublishReleaseNotes.yml b/.github/workflows/PublishReleaseNotes.yml index 3585bbe..2d8358d 100644 --- a/.github/workflows/PublishReleaseNotes.yml +++ b/.github/workflows/PublishReleaseNotes.yml @@ -91,8 +91,9 @@ on: type: string assets: description: 'Multi-line string containing artifact:file:title asset descriptions.' - required: true + required: false type: string + default: '' inventory-json: type: string required: false From 39ae93c2006edc49040620d267c146504478d8dc Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 18:35:58 +0200 Subject: [PATCH 11/27] Use secrets: inherit. --- .github/workflows/CompletePipeline.yml | 1 + .github/workflows/_Checking_JobTemplates.yml | 11 ++++------- .../workflows/_Checking_NamespacePackage_Pipeline.yml | 5 +---- .github/workflows/_Checking_Nightly.yml | 10 ++++------ .../workflows/_Checking_SimplePackage_Pipeline.yml | 5 +---- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 7ec64de..df9a12c 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -327,6 +327,7 @@ jobs: actions: write with: tag: ${{ needs.Prepare.outputs.version }} + secrets: inherit PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index e726dfe..7d98b8b 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -115,9 +115,7 @@ jobs: coverage_report_html_directory: ${{ needs.ConfigParams.outputs.coverage_report_html_directory }} codecov: true codacy: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - CODACY_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit PublishTestResults: uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@dev @@ -132,8 +130,7 @@ jobs: merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} codecov: true dorny: true - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + secrets: inherit # VerifyDocs: # uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@dev @@ -225,6 +222,7 @@ jobs: actions: write with: tag: ${{ needs.Prepare.outputs.version }} + secrets: inherit PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev @@ -237,8 +235,7 @@ jobs: 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 }} + secrets: inherit ArtifactCleanUp: uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@dev diff --git a/.github/workflows/_Checking_NamespacePackage_Pipeline.yml b/.github/workflows/_Checking_NamespacePackage_Pipeline.yml index 46a19dc..227d836 100644 --- a/.github/workflows/_Checking_NamespacePackage_Pipeline.yml +++ b/.github/workflows/_Checking_NamespacePackage_Pipeline.yml @@ -13,7 +13,4 @@ jobs: codecov: true codacy: true dorny: true - secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit diff --git a/.github/workflows/_Checking_Nightly.yml b/.github/workflows/_Checking_Nightly.yml index 57fcc9e..e1e012d 100644 --- a/.github/workflows/_Checking_Nightly.yml +++ b/.github/workflows/_Checking_Nightly.yml @@ -45,11 +45,9 @@ jobs: uses: ./.github/workflows/NightlyRelease.yml needs: - Build - secrets: inherit permissions: contents: write - actions: write -# attestations: write + actions: write with: can-fail: true prerelease: true @@ -78,16 +76,15 @@ jobs: document:$archive7.tar.gz: Archive 7 - tar.gz + dir document:$archive8.tzst: Archive 8 - tzst + dir document:$archive9.tar.zst:Archive 9 - tar.zst + dir + secrets: inherit NightlyPageWithInventory: uses: ./.github/workflows/NightlyRelease.yml needs: - Build - secrets: inherit permissions: contents: write - actions: write -# attestations: write + actions: write with: can-fail: true replacements: | @@ -121,3 +118,4 @@ jobs: document:$archive7.tar.gz: Archive 7 - tar.gz + dir document:$archive8.tzst: Archive 8 - tzst + dir document:$archive9.tar.zst: Archive 9 - tar.zst + dir + secrets: inherit diff --git a/.github/workflows/_Checking_SimplePackage_Pipeline.yml b/.github/workflows/_Checking_SimplePackage_Pipeline.yml index 19f9573..77907f2 100644 --- a/.github/workflows/_Checking_SimplePackage_Pipeline.yml +++ b/.github/workflows/_Checking_SimplePackage_Pipeline.yml @@ -13,7 +13,4 @@ jobs: codacy: true dorny: true cleanup: false - secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit From 9e6138b5a9e8082423e291c6e4c05105a775791a Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 18:36:57 +0200 Subject: [PATCH 12/27] Provide is_nightly_tag and is_release_tag. --- .github/workflows/PrepareJob.yml | 94 ++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/.github/workflows/PrepareJob.yml b/.github/workflows/PrepareJob.yml index 9e3337e..529ad26 100644 --- a/.github/workflows/PrepareJob.yml +++ b/.github/workflows/PrepareJob.yml @@ -19,12 +19,17 @@ on: default: 'dev' type: string release_branch: - description: 'Name of the branch containing releases.' + description: 'Name of the branch containing releases and nightly builds.' required: false default: 'main' type: string - tag_pattern: - description: 'Name of the branch containing releases.' + nightly_tag_pattern: + description: 'Pattern for nightly tags on the release branch.' + required: false + default: 'nightly' + type: string + release_tag_pattern: + description: 'Pattern for release tags on the release branch. Usually: vXX.YY.ZZ' required: false default: '(v|r)?[0-9]+(\.[0-9]+){0,2}(-(dev|alpha|beta|rc)([0-9]*))?' type: string @@ -48,6 +53,12 @@ on: is_release_commit: description: "" value: ${{ jobs.Prepare.outputs.is_release_commit }} + is_nightly_tag: + description: "" + value: ${{ jobs.Prepare.outputs.is_nightly_tag }} + is_release_tag: + description: "" + value: ${{ jobs.Prepare.outputs.is_release_tag }} ref_kind: description: "" value: ${{ jobs.Prepare.outputs.ref_kind }} @@ -84,6 +95,8 @@ jobs: is_regular_commit: ${{ steps.Classify.outputs.is_regular_commit }} is_merge_commit: ${{ steps.Classify.outputs.is_merge_commit }} is_release_commit: ${{ steps.Classify.outputs.is_release_commit }} + is_nightly_tag: ${{ steps.Classify.outputs.is_nightly_tag }} + is_release_tag: ${{ steps.Classify.outputs.is_release_tag }} ref_kind: ${{ steps.Classify.outputs.ref_kind }} branch: ${{ steps.Classify.outputs.branch }} tag: ${{ steps.Classify.outputs.tag }} @@ -118,7 +131,7 @@ jobs: ANSI_LIGHT_YELLOW=$'\x1b[93m' ANSI_LIGHT_BLUE=$'\x1b[94m' ANSI_NOCOLOR=$'\x1b[0m' - + ref="${{ github.ref }}" on_main_branch="false" on_dev_branch="false" @@ -126,20 +139,22 @@ jobs: is_regular_commit="false" is_merge_commit="false" is_release_commit="false" + is_nightly_tag="false" + is_release_tag="false" ref_kind="unknown" branch="" tag="" version="" - + if [[ "${ref:0:11}" == "refs/heads/" ]]; then ref_kind="branch" branch="${ref:11}" - + printf "Commit check:\n" - + if [[ "${branch}" == "${{ inputs.main_branch }}" ]]; then on_main_branch="true" - + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then is_regular_commit="true" printf " ${ANSI_LIGHT_YELLOW}regular " @@ -149,10 +164,10 @@ jobs: fi printf "commit${ANSI_NOCOLOR} on main branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.main_branch }}" fi - + if [[ "${branch}" == "${{ inputs.development_branch }}" ]]; then on_dev_branch="true" - + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then is_regular_commit="true" printf " ${ANSI_LIGHT_YELLOW}regular " @@ -162,10 +177,10 @@ jobs: fi printf "commit${ANSI_NOCOLOR} on development branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.development_branch }}" fi - + if [[ "${branch}" == "${{ inputs.release_branch }}" ]]; then on_release_branch="true" - + if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then is_regular_commit="true" printf " ${ANSI_LIGHT_YELLOW}regular " @@ -178,9 +193,9 @@ jobs: elif [[ "${ref:0:10}" == "refs/tags/" ]]; then ref_kind="tag" tag="${ref:10}" - + printf "Tag check:\n" - + printf " Check if tag is on release branch '%s' ... " "${{ inputs.release_branch }}" git branch --remotes --contains $(git rev-parse --verify "tags/${tag}~0") | grep "origin/${{ inputs.release_branch }}" > /dev/null if [[ $? -eq 0 ]]; then @@ -191,16 +206,23 @@ jobs: printf "::error title=TagCheck::Tag '%s' isn't on branch '%s'.\n" "${tag}" "${{ inputs.release_branch }}" exit 1 fi - - TAG_PATTERN='^${{ inputs.tag_pattern }}$' - printf " Check tag name against regexp '%s' ... " "${TAG_PATTERN}" - if [[ "${tag}" =~ $TAG_PATTERN ]]; then - printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n" + + NIGHTLY_TAG_PATTERN='^${{ inputs.nightly_tag_pattern }}$' + RELEASE_TAG_PATTERN='^${{ inputs.release_tag_pattern }}$' + printf " Check tag name against regexp '%s' ... " "${RELEASE_TAG_PATTERN}" + if [[ "${tag}" =~ NIGHTLY_TAG_PATTERN ]]; then + printf "${ANSI_LIGHT_GREEN}[NIGHTLY]${ANSI_NOCOLOR}\n" + is_nightly_tag=true + elif [[ "${tag}" =~ $RELEASE_TAG_PATTERN ]]; then + printf "${ANSI_LIGHT_GREEN}[RELEASE]${ANSI_NOCOLOR}\n" version="${tag}" + is_release_tag=true else printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" - printf "${ANSI_LIGHT_RED}Tag name '%s' doesn't conform to regexp '%s'.${ANSI_NOCOLOR}\n" "${tag}" "${TAG_PATTERN}" - printf "::error title=RexExpCheck::Tag name '%s' doesn't conform to regexp '%s'.\n" "${tag}" "${TAG_PATTERN}" + printf "${ANSI_LIGHT_RED}Tag name '%s' doesn't conform to regexp${ANSI_NOCOLOR}\n" "${tag}" + printf " ${ANSI_LIGHT_RED}nightly tag: %s${ANSI_NOCOLOR}\n" "${NIGHTLY_TAG_PATTERN}" + printf " ${ANSI_LIGHT_RED}release tag: %s${ANSI_NOCOLOR}\n" "${RELEASE_TAG_PATTERN}" + printf "::error title=RexExpCheck::Tag name '%s' doesn't conform to regexp '%s' nor '%s'.\n" "${tag}" "${NIGHTLY_TAG_PATTERN}" "${RELEASE_TAG_PATTERN}" exit 1 fi else @@ -208,7 +230,7 @@ jobs: printf "::error title=Classify Commit::Unknown Git reference '%s'.\n" "${{ github.ref }}" exit 1 fi - + tee --append "${GITHUB_OUTPUT}" < Date: Sat, 26 Apr 2025 18:37:44 +0200 Subject: [PATCH 13/27] Use is_release_tag. --- .github/workflows/CompletePipeline.yml | 26 +++++++++++++++++--- .github/workflows/_Checking_JobTemplates.yml | 5 ++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index df9a12c..5e36b26 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -311,9 +311,8 @@ jobs: coverage: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }} typing: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }} - ReleasePage: - uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@dev - if: startsWith(github.ref, 'refs/tags') + TriggerTaggedRelease: + uses: pyTooling/Actions/.github/workflows/TagReleaseCommit.yml@dev needs: - Prepare - UnitTesting @@ -321,7 +320,25 @@ jobs: # - StaticTypeCheck - Package - PublishToGitHubPages + if: needs.Prepare.outputs.is_release_commit + permissions: + contents: write # required for create tag + actions: write # required for trigger workflow + with: + version: ${{ needs.Prepare.outputs.version }} + auto_tag: ${{ needs.Prepare.outputs.is_release_commit }} secrets: inherit + + ReleasePage: + uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@dev + needs: + - Prepare + - UnitTesting +# - AppTesting +# - StaticTypeCheck + - Package + - PublishToGitHubPages + if: needs.Prepare.outputs.is_release_tag permissions: contents: write actions: write @@ -331,10 +348,11 @@ jobs: PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev - if: startsWith(github.ref, 'refs/tags') needs: + - Prepare - UnitTestingParams - ReleasePage + if: needs.Prepare.outputs.is_release_tag with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} requirements: -r dist/requirements.txt diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 7d98b8b..94846fc 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -208,7 +208,6 @@ jobs: ReleasePage: uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@dev - if: startsWith(github.ref, 'refs/tags') needs: - Prepare - UnitTesting @@ -216,7 +215,7 @@ jobs: # - StaticTypeCheck - Package - PublishToGitHubPages - secrets: inherit + if: needs.Prepare.outputs.is_release_tag permissions: contents: write actions: write @@ -226,11 +225,11 @@ jobs: PublishOnPyPI: uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@dev - if: startsWith(github.ref, 'refs/tags') needs: - UnitTestingParams - ReleasePage # - Package + if: needs.Prepare.outputs.is_release_tag with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} requirements: -r dist/requirements.txt From 4ebf262921634bfb085345824b2e2f41da9d4273 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 18:50:07 +0200 Subject: [PATCH 14/27] Fix documentation coverage search directory --- .github/workflows/CheckDocumentation.yml | 15 +++++++++++++-- .github/workflows/CompletePipeline.yml | 2 +- pyDummy/__init__.py | 12 ++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/CheckDocumentation.yml b/.github/workflows/CheckDocumentation.yml index 2eef1f2..6b6205f 100644 --- a/.github/workflows/CheckDocumentation.yml +++ b/.github/workflows/CheckDocumentation.yml @@ -64,9 +64,20 @@ jobs: - name: Run 'interrogate' Documentation Coverage Check continue-on-error: true run: | - interrogate -c pyproject.toml --fail-under=${{ inputs.fail_under }} && printf "::error title=%s::%s\n" "interrogate" "Insufficient documentation quality (goal: ${{ inputs.fail_under }})" + set +e + + interrogate -c pyproject.toml --fail-under=${{ inputs.fail_under }} ${{ inputs.directory }} + if [[ $? -ne 0 ]]; then + printf "::error title=%s::%s\n" "interrogate" "Insufficient documentation quality (goal: ${{ inputs.fail_under }})" + fi - name: Run 'docstr_coverage' Documentation Coverage Check continue-on-error: true run: | - docstr-coverage -v 2 --fail-under=${{ inputs.fail_under }} ${{ inputs.directory }} && printf "%s\n" "::error title=docstr-coverage::Insufficient documentation quality (goal: ${{ inputs.fail_under }})" + set +e + + docstr-coverage --fail-under=${{ inputs.fail_under }} ${{ inputs.directory }} + if [[ $? -ne 0 ]]; then + printf "%s\n" "::error title=docstr-coverage::Insufficient documentation quality (goal: ${{ inputs.fail_under }})" + fi + diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 5e36b26..a89e947 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -193,7 +193,7 @@ jobs: - UnitTestingParams with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} - directory: ${{ inputs.package_namespace }}/${{ inputs.package_name }} + directory: ${{ needs.ConfigParams.outputs.package_directory }} # fail_below: 70 Package: diff --git a/pyDummy/__init__.py b/pyDummy/__init__.py index 636ed39..2b2eff5 100644 --- a/pyDummy/__init__.py +++ b/pyDummy/__init__.py @@ -53,9 +53,9 @@ class Base: _value: int #: An internal value. def __init__(self) -> None: - """ - Initializes the base-class. - """ + # """ + # Initializes the base-class. + # """ self._value = 0 @readonly @@ -75,9 +75,9 @@ class Application(Base): """ def __init__(self) -> None: - """ - Initializes the dummy application. - """ + # """ + # Initializes the dummy application. + # """ super().__init__() platform = Platform() From 3f7b0c221bd865a472ce98fd44465365ca99ebdf Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 20:07:08 +0200 Subject: [PATCH 15/27] Use == 'true'. --- .github/workflows/CompletePipeline.yml | 14 +++++--------- .github/workflows/PrepareJob.yml | 4 ++-- .github/workflows/_Checking_JobTemplates.yml | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index a89e947..e0c99b6 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -234,9 +234,7 @@ jobs: coverage_report_html_directory: ${{ needs.ConfigParams.outputs.coverage_report_html_directory }} codecov: ${{ inputs.codecov }} codacy: ${{ inputs.codacy }} - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - CODACY_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit PublishTestResults: uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@dev @@ -250,8 +248,7 @@ jobs: merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} dorny: ${{ inputs.dorny }} codecov: ${{ inputs.codecov }} - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + secrets: inherit # VerifyDocs: # uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@dev @@ -338,7 +335,7 @@ jobs: # - StaticTypeCheck - Package - PublishToGitHubPages - if: needs.Prepare.outputs.is_release_tag + if: needs.Prepare.outputs.is_release_tag == 'true' permissions: contents: write actions: write @@ -352,13 +349,12 @@ jobs: - Prepare - UnitTestingParams - ReleasePage - if: needs.Prepare.outputs.is_release_tag + if: needs.Prepare.outputs.is_release_tag == 'true' 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 }} + secrets: inherit ArtifactCleanUp: uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@dev diff --git a/.github/workflows/PrepareJob.yml b/.github/workflows/PrepareJob.yml index 529ad26..64a7d88 100644 --- a/.github/workflows/PrepareJob.yml +++ b/.github/workflows/PrepareJob.yml @@ -212,11 +212,11 @@ jobs: printf " Check tag name against regexp '%s' ... " "${RELEASE_TAG_PATTERN}" if [[ "${tag}" =~ NIGHTLY_TAG_PATTERN ]]; then printf "${ANSI_LIGHT_GREEN}[NIGHTLY]${ANSI_NOCOLOR}\n" - is_nightly_tag=true + is_nightly_tag="true" elif [[ "${tag}" =~ $RELEASE_TAG_PATTERN ]]; then printf "${ANSI_LIGHT_GREEN}[RELEASE]${ANSI_NOCOLOR}\n" version="${tag}" - is_release_tag=true + is_release_tag="true" else printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" printf "${ANSI_LIGHT_RED}Tag name '%s' doesn't conform to regexp${ANSI_NOCOLOR}\n" "${tag}" diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 94846fc..677e59a 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -215,7 +215,7 @@ jobs: # - StaticTypeCheck - Package - PublishToGitHubPages - if: needs.Prepare.outputs.is_release_tag + if: needs.Prepare.outputs.is_release_tag == 'true' permissions: contents: write actions: write @@ -229,7 +229,7 @@ jobs: - UnitTestingParams - ReleasePage # - Package - if: needs.Prepare.outputs.is_release_tag + if: needs.Prepare.outputs.is_release_tag == 'true' with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} requirements: -r dist/requirements.txt From 7a57747fcd456900a49a4e179e3c407381cc1db6 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 21:29:50 +0200 Subject: [PATCH 16/27] Removed release description text, so PR text is used. --- .github/workflows/CompletePipeline.yml | 2 +- .github/workflows/NightlyRelease.yml | 2 +- .github/workflows/PublishReleaseNotes.yml | 7 +++++-- .github/workflows/TagReleaseCommit.yml | 2 +- .github/workflows/_Checking_JobTemplates.yml | 2 +- doc/requirements.txt | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index e0c99b6..9b03805 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -338,7 +338,7 @@ jobs: if: needs.Prepare.outputs.is_release_tag == 'true' permissions: contents: write - actions: write + actions: write with: tag: ${{ needs.Prepare.outputs.version }} secrets: inherit diff --git a/.github/workflows/NightlyRelease.yml b/.github/workflows/NightlyRelease.yml index 3a8ebcd..eada2f7 100644 --- a/.github/workflows/NightlyRelease.yml +++ b/.github/workflows/NightlyRelease.yml @@ -96,7 +96,7 @@ jobs: continue-on-error: ${{ inputs.can-fail }} permissions: contents: write - actions: write + actions: write # attestations: write steps: diff --git a/.github/workflows/PublishReleaseNotes.yml b/.github/workflows/PublishReleaseNotes.yml index 2d8358d..2ea96f9 100644 --- a/.github/workflows/PublishReleaseNotes.yml +++ b/.github/workflows/PublishReleaseNotes.yml @@ -52,7 +52,7 @@ on: description: description: 'Multi-line description of the release.' required: false - default: 'Release of artifacts from latest CI pipeline.' + default: '' type: string description_file: description: 'Description of the release from a Markdown file.' @@ -126,7 +126,7 @@ jobs: continue-on-error: ${{ inputs.can-fail }} permissions: contents: write - actions: write + actions: write # attestations: write outputs: release-page: ${{ steps.removeDraft.outputs.release_page }} @@ -275,6 +275,9 @@ jobs: elif [[ -s __PULLREQUEST__.md ]]; then printf "Use '__PULLREQUEST__.md' as main release description.\n" mv -v __PULLREQUEST__.md __NOTES__.md + + printf "Append '%%FOOTER%%' to '__NOTES__.md'.\n" + printf "\n%%FOOTER%%\n" >> __NOTES__.md else printf "${ANSI_LIGHT_RED}No release description specified (file, parameter, PR text).${ANSI_NOCOLOR}\n" printf "::error title=%s::%s\n" "MissingDescription" "No release description specified (file, parameter, PR text)." diff --git a/.github/workflows/TagReleaseCommit.yml b/.github/workflows/TagReleaseCommit.yml index 4aa28d3..d110164 100644 --- a/.github/workflows/TagReleaseCommit.yml +++ b/.github/workflows/TagReleaseCommit.yml @@ -54,7 +54,7 @@ jobs: permissions: contents: write # required for tag creation - actions: write # required to start a new pipeline + actions: write # required to start a new pipeline steps: - name: 🏷 Create release tag '${{ steps.FindPullRequest.outputs.version }}' diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 677e59a..19b93cc 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -218,7 +218,7 @@ jobs: if: needs.Prepare.outputs.is_release_tag == 'true' permissions: contents: write - actions: write + actions: write with: tag: ${{ needs.Prepare.outputs.version }} secrets: inherit diff --git a/doc/requirements.txt b/doc/requirements.txt index cab4a5a..2027f4c 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -15,5 +15,5 @@ sphinxcontrib-mermaid ~= 1.0 autoapi >= 2.0.1 sphinx_design ~= 0.6.1 sphinx-copybutton >= 0.5.2 -sphinx_autodoc_typehints ~= 3.1 +sphinx_autodoc_typehints ~= 3.2 sphinx_reports ~= 0.9 From 05808d405806a6fb108cc8548841700c389d6b68 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 21:33:46 +0200 Subject: [PATCH 17/27] Do not create application test parameters, if application testing isn't integrated yet. --- .github/workflows/CompletePipeline.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 9b03805..172b373 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -146,17 +146,17 @@ jobs: exclude_list: ${{ inputs.unittest_exclude_list }} disable_list: ${{ inputs.unittest_disable_list }} - AppTestingParams: - uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev - with: - package_namespace: ${{ inputs.package_namespace }} - package_name: ${{ inputs.package_name }} - python_version: ${{ inputs.apptest_python_version }} - python_version_list: ${{ inputs.apptest_python_version_list }} - system_list: ${{ inputs.apptest_system_list }} - include_list: ${{ inputs.apptest_include_list }} - exclude_list: ${{ inputs.apptest_exclude_list }} - disable_list: ${{ inputs.apptest_disable_list }} +# AppTestingParams: +# uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev +# with: +# package_namespace: ${{ inputs.package_namespace }} +# package_name: ${{ inputs.package_name }} +# python_version: ${{ inputs.apptest_python_version }} +# python_version_list: ${{ inputs.apptest_python_version_list }} +# system_list: ${{ inputs.apptest_system_list }} +# include_list: ${{ inputs.apptest_include_list }} +# exclude_list: ${{ inputs.apptest_exclude_list }} +# disable_list: ${{ inputs.apptest_disable_list }} UnitTesting: uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@dev From b0198fa45987ba7edeb05ee644fb0771c77e04ba Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Apr 2025 21:37:19 +0200 Subject: [PATCH 18/27] Run intermediate cleanup parallel to documentation, because only pre-merge artifacts (unittest and coverage) are cleaned. --- .github/workflows/CompletePipeline.yml | 1 - .github/workflows/_Checking_JobTemplates.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 172b373..722fa7f 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -279,7 +279,6 @@ jobs: - UnitTestingParams - PublishCoverageResults - PublishTestResults - - Documentation if: ${{ inputs.cleanup }} with: sqlite_coverage_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}- diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 19b93cc..3eb8629 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -161,7 +161,6 @@ jobs: - UnitTestingParams - PublishCoverageResults - PublishTestResults - - Documentation with: sqlite_coverage_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}- xml_unittest_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}- From 0b6462f4d21beab9a15e33e8beeba0ffccf01db3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 27 Apr 2025 09:12:58 +0200 Subject: [PATCH 19/27] Fixed secret name. --- .github/workflows/CompletePipeline.yml | 2 +- doc/JobTemplate/CoverageCollection.rst | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 722fa7f..be24c0c 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -120,7 +120,7 @@ on: CODECOV_TOKEN: description: "Token for pushing coverage and unittest results to Codecov." required: false - CODACY_PROJECT_TOKEN: + CODACY_TOKEN: description: "Token for pushing coverage results to Codacy." required: false diff --git a/doc/JobTemplate/CoverageCollection.rst b/doc/JobTemplate/CoverageCollection.rst index 8b9c3dc..4749ce3 100644 --- a/doc/JobTemplate/CoverageCollection.rst +++ b/doc/JobTemplate/CoverageCollection.rst @@ -55,8 +55,7 @@ Simple Example uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r0 with: artifact: Coverage - secrets: - codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit Complex Example =============== @@ -71,8 +70,7 @@ Complex Example with: python_version: ${{ needs.Params.outputs.python_version }} artifact: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }} - secrets: - codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }} + secrets: inherit Parameters ********** From 2f4ccf2af4973dd5bbbf81fee3bb2308ca68b59d Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 1 May 2025 12:59:16 +0200 Subject: [PATCH 20/27] Generate error messages if codecov or codacy fail. --- .github/workflows/PublishCoverageResults.yml | 11 +++++++++++ .github/workflows/PublishOnPyPI.yml | 1 - .github/workflows/PublishTestResults.yml | 13 +++++++++++++ tests/requirements.txt | 2 +- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 73b03ed..fcb3bc7 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -200,6 +200,7 @@ jobs: - name: 📊 Publish code coverage at CodeCov uses: codecov/codecov-action@v5 + id: codecov if: inputs.codecov continue-on-error: true with: @@ -212,8 +213,18 @@ jobs: - name: 📉 Publish code coverage at Codacy uses: codacy/codacy-coverage-reporter-action@v1 + id: codacy if: inputs.codacy continue-on-error: true with: project-token: ${{ secrets.CODACY_TOKEN }} coverage-reports: ${{ inputs.coverage_report_xml_directory }}/${{ inputs.coverage_report_xml_filename }} + + - name: Generate error messages + run: | + if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then + printf "::error title=%s::%s\n" "Codecov" "Failed to publish code coverage results." + fi + if [[ "${{ steps.codacy.outcome }}" == "failure" ]]; then + printf "::error title=%s::%s\n" "Codacy" "Failed to publish code coverage results." + fi diff --git a/.github/workflows/PublishOnPyPI.yml b/.github/workflows/PublishOnPyPI.yml index f5e976c..5f17966 100644 --- a/.github/workflows/PublishOnPyPI.yml +++ b/.github/workflows/PublishOnPyPI.yml @@ -50,7 +50,6 @@ on: required: false jobs: - PublishOnPyPI: name: 🚀 Publish to PyPI runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}" diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 41b21ac..48e2477 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -74,6 +74,11 @@ on: required: false default: true type: boolean + codecov_flags: + description: 'Flags applied to the upload to Codecov' + required: false + default: 'unittest' + type: string secrets: CODECOV_TOKEN: description: 'Token to push result to Codecov.' @@ -125,13 +130,21 @@ jobs: - name: 📊 Publish unittest results at CodeCov uses: codecov/test-results-action@v1 + id: codecov if: inputs.codecov with: token: ${{ secrets.CODECOV_TOKEN }} disable_search: true files: ${{ inputs.merged_junit_filename }} + flags: ${{ inputs.codecov_flags }} fail_ci_if_error: true + - name: Generate error messages + run: | + if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then + printf "::error title=%s::%s\n" "Codecov" "Failed to publish unittest results." + fi + - name: 📤 Upload merged 'JUnit Test Summary' artifact uses: pyTooling/upload-artifact@v4 if: inputs.merged_junit_artifact != '' diff --git a/tests/requirements.txt b/tests/requirements.txt index e44d7b6..dc267c1 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -10,4 +10,4 @@ pytest-cov ~= 6.1 # Static Type Checking mypy ~= 1.15 typing_extensions ~= 4.13 -lxml ~= 5.3 +lxml ~= 5.4 From 4addce16fa1eda2933d4bc420e869f85be36f961 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 1 May 2025 19:24:05 +0200 Subject: [PATCH 21/27] Fixed here-docs. --- .github/workflows/PublishCoverageResults.yml | 4 ++-- .github/workflows/PublishReleaseNotes.yml | 18 +++++++++--------- .github/workflows/PublishTestResults.yml | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index fcb3bc7..92ee61e 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -96,10 +96,10 @@ on: secrets: CODECOV_TOKEN: description: 'Token to push result to Codecov.' - required: true + required: false CODACY_TOKEN: description: 'Token to push result to Codacy.' - required: true + required: false jobs: PublishCoverageResults: diff --git a/.github/workflows/PublishReleaseNotes.yml b/.github/workflows/PublishReleaseNotes.yml index 2ea96f9..43e98fb 100644 --- a/.github/workflows/PublishReleaseNotes.yml +++ b/.github/workflows/PublishReleaseNotes.yml @@ -65,7 +65,7 @@ on: default: | -------- - Published from [%%gh_workflow%%](%%gh_server%%/%%gh_owner_repo%%/actions/runs/%%gh_runid%%) workflow triggered by %%gh_actor%% on %%datetime%%. + Published from [%%gh_workflow_name%%](%%gh_server%%/%%gh_owner_repo%%/actions/runs/%%gh_runid%%) workflow triggered by %%gh_actor%% on %%datetime%%. This automatic release was created by [pyTooling/Actions](http://github.com/pyTooling/Actions)::Release.yml type: string @@ -206,12 +206,12 @@ jobs: export GH_TOKEN=${{ github.token }} # Save release description (from parameter in a file) - cat <<'EOF' > __DESCRIPTION__.md + head -c -1 <<'EOF' > __DESCRIPTION__.md ${{ inputs.description }} EOF # Save release footer (from parameter in a file) - cat <<'EOF' > __FOOTER__.md + head -c -1 <<'EOF' > __FOOTER__.md ${{ inputs.description_footer }} EOF @@ -276,8 +276,8 @@ jobs: printf "Use '__PULLREQUEST__.md' as main release description.\n" mv -v __PULLREQUEST__.md __NOTES__.md - printf "Append '%%FOOTER%%' to '__NOTES__.md'.\n" - printf "\n%%FOOTER%%\n" >> __NOTES__.md + printf "Append '%%%%FOOTER%%%%' to '__NOTES__.md'.\n" + printf "\n%%%%FOOTER%%%%\n" >> __NOTES__.md else printf "${ANSI_LIGHT_RED}No release description specified (file, parameter, PR text).${ANSI_NOCOLOR}\n" printf "::error title=%s::%s\n" "MissingDescription" "No release description specified (file, parameter, PR text)." @@ -350,21 +350,21 @@ jobs: # Display partial contents for debugging if [[ -s __DESCRIPTION__.md ]]; then - printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__DESCRIPTION__.md' ...." + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__DESCRIPTION__.md' ($(stat --printf="%s" "__DESCRIPTION__.md") B) ...." cat __DESCRIPTION__.md printf "::endgroup::\n" else printf "${ANSI_LIGHT_YELLOW}No '__DESCRIPTION__.md' found.${ANSI_NOCOLOR}\n" fi if [[ -s __PULLREQUEST__.md ]]; then - printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__PULLREQUEST__.md' ...." + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__PULLREQUEST__.md' ($(stat --printf="%s" "__PULLREQUEST__.md") B) ...." cat __PULLREQUEST__.md printf "::endgroup::\n" else printf "${ANSI_LIGHT_YELLOW}No '__PULLREQUEST__.md' found.${ANSI_NOCOLOR}\n" fi if [[ -s __FOOTER__.md ]]; then - printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__FOOTER__.md' ...." + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__FOOTER__.md' ($(stat --printf="%s" "__FOOTER__.md") B) ...." cat __FOOTER__.md printf "::endgroup::\n" else @@ -372,7 +372,7 @@ jobs: fi # Print final release notes - printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__NOTES__.md' ...." + printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '__NOTES__.md' ($(stat --printf="%s" "__NOTES__.md") B) ...." cat __NOTES__.md printf "::endgroup::\n" diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 48e2477..97ab613 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -82,7 +82,7 @@ on: secrets: CODECOV_TOKEN: description: 'Token to push result to Codecov.' - required: true + required: false jobs: PublishTestResults: From 68357fddd8213f705d56a2087d05138396bb8e05 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 3 May 2025 18:31:39 +0200 Subject: [PATCH 22/27] Converted boolean parameters to string. --- .github/workflows/CompletePipeline.yml | 1 + .github/workflows/PublishCoverageResults.yml | 20 +++++++++++-------- .github/workflows/PublishTestResults.yml | 21 +++++++++++--------- pyproject.toml | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index be24c0c..4e30c57 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -347,6 +347,7 @@ jobs: needs: - Prepare - UnitTestingParams + - Package - ReleasePage if: needs.Prepare.outputs.is_release_tag == 'true' with: diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 92ee61e..0c30530 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -86,13 +86,13 @@ on: codecov: description: 'Publish merged coverage report to Codecov.' required: false - default: false - type: boolean + default: 'false' + type: string codacy: description: 'Publish merged coverage report to Codacy.' required: false - default: false - type: boolean + default: 'false' + type: string secrets: CODECOV_TOKEN: description: 'Token to push result to Codecov.' @@ -201,7 +201,7 @@ jobs: - name: 📊 Publish code coverage at CodeCov uses: codecov/codecov-action@v5 id: codecov - if: inputs.codecov + if: inputs.codecov == 'true' continue-on-error: true with: token: ${{ secrets.CODECOV_TOKEN }} @@ -214,7 +214,7 @@ jobs: - name: 📉 Publish code coverage at Codacy uses: codacy/codacy-coverage-reporter-action@v1 id: codacy - if: inputs.codacy + if: inputs.codacy == 'true' continue-on-error: true with: project-token: ${{ secrets.CODACY_TOKEN }} @@ -223,8 +223,12 @@ jobs: - name: Generate error messages run: | if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then - printf "::error title=%s::%s\n" "Codecov" "Failed to publish code coverage results." + printf "::error title=%s::%s\n" "Publish Code Coverage Results / Codecov" "Failed to publish code coverage results." + else + printf "Codecov: No errors to report." fi if [[ "${{ steps.codacy.outcome }}" == "failure" ]]; then - printf "::error title=%s::%s\n" "Codacy" "Failed to publish code coverage results." + printf "::error title=%s::%s\n" "Publish Code Coverage Results / Codacy" "Failed to publish code coverage results." + else + printf "Codacy: No errors to report." fi diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index 97ab613..e4607db 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -57,8 +57,8 @@ on: publish: description: 'Publish test report summary via Dorny Test-Reporter' required: false - default: true - type: boolean + default: 'true' + type: string report_title: description: 'Title of the summary report in the pipeline''s sidebar' required: false @@ -67,13 +67,13 @@ on: dorny: description: 'Publish merged unittest results via Dorny Test-Reporter.' required: false - default: true - type: boolean + default: 'true' + type: string codecov: description: 'Publish merged unittest results to Codecov.' required: false - default: true - type: boolean + default: 'false' + type: string codecov_flags: description: 'Flags applied to the upload to Codecov' required: false @@ -122,7 +122,7 @@ jobs: - name: 📊 Publish Unit Test Results uses: dorny/test-reporter@v2 - if: (inputs.dorny || inputs.publish) && inputs.report_title != '' + if: ( inputs.dorny == 'true' || inputs.publish == 'true' ) && inputs.report_title != '' with: name: ${{ inputs.report_title }} path: ${{ inputs.merged_junit_filename }} @@ -131,7 +131,8 @@ jobs: - name: 📊 Publish unittest results at CodeCov uses: codecov/test-results-action@v1 id: codecov - if: inputs.codecov + if: inputs.codecov == 'true' + continue-on-error: true with: token: ${{ secrets.CODECOV_TOKEN }} disable_search: true @@ -142,7 +143,9 @@ jobs: - name: Generate error messages run: | if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then - printf "::error title=%s::%s\n" "Codecov" "Failed to publish unittest results." + printf "::error title=%s::%s\n" "Publish Unit Test Results / Codecov" "Failed to publish unittest results." + else + printf "Codecov: No errors to report." fi - name: 📤 Upload merged 'JUnit Test Summary' artifact diff --git a/pyproject.toml b/pyproject.toml index eba19e1..11fc317 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] requires = [ - "setuptools ~= 79.0", + "setuptools >= 80.0", "wheel ~= 0.45", "pyTooling ~= 8.4" ] From bdf8239a73cc1a0194f5ba49cd904db5007ecb78 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 4 May 2025 11:21:05 +0200 Subject: [PATCH 23/27] Don't use "secrets: inherit"! --- .github/workflows/CompletePipeline.yml | 31 +++++++++++--------- .github/workflows/PublishCoverageResults.yml | 4 +-- .github/workflows/PublishTestResults.yml | 2 +- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 4e30c57..5731bb9 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -96,23 +96,23 @@ on: codecov: description: 'Publish merged coverage and unittest reports to Codecov.' required: false - default: false - type: boolean + default: 'false' + type: string codacy: description: 'Publish merged coverage report to Codacy.' required: false - default: false - type: boolean + default: 'false' + type: string dorny: description: 'Publish merged unittest report via Dorny Test-Reporter.' required: false - default: false - type: boolean + default: 'false' + type: string cleanup: description: 'Cleanup artifacts afterwards.' required: false - default: true - type: boolean + default: 'true' + type: string secrets: PYPI_TOKEN: description: "Token for pushing releases to PyPI." @@ -194,7 +194,6 @@ jobs: with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} directory: ${{ needs.ConfigParams.outputs.package_directory }} -# fail_below: 70 Package: uses: pyTooling/Actions/.github/workflows/Package.yml@dev @@ -234,7 +233,9 @@ jobs: coverage_report_html_directory: ${{ needs.ConfigParams.outputs.coverage_report_html_directory }} codecov: ${{ inputs.codecov }} codacy: ${{ inputs.codacy }} - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }} PublishTestResults: uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@dev @@ -248,7 +249,8 @@ jobs: merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} dorny: ${{ inputs.dorny }} codecov: ${{ inputs.codecov }} - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # VerifyDocs: # uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@dev @@ -279,7 +281,7 @@ jobs: - UnitTestingParams - PublishCoverageResults - PublishTestResults - if: ${{ inputs.cleanup }} + if: inputs.cleanup == 'true' with: sqlite_coverage_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}- xml_unittest_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}- @@ -354,7 +356,8 @@ jobs: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} requirements: -r dist/requirements.txt artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} - secrets: inherit + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} ArtifactCleanUp: uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@dev @@ -369,7 +372,7 @@ jobs: - PublishToGitHubPages # - PublishOnPyPI - IntermediateCleanUp - if: ${{ inputs.cleanup }} + if: inputs.cleanup == 'true' with: package: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} remaining: | diff --git a/.github/workflows/PublishCoverageResults.yml b/.github/workflows/PublishCoverageResults.yml index 0c30530..08f0611 100644 --- a/.github/workflows/PublishCoverageResults.yml +++ b/.github/workflows/PublishCoverageResults.yml @@ -225,10 +225,10 @@ jobs: if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then printf "::error title=%s::%s\n" "Publish Code Coverage Results / Codecov" "Failed to publish code coverage results." else - printf "Codecov: No errors to report." + printf "Codecov: No errors to report.\n" fi if [[ "${{ steps.codacy.outcome }}" == "failure" ]]; then printf "::error title=%s::%s\n" "Publish Code Coverage Results / Codacy" "Failed to publish code coverage results." else - printf "Codacy: No errors to report." + printf "Codacy: No errors to report.\n" fi diff --git a/.github/workflows/PublishTestResults.yml b/.github/workflows/PublishTestResults.yml index e4607db..c09f56c 100644 --- a/.github/workflows/PublishTestResults.yml +++ b/.github/workflows/PublishTestResults.yml @@ -145,7 +145,7 @@ jobs: if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then printf "::error title=%s::%s\n" "Publish Unit Test Results / Codecov" "Failed to publish unittest results." else - printf "Codecov: No errors to report." + printf "Codecov: No errors to report.\n" fi - name: 📤 Upload merged 'JUnit Test Summary' artifact From 330a21e6c30c63777254ee3002ef34a37399f38c Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 5 May 2025 18:53:05 +0200 Subject: [PATCH 24/27] Apply Dependabot reviewers vs. GitHub CODEOWNERS change requested by Dependabot. --- .github/CODEOWNERS | 3 +++ .github/dependabot.yml | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..6d63ee3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +* @Paebbels + +/.github/ @Paebbels diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e91b107..92e46e0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,7 +10,5 @@ updates: - Dependencies assignees: - Paebbels - reviewers: - - Paebbels schedule: interval: "daily" # Checks on Monday trough Friday. From 5891636ec9a056420219be301ebed3e1f6c9cef0 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 5 May 2025 18:55:24 +0200 Subject: [PATCH 25/27] Install Python package and readout embedded package version. --- .github/workflows/CompletePipeline.yml | 30 ++++- .github/workflows/ExtractConfiguration.yml | 22 +++- .github/workflows/InstallPackage.yml | 128 +++++++++++++++++++ .github/workflows/_Checking_JobTemplates.yml | 24 +++- doc/make.bat | 2 +- 5 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/InstallPackage.yml diff --git a/.github/workflows/CompletePipeline.yml b/.github/workflows/CompletePipeline.yml index 5731bb9..530a253 100644 --- a/.github/workflows/CompletePipeline.yml +++ b/.github/workflows/CompletePipeline.yml @@ -158,6 +158,18 @@ jobs: # exclude_list: ${{ inputs.apptest_exclude_list }} # disable_list: ${{ inputs.apptest_disable_list }} + InstallParams: + uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev + with: + package_namespace: ${{ inputs.package_namespace }} + package_name: ${{ inputs.package_name }} + python_version: ${{ inputs.unittest_python_version }} + python_version_list: '' + system_list: ${{ inputs.unittest_system_list }} + include_list: ${{ inputs.unittest_include_list }} + exclude_list: ${{ inputs.unittest_exclude_list }} + disable_list: ${{ inputs.unittest_disable_list }} + UnitTesting: uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@dev needs: @@ -199,11 +211,23 @@ jobs: uses: pyTooling/Actions/.github/workflows/Package.yml@dev needs: - UnitTestingParams - - UnitTesting +# - UnitTesting with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} + Install: + uses: pyTooling/Actions/.github/workflows/InstallPackage.yml@dev + needs: + - ConfigParams + - UnitTestingParams + - InstallParams + - Package + with: + jobs: ${{ needs.InstallParams.outputs.python_jobs }} + wheel: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} + package_name: ${{ needs.ConfigParams.outputs.package_fullname }} + # AppTesting: # uses: pyTooling/Actions/.github/workflows/ApplicationTesting.yml@dev # needs: @@ -244,7 +268,7 @@ jobs: - UnitTestingParams - UnitTesting with: - testsuite-summary-name: ${{ inputs.package_name }} + testsuite-summary-name: ${{ needs.ConfigParams.outputs.package_fullname }} merged_junit_filename: ${{ needs.ConfigParams.outputs.unittest_merged_report_xml_filename }} merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }} dorny: ${{ inputs.dorny }} @@ -314,6 +338,7 @@ jobs: needs: - Prepare - UnitTesting + - Install # - AppTesting # - StaticTypeCheck - Package @@ -332,6 +357,7 @@ jobs: needs: - Prepare - UnitTesting + - Install # - AppTesting # - StaticTypeCheck - Package diff --git a/.github/workflows/ExtractConfiguration.yml b/.github/workflows/ExtractConfiguration.yml index 7acff81..f713708 100644 --- a/.github/workflows/ExtractConfiguration.yml +++ b/.github/workflows/ExtractConfiguration.yml @@ -145,6 +145,12 @@ jobs: namespace = "${{ inputs.package_namespace }}".strip() name = "${{ inputs.package_name }}".strip() + print(dedent(f"""\ + INPUTS: + package_namespace: {namespace} + package_name: {name} + """)) + if namespace == "" or namespace == ".": fullname = f"{name}" directory = f"{name}" @@ -154,6 +160,13 @@ jobs: directory = f"{namespace}/{name}" mypy_prepare_command = f"touch {namespace}/__init__.py" + print(dedent(f"""\ + OUTPUTS: + package_fullname: {fullname} + package_directory: {directory} + mypy_prepare_command: {mypy_prepare_command} + """)) + github_output = Path(getenv("GITHUB_OUTPUT")) print(f"GITHUB_OUTPUT: {github_output}") with github_output.open("a+", encoding="utf-8") as f: @@ -234,4 +247,11 @@ jobs: coverage_report_json={coverageJSONFile.as_posix()} """)) - print(f"DEBUG:\n unittest xml: {unittestXMLFile}\n merged unittest xml: {mergedUnittestXMLFile}\n coverage html: {coverageHTMLDirectory}\n coverage xml: {coverageXMLFile}\n coverage json: {coverageJSONFile}") + print(dedent(f"""\ + DEBUG: + unittest xml: {unittestXMLFile} + merged unittest xml: {mergedUnittestXMLFile} + coverage html: {coverageHTMLDirectory} + coverage xml: {coverageXMLFile} + coverage json: {coverageJSONFile} + """)) diff --git a/.github/workflows/InstallPackage.yml b/.github/workflows/InstallPackage.yml new file mode 100644 index 0000000..6ef3e77 --- /dev/null +++ b/.github/workflows/InstallPackage.yml @@ -0,0 +1,128 @@ +# ==================================================================================================================== # +# 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: Install Package + +on: + workflow_call: + inputs: + jobs: + description: 'JSON list with environment fields, telling the system and Python versions to run tests with.' + required: true + type: string + wheel: + description: "Wheel package as input artifact." + required: true + type: string + package_name: + description: "Name of the Python package." + required: true + type: string + +jobs: + PackageInstallation: + name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Package installation using Python ${{ matrix.python }} + runs-on: ${{ matrix.runs-on }} + + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(inputs.jobs) }} + + defaults: + run: + shell: ${{ matrix.shell }} + + steps: + - name: 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job + uses: pyTooling/download-artifact@v4 + with: + name: ${{ inputs.wheel }} + path: install + + - name: '🟦 Setup MSYS2 for ${{ matrix.runtime }}' + uses: msys2/setup-msys2@v2 + if: matrix.system == 'msys2' + with: + msystem: ${{ matrix.runtime }} + update: true + pacboy: >- + python-pip:p python-wheel:p + python-lxml:p + python-ruamel-yaml:p python-ruamel.yaml.clib:p + python-tomli:p + + - name: 🐍 Setup Python ${{ matrix.python }} + uses: actions/setup-python@v5 + if: matrix.system != 'msys2' + with: + python-version: ${{ matrix.python }} + + - name: 🔧 Install wheel and pip dependencies (native) + if: matrix.system != 'msys2' + run: | + python -m pip install --disable-pip-version-check -U wheel + + - name: 🔧 Install wheel from artifact (Ubuntu/macOS) + if: matrix.system != 'windows' + run: | + python -m pip install --disable-pip-version-check -U install/*.whl + + - name: 🔧 Install wheel from artifact (Windows) + if: matrix.system == 'windows' + run: | + python -m pip install -v --disable-pip-version-check (Get-Item .\install\*.whl).FullName + + - name: 📦 Run application tests (Ubuntu/macOS) + if: matrix.system != 'windows' + run: | + set +e + + ANSI_LIGHT_RED=$'\x1b[91m' + ANSI_LIGHT_GREEN=$'\x1b[92m' + ANSI_NOCOLOR=$'\x1b[0m' + + printf "Import package and checking package version ...\n " + python3 - << EOF | tee ImportTest.log | grep -E "^Package version:\s+[0-9]+\.[0-9]+\.[0-9]+" + from ${{ inputs.package_name }} import __version__ + + print(f"Package version: {__version__}") + EOF + if [[ $? -eq 0 ]]; then + printf " ${ANSI_LIGHT_GREEN}[PASSED]${ANSI_NOCOLOR}\n" + else + printf " ${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n" + printf "::error title=%s::%s\n" "InstallPackage" "Couldn't check package version of '${{ inputs.package_name }}'." + exit 1 + fi + + - name: 📦 Run application tests (Windows) + if: matrix.system == 'windows' + run: | + $result=$(python -c "from ${{ inputs.package_name }} import __version__; print(f""Package version: {__version__}"")") + Write-Host $result + if ($result -match "Package version:\s+\d+\.\d+\.\d+") { + Write-Host -ForegroundColor Green "[PASSED]" + } else { + Write-Host -ForegroundColor Red "[FAILED]" + Write-Host ("::error title={0}::{1}" -f "InstallPackage", "Couldn't check package version of '${{ inputs.package_name }}'.") + exit 1 + } diff --git a/.github/workflows/_Checking_JobTemplates.yml b/.github/workflows/_Checking_JobTemplates.yml index 3eb8629..0f71390 100644 --- a/.github/workflows/_Checking_JobTemplates.yml +++ b/.github/workflows/_Checking_JobTemplates.yml @@ -13,6 +13,12 @@ jobs: with: package_name: pyDummy + InstallParams: + uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev + with: + package_name: pyDummy + python_version_list: '' + UnitTestingParams: uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev with: @@ -90,12 +96,24 @@ jobs: uses: pyTooling/Actions/.github/workflows/Package.yml@dev needs: - UnitTestingParams - - UnitTesting - - PlatformTesting +# - UnitTesting +# - PlatformTesting with: python_version: ${{ needs.UnitTestingParams.outputs.python_version }} artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} + Install: + uses: pyTooling/Actions/.github/workflows/InstallPackage.yml@dev + needs: + - ConfigParams + - UnitTestingParams + - InstallParams + - Package + with: + jobs: ${{ needs.InstallParams.outputs.python_jobs }} + wheel: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }} + package_name: ${{ needs.ConfigParams.outputs.package_fullname }} + PublishCoverageResults: uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@dev needs: @@ -194,6 +212,7 @@ jobs: - Prepare - UnitTesting - PlatformTesting + - Install # - StaticTypeCheck - Package - PublishToGitHubPages @@ -211,6 +230,7 @@ jobs: - Prepare - UnitTesting - PlatformTesting + - Install # - StaticTypeCheck - Package - PublishToGitHubPages diff --git a/doc/make.bat b/doc/make.bat index 39e6f08..2525c96 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -5,7 +5,7 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build + set SPHINXBUILD=py -3.13 -m sphinx.cmd.build ) set SOURCEDIR=. set BUILDDIR=_build From 034d27d4a33dd3c2ce8964d77da5f7edc9349f2e Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 28 May 2025 09:33:32 +0200 Subject: [PATCH 26/27] Added pyaml and MarkupSafe to list of preinstalled pacman packages. --- .github/workflows/ApplicationTesting.yml | 5 +++-- .github/workflows/InstallPackage.yml | 2 ++ .github/workflows/UnitTesting.yml | 6 ++++-- .github/workflows/_Checking_NamespacePackage_Pipeline.yml | 5 ++++- .github/workflows/_Checking_SimplePackage_Pipeline.yml | 5 ++++- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ApplicationTesting.yml b/.github/workflows/ApplicationTesting.yml index 3090f55..14429c3 100644 --- a/.github/workflows/ApplicationTesting.yml +++ b/.github/workflows/ApplicationTesting.yml @@ -134,20 +134,21 @@ jobs: packages = { "coverage": "python-coverage:p", - "docstr_coverage": "python-pyyaml:p", + "docstr_coverage": "python-pyyaml:p python-types-pyyaml:p", "igraph": "igraph:p", "jinja2": "python-markupsafe:p", "lxml": "python-lxml:p", "numpy": "python-numpy:p", "markupsafe": "python-markupsafe:p", "pip": "python-pip:p", - "pyyaml": "python-pyyaml:p", + "pyyaml": "python-pyyaml:p python-types-pyyaml:p", "ruamel.yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", "sphinx": "python-markupsafe:p", "tomli": "python-tomli:p", "wheel": "python-wheel:p", "pyEDAA.ProjectModel": "python-ruamel-yaml:p python-ruamel.yaml.clib:p python-lxml:p", "pyEDAA.Reports": "python-ruamel-yaml:p python-ruamel.yaml.clib:p python-lxml:p", + "sphinx-reports": "python-markupsafe:p python-pyaml:p python-types-pyyaml:p", } subPackages = { "pytooling": { diff --git a/.github/workflows/InstallPackage.yml b/.github/workflows/InstallPackage.yml index 6ef3e77..9f0ee5d 100644 --- a/.github/workflows/InstallPackage.yml +++ b/.github/workflows/InstallPackage.yml @@ -67,6 +67,8 @@ jobs: pacboy: >- python-pip:p python-wheel:p python-lxml:p + python-markupsafe:p + python-pyaml:p python-types-pyyaml:p python-ruamel-yaml:p python-ruamel.yaml.clib:p python-tomli:p diff --git a/.github/workflows/UnitTesting.yml b/.github/workflows/UnitTesting.yml index 7bab324..d3483e3 100644 --- a/.github/workflows/UnitTesting.yml +++ b/.github/workflows/UnitTesting.yml @@ -225,14 +225,14 @@ jobs: packages = { "coverage": "python-coverage:p", - "docstr_coverage": "python-pyaml:p", + "docstr_coverage": "python-pyaml:p python-types-pyyaml:p", "igraph": "igraph:p", "jinja2": "python-markupsafe:p", "lxml": "python-lxml:p", "numpy": "python-numpy:p", "markupsafe": "python-markupsafe:p", "pip": "python-pip:p", - "pyyaml": "python-pyyaml:p", + "pyyaml": "python-pyyaml:p python-types-pyyaml:p", "ruamel.yaml": "python-ruamel-yaml:p", # "ruamel.yaml": "python-ruamel-yaml:p python-ruamel.yaml.clib:p", "sphinx": "python-markupsafe:p", @@ -240,6 +240,7 @@ jobs: "wheel": "python-wheel:p", "pyedaa.projectmodel": "python-ruamel-yaml:p python-ruamel.yaml.clib:p python-lxml:p", "pyedaa.reports": "python-ruamel-yaml:p python-ruamel.yaml.clib:p python-lxml:p", + "sphinx-reports": "python-markupsafe:p python-pyaml:p python-types-pyyaml:p", } subPackages = { "pytooling": { @@ -342,6 +343,7 @@ jobs: - name: ✅ Run unit tests (Ubuntu/macOS) if: matrix.system != 'windows' + continue-on-error: true run: | export ENVIRONMENT_NAME="${{ matrix.envname }}" export PYTHONPATH=$(pwd) diff --git a/.github/workflows/_Checking_NamespacePackage_Pipeline.yml b/.github/workflows/_Checking_NamespacePackage_Pipeline.yml index 227d836..a0eb01b 100644 --- a/.github/workflows/_Checking_NamespacePackage_Pipeline.yml +++ b/.github/workflows/_Checking_NamespacePackage_Pipeline.yml @@ -13,4 +13,7 @@ jobs: codecov: true codacy: true dorny: true - secrets: inherit + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }} diff --git a/.github/workflows/_Checking_SimplePackage_Pipeline.yml b/.github/workflows/_Checking_SimplePackage_Pipeline.yml index 77907f2..9c683b8 100644 --- a/.github/workflows/_Checking_SimplePackage_Pipeline.yml +++ b/.github/workflows/_Checking_SimplePackage_Pipeline.yml @@ -13,4 +13,7 @@ jobs: codacy: true dorny: true cleanup: false - secrets: inherit + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }} From 68f708d79c90283be4f28adac3807fe6e74ca33f Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Jun 2025 12:16:45 +0200 Subject: [PATCH 27/27] Bumped dependencies. --- doc/conf.py | 45 +++++++++++++++++++++++------------------- doc/requirements.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- run.ps1 | 2 +- setup.py | 23 +++++++++++---------- tests/requirements.txt | 8 ++++---- 7 files changed, 46 insertions(+), 38 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 327b3ca..e386788 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,20 +1,29 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -from importlib.util import find_spec from sys import path as sys_path from os.path import abspath from pathlib import Path -from json import loads from pyTooling.Packaging import extractVersionInformation +# ============================================================================== +# Project configuration +# ============================================================================== +githubNamespace = "pyTooling" +githubProject = "Actions" +pythonProject = "pyDummy" +directoryName = pythonProject.replace('.', '/') + + +# ============================================================================== +# Project paths +# ============================================================================== ROOT = Path(__file__).resolve().parent sys_path.insert(0, abspath(".")) sys_path.insert(0, abspath("..")) -sys_path.insert(0, abspath("../pyDummy")) -# sys_path.insert(0, abspath("_extensions")) +sys_path.insert(0, abspath(f"../{directoryName}")) # ============================================================================== @@ -23,11 +32,7 @@ sys_path.insert(0, abspath("../pyDummy")) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -githubNamespace = "pyTooling" -githubProject = "Actions" -project = "pyDummy" - -packageInformationFile = Path(f"../{project}/__init__.py") +packageInformationFile = Path(f"../{directoryName}/__init__.py") versionInformation = extractVersionInformation(packageInformationFile) author = versionInformation.Author @@ -105,7 +110,7 @@ html_last_updated_fmt = "%d.%m.%Y" # Python settings # ============================================================================== modindex_common_prefix = [ - f"{project}." + f"{pythonProject}." ] # ============================================================================== @@ -257,13 +262,13 @@ todo_link_only = True # ============================================================================== # report_unittest_testsuites = { # "src": { -# "name": f"{project}", +# "name": f"{pythonProject}", # "xml_report": "../report/unit/unittest.xml", # } # } # report_codecov_packages = { # "src": { -# "name": f"{project}", +# "name": f"{pythonProject}", # "json_report": "../report/coverage/coverage.json", # "fail_below": 80, # "levels": "default" @@ -271,8 +276,8 @@ todo_link_only = True # } # report_doccov_packages = { # "src": { -# "name": f"{project}", -# "directory": f"../{project}", +# "name": f"{pythonProject}", +# "directory": f"../{directoryName}", # "fail_below": 80, # "levels": "default" # } @@ -289,17 +294,17 @@ todo_link_only = True # AutoAPI.Sphinx # ============================================================================== autoapi_modules = { - f"{project}": { + f"{pythonProject}": { "template": "package", - "output": project, + "output": pythonProject, "override": True } } -for directory in [mod for mod in Path(f"../{project}").iterdir() if mod.is_dir() and mod.name != "__pycache__"]: - print(f"Adding module rule for '{project}.{directory.name}'") - autoapi_modules[f"{project}.{directory.name}"] = { +for directory in [mod for mod in Path(f"../{directoryName}").iterdir() if mod.is_dir() and mod.name != "__pycache__"]: + print(f"Adding module rule for '{pythonProject}.{directory.name}'") + autoapi_modules[f"{pythonProject}.{directory.name}"] = { "template": "module", - "output": project, + "output": pythonProject, "override": True } diff --git a/doc/requirements.txt b/doc/requirements.txt index 2027f4c..709b41b 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,6 +1,6 @@ -r ../requirements.txt -pyTooling ~= 8.4 +pyTooling ~= 8.5 # Enforce latest version on ReadTheDocs sphinx ~= 8.2 diff --git a/pyproject.toml b/pyproject.toml index 11fc317..eb223ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ requires = [ "setuptools >= 80.0", "wheel ~= 0.45", - "pyTooling ~= 8.4" + "pyTooling ~= 8.5" ] build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt index 3d2b3a7..3781d6d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -pyTooling ~= 8.4 +pyTooling ~= 8.5 diff --git a/run.ps1 b/run.ps1 index e18144f..f55babc 100644 --- a/run.ps1 +++ b/run.ps1 @@ -88,7 +88,7 @@ if ($build) rm -Force .\build\bdist.win-amd64 rm -Force .\build\lib Write-Host -ForegroundColor Yellow "[live][BUILD] Building $PackageName package as wheel ..." - py -3.13 -m build --wheel + py -3.13 -m build --wheel --no-isolation Write-Host -ForegroundColor Yellow "[live][BUILD] Building wheel finished" } diff --git a/setup.py b/setup.py index af9a65c..f6b637a 100644 --- a/setup.py +++ b/setup.py @@ -39,13 +39,16 @@ packageName = "pyDummy" packageDirectory = packageName packageInformationFile = Path(f"{packageDirectory}/__init__.py") -setup(**DescribePythonPackageHostedOnGitHub( - packageName=packageName, - description="pyDummy is a test package to verify GitHub actions for Python projects.", - gitHubNamespace=gitHubNamespace, - unittestRequirementsFile=Path("tests/requirements.txt"), - sourceFileWithVersion=packageInformationFile, - dataFiles={ - packageName: ["py.typed"] - } -)) +setup( + **DescribePythonPackageHostedOnGitHub( + packageName=packageName, + description="pyDummy is a test package to verify GitHub actions for Python projects.", + gitHubNamespace=gitHubNamespace, + unittestRequirementsFile=Path("tests/requirements.txt"), + sourceFileWithVersion=packageInformationFile, + dataFiles={ + packageName: ["py.typed"] + }, + debug=True + ) +) diff --git a/tests/requirements.txt b/tests/requirements.txt index dc267c1..f83dca0 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,13 +1,13 @@ -r ../requirements.txt # Coverage collection -Coverage ~= 7.8 +Coverage ~= 7.9 # Test Runner -pytest ~= 8.3 -pytest-cov ~= 6.1 +pytest ~= 8.4 +pytest-cov ~= 6.2 # Static Type Checking -mypy ~= 1.15 +mypy ~= 1.16 typing_extensions ~= 4.13 lxml ~= 5.4