mirror of
https://github.com/pyTooling/Actions.git
synced 2026-02-14 12:06:56 +08:00
Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2eebeec719 | ||
|
|
5b97eaf241 | ||
|
|
1e694005ed | ||
|
|
46a2764e73 | ||
|
|
626d64ef6a | ||
|
|
fe4c9139c1 | ||
|
|
ae8a961e93 | ||
|
|
e4b5ea3895 | ||
|
|
b61f479180 | ||
|
|
9e6bbd52a6 | ||
|
|
438207a68d | ||
|
|
c08a164b9e | ||
|
|
2e4f6f3e7c | ||
|
|
a8e4c60424 | ||
|
|
c0547188f9 | ||
|
|
53a32fbf35 | ||
|
|
91736df13e | ||
|
|
d190b1a3b1 | ||
|
|
055863ee5f | ||
|
|
22bbe48d4b | ||
|
|
4d260bfdf5 | ||
|
|
f684e67bca | ||
|
|
8ecefcec59 | ||
|
|
b247eb4a53 | ||
|
|
fb67dd0fdb | ||
|
|
bfe857a4af | ||
|
|
1041e7b5c7 | ||
|
|
e2e8b39c41 | ||
|
|
ae6f532e52 | ||
|
|
2fe6be15c7 | ||
|
|
15c9a23136 | ||
|
|
f79a63bf8e | ||
|
|
0c8f81d52e | ||
|
|
250ad53b7b | ||
|
|
d1d591efb8 | ||
|
|
57f88b158f | ||
|
|
f37f087334 | ||
|
|
dd30d0bc18 | ||
|
|
35dd52d018 | ||
|
|
a3816bfd59 | ||
|
|
e6b2d0a876 | ||
|
|
52712f8491 | ||
|
|
d005debf69 | ||
|
|
ee869dead5 | ||
|
|
1c99a4a914 | ||
|
|
d62ba6c06b | ||
|
|
e5b29528b7 | ||
|
|
e559fb8219 | ||
|
|
d5ad74fa89 | ||
|
|
e5706693e2 | ||
|
|
729e406294 | ||
|
|
bb03bdcc11 | ||
|
|
0adc72d26a | ||
|
|
277df7ea7f | ||
|
|
817c84af2e | ||
|
|
99c3752847 | ||
|
|
13e42615b2 | ||
|
|
6d75b849f5 | ||
|
|
4f49964e57 | ||
|
|
b4d45277d1 | ||
|
|
0f66b32418 | ||
|
|
4badbda8e7 | ||
|
|
3141de852a | ||
|
|
a2db5ec238 | ||
|
|
c78cb4062f | ||
|
|
2c0e88f39a | ||
|
|
e962cd6953 | ||
|
|
bde1b15783 | ||
|
|
d6342484cd | ||
|
|
ba3d82668e | ||
|
|
4b0b103c5f | ||
|
|
ba6f55dd57 | ||
|
|
d48de1d02d | ||
|
|
744f08b9bf | ||
|
|
fb546453ae | ||
|
|
1a3ba03626 | ||
|
|
4d2d4c47fc | ||
|
|
962827936c | ||
|
|
2307b526df | ||
|
|
f3e2e42ae3 | ||
|
|
2f7fa88c36 | ||
|
|
2ee14e88a2 | ||
|
|
68f708d79c | ||
|
|
034d27d4a3 | ||
|
|
5891636ec9 | ||
|
|
330a21e6c3 | ||
|
|
bdf8239a73 | ||
|
|
68357fddd8 | ||
|
|
4addce16fa | ||
|
|
2f4ccf2af4 | ||
|
|
0b6462f4d2 | ||
|
|
b0198fa459 | ||
|
|
05808d4058 | ||
|
|
7a57747fcd | ||
|
|
3f7b0c221b | ||
|
|
4ebf262921 | ||
|
|
f015e1c3a0 | ||
|
|
9e6138b5a9 | ||
|
|
39ae93c200 | ||
|
|
1b6454ba91 | ||
|
|
12389ac0f0 | ||
|
|
c1f0e4a16b | ||
|
|
8d0c46d6b5 | ||
|
|
70f5fe1fc8 | ||
|
|
a1309f9f42 | ||
|
|
8e94b774da | ||
|
|
aaf283515b | ||
|
|
f10daa2e2c | ||
|
|
27d45b9766 | ||
|
|
33edd82e6f | ||
|
|
d08f312904 | ||
|
|
731d0d2369 | ||
|
|
de400ae2db | ||
|
|
cb3c338df6 | ||
|
|
79c8526437 | ||
|
|
0f7d062c38 | ||
|
|
d5635a8842 | ||
|
|
6aa6af95ee | ||
|
|
15bf375fe6 | ||
|
|
a1b03cfe2a | ||
|
|
79620e267d | ||
|
|
fffef5c814 | ||
|
|
42e17fae05 | ||
|
|
9b7032a585 | ||
|
|
9110c85738 | ||
|
|
c81d139080 | ||
|
|
c64e054bcd | ||
|
|
78fdb584aa | ||
|
|
a456635686 | ||
|
|
befc59f22d | ||
|
|
d6fc0efd47 | ||
|
|
c018acc3c1 | ||
|
|
d74c610bb4 | ||
|
|
edc4ab3e86 | ||
|
|
0a338ae8b7 | ||
|
|
4069da0a74 | ||
|
|
679ec24c80 | ||
|
|
3a13486ea6 | ||
|
|
34fb9c9869 | ||
|
|
7523c4adca | ||
|
|
530ad7a4a1 | ||
|
|
bd3f2afaf3 | ||
|
|
b1e4cb961f | ||
|
|
1e6b71e87b | ||
|
|
5d8a608893 | ||
|
|
c3b7b3ca64 | ||
|
|
f61b77ee72 | ||
|
|
5f18024dd4 | ||
|
|
d0f07e1af4 | ||
|
|
2b5a9bdeff | ||
|
|
d324bdacee | ||
|
|
9296bd6e7d | ||
|
|
c37f727e2d | ||
|
|
a4559e8e63 | ||
|
|
bc94fba95e | ||
|
|
d6ec94fea7 | ||
|
|
4bc4ec5cf4 | ||
|
|
e21f89670a | ||
|
|
c13dd2521c | ||
|
|
cf2e89a622 | ||
|
|
a9a3c400fd | ||
|
|
970b4ae021 | ||
|
|
1807741b0a | ||
|
|
cf095afe77 | ||
|
|
12991ee38a | ||
|
|
70134b31c3 | ||
|
|
38514a9005 |
3
.github/CODEOWNERS
vendored
Normal file
3
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
* @Paebbels
|
||||
|
||||
/.github/ @Paebbels
|
||||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -10,9 +10,5 @@ updates:
|
||||
- Dependencies
|
||||
assignees:
|
||||
- Paebbels
|
||||
- umarcor
|
||||
reviewers:
|
||||
- Paebbels
|
||||
- umarcor
|
||||
schedule:
|
||||
interval: "daily" # Checks on Monday trough Friday.
|
||||
|
||||
24
.github/workflows/ApplicationTesting.yml
vendored
24
.github/workflows/ApplicationTesting.yml
vendored
@@ -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. #
|
||||
@@ -86,14 +86,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job
|
||||
uses: pyTooling/download-artifact@v4
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
name: ${{ inputs.wheel }}
|
||||
path: install
|
||||
|
||||
# TODO: extract step to an Action so package lists are shared with UnitTesting (and GHDL?)
|
||||
- name: Compute pacman/pacboy packages
|
||||
id: pacboy
|
||||
if: matrix.system == 'msys2'
|
||||
@@ -134,20 +135,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": {
|
||||
@@ -188,8 +190,8 @@ jobs:
|
||||
f.write(f"pacboy_packages={' '.join(pacboyPackages)}\n")
|
||||
|
||||
- name: '🟦 Setup MSYS2 for ${{ matrix.runtime }}'
|
||||
if: matrix.system == 'msys2'
|
||||
uses: msys2/setup-msys2@v2
|
||||
if: matrix.system == 'msys2'
|
||||
with:
|
||||
msystem: ${{ matrix.runtime }}
|
||||
update: true
|
||||
@@ -198,8 +200,8 @@ jobs:
|
||||
${{ inputs.pacboy }}
|
||||
|
||||
- name: 🐍 Setup Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v6
|
||||
if: matrix.system != 'msys2'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
@@ -224,22 +226,22 @@ jobs:
|
||||
python -m pip install --disable-pip-version-check -U install/*.whl
|
||||
|
||||
- name: ✅ Run application tests (Ubuntu/macOS)
|
||||
if: matrix.system != 'windows'
|
||||
if: ( matrix.system != 'windows' && matrix.system != 'windows-arm' )
|
||||
run: |
|
||||
export ENVIRONMENT_NAME="${{ matrix.envname }}"
|
||||
|
||||
cd "${{ inputs.root_directory || '.' }}"
|
||||
[ -n '${{ inputs.apptest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=report/unit/TestReportSummary.xml' || unset PYTEST_ARGS
|
||||
if [ -n '${{ inputs.coverage_config }}' ]; then
|
||||
echo "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
|
||||
printf "%s\n" "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
|
||||
coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
|
||||
else
|
||||
echo "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
|
||||
printf "%s\n" "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
|
||||
python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
|
||||
fi
|
||||
|
||||
- name: ✅ Run application tests (Windows)
|
||||
if: matrix.system == 'windows'
|
||||
if: ( matrix.system == 'windows' || matrix.system == 'windows-arm' )
|
||||
run: |
|
||||
$env:ENVIRONMENT_NAME = "${{ matrix.envname }}"
|
||||
|
||||
|
||||
6
.github/workflows/ArtifactCleanUp.yml
vendored
6
.github/workflows/ArtifactCleanUp.yml
vendored
@@ -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. #
|
||||
@@ -47,13 +47,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 🗑️ Delete package Artifacts
|
||||
if: ${{ ! startsWith(github.ref, 'refs/tags') }}
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
if: ${{ ! startsWith(github.ref, 'refs/tags') }}
|
||||
with:
|
||||
name: ${{ inputs.package }}
|
||||
|
||||
- name: 🗑️ Delete remaining Artifacts
|
||||
if: ${{ inputs.remaining != '' }}
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
if: ${{ inputs.remaining != '' }}
|
||||
with:
|
||||
name: ${{ inputs.remaining }}
|
||||
|
||||
10
.github/workflows/BuildTheDocs.yml
vendored
10
.github/workflows/BuildTheDocs.yml
vendored
@@ -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. #
|
||||
@@ -37,11 +37,11 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: '❗ Deprecation message'
|
||||
run: echo "::warning title=Deprecated::'BuildTheDocs.yml' is not maintained anymore. Please switch to 'SphinxDocumentation.yml', 'LaTeXDocumentation.yml' and 'ExtractConfiguration.yml'."
|
||||
- name: ⚠️ Deprecation Warning
|
||||
run: printf "::warning title=%s::%s\n" "Deprecated" "'BuildTheDocs.yml' template is deprecated. Please switch to 'SphinxDocumentation.yml'. See https://pytooling.github.io/Actions/JobTemplate/Documentation/SphinxDocumentation.html"
|
||||
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🛳️ Build documentation
|
||||
uses: buildthedocs/btd@v0
|
||||
@@ -49,8 +49,8 @@ jobs:
|
||||
skip-deploy: true
|
||||
|
||||
- name: 📤 Upload 'documentation' artifacts
|
||||
if: inputs.artifact != ''
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.artifact != ''
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
working-directory: doc/_build/html
|
||||
|
||||
201
.github/workflows/CheckCodeQuality.yml
vendored
Normal file
201
.github/workflows/CheckCodeQuality.yml
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
# ==================================================================================================================== #
|
||||
# Authors: #
|
||||
# Patrick Lehmann #
|
||||
# #
|
||||
# ==================================================================================================================== #
|
||||
# Copyright 2025-2025 The pyTooling Authors #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
# SPDX-License-Identifier: Apache-2.0 #
|
||||
# ==================================================================================================================== #
|
||||
name: Code Quality Checking
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ubuntu_image_version:
|
||||
description: 'Ubuntu image version.'
|
||||
required: false
|
||||
default: '24.04'
|
||||
type: string
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.13'
|
||||
type: string
|
||||
package_directory:
|
||||
description: 'The package''s directory'
|
||||
required: true
|
||||
type: string
|
||||
requirements:
|
||||
description: 'Python dependencies to be installed through pip.'
|
||||
required: false
|
||||
default: '-r requirements.txt'
|
||||
type: string
|
||||
bandit:
|
||||
description: 'Run bandit checks.'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: string
|
||||
radon:
|
||||
description: 'Run radon checks.'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: string
|
||||
pylint:
|
||||
description: 'Run pylint checks.'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: string
|
||||
artifact:
|
||||
description: 'Name of the package artifact.'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
Bandit:
|
||||
name: 🚨 Security Scanning (Bandit)
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
if: inputs.bandit == 'true'
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
- name: ⚙ Install dependencies for running bandit
|
||||
run: python -m pip install --disable-pip-version-check bandit
|
||||
|
||||
- name: 👮 Bandit
|
||||
id: bandit
|
||||
if: inputs.artifact != ''
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ANSI_LIGHT_RED=$'\x1b[91m'
|
||||
ANSI_LIGHT_GREEN=$'\x1b[92m'
|
||||
ANSI_LIGHT_BLUE=$'\x1b[94m'
|
||||
ANSI_NOCOLOR=$'\x1b[0m'
|
||||
|
||||
bandit_directory=report/bandit
|
||||
bandit_fullpath=report/bandit/report.xml
|
||||
|
||||
tee "${GITHUB_OUTPUT}" <<EOF
|
||||
bandit_directory=${bandit_directory}
|
||||
bandit_fullpath=${bandit_fullpath}
|
||||
EOF
|
||||
|
||||
mkdir -p ${bandit_directory}
|
||||
printf "\nRun bandit ...\n"
|
||||
bandit -c pyproject.toml -r ${{ inputs.package_directory }} -f xml -o ${bandit_fullpath}
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "Bandit result: ${ANSI_LIGHT_GREEN}[PASSED]${ANSI_NOCOLOR}\n"
|
||||
|
||||
printf "bandit_passed=true\n" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
faults=$(grep -Poh '(?<=<testsuite\sname="bandit"\stests=")(\d+)(?=">)' ${bandit_fullpath})
|
||||
|
||||
printf "Bandit result: ${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n"
|
||||
printf " ${ANSI_LIGHT_RED}Bandit found %s issues.${ANSI_NOCOLOR}\n" "${faults}"
|
||||
printf "::error title=%s::%s\n" "🚨 Security Scanning (Bandit)" "Bandi found ${faults} issues."
|
||||
|
||||
printf "bandit_passed=false\n" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
printf "::group::${ANSI_LIGHT_BLUE}JUnit XML report created by Bandit ...${ANSI_NOCOLOR}\n"
|
||||
cat ${bandit_fullpath}
|
||||
printf "\n::endgroup::\n"
|
||||
fi
|
||||
|
||||
- name: 📊 Publish Bandit Results
|
||||
uses: dorny/test-reporter@v2
|
||||
if: steps.bandit.outputs.bandit_passed == 'false'
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: 'Bandit Results'
|
||||
path: ${{ steps.bandit.outputs.bandit_fullpath }}
|
||||
reporter: java-junit
|
||||
|
||||
Radon:
|
||||
name: ☢️ Metrics and Complexity
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
if: inputs.radon == 'true'
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
- name: ⚙ Install dependencies for running radon
|
||||
run: python -m pip install --disable-pip-version-check radon
|
||||
|
||||
- name: Code Metrics
|
||||
# if: inputs.artifact != ''
|
||||
run: |
|
||||
radon raw ${{ inputs.package_directory }} -s
|
||||
|
||||
- name: Code Complexity
|
||||
# if: inputs.artifact != ''
|
||||
run: |
|
||||
radon cc ${{ inputs.package_directory }} --total-average
|
||||
|
||||
- name: Halstead Complexity Metrics
|
||||
# if: inputs.artifact != ''
|
||||
run: |
|
||||
radon hal ${{ inputs.package_directory }}
|
||||
|
||||
- name: Maintainability Index
|
||||
# if: inputs.artifact != ''
|
||||
run: |
|
||||
radon mi ${{ inputs.package_directory }} -s
|
||||
|
||||
PyLint:
|
||||
name: 🩺 Linting
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
if: inputs.pylint == 'true'
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
- name: ⚙ Install dependencies for running PyLint
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check pylint
|
||||
python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
|
||||
|
||||
- name: 🩺 PyLint
|
||||
# if: inputs.artifact != ''
|
||||
run: |
|
||||
pylint ${{ inputs.package_directory }}
|
||||
28
.github/workflows/CheckDocumentation.yml
vendored
28
.github/workflows/CheckDocumentation.yml
vendored
@@ -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. #
|
||||
@@ -32,7 +32,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
directory:
|
||||
description: 'Source code directory to check.'
|
||||
@@ -41,7 +41,7 @@ on:
|
||||
fail_under:
|
||||
description: 'Minimum required documentation coverage level'
|
||||
required: false
|
||||
default: 80
|
||||
default: '80'
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
@@ -50,23 +50,33 @@ jobs:
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
- name: 🔧 Install wheel,tomli and pip dependencies (native)
|
||||
- name: 🔧 Install docstr_coverage and interrogate dependencies
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check -U docstr_coverage interrogate
|
||||
python -m pip install --disable-pip-version-check -U docstr_coverage interrogate[png]
|
||||
|
||||
- name: Run 'interrogate' Documentation Coverage Check
|
||||
continue-on-error: true
|
||||
run: |
|
||||
interrogate -c pyproject.toml --fail-under=${{ inputs.fail_under }} && echo "::error title=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 }} && echo "::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
|
||||
|
||||
239
.github/workflows/CompletePipeline.yml
vendored
239
.github/workflows/CompletePipeline.yml
vendored
@@ -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. #
|
||||
@@ -46,7 +46,7 @@ on:
|
||||
unittest_system_list:
|
||||
description: 'Space separated list of systems to run tests on.'
|
||||
required: false
|
||||
default: 'ubuntu windows macos macos-arm mingw64 ucrt64'
|
||||
default: 'ubuntu ubuntu-arm windows windows-arm macos macos-arm mingw64 ucrt64'
|
||||
type: string
|
||||
unittest_include_list:
|
||||
description: 'Space separated list of system:python items to be included into the list of test.'
|
||||
@@ -56,12 +56,12 @@ on:
|
||||
unittest_exclude_list:
|
||||
description: 'Space separated list of system:python items to be excluded from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:3.9 windows-arm:3.10'
|
||||
type: string
|
||||
unittest_disable_list:
|
||||
description: 'Space separated list of system:python items to be disabled from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:pypy-3.10 windows-arm:pypy-3.11'
|
||||
type: string
|
||||
apptest_python_version:
|
||||
description: 'Python version.'
|
||||
@@ -71,12 +71,12 @@ on:
|
||||
apptest_python_version_list:
|
||||
description: 'Space separated list of Python versions to run tests with.'
|
||||
required: false
|
||||
default: ""
|
||||
default: ''
|
||||
type: string
|
||||
apptest_system_list:
|
||||
description: 'Space separated list of systems to run tests on.'
|
||||
required: false
|
||||
default: 'ubuntu windows macos macos-arm ucrt64'
|
||||
default: 'ubuntu ubuntu-arm windows windows-arm macos macos-arm ucrt64'
|
||||
type: string
|
||||
apptest_include_list:
|
||||
description: 'Space separated list of system:python items to be included into the list of test.'
|
||||
@@ -86,27 +86,50 @@ on:
|
||||
apptest_exclude_list:
|
||||
description: 'Space separated list of system:python items to be excluded from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:3.9 windows-arm:3.10'
|
||||
type: string
|
||||
apptest_disable_list:
|
||||
description: 'Space separated list of system:python items to be disabled from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:pypy-3.10 windows-arm:pypy-3.11'
|
||||
type: string
|
||||
codecov:
|
||||
description: 'Publish merged coverage and unittest reports to Codecov.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
codacy:
|
||||
description: 'Publish merged coverage report to Codacy.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
dorny:
|
||||
description: 'Publish merged unittest report via Dorny Test-Reporter.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
cleanup:
|
||||
description: 'Cleanup artifacts afterwards.'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: string
|
||||
secrets:
|
||||
PYPI_TOKEN:
|
||||
description: "Token for pushing releases to PyPI."
|
||||
required: false
|
||||
CODACY_PROJECT_TOKEN:
|
||||
CODECOV_TOKEN:
|
||||
description: "Token for pushing coverage and unittest results to Codecov."
|
||||
required: false
|
||||
CODACY_TOKEN:
|
||||
description: "Token for pushing coverage results to Codacy."
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@main
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@main
|
||||
with:
|
||||
package_namespace: ${{ inputs.package_namespace }}
|
||||
package_name: ${{ inputs.package_name }}
|
||||
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
@@ -115,32 +138,50 @@ 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:
|
||||
# AppTestingParams:
|
||||
# uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
# 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 }}
|
||||
|
||||
InstallParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
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 }}
|
||||
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@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }}
|
||||
# TODO: shouldn't this be configured by a parameter? Same as directories
|
||||
requirements: "-r tests/unit/requirements.txt"
|
||||
# pacboy: "msys/git python-lxml:p"
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
|
||||
StaticTypeCheck:
|
||||
@@ -149,31 +190,50 @@ jobs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
commands: |
|
||||
${{ needs.ConfigParams.outputs.mypy_prepare_command }}
|
||||
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 }}
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
cobertura_report: ${{ needs.ConfigParams.outputs.typing_report_cobertura }}
|
||||
junit_report: ${{ needs.ConfigParams.outputs.typing_report_junit }}
|
||||
html_report: ${{ needs.ConfigParams.outputs.typing_report_html }}
|
||||
cobertura_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_cobertura }}
|
||||
junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_junit }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
CodeQuality:
|
||||
uses: pyTooling/Actions/.github/workflows/CheckCodeQuality.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
package_directory: ${{ needs.UnitTestingParams.outputs.package_directory }}
|
||||
artifact: CodeQuality
|
||||
|
||||
DocCoverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
directory: ${{ inputs.package_namespace }}/${{ inputs.package_name }}
|
||||
# fail_below: 70
|
||||
directory: ${{ needs.UnitTestingParams.outputs.package_directory }}
|
||||
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
# - UnitTesting
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
|
||||
Install:
|
||||
uses: pyTooling/Actions/.github/workflows/InstallPackage.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- InstallParams
|
||||
- Package
|
||||
with:
|
||||
jobs: ${{ needs.InstallParams.outputs.python_jobs }}
|
||||
wheel: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
package_name: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
|
||||
# AppTesting:
|
||||
# uses: pyTooling/Actions/.github/workflows/ApplicationTesting.yml@main
|
||||
@@ -189,23 +249,40 @@ jobs:
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
if: success() || failure()
|
||||
with:
|
||||
# coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
# coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
# coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
# coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
# coverage_report_xml_directory: ${{ needs.ConfigParams.outputs.coverage_report_xml_directory }}
|
||||
# coverage_report_xml_filename: ${{ needs.ConfigParams.outputs.coverage_report_xml_filename }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
codecov: ${{ inputs.codecov }}
|
||||
codacy: ${{ inputs.codacy }}
|
||||
secrets:
|
||||
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }}
|
||||
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
if: success() || failure()
|
||||
with:
|
||||
merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
testsuite-summary-name: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
merged_junit_filename: ${{ fromJson(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 }}
|
||||
|
||||
# VerifyDocs:
|
||||
# uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@main
|
||||
@@ -222,13 +299,14 @@ jobs:
|
||||
- PublishTestResults
|
||||
- PublishCoverageResults
|
||||
# - VerifyDocs
|
||||
if: success() || failure()
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
coverage_report_json_directory: ${{ needs.ConfigParams.outputs.coverage_report_json_directory }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-ubuntu-native-3.12
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
|
||||
IntermediateCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/IntermediateCleanUp.yml@main
|
||||
@@ -236,20 +314,21 @@ jobs:
|
||||
- UnitTestingParams
|
||||
- PublishCoverageResults
|
||||
- PublishTestResults
|
||||
- Documentation
|
||||
if: ( success() || failure() ) && 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 }}-
|
||||
xml_unittest_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-
|
||||
|
||||
# PDFDocumentation:
|
||||
# uses: pyTooling/Actions/.github/workflows/LaTeXDocumentation.yml@main
|
||||
# needs:
|
||||
# - UnitTestingParams
|
||||
# - Documentation
|
||||
# with:
|
||||
# document: pyEDAA.ProjectModel
|
||||
# latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
# pdf_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_pdf }}
|
||||
PDFDocumentation:
|
||||
uses: pyTooling/Actions/.github/workflows/LaTeXDocumentation.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- Documentation
|
||||
with:
|
||||
document: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
pdf_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_pdf }}
|
||||
can-fail: 'true'
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@main
|
||||
@@ -260,30 +339,61 @@ 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 }}
|
||||
|
||||
TriggerTaggedRelease:
|
||||
uses: pyTooling/Actions/.github/workflows/TagReleaseCommit.yml@main
|
||||
needs:
|
||||
- Prepare
|
||||
- UnitTesting
|
||||
- Install
|
||||
# - AppTesting
|
||||
# - StaticTypeCheck
|
||||
- Package
|
||||
- PublishToGitHubPages
|
||||
if: needs.Prepare.outputs.is_release_commit == 'true' && github.event_name != 'schedule'
|
||||
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/Release.yml@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@main
|
||||
needs:
|
||||
- Package
|
||||
- Prepare
|
||||
- UnitTesting
|
||||
- Install
|
||||
# - AppTesting
|
||||
# - StaticTypeCheck
|
||||
- Package
|
||||
- PublishToGitHubPages
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
tag: ${{ needs.Prepare.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- Prepare
|
||||
- UnitTestingParams
|
||||
- Package
|
||||
- ReleasePage
|
||||
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 }}
|
||||
requirements: '-r dist/requirements.txt'
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@main
|
||||
@@ -298,6 +408,7 @@ jobs:
|
||||
- PublishToGitHubPages
|
||||
# - PublishOnPyPI
|
||||
- IntermediateCleanUp
|
||||
if: inputs.cleanup == 'true'
|
||||
with:
|
||||
package: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
remaining: |
|
||||
|
||||
12
.github/workflows/CoverageCollection.yml
vendored
12
.github/workflows/CoverageCollection.yml
vendored
@@ -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. #
|
||||
@@ -71,17 +71,17 @@ jobs:
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
|
||||
steps:
|
||||
- name: '❗ Deprecation message'
|
||||
run: echo "::warning title=Deprecated::'CoverageCollection.yml' is not maintained anymore. Please switch to 'UnitTesting.yml', 'PublishCoverageResults.yml' and 'PublishTestResults.yml'."
|
||||
- name: ⚠️ Deprecation Warning
|
||||
run: printf "::warning title=%s::%s\n" "Deprecated" "'CoverageCollection.yml' template is deprecated. Please switch to 'PublishReleaseNotes.yml'. See https://pytooling.github.io/Actions/JobTemplate/Testing/UnitTesting.html"
|
||||
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -150,7 +150,7 @@ jobs:
|
||||
ABSDIR=$(pwd)
|
||||
cd "${{ inputs.tests_directory || '.' }}"
|
||||
[ -n '${{ inputs.coverage_config }}' ] && PYCOV_ARGS="--cov-config=${ABSDIR}/${{ inputs.coverage_config }}" || unset PYCOV_ARGS
|
||||
echo "python -m pytest -rA --cov=${ABSDIR} ${PYCOV_ARGS} ${{ inputs.unittest_directory }} --color=yes"
|
||||
printf "%s\n" "python -m pytest -rA --cov=${ABSDIR} ${PYCOV_ARGS} ${{ inputs.unittest_directory }} --color=yes"
|
||||
python -m pytest -rA --cov=${ABSDIR} $PYCOV_ARGS ${{ inputs.unittest_directory }} --color=yes
|
||||
|
||||
- name: Convert to cobertura format
|
||||
|
||||
230
.github/workflows/ExtractConfiguration.yml
vendored
230
.github/workflows/ExtractConfiguration.yml
vendored
@@ -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. #
|
||||
@@ -32,16 +32,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
type: string
|
||||
package_namespace:
|
||||
description: 'Name of the tool''s namespace.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
package_name:
|
||||
description: 'Name of the tool''s package.'
|
||||
required: true
|
||||
default: '3.13'
|
||||
type: string
|
||||
coverage_config:
|
||||
description: 'Path to the .coveragerc file. Use pyproject.toml by default.'
|
||||
@@ -50,51 +41,51 @@ on:
|
||||
type: string
|
||||
|
||||
outputs:
|
||||
package_fullname:
|
||||
unittest_report_xml:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.package_fullname }}
|
||||
package_directory:
|
||||
value: ${{ jobs.Extract.outputs.unittest_report_xml }}
|
||||
unittest_merged_report_xml:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.package_directory }}
|
||||
mypy_prepare_command:
|
||||
value: ${{ jobs.Extract.outputs.unittest_merged_report_xml }}
|
||||
coverage_report_html:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.mypy_prepare_command }}
|
||||
coverage_report_html_directory:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_html_directory }}
|
||||
coverage_report_xml_directory:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_xml_directory }}
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_html }}
|
||||
coverage_report_xml:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_xml }}
|
||||
coverage_report_json_directory:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_json_directory }}
|
||||
coverage_report_json:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.coverage_report_json }}
|
||||
typing_report_cobertura:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.typing_report_cobertura }}
|
||||
typing_report_junit:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.typing_report_junit }}
|
||||
typing_report_html:
|
||||
description: ""
|
||||
value: ${{ jobs.Extract.outputs.typing_report_html }}
|
||||
|
||||
jobs:
|
||||
Extract:
|
||||
name: 📓 Extract configurations from pyproject.toml
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
outputs:
|
||||
package_fullname: ${{ steps.getPackageName.outputs.package_fullname }}
|
||||
package_directory: ${{ steps.getPackageName.outputs.package_directory }}
|
||||
mypy_prepare_command: ${{ steps.getPackageName.outputs.mypy_prepare_command }}
|
||||
coverage_report_html_directory: ${{ steps.getVariables.outputs.coverage_report_html_directory }}
|
||||
coverage_report_xml_directory: ${{ steps.getVariables.outputs.coverage_report_xml_directory }}
|
||||
coverage_report_xml: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
coverage_report_json_directory: ${{ steps.getVariables.outputs.coverage_report_json_directory }}
|
||||
coverage_report_json: ${{ steps.getVariables.outputs.coverage_report_json }}
|
||||
unittest_report_xml: ${{ steps.getVariables.outputs.unittest_report_xml }}
|
||||
unittest_merged_report_xml: ${{ steps.getVariables.outputs.unittest_merged_report_xml }}
|
||||
coverage_report_html: ${{ steps.getVariables.outputs.coverage_report_html }}
|
||||
coverage_report_xml: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ steps.getVariables.outputs.coverage_report_json }}
|
||||
typing_report_cobertura: ${{ steps.getVariables.outputs.typing_report_cobertura }}
|
||||
typing_report_junit: ${{ steps.getVariables.outputs.typing_report_junit }}
|
||||
typing_report_html: ${{ steps.getVariables.outputs.typing_report_html }}
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -102,52 +93,28 @@ jobs:
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check -U wheel tomli
|
||||
|
||||
- name: 🔁 Full package name and directory
|
||||
id: getPackageName
|
||||
shell: python
|
||||
run: |
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
|
||||
namespace = "${{ inputs.package_namespace }}".strip()
|
||||
name = "${{ inputs.package_name }}".strip()
|
||||
|
||||
if namespace == "" or namespace == ".":
|
||||
fullname = f"{name}"
|
||||
directory = f"{name}"
|
||||
mypy_prepare_command = ""
|
||||
else:
|
||||
fullname = f"{namespace}.{name}"
|
||||
directory = f"{namespace}/{name}"
|
||||
mypy_prepare_command = f"touch {namespace}/__init__.py"
|
||||
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
package_fullname={fullname}
|
||||
package_directory={directory}
|
||||
mypy_prepare_command={mypy_prepare_command}
|
||||
"""))
|
||||
|
||||
- name: 🔁 Extract configurations from pyproject.toml
|
||||
id: getVariables
|
||||
shell: python
|
||||
run: |
|
||||
from json import dumps as json_dumps
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from sys import version
|
||||
from textwrap import dedent
|
||||
|
||||
print(f"Python: {version}")
|
||||
print(f"Python: {version} (of default installation)")
|
||||
|
||||
from tomli import load as tomli_load
|
||||
|
||||
htmlDirectory = Path("htmlcov")
|
||||
xmlFile = Path("./coverage.xml")
|
||||
jsonFile = Path("./coverage.json")
|
||||
coverageRC = "${{ inputs.coverage_config }}".strip()
|
||||
unittestXMLFile = Path("./unittest.xml")
|
||||
coverageHTMLDirectory = Path("htmlcov")
|
||||
coverageXMLFile = Path("./coverage.xml")
|
||||
coverageJSONFile = Path("./coverage.json")
|
||||
coverageRC = "${{ inputs.coverage_config }}".strip()
|
||||
typingCoberturaFile = Path("report/typing/cobertura.xml")
|
||||
typingJUnitFile = Path("report/typing/StaticTypingSummary.xml")
|
||||
typingHTMLDirectory = Path("htmlmypy")
|
||||
|
||||
# Read output paths from 'pyproject.toml' file
|
||||
if coverageRC == "pyproject.toml":
|
||||
@@ -156,9 +123,14 @@ jobs:
|
||||
with pyProjectFile.open("rb") as file:
|
||||
pyProjectSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"])
|
||||
xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"])
|
||||
jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"])
|
||||
unittestXMLFile = Path(pyProjectSettings["tool"]["pytest"]["junit_xml"])
|
||||
mergedUnittestXMLFile = Path(pyProjectSettings["tool"]["pyedaa-reports"]["junit_xml"])
|
||||
coverageHTMLDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"])
|
||||
coverageXMLFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"])
|
||||
coverageJSONFile= Path(pyProjectSettings["tool"]["coverage"]["json"]["output"])
|
||||
typingCoberturaFile = Path(pyProjectSettings["tool"]["mypy"]["cobertura_xml_report"]) / "cobertura.xml"
|
||||
typingJUnitFile = Path(pyProjectSettings["tool"]["mypy"]["junit_xml"])
|
||||
typingHTMLDirectory = Path(pyProjectSettings["tool"]["mypy"]["html_report"])
|
||||
else:
|
||||
print(f"File '{pyProjectFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{pyProjectFile}' not found.")
|
||||
@@ -166,29 +138,123 @@ jobs:
|
||||
|
||||
# Read output paths from '.coveragerc' file
|
||||
elif len(coverageRC) > 0:
|
||||
print(f"::warning title=Deprecated::Using '{coverageRCFile}' is deprecated. Please use 'pyproject.toml'.")
|
||||
|
||||
coverageRCFile = Path(coverageRC)
|
||||
if coverageRCFile.exists():
|
||||
with coverageRCFile.open("rb") as file:
|
||||
coverageRCSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(coverageRCSettings["html"]["directory"])
|
||||
xmlFile = Path(coverageRCSettings["xml"]["output"])
|
||||
jsonFile = Path(coverageRCSettings["json"]["output"])
|
||||
coverageHTMLDirectory = Path(coverageRCSettings["html"]["directory"])
|
||||
coverageXMLFile = Path(coverageRCSettings["xml"]["output"])
|
||||
coverageJSONFile = Path(coverageRCSettings["json"]["output"])
|
||||
else:
|
||||
print(f"File '{coverageRCFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{coverageRCFile}' not found.")
|
||||
exit(1)
|
||||
|
||||
unittest_report_xml = {
|
||||
"fullpath": unittestXMLFile.as_posix(),
|
||||
"directory": unittestXMLFile.parent.as_posix(),
|
||||
"filename": unittestXMLFile.name
|
||||
}
|
||||
unittest_merged_report_xml = {
|
||||
"fullpath": mergedUnittestXMLFile.as_posix(),
|
||||
"directory": mergedUnittestXMLFile.parent.as_posix(),
|
||||
"filename": mergedUnittestXMLFile.name
|
||||
}
|
||||
coverage_report_html = {
|
||||
"fullpath": coverageHTMLDirectory.as_posix(),
|
||||
"directory": coverageHTMLDirectory.as_posix()
|
||||
}
|
||||
coverage_report_xml = {
|
||||
"fullpath": coverageXMLFile.as_posix(),
|
||||
"directory": coverageXMLFile.parent.as_posix(),
|
||||
"filename": coverageXMLFile.name
|
||||
}
|
||||
coverage_report_json = {
|
||||
"fullpath": coverageJSONFile.as_posix(),
|
||||
"directory": coverageJSONFile.parent.as_posix(),
|
||||
"filename": coverageJSONFile.name
|
||||
}
|
||||
typing_report_cobertura = {
|
||||
"fullpath": typingCoberturaFile.as_posix(),
|
||||
"directory": typingCoberturaFile.parent.as_posix(),
|
||||
"filename": typingCoberturaFile.name
|
||||
}
|
||||
typing_report_junit = {
|
||||
"fullpath": typingJUnitFile.as_posix(),
|
||||
"directory": typingJUnitFile.parent.as_posix(),
|
||||
"filename": typingJUnitFile.name
|
||||
}
|
||||
typing_report_html = {
|
||||
"fullpath": typingHTMLDirectory.as_posix(),
|
||||
"directory": typingHTMLDirectory.as_posix()
|
||||
}
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
coverage_report_html_directory={htmlDirectory.as_posix()}
|
||||
coverage_report_xml_directory={xmlFile.parent.as_posix()}
|
||||
coverage_report_xml={xmlFile.as_posix()}
|
||||
coverage_report_json_directory={jsonFile.parent.as_posix()}
|
||||
coverage_report_json={jsonFile.as_posix()}
|
||||
unittest_report_xml={json_dumps(unittest_report_xml)}
|
||||
unittest_merged_report_xml={json_dumps(unittest_merged_report_xml)}
|
||||
coverage_report_html={json_dumps(coverage_report_html)}
|
||||
coverage_report_xml={json_dumps(coverage_report_xml)}
|
||||
coverage_report_json={json_dumps(coverage_report_json)}
|
||||
typing_report_cobertura={json_dumps(typing_report_cobertura)}
|
||||
typing_report_junit={json_dumps(typing_report_junit)}
|
||||
typing_report_html={json_dumps(typing_report_html)}
|
||||
"""))
|
||||
|
||||
print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}")
|
||||
print(dedent(f"""\
|
||||
DEBUG:
|
||||
unittest xml: {unittestXMLFile}
|
||||
merged unittest xml: {mergedUnittestXMLFile}
|
||||
coverage html: {coverageHTMLDirectory}
|
||||
coverage xml: {coverageXMLFile}
|
||||
coverage json: {coverageJSONFile}
|
||||
typing cobertura: {typingCoberturaFile}
|
||||
typing junit: {typingJUnitFile}
|
||||
typing html: {typingHTMLDirectory}
|
||||
"""))
|
||||
|
||||
- name: Debug JSON objects
|
||||
run: |
|
||||
printf "unittest_report_xml: JSON=%s\n" "${{ steps.getVariables.outputs.unittest_report_xml }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_report_xml).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_report_xml).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_report_xml).filename }}"
|
||||
|
||||
printf "unittest_merged_report_xml: JSON=%s\n" "${{ steps.getVariables.outputs.unittest_merged_report_xml }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_merged_report_xml).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_merged_report_xml).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.unittest_merged_report_xml).filename }}"
|
||||
|
||||
printf "coverage_report_html: JSON=%s\n" "${{ steps.getVariables.outputs.coverage_report_html }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_html).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_html).directory }}"
|
||||
|
||||
printf "coverage_report_xml: JSON=%s\n" "${{ steps.getVariables.outputs.coverage_report_xml }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_xml).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_xml).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_xml).filename }}"
|
||||
|
||||
printf "coverage_report_json: JSON=%s\n" "${{ steps.getVariables.outputs.coverage_report_json }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_json).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_json).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.coverage_report_json).filename }}"
|
||||
|
||||
printf "typing_report_cobertura: JSON=%s\n" "${{ steps.getVariables.outputs.typing_report_cobertura }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_cobertura).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_cobertura).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_cobertura).filename }}"
|
||||
|
||||
printf "typing_report_junit: JSON=%s\n" "${{ steps.getVariables.outputs.typing_report_junit }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_junit).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_junit).directory }}"
|
||||
printf " filename: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_junit).filename }}"
|
||||
|
||||
printf "typing_report_html: JSON=%s\n" "${{ steps.getVariables.outputs.typing_report_html }}"
|
||||
printf " fullpath: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_html).fullpath }}"
|
||||
printf " directory: %s\n" "${{ fromJSON(steps.getVariables.outputs.typing_report_html).directory }}"
|
||||
|
||||
130
.github/workflows/InstallPackage.yml
vendored
Normal file
130
.github/workflows/InstallPackage.yml
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
# ==================================================================================================================== #
|
||||
# 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@v5
|
||||
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-markupsafe:p
|
||||
python-pyaml:p python-types-pyyaml:p
|
||||
python-ruamel-yaml:p python-ruamel.yaml.clib:p
|
||||
python-tomli:p
|
||||
|
||||
- name: 🐍 Setup Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v6
|
||||
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' && matrix.system != 'windows-arm' )
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check -U install/*.whl
|
||||
|
||||
- name: 🔧 Install wheel from artifact (Windows)
|
||||
if: ( matrix.system == 'windows' || matrix.system == 'windows-arm' )
|
||||
run: |
|
||||
python -m pip install -v --disable-pip-version-check (Get-Item .\install\*.whl).FullName
|
||||
|
||||
- name: 📦 Run Package Version Check (Ubuntu/macOS)
|
||||
if: ( matrix.system != 'windows' && matrix.system != 'windows-arm' )
|
||||
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 Package Version Check (Windows)
|
||||
if: ( matrix.system == 'windows' || matrix.system == 'windows-arm' )
|
||||
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
|
||||
}
|
||||
8
.github/workflows/IntermediateCleanUp.yml
vendored
8
.github/workflows/IntermediateCleanUp.yml
vendored
@@ -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. #
|
||||
@@ -30,12 +30,14 @@ on:
|
||||
default: '24.04'
|
||||
type: string
|
||||
sqlite_coverage_artifacts_prefix:
|
||||
description: 'Prefix for SQLite coverage artifacts'
|
||||
description: 'Prefix for SQLite coverage artifacts to be removed.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
xml_unittest_artifacts_prefix:
|
||||
description: 'Prefix for XML unittest artifacts'
|
||||
description: 'Prefix for XML unittest artifacts to be removed.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
|
||||
40
.github/workflows/LaTeXDocumentation.yml
vendored
40
.github/workflows/LaTeXDocumentation.yml
vendored
@@ -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. #
|
||||
@@ -29,43 +29,65 @@ on:
|
||||
required: false
|
||||
default: '24.04'
|
||||
type: string
|
||||
latex_artifact:
|
||||
description: 'Name of the LaTeX documentation artifact.'
|
||||
required: true
|
||||
type: string
|
||||
document:
|
||||
description: 'LaTeX root document without *.tex extension.'
|
||||
required: true
|
||||
type: string
|
||||
latex_artifact:
|
||||
description: 'Name of the LaTeX documentation artifact.'
|
||||
processor:
|
||||
description: 'Name of the used LaTeX processor.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'xelatex'
|
||||
type: string
|
||||
pdf_artifact:
|
||||
description: 'Name of the PDF documentation artifact.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
can-fail:
|
||||
description: 'Translation from LaTeX to PDF may fail.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
PDFDocumentation:
|
||||
name: 📓 Converting LaTeX Documentation to PDF
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
continue-on-error: ${{ inputs.can-fail == 'true' }}
|
||||
steps:
|
||||
- name: 📥 Download artifacts '${{ inputs.latex_artifact }}' from 'SphinxDocumentation' job
|
||||
uses: pyTooling/download-artifact@v4
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
name: ${{ inputs.latex_artifact }}
|
||||
path: latex
|
||||
|
||||
- name: Compile LaTeX document
|
||||
uses: xu-cheng/latex-action@master
|
||||
# - name: Debug
|
||||
# run: |
|
||||
# tree -pash .
|
||||
|
||||
- name: Build LaTeX document using 'pytooling/miktex:sphinx'
|
||||
uses: addnab/docker-run-action@v3
|
||||
if: inputs.pdf_artifact != ''
|
||||
with:
|
||||
working_directory: latex
|
||||
root_file: ${{ inputs.document }}.tex
|
||||
image: pytooling/miktex:sphinx
|
||||
options: -v ${{ github.workspace }}/latex:/latex --workdir /latex
|
||||
run: |
|
||||
# which ${{ inputs.processor }}
|
||||
# pwd
|
||||
# ls -lAh
|
||||
|
||||
latexmk -${{ inputs.processor }} "${{ inputs.document }}.tex"
|
||||
|
||||
- name: 📤 Upload 'PDF Documentation' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.pdf_artifact != ''
|
||||
with:
|
||||
name: ${{ inputs.pdf_artifact }}
|
||||
working-directory: latex
|
||||
path: ${{ inputs.document }}.pdf
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
331
.github/workflows/NightlyRelease.yml
vendored
331
.github/workflows/NightlyRelease.yml
vendored
@@ -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. #
|
||||
@@ -68,23 +68,43 @@ on:
|
||||
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
|
||||
|
||||
jobs:
|
||||
Release:
|
||||
name: 📝 Update 'Nightly Page' on GitHub
|
||||
runs-on: ${{ inputs.ubuntu_image }}
|
||||
continue-on-error: ${{ inputs.can-fail }}
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
actions: write
|
||||
# attestations: write
|
||||
|
||||
steps:
|
||||
- name: ⚠️ Deprecation Warning
|
||||
run: printf "::warning title=%s::%s\n" "NightlyRelease" "'NightlyRelease.yml' template is deprecated. Please switch to 'PublishReleaseNotes.yml'. See https://pytooling.github.io/Actions/JobTemplate/Release/PublishReleaseNotes.html"
|
||||
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
# The command 'git describe' (used for version) needs the history.
|
||||
fetch-depth: 0
|
||||
@@ -97,23 +117,23 @@ jobs:
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ANSI_LIGHT_RED="\e[91m"
|
||||
ANSI_LIGHT_GREEN="\e[92m"
|
||||
ANSI_LIGHT_YELLOW="\e[93m"
|
||||
ANSI_NOCOLOR="\e[0m"
|
||||
ANSI_LIGHT_RED=$'\x1b[91m'
|
||||
ANSI_LIGHT_GREEN=$'\x1b[92m'
|
||||
ANSI_LIGHT_YELLOW=$'\x1b[93m'
|
||||
ANSI_NOCOLOR=$'\x1b[0m'
|
||||
|
||||
export GH_TOKEN=${{ github.token }}
|
||||
|
||||
echo -n "Deleting release '${{ inputs.nightly_name }}' ... "
|
||||
printf "%s" "Deleting release '${{ inputs.nightly_name }}' ... "
|
||||
message="$(gh release delete ${{ inputs.nightly_name }} --yes 2>&1)"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
elif [[ "${message}" == "release not found" ]]; then
|
||||
echo -e "${ANSI_LIGHT_YELLOW}[NOT FOUND]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_YELLOW}[NOT FOUND]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=InternalError::Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'."
|
||||
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 "::error title=%s::%s\n" "InternalError" "Couldn't delete release '${{ inputs.nightly_name }}' -> Error: '${message}'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -122,19 +142,19 @@ jobs:
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ANSI_LIGHT_RED="\e[91m"
|
||||
ANSI_LIGHT_GREEN="\e[92m"
|
||||
ANSI_NOCOLOR="\e[0m"
|
||||
ANSI_LIGHT_RED=$'\x1b[91m'
|
||||
ANSI_LIGHT_GREEN=$'\x1b[92m'
|
||||
ANSI_NOCOLOR=$'\x1b[0m'
|
||||
|
||||
export GH_TOKEN=${{ github.token }}
|
||||
|
||||
addDraft="--draft"
|
||||
|
||||
if ${{ inputs.prerelease }}; then
|
||||
if [[ "${{ inputs.prerelease }}" == "true" ]]; then
|
||||
addPreRelease="--prerelease"
|
||||
fi
|
||||
|
||||
if ! ${{ inputs.latest }}; then
|
||||
if [[ "${{ inputs.latest }}" == "false" ]]; then
|
||||
addLatest="--latest=false"
|
||||
fi
|
||||
|
||||
@@ -163,17 +183,17 @@ jobs:
|
||||
cat <<EOF >> __NoTeS__.md
|
||||
|
||||
--------
|
||||
Published from [${{ github.workflow }}](https://github.com/Paebbels/ghdl/actions/runs/${{ github.run_id }}) workflow triggered by @${{ github.actor }} on $(date '+%Y-%m-%d %H:%M:%S').
|
||||
Published from [${{ github.workflow }}](https://github.com/Paebbels/ghdl/actions/runs/${{ github.run_id }}) workflow triggered by @${{ github.actor }} on $(date '+%Y-%m-%d %H:%M:%S %Z').
|
||||
EOF
|
||||
|
||||
echo "Creating release '${{ inputs.nightly_name }}' ... "
|
||||
printf "%s\n" "Creating release '${{ inputs.nightly_name }}' ... "
|
||||
message="$(gh release create "${{ inputs.nightly_name }}" --verify-tag $addDraft $addPreRelease $addLatest "${addTitle[@]}" "${addNotes[@]}" 2>&1)"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=InternalError::Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'."
|
||||
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 "::error title=%s::%s\n" "InternalError" "Couldn't create release '${{ inputs.nightly_name }}' -> Error: '${message}'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -182,10 +202,11 @@ jobs:
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ANSI_LIGHT_RED="\e[91m"
|
||||
ANSI_LIGHT_GREEN="\e[92m"
|
||||
ANSI_LIGHT_YELLOW="\e[93m"
|
||||
ANSI_NOCOLOR="\e[0m"
|
||||
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 }}
|
||||
|
||||
@@ -199,199 +220,293 @@ jobs:
|
||||
replacement="${patternLine#*=}"
|
||||
line="${line//"%$pattern%"/"$replacement"}"
|
||||
done <<<'${{ inputs.replacements }}'
|
||||
echo "$line"
|
||||
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.nightly_name }}" \
|
||||
--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.nightly_name }}" \
|
||||
--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}" == "" ]]; then
|
||||
if [[ "${assetLine}" == "" || "${assetLine:0:1}" == "#" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# split assetLine colon separated triple: artifact:asset:title
|
||||
artifact="${assetLine%%:*}"
|
||||
remaining="${assetLine#*:}"
|
||||
asset="${remaining%%:*}"
|
||||
title="${remaining##*:}"
|
||||
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}")"
|
||||
|
||||
echo "Publish asset '${asset}' from artifact '${artifact}' with title '${title}'"
|
||||
echo -n " Checked asset for duplicates ... "
|
||||
printf "%s\n" "Publish asset '${asset}' from artifact '${artifact}' with title '${title}'"
|
||||
printf " %s" "Checked asset for duplicates ... "
|
||||
if [[ -n "${assetFilenames[$asset]}" ]]; then
|
||||
echo -e "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo "::error title=DuplicateAsset::Asset '${asset}' from artifact '${artifact}' was already uploaded to release '${{ inputs.nightly_name }}'."
|
||||
ERRORS=1
|
||||
printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
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
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
assetFilenames[$asset]=1
|
||||
fi
|
||||
|
||||
# Download artifact by artifact name
|
||||
if [[ -n "${downloadedArtifacts[$artifact]}" ]]; then
|
||||
echo -e " downloading '${artifact}' ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}"
|
||||
printf " %s\n" "downloading '${artifact}' ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo " downloading '${artifact}' ... "
|
||||
echo -n " gh run download $GITHUB_RUN_ID --dir \"${artifact}\" --name \"${artifact}\" "
|
||||
printf " downloading '${artifact}' ...\n"
|
||||
printf " %s" "gh run download $GITHUB_RUN_ID --dir \"${artifact}\" --name \"${artifact}\" "
|
||||
gh run download $GITHUB_RUN_ID --dir "${artifact}" --name "${artifact}"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't download artifact '${artifact}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=ArtifactNotFound::Couldn't download artifact '${artifact}'."
|
||||
ERRORS=1
|
||||
printf "%s\n" "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
printf " %s\n" "${ANSI_LIGHT_RED}Couldn't download artifact '${artifact}'.${ANSI_NOCOLOR}"
|
||||
printf "::error title=%s::%s\n" "ArtifactNotFound" "Couldn't download artifact '${artifact}'."
|
||||
ERRORS=$((ERRORS + 1))
|
||||
continue
|
||||
fi
|
||||
downloadedArtifacts[$artifact]=1
|
||||
|
||||
echo -n " Checking for embedded tarball ... "
|
||||
printf " %s" "Checking for embedded tarball ... "
|
||||
if [[ -f "${artifact}/${{ inputs.tarball-name }}" ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[FOUND]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[FOUND]${ANSI_NOCOLOR}"
|
||||
|
||||
pushd "${artifact}" > /dev/null
|
||||
|
||||
echo -n " Extracting embedded tarball ... "
|
||||
printf " %s" "Extracting embedded tarball ... "
|
||||
tar -xf "${{ inputs.tarball-name }}"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
fi
|
||||
|
||||
echo -n " Removing temporary tarball ... "
|
||||
printf " %s" "Removing temporary tarball ... "
|
||||
rm -f "${{ inputs.tarball-name }}"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
fi
|
||||
|
||||
popd > /dev/null
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if artifact should be compressed (zip, tgz) or if asset was part of the downloaded artifact.
|
||||
echo -n " checking asset '${artifact}/${asset}' ... "
|
||||
printf " %s" "checking asset '${artifact}/${asset}' ... "
|
||||
if [[ "${asset}" == !*.zip ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[ZIP]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[ZIP]${ANSI_NOCOLOR}"
|
||||
asset="${asset##*!}"
|
||||
echo " Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
printf "::group:: %s\n" "Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
(
|
||||
cd "${artifact}" && \
|
||||
zip -r "../${asset}" *
|
||||
)
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
retCode=$?
|
||||
printf "::endgroup::\n"
|
||||
if [[ $retCode -eq 0 ]]; then
|
||||
printf " %s\n" "Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
uploadFile="${asset}"
|
||||
else
|
||||
echo -e " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to zip file '${asset}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=CompressionError::Couldn't compress '${artifact}' to zip file '${asset}'."
|
||||
ERRORS=1
|
||||
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 "::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
|
||||
echo -e "${ANSI_LIGHT_GREEN}[TAR/GZ]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[TAR/GZ]${ANSI_NOCOLOR}"
|
||||
|
||||
if [[ "${asset:0:1}" == "\$" ]]; then
|
||||
asset="${asset##*$}"
|
||||
dirName="${asset%.*}"
|
||||
echo " Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
tar -c --gzip --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" .
|
||||
printf " %s\n" "Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
tar -c --gzip --owner=0 --group=0 --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" .
|
||||
retCode=$?
|
||||
else
|
||||
asset="${asset##*!}"
|
||||
echo " Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
printf " %s\n" "Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
(
|
||||
cd "${artifact}" && \
|
||||
tar -c --gzip --file="../${asset}" *
|
||||
tar -c --gzip --owner=0 --group=0 --file="../${asset}" *
|
||||
)
|
||||
retCode=$?
|
||||
fi
|
||||
|
||||
if [[ $retCode -eq 0 ]]; then
|
||||
echo -e " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf " %s\n" "Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
uploadFile="${asset}"
|
||||
else
|
||||
echo -e " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to tgz file '${asset}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=CompressionError::Couldn't compress '${artifact}' to tgz file '${asset}'."
|
||||
ERRORS=1
|
||||
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 "::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
|
||||
echo -e "${ANSI_LIGHT_GREEN}[ZST]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[ZST]${ANSI_NOCOLOR}"
|
||||
|
||||
if [[ "${asset:0:1}" == "\$" ]]; then
|
||||
asset="${asset##*$}"
|
||||
dirName="${asset%.*}"
|
||||
echo " Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
tar -c --zstd --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" .
|
||||
printf " %s\n" "Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
tar -c --zstd --owner=0 --group=0 --file="${asset}" --directory="${artifact}" --transform "s|^\.|${dirName%.tar}|" .
|
||||
retCode=$?
|
||||
else
|
||||
asset="${asset##*!}"
|
||||
echo " Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
printf " %s\n" "Compressing artifact '${artifact}' to '${asset}' ..."
|
||||
(
|
||||
cd "${artifact}" && \
|
||||
tar -c --zstd --file="../${asset}" *
|
||||
tar -c --zstd --owner=0 --group=0 --file="../${asset}" *
|
||||
)
|
||||
retCode=$?
|
||||
fi
|
||||
|
||||
if [[ $retCode -eq 0 ]]; then
|
||||
echo -e " Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf " %s\n" "Compression ${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
uploadFile="${asset}"
|
||||
else
|
||||
echo -e " Compression ${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't compress '${artifact}' to zst file '${asset}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=CompressionError::Couldn't compress '${artifact}' to zst file '${asset}'."
|
||||
ERRORS=1
|
||||
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 "::error title=%s::%s\n" "CompressionError" "Couldn't compress '${artifact}' to zst file '${asset}'."
|
||||
ERRORS=$((ERRORS + 1))
|
||||
continue
|
||||
fi
|
||||
elif [[ -e "${artifact}/${asset}" ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
uploadFile="${artifact}/${asset}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't find asset '${asset}' in artifact '${artifact}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=FileNotFound::Couldn't find asset '${asset}' in artifact '${artifact}'."
|
||||
ERRORS=1
|
||||
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 "::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 " %s\n" "adding file '${uploadFile#*/}' with '${categories//;/ → }' to JSON inventory ..."
|
||||
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 " %s\n" "adding file '${uploadFile#*/}' to JSON inventory ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Upload asset to existing release page
|
||||
echo -n " uploading asset '${asset}' from '${uploadFile}' with title '${title}' ... "
|
||||
printf " %s" "uploading asset '${asset}' from '${uploadFile}' with title '${title}' ... "
|
||||
gh release upload ${{ inputs.nightly_name }} "${uploadFile}#${title}" --clobber
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=UploadError::Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'."
|
||||
ERRORS=1
|
||||
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 "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${asset}' from '${uploadFile}' to release '${{ inputs.nightly_name }}'."
|
||||
ERRORS=$((ERRORS + 1))
|
||||
continue
|
||||
fi
|
||||
done <<<'${{ inputs.assets }}'
|
||||
|
||||
echo "Inspecting downloaded artifacts ..."
|
||||
tree -L 3 .
|
||||
if [[ "${{ inputs.inventory-json }}" != "" ]]; then
|
||||
inventoryTitle="Release Inventory (JSON)"
|
||||
|
||||
if [[ $ERROR -ne 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_RED}Errors detected in previous steps.${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "Publish asset '${{ inputs.inventory-json }}' with title '${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 " %s" "uploading asset '${{ inputs.inventory-json }}' title '${inventoryTitle}' ... "
|
||||
gh release upload ${{ inputs.nightly_name }} "${{ inputs.inventory-json }}#${inventoryTitle}" --clobber
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
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 "::error title=%s::%s\n" "UploadError" "Couldn't upload asset '${{ inputs.inventory-json }}' to release '${{ inputs.nightly_name }}'."
|
||||
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 "%s\n" "${ANSI_LIGHT_RED}${ERRORS} errors detected in previous steps.${ANSI_NOCOLOR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -400,19 +515,19 @@ jobs:
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ANSI_LIGHT_RED="\e[91m"
|
||||
ANSI_LIGHT_GREEN="\e[92m"
|
||||
ANSI_NOCOLOR="\e[0m"
|
||||
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
|
||||
echo -n "Remove draft-state from release '${title}' ... "
|
||||
printf "%s" "Remove draft-state from release '${title}' ... "
|
||||
gh release edit --draft=false "${{ inputs.nightly_name }}"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
printf "%s\n" "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}"
|
||||
else
|
||||
echo -e "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}"
|
||||
echo -e "${ANSI_LIGHT_RED}Couldn't remove draft-state from release '${{ inputs.nightly_name }}'.${ANSI_NOCOLOR}"
|
||||
echo "::error title=ReleasePage::Couldn't remove draft-state from release '${{ inputs.nightly_name }}'."
|
||||
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 "::error title=%s::%s\n" "ReleasePage" "Couldn't remove draft-state from release '${{ inputs.nightly_name }}'."
|
||||
fi
|
||||
|
||||
18
.github/workflows/Package.yml
vendored
18
.github/workflows/Package.yml
vendored
@@ -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. #
|
||||
@@ -33,7 +33,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
requirements:
|
||||
description: 'Python dependencies to be installed through pip; if empty, use pyproject.toml through build.'
|
||||
@@ -46,20 +46,20 @@ on:
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
|
||||
Package:
|
||||
name: 📦 Package in Source and Wheel Format
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
|
||||
env:
|
||||
artifact: ${{ inputs.artifact }}
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -79,15 +79,15 @@ jobs:
|
||||
|
||||
# build (not isolated)
|
||||
|
||||
- name: 🔧 [build] Install dependencies for packaging and release
|
||||
- name: 🔧 [build - no-isolation] Install dependencies for packaging and release
|
||||
if: inputs.requirements == 'no-isolation'
|
||||
run: python -m pip install --disable-pip-version-check build
|
||||
|
||||
- name: 🔨 [build] Build Python package (source distribution)
|
||||
- name: 🔨 [build - no-isolation] Build Python package (source distribution)
|
||||
if: inputs.requirements == 'no-isolation'
|
||||
run: python -m build --no-isolation --sdist
|
||||
|
||||
- name: 🔨 [build] Build Python package (binary distribution - wheel)
|
||||
- name: 🔨 [build - no-isolation] Build Python package (binary distribution - wheel)
|
||||
if: inputs.requirements == 'no-isolation'
|
||||
run: python -m build --no-isolation --wheel
|
||||
|
||||
|
||||
232
.github/workflows/Parameters.yml
vendored
232
.github/workflows/Parameters.yml
vendored
@@ -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. #
|
||||
@@ -58,7 +58,7 @@ on:
|
||||
system_list:
|
||||
description: 'Space separated list of systems to run tests on.'
|
||||
required: false
|
||||
default: 'ubuntu windows macos macos-arm mingw64 ucrt64'
|
||||
default: 'ubuntu ubuntu-arm windows windows-arm macos macos-arm mingw64 ucrt64'
|
||||
type: string
|
||||
include_list:
|
||||
description: 'Space separated list of system:python items to be included into the list of test.'
|
||||
@@ -68,22 +68,32 @@ on:
|
||||
exclude_list:
|
||||
description: 'Space separated list of system:python items to be excluded from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:3.9 windows-arm:3.10'
|
||||
type: string
|
||||
disable_list:
|
||||
description: 'Space separated list of system:python items to be disabled from the list of test.'
|
||||
required: false
|
||||
default: ''
|
||||
default: 'windows-arm:pypy-3.10 windows-arm:pypy-3.11'
|
||||
type: string
|
||||
ubuntu_image:
|
||||
description: 'The used GitHub Action image for Ubuntu based jobs.'
|
||||
description: 'The used GitHub Action image for Ubuntu (x86-64) based jobs.'
|
||||
required: false
|
||||
default: 'ubuntu-24.04'
|
||||
type: string
|
||||
windows_image:
|
||||
description: 'The used GitHub Action image for Windows based jobs.'
|
||||
ubuntu_arm_image:
|
||||
description: 'The used GitHub Action image for Ubuntu (aarch64) based jobs.'
|
||||
required: false
|
||||
default: 'windows-2022'
|
||||
default: 'ubuntu-24.04-arm'
|
||||
type: string
|
||||
windows_image:
|
||||
description: 'The used GitHub Action image for Windows Server (x86-64) based jobs.'
|
||||
required: false
|
||||
default: 'windows-2025'
|
||||
type: string
|
||||
windows_arm_image:
|
||||
description: 'The used GitHub Action image for Windows (aarch64) based jobs.'
|
||||
required: false
|
||||
default: 'windows-11-arm'
|
||||
type: string
|
||||
macos_intel_image:
|
||||
description: 'The used GitHub Action image for macOS (Intel x86-64) based jobs.'
|
||||
@@ -93,36 +103,145 @@ on:
|
||||
macos_arm_image:
|
||||
description: 'The used GitHub Action image for macOS (ARM aarch64) based jobs.'
|
||||
required: false
|
||||
default: 'macos-14'
|
||||
default: 'macos-15'
|
||||
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:
|
||||
description: "Default Python version for other jobs."
|
||||
value: ${{ jobs.Parameters.outputs.python_version }}
|
||||
python_jobs:
|
||||
description: "List of Python versions (and system combinations) to be used in the matrix of other jobs."
|
||||
value: ${{ jobs.Parameters.outputs.python_jobs }}
|
||||
package_fullname:
|
||||
description: "The package's full name."
|
||||
value: ${{ jobs.Parameters.outputs.package_fullname }}
|
||||
package_directory:
|
||||
description: "The package's directory."
|
||||
value: ${{ jobs.Parameters.outputs.package_directory }}
|
||||
artifact_basename:
|
||||
description: "Artifact base name."
|
||||
value: ${{ jobs.Parameters.outputs.artifact_basename }}
|
||||
artifact_names:
|
||||
description: "Pre-defined artifact names for other jobs."
|
||||
value: ${{ jobs.Parameters.outputs.artifact_names }}
|
||||
params:
|
||||
description: "Parameters to be used in other jobs."
|
||||
value: ${{ jobs.Parameters.outputs.params }}
|
||||
python_jobs:
|
||||
description: "List of Python versions (and system combinations) to be used in the matrix of other jobs."
|
||||
value: ${{ jobs.Parameters.outputs.python_jobs }}
|
||||
|
||||
jobs:
|
||||
Parameters:
|
||||
name: ✎ Generate pipeline parameters
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
outputs:
|
||||
python_version: ${{ steps.params.outputs.python_version }}
|
||||
python_jobs: ${{ steps.params.outputs.python_jobs }}
|
||||
artifact_names: ${{ steps.params.outputs.artifact_names }}
|
||||
params: ${{ steps.params.outputs.params }}
|
||||
python_version: ${{ steps.variables.outputs.python_version }}
|
||||
package_fullname: ${{ steps.variables.outputs.package_fullname }}
|
||||
package_directory: ${{ steps.variables.outputs.package_directory }}
|
||||
artifact_basename: ${{ steps.variables.outputs.artifact_basename }}
|
||||
artifact_names: ${{ steps.artifacts.outputs.artifact_names }}
|
||||
python_jobs: ${{ steps.jobs.outputs.python_jobs }}
|
||||
|
||||
steps:
|
||||
- name: Generate 'params' and 'python_jobs'
|
||||
id: params
|
||||
- name: Generate a startup delay of ${{ inputs.pipeline-delay }} seconds
|
||||
id: delay
|
||||
if: inputs.pipeline-delay >= 0
|
||||
run: |
|
||||
sleep ${{ inputs.pipeline-delay }}
|
||||
|
||||
- name: Generate 'python_version'
|
||||
id: variables
|
||||
shell: python
|
||||
run: |
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from sys import exit
|
||||
from textwrap import dedent
|
||||
|
||||
python_version = "${{ inputs.python_version }}".strip()
|
||||
package_namespace = "${{ inputs.package_namespace }}".strip()
|
||||
package_name = "${{ inputs.package_name }}".strip()
|
||||
name = "${{ inputs.name }}".strip()
|
||||
|
||||
if package_namespace == "": # or package_namespace == ".":
|
||||
package_fullname = package_name
|
||||
package_directory = package_name
|
||||
elif package_namespace[-2:] == ".*":
|
||||
package_fullname = package_namespace[:-2]
|
||||
package_directory = package_namespace[:-2]
|
||||
else:
|
||||
package_fullname = f"{package_namespace}.{package_name}"
|
||||
package_directory = f"{package_namespace}/{package_name}"
|
||||
|
||||
artifact_basename = package_fullname if name == "" else name
|
||||
if artifact_basename == "" or artifact_basename == ".":
|
||||
print("::error title=Parameter::artifact_basename is empty.")
|
||||
exit(1)
|
||||
|
||||
print("Variables:")
|
||||
print(f" python_version: {python_version}")
|
||||
print(f" package_fullname: {package_fullname}")
|
||||
print(f" package_directory: {package_directory}")
|
||||
print(f" artifact_basename: {artifact_basename}")
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
python_version={python_version}
|
||||
package_fullname={package_fullname}
|
||||
package_directory={package_directory}
|
||||
artifact_basename={artifact_basename}
|
||||
"""))
|
||||
|
||||
- name: Generate 'artifact_names'
|
||||
id: artifacts
|
||||
shell: python
|
||||
run: |
|
||||
from json import dumps as json_dumps
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
|
||||
package_namespace = "${{ inputs.package_namespace }}".strip()
|
||||
package_name = "${{ inputs.package_name }}".strip()
|
||||
artifact_basename = "${{ steps.variables.outputs.artifact_basename }}"
|
||||
|
||||
artifact_names = {
|
||||
"unittesting_xml": f"{artifact_basename}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{artifact_basename}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{artifact_basename}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{artifact_basename}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{artifact_basename}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{artifact_basename}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{artifact_basename}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{artifact_basename}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{artifact_basename}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{artifact_basename}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{artifact_basename}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{artifact_basename}-StaticTyping-HTML",
|
||||
"package_all": f"{artifact_basename}-Packages",
|
||||
"documentation_html": f"{artifact_basename}-Documentation-HTML",
|
||||
"documentation_latex": f"{artifact_basename}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{artifact_basename}-Documentation-PDF",
|
||||
}
|
||||
|
||||
print("Artifacts Names ({len(artifact_names)}):")
|
||||
for id, artifactName in artifact_names.items():
|
||||
print(f" {id:>24}: {artifactName}")
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
artifact_names={json_dumps(artifact_names)}
|
||||
"""))
|
||||
|
||||
- name: Generate 'python_jobs'
|
||||
id: jobs
|
||||
shell: python
|
||||
run: |
|
||||
from json import dumps as json_dumps
|
||||
@@ -131,25 +250,17 @@ jobs:
|
||||
from textwrap import dedent
|
||||
from typing import Iterable
|
||||
|
||||
package_namespace = "${{ inputs.package_namespace }}".strip()
|
||||
package_name = "${{ inputs.package_name }}".strip()
|
||||
name = "${{ inputs.name }}".strip()
|
||||
python_version = "${{ inputs.python_version }}".strip()
|
||||
python_version = "${{ steps.variables.outputs.python_version }}"
|
||||
name = "${{ steps.variables.outputs.artifact_basename }}"
|
||||
systems = "${{ inputs.system_list }}".strip()
|
||||
versions = "${{ inputs.python_version_list }}".strip()
|
||||
include_list = "${{ inputs.include_list }}".strip()
|
||||
exclude_list = "${{ inputs.exclude_list }}".strip()
|
||||
disable_list = "${{ inputs.disable_list }}".strip()
|
||||
|
||||
if name == "":
|
||||
if package_namespace == "" or package_namespace == ".":
|
||||
name = f"{package_name}"
|
||||
else:
|
||||
name = f"{package_namespace}.{package_name}"
|
||||
|
||||
currentMSYS2Version = "3.11"
|
||||
currentMSYS2Version = "3.12"
|
||||
currentAlphaVersion = "3.14"
|
||||
currentAlphaRelease = "3.14.0-alpha.1"
|
||||
currentAlphaRelease = "3.14.0-rc.3"
|
||||
|
||||
if systems == "":
|
||||
print("::error title=Parameter::system_list is empty.")
|
||||
@@ -183,7 +294,7 @@ jobs:
|
||||
if currentAlphaVersion in versions:
|
||||
print(f"::notice title=Experimental::Python {currentAlphaVersion} ({currentAlphaRelease}) is a pre-release.")
|
||||
for disable in disabled:
|
||||
print(f"::warning title=Disabled Python Job::System '{disable}' temporarily disabled.")
|
||||
print(f"::warning title=Disabled Python Job::{name}: Job combination '{disable}' temporarily disabled.")
|
||||
|
||||
# see https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
|
||||
data = {
|
||||
@@ -197,16 +308,19 @@ jobs:
|
||||
"3.13": { "icon": "🟢", "until": "2029.10" },
|
||||
"3.14": { "icon": "🟣", "until": "2030.10" },
|
||||
"pypy-3.7": { "icon": "⟲⚫", "until": "????.??" },
|
||||
"pypy-3.8": { "icon": "⟲🔴", "until": "????.??" },
|
||||
"pypy-3.9": { "icon": "⟲🟠", "until": "????.??" },
|
||||
"pypy-3.10": { "icon": "⟲🟡", "until": "????.??" },
|
||||
"pypy-3.8": { "icon": "⟲⚫", "until": "????.??" },
|
||||
"pypy-3.9": { "icon": "⟲🔴", "until": "????.??" },
|
||||
"pypy-3.10": { "icon": "⟲🟠", "until": "????.??" },
|
||||
"pypy-3.11": { "icon": "⟲🟡", "until": "????.??" },
|
||||
},
|
||||
# Runner systems (runner images) supported by GitHub Actions
|
||||
"sys": {
|
||||
"ubuntu": { "icon": "🐧", "runs-on": "${{ inputs.ubuntu_image }}", "shell": "bash", "name": "Linux (x86-64)" },
|
||||
"windows": { "icon": "🪟", "runs-on": "${{ inputs.windows_image }}", "shell": "pwsh", "name": "Windows (x86-64)" },
|
||||
"macos": { "icon": "🍎", "runs-on": "${{ inputs.macos_intel_image }}", "shell": "bash", "name": "macOS (x86-64)" },
|
||||
"macos-arm": { "icon": "🍏", "runs-on": "${{ inputs.macos_arm_image }}", "shell": "bash", "name": "macOS (aarch64)" },
|
||||
"ubuntu": { "icon": "🐧", "runs-on": "${{ inputs.ubuntu_image }}", "shell": "bash", "name": "Linux (x86-64)" },
|
||||
"ubuntu-arm": { "icon": "⛄", "runs-on": "${{ inputs.ubuntu_arm_image }}", "shell": "bash", "name": "Linux (aarch64)" },
|
||||
"windows": { "icon": "🪟", "runs-on": "${{ inputs.windows_image }}", "shell": "pwsh", "name": "Windows (x86-64)" },
|
||||
"windows-arm": { "icon": "🏢", "runs-on": "${{ inputs.windows_arm_image }}", "shell": "pwsh", "name": "Windows (aarch64)" },
|
||||
"macos": { "icon": "🍎", "runs-on": "${{ inputs.macos_intel_image }}", "shell": "bash", "name": "macOS (x86-64)" },
|
||||
"macos-arm": { "icon": "🍏", "runs-on": "${{ inputs.macos_arm_image }}", "shell": "bash", "name": "macOS (aarch64)" },
|
||||
},
|
||||
# Runtimes provided by MSYS2
|
||||
"runtime": {
|
||||
@@ -288,7 +402,7 @@ jobs:
|
||||
{
|
||||
"sysicon": data["runtime"][runtime]["icon"],
|
||||
"system": "msys2",
|
||||
"runs-on": "windows-latest",
|
||||
"runs-on": "${{ inputs.windows_image }}",
|
||||
"runtime": runtime.upper(),
|
||||
"shell": "msys2 {0}",
|
||||
"pyicon": data["python"][currentMSYS2Version]["icon"],
|
||||
@@ -298,31 +412,11 @@ jobs:
|
||||
for runtime, version in combinations if runtime not in data["sys"]
|
||||
]
|
||||
|
||||
artifact_names = {
|
||||
"unittesting_xml": f"{name}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{name}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{name}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{name}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{name}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{name}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{name}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{name}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{name}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{name}-StaticTyping-HTML",
|
||||
"package_all": f"{name}-Packages",
|
||||
"documentation_html": f"{name}-Documentation-HTML",
|
||||
"documentation_latex": f"{name}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{name}-Documentation-PDF",
|
||||
}
|
||||
|
||||
print("Parameters:")
|
||||
print(f" python_version: {python_version}")
|
||||
print(f" python_jobs ({len(jobs)}):\n" +
|
||||
"".join([f" {{ " + ", ".join([f"\"{key}\": \"{value}\"" for key, value in job.items()]) + f" }},\n" for job in jobs])
|
||||
)
|
||||
print(f" artifact_names ({len(artifact_names)}):")
|
||||
for id, name in artifact_names.items():
|
||||
print(f" {id:>20}: {name}")
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
@@ -331,13 +425,17 @@ jobs:
|
||||
f.write(dedent(f"""\
|
||||
python_version={python_version}
|
||||
python_jobs={json_dumps(jobs)}
|
||||
artifact_names={json_dumps(artifact_names)}
|
||||
"""))
|
||||
|
||||
- name: Verify out parameters
|
||||
id: verify
|
||||
run: |
|
||||
echo 'python_version: ${{ steps.params.outputs.python_version }}'
|
||||
echo 'python_jobs: ${{ steps.params.outputs.python_jobs }}'
|
||||
echo 'artifact_names: ${{ steps.params.outputs.artifact_names }}'
|
||||
echo 'params: ${{ steps.params.outputs.params }}'
|
||||
printf "python_version: %s\n" '${{ steps.variables.outputs.python_version }}'
|
||||
printf "package_fullname: %s\n" '${{ steps.variables.outputs.package_fullname }}'
|
||||
printf "package_directory: %s\n" '${{ steps.variables.outputs.package_directory }}'
|
||||
printf "artifact_basename: %s\n" '${{ steps.variables.outputs.artifact_basename }}'
|
||||
printf "====================\n"
|
||||
printf "artifact_names: %s\n" '${{ steps.artifacts.outputs.artifact_names }}'
|
||||
printf "====================\n"
|
||||
printf "python_jobs: %s\n" '${{ steps.jobs.outputs.python_jobs }}'
|
||||
printf "====================\n"
|
||||
|
||||
424
.github/workflows/PrepareJob.yml
vendored
Normal file
424
.github/workflows/PrepareJob.yml
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
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 and nightly builds.'
|
||||
required: false
|
||||
default: 'main'
|
||||
type: string
|
||||
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
|
||||
|
||||
outputs:
|
||||
on_default_branch:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.on_default_branch }}
|
||||
on_main_branch:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.on_main_branch }}
|
||||
on_release_branch:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.on_release_branch }}
|
||||
on_dev_branch:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.on_dev_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 }}
|
||||
is_nightly_tag:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.is_nightly_tag }}
|
||||
is_release_tag:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.is_release_tag }}
|
||||
has_submodules:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.has_submodules }}
|
||||
ref_kind:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.ref_kind }}
|
||||
default_branch:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.default_branch }}
|
||||
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 }}
|
||||
git_submodule_count:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.git_submodule_count }}
|
||||
git_submodule_names:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.git_submodule_names }}
|
||||
git_submodule_paths:
|
||||
description: ""
|
||||
value: ${{ jobs.Prepare.outputs.git_submodule_paths }}
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
name: Extract Information
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
on_default_branch: ${{ steps.Classify.outputs.on_default_branch }}
|
||||
on_main_branch: ${{ steps.Classify.outputs.on_main_branch }}
|
||||
on_release_branch: ${{ steps.Classify.outputs.on_release_branch }}
|
||||
on_dev_branch: ${{ steps.Classify.outputs.on_dev_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 }}
|
||||
is_nightly_tag: ${{ steps.Classify.outputs.is_nightly_tag }}
|
||||
is_release_tag: ${{ steps.Classify.outputs.is_release_tag }}
|
||||
has_submodules: ${{ steps.Classify.outputs.has_submodules }}
|
||||
ref_kind: ${{ steps.Classify.outputs.ref_kind }}
|
||||
default_branch: ${{ steps.Classify.outputs.default_branch }}
|
||||
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.Classify.outputs.pr_number || steps.FindPullRequest.outputs.pr_number }}
|
||||
git_submodule_count: ${{ steps.Classify.outputs.git_submodule_count }}
|
||||
git_submodule_names: ${{ steps.Classify.outputs.git_submodule_names }}
|
||||
git_submodule_paths: ${{ steps.Classify.outputs.git_submodule_paths }}
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
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'
|
||||
|
||||
export GH_TOKEN=${{ github.token }}
|
||||
|
||||
ref="${{ github.ref }}"
|
||||
on_default_branch="false"
|
||||
on_main_branch="false"
|
||||
on_release_branch="false"
|
||||
on_dev_branch="false"
|
||||
is_regular_commit="false"
|
||||
is_merge_commit="false"
|
||||
is_release_commit="false"
|
||||
is_nightly_tag="false"
|
||||
is_release_tag="false"
|
||||
has_submodules="false"
|
||||
ref_kind="unknown"
|
||||
default_branch=""
|
||||
branch=""
|
||||
tag=""
|
||||
pr_number=""
|
||||
version=""
|
||||
git_submodule_count="0"
|
||||
git_submodule_names=""
|
||||
git_submodule_paths=""
|
||||
|
||||
printf "Classify Git reference '%s' " "${ref}"
|
||||
if [[ "${ref:0:11}" == "refs/heads/" ]]; then
|
||||
printf "${ANSI_LIGHT_GREEN}[BRANCH]\n"
|
||||
ref_kind="branch"
|
||||
branch="${ref:11}"
|
||||
|
||||
printf "Get default branch name ... "
|
||||
defaultBranch=$(gh repo view "${{ github.repository }}" --json defaultBranchRef --jq '.defaultBranchRef.name' 2>&1)
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "${ANSI_LIGHT_GREEN} [OK]\n"
|
||||
|
||||
default_branch="${defaultBranch}"
|
||||
printf " default_branch=%s\n" "${default_branch}"
|
||||
else
|
||||
printf "${ANSI_LIGHT_RED} [FAILED]\n"
|
||||
printf " %s\n" "${default_branch}"
|
||||
fi
|
||||
|
||||
printf "Commit checks:\n"
|
||||
printf " Commit kind "
|
||||
if [[ -z "$(git rev-list -1 --merges ${{ github.sha }}~1..${{ github.sha }})" ]]; then
|
||||
is_regular_commit="true"
|
||||
printf "${ANSI_LIGHT_YELLOW}[REGULAR]${ANSI_NOCOLOR}\n"
|
||||
else
|
||||
is_merge_commit="true"
|
||||
printf "${ANSI_LIGHT_GREEN}[MERGE]${ANSI_NOCOLOR}\n"
|
||||
fi
|
||||
|
||||
printf "Branch checks:\n"
|
||||
if [[ "${branch}" == "${defaultBranch}" ]]; then
|
||||
on_default_branch="true"
|
||||
printf " Commit on default branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${defaultBranch}"
|
||||
fi
|
||||
|
||||
if [[ "${branch}" == "${{ inputs.main_branch }}" ]]; then
|
||||
on_main_branch="true"
|
||||
printf " Commit on main branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.main_branch }}"
|
||||
fi
|
||||
|
||||
if [[ "${branch}" == "${{ inputs.release_branch }}" ]]; then
|
||||
on_release_branch="true"
|
||||
printf " Commit on release branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.release_branch }}"
|
||||
fi
|
||||
|
||||
if [[ "${branch}" == "${{ inputs.development_branch }}" ]]; then
|
||||
on_dev_branch="true"
|
||||
printf " Commit on development branch ${ANSI_LIGHT_BLUE}'%s'${ANSI_NOCOLOR}\n" "${{ inputs.development_branch }}"
|
||||
fi
|
||||
|
||||
if [[ "${is_merge_commit}" == "true" ]]; then
|
||||
printf "Release checks:\n"
|
||||
printf " Release kind "
|
||||
if [[ "${on_main_branch}" == "true" ]]; then
|
||||
is_release_commit="true"
|
||||
printf "${ANSI_LIGHT_GREEN}[RELEASE]${ANSI_NOCOLOR}\n"
|
||||
elif [[ "${on_version_branch}" == "true" ]]; then
|
||||
is_release_commit="true"
|
||||
printf "${ANSI_LIGHT_GREEN}[RELEASE]${ANSI_NOCOLOR}\n"
|
||||
elif [[ "${on_release_branch}" == "true" ]]; then
|
||||
is_prerelease_commit="true"
|
||||
printf "${ANSI_LIGHT_YELLOW}[PRERELEASE]${ANSI_NOCOLOR}\n"
|
||||
fi
|
||||
fi
|
||||
elif [[ "${ref:0:10}" == "refs/tags/" ]]; then
|
||||
printf "${ANSI_LIGHT_GREEN}[TAG]\n"
|
||||
ref_kind="tag"
|
||||
tag="${ref:10}"
|
||||
|
||||
printf "Tag checks:\n"
|
||||
printf " Check if tag is on main branch '%s' ... " "${{ inputs.main_branch }}"
|
||||
git branch --remotes --contains $(git rev-parse --verify "tags/${tag}~0") | grep "origin/${{ inputs.main_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.main_branch }}"
|
||||
printf "::error title=TagCheck::Tag '%s' isn't on branch '%s'.\n" "${tag}" "${{ inputs.main_branch }}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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${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
|
||||
elif [[ "${ref:0:10}" == "refs/pull/" ]]; then
|
||||
printf "${ANSI_LIGHT_YELLOW}[PULL REQUEST]\n"
|
||||
ref_kind="pullrequest"
|
||||
pr_number=${ref:11}
|
||||
pr_number=${pr_number%%/*}
|
||||
|
||||
printf "Pull Request checks:\n"
|
||||
printf " Number: %s\n" "${pr_number}"
|
||||
else
|
||||
printf "${ANSI_LIGHT_RED}[UNKNOWN]\n"
|
||||
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
|
||||
|
||||
# Submodules
|
||||
if [[ -f .gitsubmodules ]]; then
|
||||
has_submodules="true"
|
||||
git_modules_file=.gitmodules # $(git rev-parse --show-toplevel)/.gitmodules
|
||||
git_submodule_count="$(grep -Po '(?<=\[submodule \")(.*)(?=\"\])' "${git_modules_file}" | wc -l)"
|
||||
git_submodule_names="$(grep -Po '(?<=\[submodule \")(.*)(?=\"\])' "${git_modules_file}" | paste -sd ':' -)"
|
||||
git_submodule_paths="$(git config --file "${git_modules_file}" --null --name-only --get-regexp '\.path$' | xargs -0 -n1 git config --file "${git_modules_file}" --get | paste -sd ':' -)"
|
||||
fi
|
||||
|
||||
printf "\nWriting output variables ...\n"
|
||||
tee --append "${GITHUB_OUTPUT}" <<EOF
|
||||
on_default_branch=${on_default_branch}
|
||||
on_main_branch=${on_main_branch}
|
||||
on_release_branch=${on_release_branch}
|
||||
on_dev_branch=${on_dev_branch}
|
||||
is_regular_commit=${is_regular_commit}
|
||||
is_merge_commit=${is_merge_commit}
|
||||
is_release_commit=${is_release_commit}
|
||||
is_nightly_tag=${is_nightly_tag}
|
||||
is_release_tag=${is_release_tag}
|
||||
has_submodules=${has_submodules}
|
||||
ref_kind=${ref_kind}
|
||||
default_branch=${default_branch}
|
||||
branch=${branch}
|
||||
tag=${tag}
|
||||
pr_number=${pr_number}
|
||||
version=${version}
|
||||
git_submodule_count=${git_submodule_count}
|
||||
git_submodule_names=${git_submodule_names}
|
||||
git_submodule_paths=${git_submodule_paths}
|
||||
EOF
|
||||
|
||||
# TODO: why not is_release_commit?
|
||||
# TODO: how to support version branches and hotfix releases on version branches?
|
||||
|
||||
- name: 🔁 Find merged PullRequest from second parent of current SHA (${{ github.sha }})
|
||||
id: FindPullRequest
|
||||
if: steps.Classify.outputs.is_merge_commit == 'true'
|
||||
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 }}
|
||||
|
||||
printf "Read second parent of current SHA (%s) ... " "${{ github.ref }}"
|
||||
FATHER_SHA=$(git rev-parse ${{ github.ref }}^2)
|
||||
if [[ $? -ne 0 || "{FATHER_SHA}" == "" ]]; then
|
||||
printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n"
|
||||
printf "${ANSI_LIGHT_RED}Couldn't read second parent (father) of '%s'.${ANSI_NOCOLOR}\n" "${{ github.ref }}^2"
|
||||
printf "::error title=GitCommitHistoryError::Couldn't read second parent (father) of '%s'. -> %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
|
||||
|
||||
RELEASE_TAG_PATTERN='^${{ inputs.release_tag_pattern }}$'
|
||||
printf "Check Pull Request title against regexp '%s' ... " "${RELEASE_TAG_PATTERN}"
|
||||
if [[ "${PR_TITLE}" =~ $RELEASE_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}" "${RELEASE_TAG_PATTERN}"
|
||||
printf "::error title=RexExpCheck::Pull Request title '%s' doesn't conform to regexp '%s'.\n" "${PR_TITLE}" "${RELEASE_TAG_PATTERN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf "Release tag: ${ANSI_LIGHT_GREEN}%s${ANSI_NOCOLOR}\n" "${RELEASE_VERSION}"
|
||||
tee --append "${GITHUB_OUTPUT}" <<EOF
|
||||
pr_version=${RELEASE_VERSION}
|
||||
pr_title=${PR_TITLE}
|
||||
pr_number=${PR_NUMBER}
|
||||
pr_mergedby=${PR_MERGED_BY}
|
||||
pr_mergedat=${PR_MERGED_AT}
|
||||
EOF
|
||||
|
||||
- name: Debug
|
||||
run: |
|
||||
printf "on_default_branch: %s\n" "${{ steps.Classify.outputs.on_default_branch }}"
|
||||
printf "on_main_branch: %s\n" "${{ steps.Classify.outputs.on_main_branch }}"
|
||||
printf "on_release_branch: %s\n" "${{ steps.Classify.outputs.on_release_branch }}"
|
||||
printf "on_dev_branch: %s\n" "${{ steps.Classify.outputs.on_dev_branch }}"
|
||||
printf "is_regular_commit: %s\n" "${{ steps.Classify.outputs.is_regular_commit }}"
|
||||
printf "is_merge_commit: %s\n" "${{ steps.Classify.outputs.is_merge_commit }}"
|
||||
printf "is_release_commit: %s\n" "${{ steps.Classify.outputs.is_release_commit }}"
|
||||
printf "is_nightly_tag: %s\n" "${{ steps.Classify.outputs.is_nightly_tag }}"
|
||||
printf "is_release_tag: %s\n" "${{ steps.Classify.outputs.is_release_tag }}"
|
||||
printf "has_submodules: %s\n" "${{ steps.Classify.outputs.has_submodules }}"
|
||||
printf "ref_kind: %s\n" "${{ steps.Classify.outputs.ref_kind }}"
|
||||
printf "default_branch: %s\n" "${{ steps.Classify.outputs.default_branch }}"
|
||||
printf "branch: %s\n" "${{ steps.Classify.outputs.branch }}"
|
||||
printf "tag: %s\n" "${{ steps.Classify.outputs.tag }}"
|
||||
printf "version: %s\n" "${{ steps.Classify.outputs.version || steps.FindPullRequest.outputs.pr_version }}"
|
||||
printf " from tag: %s\n" "${{ steps.Classify.outputs.version }}"
|
||||
printf " from pr: %s\n" "${{ steps.FindPullRequest.outputs.pr_version }}"
|
||||
printf "pr title: %s\n" "${{ steps.FindPullRequest.outputs.pr_title }}"
|
||||
printf "pr number: %s\n" "${{ steps.Classify.outputs.pr_number || steps.FindPullRequest.outputs.pr_number }}"
|
||||
printf " from merge: %s\n" "${{ steps.Classify.outputs.pr_number }}"
|
||||
printf " from pr: %s\n" "${{ steps.FindPullRequest.outputs.pr_number }}"
|
||||
printf "git_submodule_*:\n"
|
||||
printf " *_count_: %s\n" "${{ steps.FindPullRequest.outputs.git_submodule_count }}"
|
||||
printf " *_names: %s\n" "${{ steps.FindPullRequest.outputs.git_submodule_names }}"
|
||||
printf " *_paths: %s\n" "${{ steps.FindPullRequest.outputs.git_submodule_paths }}"
|
||||
184
.github/workflows/PublishCoverageResults.yml
vendored
184
.github/workflows/PublishCoverageResults.yml
vendored
@@ -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. #
|
||||
@@ -31,13 +31,38 @@ on:
|
||||
type: string
|
||||
coverage_artifacts_pattern:
|
||||
required: false
|
||||
default: '*-CodeCoverage-*'
|
||||
default: '*-CodeCoverage-SQLite-*'
|
||||
type: string
|
||||
coverage_config:
|
||||
description: 'Path to the .coveragerc file. Use pyproject.toml by default.'
|
||||
required: false
|
||||
default: 'pyproject.toml'
|
||||
type: string
|
||||
coverage_report_xml:
|
||||
description: 'Directory containing the XML coverage report file.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage",
|
||||
"filename": "coverage.xml",
|
||||
"fullpath": "report/coverage/coverage.xml"
|
||||
}
|
||||
type: string
|
||||
coverage_report_json:
|
||||
description: 'Directory containing the JSON coverage report file.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage",
|
||||
"filename": "coverage.json",
|
||||
"fullpath": "report/coverage/coverage.json"
|
||||
}
|
||||
type: string
|
||||
coverage_report_html:
|
||||
description: 'HTML root directory of the generated coverage report.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage/html"
|
||||
}
|
||||
type: string
|
||||
coverage_sqlite_artifact:
|
||||
description: 'Name of the SQLite coverage artifact.'
|
||||
required: false
|
||||
@@ -58,10 +83,23 @@ on:
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
codecov:
|
||||
description: 'Publish merged coverage report to Codecov.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
codacy:
|
||||
description: 'Publish merged coverage report to Codacy.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
secrets:
|
||||
codacy_token:
|
||||
description: 'Token to push result to codacy.'
|
||||
required: true
|
||||
CODECOV_TOKEN:
|
||||
description: 'Token to push result to Codecov.'
|
||||
required: false
|
||||
CODACY_TOKEN:
|
||||
description: 'Token to push result to Codacy.'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
PublishCoverageResults:
|
||||
@@ -71,118 +109,56 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
|
||||
- name: Download Artifacts
|
||||
uses: pyTooling/download-artifact@v4
|
||||
- name: 📥 Download Artifacts
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
pattern: ${{ inputs.coverage_artifacts_pattern }}
|
||||
path: artifacts
|
||||
|
||||
- name: 🔎 Inspect extracted artifact (tarball)
|
||||
run: |
|
||||
tree -psh artifacts
|
||||
tree -pash artifacts
|
||||
|
||||
- name: 🔧 Install coverage and tomli
|
||||
run: |
|
||||
python -m pip install -U --disable-pip-version-check --break-system-packages coverage[toml] tomli
|
||||
|
||||
- name: 🔁 Extract configurations from pyproject.toml
|
||||
id: getVariables
|
||||
shell: python
|
||||
- name: Rename .coverage files and move them all into 'coverage/'
|
||||
run: |
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from sys import version
|
||||
from textwrap import dedent
|
||||
|
||||
print(f"Python: {version}")
|
||||
|
||||
from tomli import load as tomli_load
|
||||
|
||||
htmlDirectory = Path("htmlcov")
|
||||
xmlFile = Path("./coverage.xml")
|
||||
jsonFile = Path("./coverage.json")
|
||||
coverageRC = "${{ inputs.coverage_config }}".strip()
|
||||
|
||||
# Read output paths from 'pyproject.toml' file
|
||||
if coverageRC == "pyproject.toml":
|
||||
pyProjectFile = Path("pyproject.toml")
|
||||
if pyProjectFile.exists():
|
||||
with pyProjectFile.open("rb") as file:
|
||||
pyProjectSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"])
|
||||
xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"])
|
||||
jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"])
|
||||
else:
|
||||
print(f"File '{pyProjectFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{pyProjectFile}' not found.")
|
||||
exit(1)
|
||||
|
||||
# Read output paths from '.coveragerc' file
|
||||
elif len(coverageRC) > 0:
|
||||
coverageRCFile = Path(coverageRC)
|
||||
if coverageRCFile.exists():
|
||||
with coverageRCFile.open("rb") as file:
|
||||
coverageRCSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(coverageRCSettings["html"]["directory"])
|
||||
xmlFile = Path(coverageRCSettings["xml"]["output"])
|
||||
jsonFile = Path(coverageRCSettings["json"]["output"])
|
||||
else:
|
||||
print(f"File '{coverageRCFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{coverageRCFile}' not found.")
|
||||
exit(1)
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
coverage_report_html_directory={htmlDirectory.as_posix()}
|
||||
coverage_report_xml={xmlFile}
|
||||
coverage_report_json={jsonFile}
|
||||
"""))
|
||||
|
||||
print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}")
|
||||
|
||||
- name: Rename .coverage files and collect them all to coverage/
|
||||
run: |
|
||||
ls -lAh artifacts/
|
||||
ls -lAh artifacts/*/.coverage
|
||||
mkdir -p coverage
|
||||
find artifacts/ -type f -path "*SQLite*.coverage" -exec sh -c 'cp -v $0 "coverage/$(basename $0).$(basename $(dirname $0))"' {} ';'
|
||||
tree -a coverage
|
||||
tree -pash coverage
|
||||
|
||||
- name: Combine SQLite files (using Coverage.py)
|
||||
run: coverage combine --data-file=.coverage coverage/
|
||||
|
||||
- name: Report code coverage
|
||||
run: coverage report --rcfile=pyproject.toml --data-file=.coverage
|
||||
run: coverage report --rcfile=${{ inputs.coverage_config }} --data-file=.coverage
|
||||
|
||||
- name: Convert to XML format (Cobertura)
|
||||
if: inputs.coverage_xml_artifact != ''
|
||||
run: coverage xml --data-file=.coverage
|
||||
if: inputs.coverage_xml_artifact != '' || inputs.codecov || inputs.codacy
|
||||
run: coverage xml --rcfile=${{ inputs.coverage_config }} --data-file=.coverage
|
||||
|
||||
- name: Convert to JSON format
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
run: coverage json --data-file=.coverage
|
||||
run: coverage json --rcfile=${{ inputs.coverage_config }} --data-file=.coverage
|
||||
|
||||
- name: Convert to HTML format
|
||||
if: inputs.coverage_html_artifact != ''
|
||||
run: |
|
||||
coverage html --data-file=.coverage -d report/coverage/html
|
||||
rm report/coverage/html/.gitignore
|
||||
tree -a report/coverage/html
|
||||
coverage html --rcfile=${{ inputs.coverage_config }} --data-file=.coverage
|
||||
rm ${{ fromJson(inputs.coverage_report_html).directory }}/.gitignore
|
||||
tree -pash ${{ fromJson(inputs.coverage_report_html).directory }}
|
||||
|
||||
- name: 📤 Upload 'Coverage SQLite Database' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.coverage_sqlite_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_sqlite_artifact }}
|
||||
path: .coverage
|
||||
@@ -190,49 +166,69 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage XML Report' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.coverage_xml_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_xml_artifact }}
|
||||
path: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_xml).directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_xml).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage JSON Report' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_json_artifact }}
|
||||
path: ${{ steps.getVariables.outputs.coverage_report_json }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_json).directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_json).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage HTML Report' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.coverage_html_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_html_artifact }}
|
||||
working-directory: ${{ steps.getVariables.outputs.coverage_report_html_directory }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_html).directory }}
|
||||
path: '*'
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📊 Publish code coverage at CodeCov
|
||||
if: inputs.CodeCov == true
|
||||
continue-on-error: true
|
||||
uses: codecov/codecov-action@v5
|
||||
id: codecov
|
||||
if: inputs.codecov == 'true'
|
||||
continue-on-error: true
|
||||
with:
|
||||
files: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
disable_search: true
|
||||
files: ${{ fromJson(inputs.coverage_report_xml).fullpath }}
|
||||
flags: unittests
|
||||
env_vars: PYTHON
|
||||
fail_ci_if_error: true
|
||||
|
||||
- name: 📉 Publish code coverage at Codacy
|
||||
if: inputs.Codacy == true
|
||||
continue-on-error: true
|
||||
uses: codacy/codacy-coverage-reporter-action@v1
|
||||
id: codacy
|
||||
if: inputs.codacy == 'true'
|
||||
continue-on-error: true
|
||||
with:
|
||||
project-token: ${{ secrets.codacy_token }}
|
||||
coverage-reports: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
project-token: ${{ secrets.CODACY_TOKEN }}
|
||||
coverage-reports: ${{ fromJson(inputs.coverage_report_xml).fullpath }}
|
||||
|
||||
- name: Generate error messages
|
||||
run: |
|
||||
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.\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.\n"
|
||||
fi
|
||||
|
||||
23
.github/workflows/PublishOnPyPI.yml
vendored
23
.github/workflows/PublishOnPyPI.yml
vendored
@@ -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. #
|
||||
@@ -33,7 +33,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
requirements:
|
||||
description: 'Python dependencies to be installed through pip.'
|
||||
@@ -50,38 +50,37 @@ on:
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
|
||||
PublishOnPyPI:
|
||||
name: 🚀 Publish to PyPI
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
|
||||
steps:
|
||||
- name: 📥 Download artifacts '${{ inputs.artifact }}' from 'Package' job
|
||||
uses: pyTooling/download-artifact@v4
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
path: dist
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
- name: ⚙ Install dependencies for packaging and release
|
||||
run: python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
|
||||
|
||||
- name: ⤴ Release Python source package to PyPI
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
||||
run: twine upload dist/*.tar.gz
|
||||
|
||||
- name: ⤴ Release Python wheel package to PyPI
|
||||
- name: ⤴ Publish Python wheel package to PyPI
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
||||
run: twine upload dist/*.whl
|
||||
|
||||
- name: ⤴ Publish Python source package to PyPI
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
||||
run: twine upload dist/*.tar.gz
|
||||
|
||||
- name: 🗑️ Delete packaging Artifacts
|
||||
uses: geekyeggo/delete-artifact@v5
|
||||
with:
|
||||
|
||||
856
.github/workflows/PublishReleaseNotes.yml
vendored
Normal file
856
.github/workflows/PublishReleaseNotes.yml
vendored
Normal file
@@ -0,0 +1,856 @@
|
||||
# ==================================================================================================================== #
|
||||
# Authors: #
|
||||
# Patrick Lehmann #
|
||||
# #
|
||||
# ==================================================================================================================== #
|
||||
# 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: Release
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ubuntu_image:
|
||||
description: 'Name of the Ubuntu image.'
|
||||
required: false
|
||||
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: true
|
||||
type: string
|
||||
title:
|
||||
description: 'Title of the release.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
description:
|
||||
description: 'Multi-line description of the release.'
|
||||
required: false
|
||||
default: ''
|
||||
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_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
|
||||
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: true
|
||||
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: false
|
||||
type: string
|
||||
default: ''
|
||||
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 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: ⏬ Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
# The command 'git describe' (used for version) needs the history.
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🔧 Install zstd
|
||||
run: sudo apt-get install -y --no-install-recommends zstd
|
||||
|
||||
- name: 📑 Prepare
|
||||
id: prepare
|
||||
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'
|
||||
|
||||
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
|
||||
|
||||
- name: 📑 Delete (old) Release Page
|
||||
id: deleteReleasePage
|
||||
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 }}
|
||||
|
||||
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
|
||||
|
||||
- name: 📑 Assemble Release Notes
|
||||
id: createReleaseNotes
|
||||
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 }}
|
||||
|
||||
# Save release description (from parameter in a file)
|
||||
head -c -1 <<'EOF' > __DESCRIPTION__.md
|
||||
${{ inputs.description }}
|
||||
EOF
|
||||
|
||||
# Save release footer (from parameter in a file)
|
||||
head -c -1 <<'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
|
||||
|
||||
printf "%s\n" "${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
|
||||
|
||||
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)."
|
||||
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)}"
|
||||
else
|
||||
NOTES="${NOTES//%%DESCRIPTION%%/}"
|
||||
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
|
||||
else
|
||||
while [[ "${NOTES}" =~ %%(PULLREQUEST(\+[0-3])?)%% ]]; do
|
||||
NOTES="${NOTES//${BASH_REMATCH[0]}/}"
|
||||
done
|
||||
fi
|
||||
|
||||
# inline Footer
|
||||
if [[ -s __FOOTER__.md ]]; then
|
||||
NOTES="${NOTES//%%FOOTER%%/$(<__FOOTER__.md)}"
|
||||
else
|
||||
NOTES="${NOTES//%%FOOTER%%/}"
|
||||
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 }}}"
|
||||
#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
|
||||
printf "%s\n" "${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' ($(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' ($(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' ($(stat --printf="%s" "__FOOTER__.md") B) ...."
|
||||
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' ($(stat --printf="%s" "__NOTES__.md") B) ...."
|
||||
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
|
||||
STRUCT_VERSION="1.1"
|
||||
|
||||
# Use GitHub API to ask for latest version
|
||||
printf "Get latest released version via GitHub API ...\n"
|
||||
printf " gh release list --json tagName,isLatest --jq '.[] | select(.isLatest == true) | .tagName' "
|
||||
latestVersion=$(gh release list --json tagName,isLatest --jq '.[] | select(.isLatest == true) | .tagName')
|
||||
if [[ $? -eq 0 ]]; then
|
||||
if [[ -z "${latestVersion}" ]]; then
|
||||
printf "${ANSI_LIGHT_RED}[UNKNOWN]${ANSI_NOCOLOR}\n"
|
||||
printf " latest=unknown\n"
|
||||
latestVersion="unknown"
|
||||
else
|
||||
printf "${ANSI_LIGHT_GREEN}[OK]${ANSI_NOCOLOR}\n"
|
||||
printf " latest=%s\n" "${latestVersion}"
|
||||
fi
|
||||
else
|
||||
printf "${ANSI_LIGHT_RED}[ERROR]${ANSI_NOCOLOR}\n"
|
||||
printf " ${ANSI_LIGHT_RED}Couldn't get latest released version '%s'.${ANSI_NOCOLOR}\n" "${latestVersion}"
|
||||
printf "::error title=%s::%s\n" "GitHub Release API" "Couldn't get latest released version '${latestVersion}'."
|
||||
|
||||
latestVersion="error"
|
||||
fi
|
||||
|
||||
# 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 structVersion "${STRUCT_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 jsonLatest "$(jq -c -n \
|
||||
--arg version "${latestVersion}" \
|
||||
--arg release "${{ github.server_url }}/${{ github.repository }}/releases/download/${latestVersion}" \
|
||||
'{"version": $version, "release-url": $release}' \
|
||||
)" \
|
||||
--argjson categories "$(jq -c -n \
|
||||
'$ARGS.positional' \
|
||||
--args "${inventoryCategories[@]}" \
|
||||
)" \
|
||||
'{"tag": $tag, "version": $version, "git-hash": $hash, "repository-url": $repo, "release-url": $release, "categories": $categories, "latest": $jsonLatest}' \
|
||||
)" \
|
||||
'{"version": "$structVersion", "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
|
||||
# A dictionary of SHA256 checksums
|
||||
declare -A sha256Checksums
|
||||
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 "${ANSI_LIGHT_BLUE}Publish asset '%s' from artifact '%s' with title '%s'${ANSI_NOCOLOR}\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 artifact '%s' ... ${ANSI_LIGHT_YELLOW}[SKIPPED]${ANSI_NOCOLOR}\n" "${artifact}"
|
||||
else
|
||||
printf " downloading '${artifact}' ...\n"
|
||||
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
|
||||
|
||||
printf " compute SHA256 checksum of '${uploadFile}' ... "
|
||||
sha256=$(sha256sum -b ${uploadFile} | cut -d " " -f1)
|
||||
sha256Checksums[$asset]="sha256:${sha256}"
|
||||
printf "${ANSI_LIGHT_BLUE}${sha256}${ANSI_NOCOLOR}\n"
|
||||
|
||||
# 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 sha256 "${sha256}" \
|
||||
--arg file "${uploadFile#*/}" \
|
||||
'{"file": $file, "sha256": $sha256, "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"
|
||||
|
||||
printf " checking assets SHA256 checksum ... \n"
|
||||
ghSHA256=$(gh release view --json assets --jq ".assets[] | select(.name == \"${asset}\") | .digest" ${{ inputs.tag }})
|
||||
if [[ "${ghSHA256}" == "${sha256Checksums[$asset]}" ]]; then
|
||||
printf "${ANSI_LIGHT_GREEN}[PASSED]${ANSI_NOCOLOR}\n"
|
||||
else
|
||||
printf "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR}\n"
|
||||
printf " ${ANSI_LIGHT_RED}SHA256 checksum compare failed.${ANSI_NOCOLOR}\n"
|
||||
printf " ${ANSI_LIGHT_RED}Local: %s${ANSI_NOCOLOR}\n" "${sha256Checksums[$asset]}"
|
||||
printf " ${ANSI_LIGHT_RED}GitHub: %s${ANSI_NOCOLOR}\n" "${ghSHA256}"
|
||||
printf "::error title=%s::%s\n" "ChecksumError" "SHA256 checksum compare failed. Local=${sha256Checksums[$asset]} GitHub=${ghSHA256}"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
continue
|
||||
fi
|
||||
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
|
||||
119
.github/workflows/PublishTestResults.yml
vendored
119
.github/workflows/PublishTestResults.yml
vendored
@@ -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. #
|
||||
@@ -32,28 +32,67 @@ on:
|
||||
type: string
|
||||
unittest_artifacts_pattern:
|
||||
required: false
|
||||
default: '*-UnitTestReportSummary-*'
|
||||
default: '*-UnitTestReportSummary-XML-*'
|
||||
type: string
|
||||
merged_junit_filename:
|
||||
description: 'Filename of the merged JUnit Test Summary.'
|
||||
required: false
|
||||
default: 'Unittesting.xml'
|
||||
type: string
|
||||
merged_junit_artifact:
|
||||
description: 'Name of the merged JUnit Test Summary artifact.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
merge-input-dialect:
|
||||
description: 'JUnit dialect used to load and parse inputs for merging.'
|
||||
required: false
|
||||
default: 'pyTest-JUnit'
|
||||
type: string
|
||||
merge-output-dialect:
|
||||
description: 'JUnit dialect used for writing the merged report.'
|
||||
required: false
|
||||
default: 'pyTest-JUnit'
|
||||
type: string
|
||||
additional_merge_args:
|
||||
description: 'Additional merging arguments.'
|
||||
required: false
|
||||
default: '"--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit"'
|
||||
type: string
|
||||
testsuite-summary-name:
|
||||
description: 'Set TestsuiteSummary name.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
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
|
||||
default: 'Unit Test Results'
|
||||
type: string
|
||||
dorny:
|
||||
description: 'Publish merged unittest results via Dorny Test-Reporter.'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: string
|
||||
codecov:
|
||||
description: 'Publish merged unittest results to Codecov.'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
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.'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
PublishTestResults:
|
||||
@@ -63,48 +102,86 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download Artifacts
|
||||
uses: pyTooling/download-artifact@v4
|
||||
- name: 📥 Download Artifacts
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
pattern: ${{ inputs.unittest_artifacts_pattern }}
|
||||
path: artifacts
|
||||
path: artifacts
|
||||
|
||||
- name: 🔎 Inspect extracted artifact (tarball)
|
||||
run: |
|
||||
tree -psh artifacts
|
||||
tree -pash artifacts
|
||||
|
||||
- name: 🔧 Install pyEDAA.Reports (JUunit Parser and Merger)
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check --break-system-packages -U pyEDAA.Reports
|
||||
|
||||
- name: Move JUnit files and collect them all to junit/
|
||||
- name: Rename JUnit files and move them all into 'junit/'
|
||||
run: |
|
||||
mkdir -p junit
|
||||
ls -lAh artifacts/*/*.xml
|
||||
find artifacts/ -type f -path "*TestReportSummary*.xml" -exec sh -c 'cp -v $0 "junit/$(basename $(dirname $0)).$(basename $0)"' {} ';'
|
||||
tree -a junit
|
||||
find artifacts/ -type f -path "*.xml" -exec sh -c 'cp -v $0 "junit/$(basename $(dirname $0)).$(basename $0)"' {} ';'
|
||||
tree -pash junit
|
||||
|
||||
- name: 🔁 Merge JUnit Unit Test Summaries
|
||||
run: |
|
||||
pyedaa-reports -v unittest "--merge=pyTest-JUnit:junit/*.xml" ${{ inputs.additional_merge_args }} "--output=pyTest-JUnit:Unittesting.xml"
|
||||
echo "cat Unittesting.xml"
|
||||
cat Unittesting.xml
|
||||
if [[ -n "${{ inputs.testsuite-summary-name }}" ]]; then
|
||||
name="\"--name=${{ inputs.testsuite-summary-name }}\""
|
||||
fi
|
||||
pyedaa-reports -v unittest $name "--merge=${{ inputs.merge-input-dialect }}:junit/*.xml" ${{ inputs.additional_merge_args }} "--output=${{ inputs.merge-output-dialect }}:${{ inputs.merged_junit_filename }}"
|
||||
printf "%s\n" "cat ${{ inputs.merged_junit_filename }}"
|
||||
cat ${{ inputs.merged_junit_filename }}
|
||||
|
||||
- name: 📊 Publish Unit Test Results
|
||||
uses: dorny/test-reporter@v1
|
||||
if: inputs.publish && inputs.report_title != ''
|
||||
uses: dorny/test-reporter@v2
|
||||
id: test-reporter
|
||||
if: ( inputs.dorny == 'true' || inputs.publish == 'true' ) && inputs.report_title != ''
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: ${{ inputs.report_title }}
|
||||
path: Unittesting.xml
|
||||
path: ${{ inputs.merged_junit_filename }}
|
||||
reporter: java-junit
|
||||
|
||||
- name: 📊 Publish unittest results at CodeCov
|
||||
uses: codecov/test-results-action@v1
|
||||
id: codecov
|
||||
if: inputs.codecov == 'true'
|
||||
continue-on-error: true
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
disable_search: true
|
||||
files: ${{ inputs.merged_junit_filename }}
|
||||
flags: ${{ inputs.codecov_flags }}
|
||||
fail_ci_if_error: true
|
||||
|
||||
- name: 📤 Upload merged 'JUnit Test Summary' artifact
|
||||
if: inputs.merged_junit_artifact != ''
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.merged_junit_artifact != ''
|
||||
with:
|
||||
name: ${{ inputs.merged_junit_artifact }}
|
||||
path: Unittesting.xml
|
||||
path: ${{ inputs.merged_junit_filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
investigate: true
|
||||
|
||||
- name: Generate error messages
|
||||
run: |
|
||||
exitCode=0
|
||||
if [[ "${{ steps.test-reporter.outcome }}" == "failure" ]]; then
|
||||
printf "❌ Dorney/Test-Reporter: %s\n" "Failed to publish unittest results."
|
||||
printf "::error title=%s::%s\n" "Dorney/Test-Reporter" "Failed to publish unittest results."
|
||||
exitCode=1
|
||||
else
|
||||
printf "✅ Dorney/Test-Reporter: No errors to report.\n"
|
||||
fi
|
||||
|
||||
if [[ "${{ steps.codecov.outcome }}" == "failure" ]]; then
|
||||
printf "❌ CodeCov: %s\n" "Failed to publish unittest and code coverage results."
|
||||
printf "::error title=%s::%s\n" "CodeCov" "Failed to publish unittest and code coverage results."
|
||||
exitCode=1
|
||||
else
|
||||
printf "✅ CodeCov: No errors to report.\n"
|
||||
fi
|
||||
|
||||
exit $exitCode
|
||||
|
||||
12
.github/workflows/PublishToGitHubPages.yml
vendored
12
.github/workflows/PublishToGitHubPages.yml
vendored
@@ -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. #
|
||||
@@ -53,24 +53,24 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.doc }}' from 'BuildTheDocs' job
|
||||
uses: pyTooling/download-artifact@v4
|
||||
- name: 📥 Download artifacts '${{ inputs.doc }}' from 'SphinxDocumentation' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
with:
|
||||
name: ${{ inputs.doc }}
|
||||
path: public
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.coverage }}' from 'Coverage' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: ${{ inputs.coverage != '' }}
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage }}
|
||||
path: public/coverage
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.typing }}' from 'StaticTypeCheck' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: ${{ inputs.typing != '' }}
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.typing }}
|
||||
path: public/typing
|
||||
|
||||
137
.github/workflows/SphinxDocumentation.yml
vendored
137
.github/workflows/SphinxDocumentation.yml
vendored
@@ -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. #
|
||||
@@ -32,7 +32,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
requirements:
|
||||
description: 'Python dependencies to be installed through pip.'
|
||||
@@ -44,24 +44,29 @@ on:
|
||||
required: false
|
||||
default: 'doc'
|
||||
type: string
|
||||
coverage_report_json_directory:
|
||||
description: ''
|
||||
required: true
|
||||
type: string
|
||||
coverage_json_artifact:
|
||||
description: 'Name of the coverage JSON artifact.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
coverage_report_json:
|
||||
description: 'Directory where coverage JSON artifact will be extracted.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage"
|
||||
}
|
||||
type: string
|
||||
unittest_xml_artifact:
|
||||
description: 'Name of the unittest XML artifact.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
unittest_xml_directory:
|
||||
description: 'Directory where unittest XML artifact is extracted.'
|
||||
unittest_xml:
|
||||
description: 'Directory where unittest XML artifact will be extracted.'
|
||||
required: false
|
||||
default: 'report/unit'
|
||||
default: >-
|
||||
{ "directory": "report/unit"
|
||||
}
|
||||
type: string
|
||||
html_artifact:
|
||||
description: 'Name of the HTML documentation artifact.'
|
||||
@@ -81,7 +86,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
@@ -90,7 +95,7 @@ jobs:
|
||||
run: sudo apt-get install -y --no-install-recommends graphviz
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -100,18 +105,20 @@ jobs:
|
||||
python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.unittest_xml_artifact }}' from 'Unittesting' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: inputs.unittest_xml_artifact != ''
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.unittest_xml_artifact }}
|
||||
path: ${{ inputs.unittest_xml_directory }}
|
||||
path: ${{ fromJson(inputs.unittest_xml).directory }}
|
||||
investigate: true
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.coverage_json_artifact }}' from 'PublishCoverageResults' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_json_artifact }}
|
||||
path: ${{ inputs.coverage_report_json_directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_json).directory }}
|
||||
investigate: true
|
||||
|
||||
- name: ☑ Generate HTML documentation
|
||||
if: inputs.html_artifact != ''
|
||||
@@ -122,9 +129,9 @@ jobs:
|
||||
sphinx-build -v -n -b html -d _build/doctrees -j $(nproc) -w _build/html.log . _build/html
|
||||
|
||||
- name: 📤 Upload 'HTML Documentation' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.html_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.html_artifact }}
|
||||
working-directory: ${{ inputs.doc_directory }}/_build/html
|
||||
@@ -138,7 +145,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
@@ -147,7 +154,7 @@ jobs:
|
||||
run: sudo apt-get install -y --no-install-recommends graphviz
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -157,18 +164,20 @@ jobs:
|
||||
python -m pip install --disable-pip-version-check ${{ inputs.requirements }}
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.unittest_xml_artifact }}' from 'Unittesting' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: inputs.unittest_xml_artifact != ''
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.unittest_xml_artifact }}
|
||||
path: ${{ inputs.unittest_xml_directory }}
|
||||
path: ${{ fromJson(inputs.unittest_xml).directory }}
|
||||
investigate: true
|
||||
|
||||
- name: 📥 Download artifacts '${{ inputs.coverage_json_artifact }}' from 'PublishCoverageResults' job
|
||||
uses: pyTooling/download-artifact@v5
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
uses: pyTooling/download-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_json_artifact }}
|
||||
path: ${{ inputs.coverage_report_json_directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_json).directory }}
|
||||
investigate: true
|
||||
|
||||
- name: ☑ Generate LaTeX documentation
|
||||
if: inputs.latex_artifact != ''
|
||||
@@ -180,10 +189,92 @@ jobs:
|
||||
sphinx-build -v -n -b latex -d _build/doctrees -j $(nproc) -w _build/latex.log . _build/latex
|
||||
# --builder html --doctree-dir _build/doctrees --verbose --fresh-env --write-all --nitpicky --warning-file _build/html.log . _build/html
|
||||
|
||||
- name: Workaround I - https://github.com/sphinx-doc/sphinx/issues/13190
|
||||
if: inputs.latex_artifact != ''
|
||||
run: |
|
||||
printf "Changing directory to '${{ inputs.doc_directory || '.' }}/_build/latex' ...\n"
|
||||
cd ${{ inputs.doc_directory || '.' }}/_build/latex
|
||||
|
||||
MIMETYPE_EXTENSIONS=(
|
||||
"image/png:png"
|
||||
"image/jpeg:jpg"
|
||||
"image/svg+xml:svg"
|
||||
)
|
||||
|
||||
printf "Changing file extension according to MIME type ...\n"
|
||||
while IFS=$'\n' read -r file; do
|
||||
printf " Checking '%s' ... " "${file}"
|
||||
mime="$(file --mime-type -b "${file}")"
|
||||
printf "[%s]\n" "${mime}"
|
||||
|
||||
found=0
|
||||
for MIME in "${MIMETYPE_EXTENSIONS[@]}"; do
|
||||
mimetype="${MIME%%:*}"
|
||||
extension="${MIME#*:}"
|
||||
|
||||
if [[ "${mime}" == "${mimetype}" && "${file##*.}" != "${extension}" ]]; then
|
||||
printf " Rename file to '%s' " "${file}.${extension}"
|
||||
mv "${file}" "${file}.${extension}"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "[OK]\n"
|
||||
else
|
||||
printf "[FAILED]\n"
|
||||
fi
|
||||
|
||||
printf " Patching LaTeX file for '%s' " "${file}"
|
||||
sed -i "s:{{${file%.*}}\.${file##*.}}:{{${file}}.${extension}}:g" *.tex
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "[OK]\n"
|
||||
else
|
||||
printf "[FAILED]\n"
|
||||
fi
|
||||
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ $found -eq 0 ]]; then
|
||||
printf "[SKIPPED]\n"
|
||||
fi
|
||||
done < <(find . -type f -not -iname "*.cls" -not -iname "*.sty" -not -iname "*.xdy" -not -iname "*.svg" -not -iname "*.png" -not -iname "*.jpg" | sed 's:./::')
|
||||
|
||||
- name: Workaround II - https://github.com/sphinx-doc/sphinx/issues/13189
|
||||
if: inputs.latex_artifact != ''
|
||||
run: |
|
||||
printf "Changing directory to '${{ inputs.doc_directory || '.' }}/_build/latex' ...\n"
|
||||
cd ${{ inputs.doc_directory || '.' }}/_build/latex
|
||||
|
||||
printf "Searching for downloaded images, that need normalization ...\n"
|
||||
for imageExt in png svg jpg jpeg; do
|
||||
printf " Processing '%s' ...\n" "${imageExt}"
|
||||
while IFS=$'\n' read -r imageFile; do
|
||||
newFile="${imageFile//%/_}";
|
||||
|
||||
printf " %s\n" "$imageFile";
|
||||
if [[ "${imageFile}" != "${newFile}" ]]; then
|
||||
printf " Rename file to '%s' " "${newFile}"
|
||||
mv "${imageFile}" "${newFile}"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "[OK]\n"
|
||||
else
|
||||
printf "[FAILED]\n"
|
||||
fi
|
||||
|
||||
printf " Patching LaTeX file for '%s' " "${newFile}"
|
||||
sed -i "s:{{${imageFile%.*}}\.${imageFile##*.}}:{{${newFile%.*}}.${newFile##*.}}:g" *.tex
|
||||
if [[ $? -eq 0 ]]; then
|
||||
printf "[OK]\n"
|
||||
else
|
||||
printf "[FAILED]\n"
|
||||
fi
|
||||
fi
|
||||
done < <(find . -type f -iname "*.$imageExt" | sed 's:./::')
|
||||
done
|
||||
|
||||
- name: 📤 Upload 'LaTeX Documentation' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.latex_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.latex_artifact }}
|
||||
working-directory: ${{ inputs.doc_directory }}/_build/latex
|
||||
|
||||
113
.github/workflows/StaticTypeCheck.yml
vendored
113
.github/workflows/StaticTypeCheck.yml
vendored
@@ -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. #
|
||||
@@ -33,49 +33,71 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
requirements:
|
||||
description: 'Python dependencies to be installed through pip.'
|
||||
required: false
|
||||
default: '-r tests/requirements.txt'
|
||||
type: string
|
||||
commands:
|
||||
description: 'Commands to run the static type checks.'
|
||||
required: true
|
||||
mypy_options:
|
||||
description: 'Additional mypy options.'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
cobertura_report:
|
||||
description: 'Cobertura file to upload as an artifact.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "fullpath": "report/typing/cobertura.xml",
|
||||
"directory": "report/typing",
|
||||
"filename": "cobertura.xml"
|
||||
}
|
||||
type: string
|
||||
junit_report:
|
||||
description: 'JUnit file to upload as an artifact.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "fullpath": "report/typing/StaticTypingSummary.xml",
|
||||
"directory": "report/typing",
|
||||
"filename": "StaticTypingSummary.xml"
|
||||
}
|
||||
type: string
|
||||
html_report:
|
||||
description: 'Directory to upload as an artifact.'
|
||||
required: false
|
||||
default: 'htmlmypy'
|
||||
default: >-
|
||||
{ "directory": "report/typing/html"
|
||||
}
|
||||
# "fullpath": "report/typing/html",
|
||||
type: string
|
||||
junit_report:
|
||||
description: 'junit file to upload as an artifact.'
|
||||
cobertura_artifact:
|
||||
description: 'Name of the typing cobertura artifact (Cobertura XML).'
|
||||
required: false
|
||||
default: 'StaticTypingSummary.xml'
|
||||
default: ''
|
||||
type: string
|
||||
junit_artifact:
|
||||
description: 'Name of the typing junit artifact (JUnit XML).'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
html_artifact:
|
||||
description: 'Name of the typing artifact (HTML report).'
|
||||
required: true
|
||||
type: string
|
||||
junit_artifact:
|
||||
description: 'Name of the typing junit artifact (junit XML).'
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
|
||||
StaticTypeCheck:
|
||||
name: 👀 Check Static Typing using Python ${{ inputs.python_version }}
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🐍 Setup Python ${{ inputs.python_version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
@@ -84,25 +106,70 @@ jobs:
|
||||
|
||||
- name: Check Static Typing
|
||||
continue-on-error: true
|
||||
run: ${{ inputs.commands }}
|
||||
run: mypy ${{ inputs.mypy_options }}
|
||||
|
||||
- name: 📤 Upload 'Static Typing Report' HTML artifact
|
||||
- name: Debug output directories
|
||||
continue-on-error: true
|
||||
run: |
|
||||
# List directory contents
|
||||
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'
|
||||
|
||||
if [[ "${{ fromJson(inputs.html_report).directory }}" != "" ]]; then
|
||||
printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '${{ fromJson(inputs.html_report).directory }}' ..."
|
||||
tree ${{ fromJson(inputs.html_report).directory }}
|
||||
printf "::endgroup::\n"
|
||||
fi
|
||||
|
||||
if [[ "${{ fromJson(inputs.junit_report).directory }}" != "" ]]; then
|
||||
printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '${{ fromJson(inputs.junit_report).directory }}' ..."
|
||||
tree ${{ fromJson(inputs.junit_report).directory }}
|
||||
printf "::endgroup::\n"
|
||||
if [[ "${{ fromJson(inputs.cobertura_report).directory }}" != "" && "${{ fromJson(inputs.junit_report).directory }}" != "${{ fromJson(inputs.cobertura_report).directory }}" ]]; then
|
||||
printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '${{ fromJson(inputs.cobertura_report).directory }}' ..."
|
||||
tree ${{ fromJson(inputs.cobertura_report).directory }}
|
||||
printf "::endgroup::\n"
|
||||
fi
|
||||
elif [[ "${{ fromJson(inputs.cobertura_report).directory }}" != "" ]]; then
|
||||
printf "::group::${ANSI_LIGHT_BLUE}%s${ANSI_NOCOLOR}\n" "Content of '${{ fromJson(inputs.cobertura_report).directory }}' ..."
|
||||
tree ${{ fromJson(inputs.cobertura_report).directory }}
|
||||
printf "::endgroup::\n"
|
||||
fi
|
||||
|
||||
- name: 📤 Upload '${{ inputs.html_artifact }}' HTML artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: ${{ inputs.html_artifact != '' }}
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.html_artifact }}
|
||||
working-directory: ${{ inputs.html_report }}
|
||||
working-directory: ${{ fromJson(inputs.html_report).directory }}
|
||||
path: '*'
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Static Typing Report' JUnit artifact
|
||||
- name: 📤 Upload '${{ inputs.junit_artifact }}' JUnit artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: ${{ inputs.junit_artifact != '' }}
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.junit_artifact }}
|
||||
path: ${{ inputs.junit_report }}
|
||||
working-directory: ${{ fromJson(inputs.junit_report).directory }}
|
||||
path: ${{ fromJson(inputs.junit_report).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload '${{ inputs.cobertura_artifact }}' Cobertura artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: ${{ inputs.cobertura_artifact != '' }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: ${{ inputs.cobertura_artifact }}
|
||||
working-directory: ${{ fromJson(inputs.cobertura_report).directory }}
|
||||
path: ${{ fromJson(inputs.cobertura_report).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
@@ -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. #
|
||||
@@ -20,74 +20,65 @@
|
||||
# #
|
||||
# SPDX-License-Identifier: Apache-2.0 #
|
||||
# ==================================================================================================================== #
|
||||
name: Release
|
||||
name: Auto Tag
|
||||
|
||||
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
|
||||
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:
|
||||
Release:
|
||||
name: 📝 Create 'Release Page' on GitHub
|
||||
runs-on: "ubuntu-${{ inputs.ubuntu_image_version }}"
|
||||
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: 🔁 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
|
||||
echo "gitTag=${GIT_TAG}" >> $GITHUB_OUTPUT
|
||||
echo "version=${RELEASE_VERSION}" >> $GITHUB_OUTPUT
|
||||
echo "datetime=${RELEASE_DATETIME}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: 📑 Create Release Page
|
||||
id: createReleasePage
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: 🏷 Create release tag '${{ steps.FindPullRequest.outputs.version }}'
|
||||
uses: actions/github-script@v8
|
||||
id: createReleaseTag
|
||||
# if: inputs.auto_tag == 'true'
|
||||
with:
|
||||
tag_name: ${{ steps.getVariables.outputs.gitTag }}
|
||||
# release_name: ${{ steps.getVariables.outputs.gitTag }}
|
||||
body: |
|
||||
**Automated Release created on: ${{ steps.getVariables.outputs.datetime }}**
|
||||
script: |
|
||||
github.rest.git.createRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: 'refs/tags/${{ inputs.version }}',
|
||||
sha: context.sha
|
||||
})
|
||||
|
||||
# New Features
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Changes
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Bug Fixes
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Documentation
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Unit Tests
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
----------
|
||||
# Related Issues and Pull-Requests
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
draft: true
|
||||
prerelease: false
|
||||
- name: Trigger Workflow
|
||||
uses: actions/github-script@v8
|
||||
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 }}'
|
||||
})
|
||||
176
.github/workflows/TestReleaser.yml
vendored
176
.github/workflows/TestReleaser.yml
vendored
@@ -1,176 +0,0 @@
|
||||
# ==================================================================================================================== #
|
||||
# Authors: #
|
||||
# Unai Martinez-Corral #
|
||||
# #
|
||||
# ==================================================================================================================== #
|
||||
# Copyright 2020-2024 The pyTooling Authors #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
# SPDX-License-Identifier: Apache-2.0 #
|
||||
# ==================================================================================================================== #
|
||||
name: Test Releaser
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
- '!tip'
|
||||
- '!v*'
|
||||
branches:
|
||||
- '**'
|
||||
- '!r*'
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * 4'
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
jobs:
|
||||
|
||||
|
||||
Image:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build container image
|
||||
run: docker build -t ghcr.io/pytooling/releaser -f releaser/Dockerfile releaser
|
||||
|
||||
- name: Push container image
|
||||
uses: ./with-post-step
|
||||
with:
|
||||
main: |
|
||||
echo '${{ github.token }}' | docker login ghcr.io -u GitHub-Actions --password-stdin
|
||||
docker push ghcr.io/pytooling/releaser
|
||||
post: docker logout ghcr.io
|
||||
|
||||
|
||||
Composite:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- run: echo "Build some tool and generate some (versioned) artifacts" > artifact-$(date -u +"%Y-%m-%dT%H-%M-%SZ").txt
|
||||
|
||||
- name: Single
|
||||
uses: ./releaser/composite
|
||||
with:
|
||||
rm: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifact-*.txt
|
||||
|
||||
- name: List
|
||||
uses: ./releaser/composite
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: |
|
||||
artifact-*.txt
|
||||
README.md
|
||||
|
||||
- name: Add artifacts/*.txt
|
||||
run: |
|
||||
mkdir artifacts
|
||||
echo "Build some tool and generate some artifacts" > artifacts/artifact.txt
|
||||
touch artifacts/empty_file.txt
|
||||
|
||||
- name: Single in subdir
|
||||
uses: ./releaser/composite
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/artifact.txt
|
||||
|
||||
- name: Add artifacts/*.md
|
||||
run: |
|
||||
echo "releaser hello" > artifacts/hello.md
|
||||
echo "releaser world" > artifacts/world.md
|
||||
|
||||
- name: Directory wildcard
|
||||
uses: ./releaser/composite
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/*
|
||||
|
||||
- name: Add artifacts/subdir
|
||||
run: |
|
||||
mkdir artifacts/subdir
|
||||
echo "Test recursive glob" > artifacts/subdir/deep_file.txt
|
||||
|
||||
- name: Directory wildcard (recursive)
|
||||
uses: ./releaser/composite
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/**
|
||||
|
||||
|
||||
Test:
|
||||
needs:
|
||||
- Image
|
||||
- Composite
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- run: echo "Build some tool and generate some (versioned) artifacts" > artifact-$(date -u +"%Y-%m-%dT%H-%M-%SZ").txt
|
||||
|
||||
- name: Single
|
||||
uses: ./releaser
|
||||
with:
|
||||
rm: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifact-*.txt
|
||||
|
||||
- name: List
|
||||
uses: ./releaser
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: |
|
||||
artifact-*.txt
|
||||
README.md
|
||||
|
||||
- name: Add artifacts/*.txt
|
||||
run: |
|
||||
mkdir artifacts
|
||||
echo "Build some tool and generate some artifacts" > artifacts/artifact.txt
|
||||
touch artifacts/empty_file.txt
|
||||
|
||||
- name: Single in subdir
|
||||
uses: ./releaser
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/artifact.txt
|
||||
|
||||
- name: Add artifacts/*.md
|
||||
run: |
|
||||
echo "releaser hello" > artifacts/hello.md
|
||||
echo "releaser world" > artifacts/world.md
|
||||
|
||||
- name: Directory wildcard
|
||||
uses: ./releaser
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/*
|
||||
|
||||
- name: Add artifacts/subdir
|
||||
run: |
|
||||
mkdir artifacts/subdir
|
||||
echo "Test recursive glob" > artifacts/subdir/deep_file.txt
|
||||
|
||||
- name: Directory wildcard (recursive)
|
||||
uses: ./releaser
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: artifacts/**
|
||||
183
.github/workflows/UnitTesting.yml
vendored
183
.github/workflows/UnitTesting.yml
vendored
@@ -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. #
|
||||
@@ -85,20 +85,55 @@ on:
|
||||
default: ''
|
||||
type: string
|
||||
tests_directory:
|
||||
description: 'Path to the directory containing tests (relative to root_directory).'
|
||||
description: 'Path to the directory containing tests (relative from root_directory).'
|
||||
required: false
|
||||
default: 'tests'
|
||||
type: string
|
||||
unittest_directory:
|
||||
description: 'Path to the directory containing unit tests (relative to tests_directory).'
|
||||
description: 'Path to the directory containing unit tests (relative from tests_directory).'
|
||||
required: false
|
||||
default: 'unit'
|
||||
type: string
|
||||
unittest_report_xml:
|
||||
description: 'JSON object describing the path where to save the unittest summary report XML.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/unit",
|
||||
"filename": "TestReportSummary.xml",
|
||||
"fullpath": "report/unit/TestReportSummary.xml"
|
||||
}
|
||||
type: string
|
||||
coverage_config:
|
||||
description: 'Path to the .coveragerc file. Use pyproject.toml by default.'
|
||||
required: false
|
||||
default: 'pyproject.toml'
|
||||
type: string
|
||||
coverage_report_xml:
|
||||
description: 'JSON object describing the path where the coverage report in XML format will be generated.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage",
|
||||
"filename": "coverage.xml",
|
||||
"fullpath": "report/coverage/coverage.xml"
|
||||
}
|
||||
type: string
|
||||
coverage_report_json:
|
||||
description: 'JSON object describing the path where the coverage report in JSON format will be generated.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage",
|
||||
"filename": "coverage.json",
|
||||
"fullpath": "report/coverage/coverage.json"
|
||||
}
|
||||
type: string
|
||||
coverage_report_html:
|
||||
description: 'JSON object describing the path where the coverage report in HTML format will be generated.'
|
||||
required: false
|
||||
default: >-
|
||||
{ "directory": "report/coverage/html",
|
||||
}
|
||||
# "fullpath": "report/coverage/html"
|
||||
type: string
|
||||
unittest_xml_artifact:
|
||||
description: "Generate unit test report with junitxml and upload results as an artifact."
|
||||
required: false
|
||||
@@ -146,7 +181,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
lfs: true
|
||||
submodules: true
|
||||
@@ -157,7 +192,7 @@ jobs:
|
||||
run: brew install ${{ inputs.brew }}
|
||||
|
||||
- name: 🔧 Install apt dependencies on Ubuntu
|
||||
if: matrix.system == 'ubuntu' && inputs.apt != ''
|
||||
if: ( matrix.system == 'ubuntu' || matrix.system == 'ubuntu-arm' ) && inputs.apt != ''
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends ${{ inputs.apt }}
|
||||
@@ -210,14 +245,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",
|
||||
@@ -225,6 +260,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": {
|
||||
@@ -267,8 +303,8 @@ jobs:
|
||||
# Python setup
|
||||
|
||||
- name: '🟦 Setup MSYS2 for ${{ matrix.runtime }}'
|
||||
if: matrix.system == 'msys2'
|
||||
uses: msys2/setup-msys2@v2
|
||||
if: matrix.system == 'msys2'
|
||||
with:
|
||||
msystem: ${{ matrix.runtime }}
|
||||
update: true
|
||||
@@ -277,8 +313,8 @@ jobs:
|
||||
${{ inputs.pacboy }}
|
||||
|
||||
- name: 🐍 Setup Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v6
|
||||
if: matrix.system != 'msys2'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
@@ -310,10 +346,10 @@ jobs:
|
||||
run: ${{ inputs.macos_arm_before_script }}
|
||||
|
||||
- name: 🐧 Ubuntu before scripts
|
||||
if: matrix.system == 'ubuntu' && inputs.ubuntu_before_script != ''
|
||||
if: ( matrix.system == 'ubuntu' || matrix.system == 'ubuntu-arm' ) && inputs.ubuntu_before_script != ''
|
||||
run: ${{ inputs.ubuntu_before_script }}
|
||||
|
||||
# Windows before script
|
||||
# TODO: Windows before script
|
||||
|
||||
- name: 🪟🟦 MinGW64 before scripts
|
||||
if: matrix.system == 'msys2' && matrix.runtime == 'MINGW64' && inputs.mingw64_before_script != ''
|
||||
@@ -323,95 +359,37 @@ jobs:
|
||||
if: matrix.system == 'msys2' && matrix.runtime == 'UCRT64' && inputs.ucrt64_before_script != ''
|
||||
run: ${{ inputs.ucrt64_before_script }}
|
||||
|
||||
# Read pyproject.toml
|
||||
|
||||
- name: 🔁 Extract configurations from pyproject.toml
|
||||
id: getVariables
|
||||
shell: python
|
||||
run: |
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
from sys import version
|
||||
from textwrap import dedent
|
||||
|
||||
print(f"Python: {version}")
|
||||
|
||||
from tomli import load as tomli_load
|
||||
|
||||
htmlDirectory = Path("htmlcov")
|
||||
xmlFile = Path("./coverage.xml")
|
||||
jsonFile = Path("./coverage.json")
|
||||
coverageRC = "${{ inputs.coverage_config }}".strip()
|
||||
|
||||
# Read output paths from 'pyproject.toml' file
|
||||
if coverageRC == "pyproject.toml":
|
||||
pyProjectFile = Path("pyproject.toml")
|
||||
if pyProjectFile.exists():
|
||||
with pyProjectFile.open("rb") as file:
|
||||
pyProjectSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(pyProjectSettings["tool"]["coverage"]["html"]["directory"])
|
||||
xmlFile = Path(pyProjectSettings["tool"]["coverage"]["xml"]["output"])
|
||||
jsonFile = Path(pyProjectSettings["tool"]["coverage"]["json"]["output"])
|
||||
else:
|
||||
print(f"File '{pyProjectFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{pyProjectFile}' not found.")
|
||||
exit(1)
|
||||
|
||||
# Read output paths from '.coveragerc' file
|
||||
elif len(coverageRC) > 0:
|
||||
coverageRCFile = Path(coverageRC)
|
||||
if coverageRCFile.exists():
|
||||
with coverageRCFile.open("rb") as file:
|
||||
coverageRCSettings = tomli_load(file)
|
||||
|
||||
htmlDirectory = Path(coverageRCSettings["html"]["directory"])
|
||||
xmlFile = Path(coverageRCSettings["xml"]["output"])
|
||||
jsonFile = Path(coverageRCSettings["json"]["output"])
|
||||
else:
|
||||
print(f"File '{coverageRCFile}' not found.")
|
||||
print(f"::error title=FileNotFoundError::File '{coverageRCFile}' not found.")
|
||||
exit(1)
|
||||
|
||||
# Write jobs to special file
|
||||
github_output = Path(getenv("GITHUB_OUTPUT"))
|
||||
print(f"GITHUB_OUTPUT: {github_output}")
|
||||
with github_output.open("a+", encoding="utf-8") as f:
|
||||
f.write(dedent(f"""\
|
||||
unittest_report_html_directory={htmlDirectory}
|
||||
coverage_report_html_directory={htmlDirectory.as_posix()}
|
||||
coverage_report_xml={xmlFile}
|
||||
coverage_report_json={jsonFile}
|
||||
"""))
|
||||
|
||||
print(f"DEBUG:\n html={htmlDirectory}\n xml={xmlFile}\n json={jsonFile}")
|
||||
|
||||
# Run pytests
|
||||
|
||||
# TODO: allow configuration of pytest_args
|
||||
- name: ✅ Run unit tests (Ubuntu/macOS)
|
||||
if: matrix.system != 'windows'
|
||||
id: pytest_bash
|
||||
if: ( matrix.system != 'windows' && matrix.system != 'windows-arm' )
|
||||
continue-on-error: true
|
||||
run: |
|
||||
export ENVIRONMENT_NAME="${{ matrix.envname }}"
|
||||
export PYTHONPATH=$(pwd)
|
||||
|
||||
cd "${{ inputs.root_directory || '.' }}"
|
||||
[ -n '${{ inputs.unittest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=report/unit/TestReportSummary.xml' || unset PYTEST_ARGS
|
||||
[ -n '${{ inputs.unittest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=${{ fromJson(inputs.unittest_report_xml).fullpath }}' || unset PYTEST_ARGS
|
||||
if [ -n '${{ inputs.coverage_config }}' ]; then
|
||||
echo "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
|
||||
printf "%s\n" "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
|
||||
coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}
|
||||
else
|
||||
echo "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
|
||||
printf "%s\n" "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
|
||||
python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}
|
||||
fi
|
||||
|
||||
- name: ✅ Run unit tests (Windows)
|
||||
if: matrix.system == 'windows'
|
||||
id: pytest_posh
|
||||
if: ( matrix.system == 'windows' || matrix.system == 'windows-arm' )
|
||||
continue-on-error: true
|
||||
run: |
|
||||
$env:ENVIRONMENT_NAME = "${{ matrix.envname }}"
|
||||
$env:PYTHONPATH = (Get-Location).ToString()
|
||||
|
||||
cd "${{ inputs.root_directory || '.' }}"
|
||||
$PYTEST_ARGS = if ("${{ inputs.unittest_xml_artifact }}") { "--junitxml=report/unit/TestReportSummary.xml" } else { "" }
|
||||
$PYTEST_ARGS = if ("${{ inputs.unittest_xml_artifact }}") { "--junitxml=${{ fromJson(inputs.unittest_report_xml).fullpath }}" } else { "" }
|
||||
if ("${{ inputs.coverage_config }}") {
|
||||
Write-Host "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}"
|
||||
coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.unittest_directory }}
|
||||
@@ -421,32 +399,35 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Convert coverage to XML format (Cobertura)
|
||||
id: convert_xml
|
||||
if: inputs.coverage_xml_artifact != ''
|
||||
continue-on-error: true
|
||||
run: coverage xml --data-file=.coverage
|
||||
|
||||
- name: Convert coverage to JSON format
|
||||
id: convert_json
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
continue-on-error: true
|
||||
run: coverage json --data-file=.coverage
|
||||
|
||||
- name: Convert coverage to HTML format
|
||||
id: convert_html
|
||||
if: inputs.coverage_html_artifact != ''
|
||||
continue-on-error: true
|
||||
run: |
|
||||
coverage html --data-file=.coverage -d ${{ steps.getVariables.outputs.coverage_report_html_directory }}
|
||||
rm ${{ steps.getVariables.outputs.coverage_report_html_directory }}/.gitignore
|
||||
coverage html --data-file=.coverage -d ${{ fromJson(inputs.coverage_report_html).directory }}
|
||||
rm ${{ fromJson(inputs.coverage_report_html).directory }}/.gitignore
|
||||
|
||||
# Upload artifacts
|
||||
|
||||
- name: 📤 Upload 'TestReportSummary.xml' artifact
|
||||
- name: 📤 Upload '${{ fromJson(inputs.unittest_report_xml).filename }}' artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
if: inputs.unittest_xml_artifact != ''
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.unittest_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
|
||||
working-directory: report/unit
|
||||
path: TestReportSummary.xml
|
||||
working-directory: ${{ fromJson(inputs.unittest_report_xml).directory }}
|
||||
path: ${{ fromJson(inputs.unittest_report_xml).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
@@ -456,7 +437,7 @@ jobs:
|
||||
# uses: pyTooling/upload-artifact@v4
|
||||
# with:
|
||||
# name: ${{ inputs.unittest_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
|
||||
# path: ${{ steps.getVariables.outputs.unittest_report_html_directory }}
|
||||
# path: ${{ inputs.unittest_report_html_directory }}
|
||||
# if-no-files-found: error
|
||||
# retention-days: 1
|
||||
|
||||
@@ -472,32 +453,48 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage XML Report' artifact
|
||||
if: inputs.coverage_xml_artifact != ''
|
||||
if: inputs.coverage_xml_artifact != '' && steps.convert_xml.outcome == 'success'
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
|
||||
path: ${{ steps.getVariables.outputs.coverage_report_xml }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_xml).directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_xml).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage JSON Report' artifact
|
||||
if: inputs.coverage_json_artifact != ''
|
||||
if: inputs.coverage_json_artifact != '' && steps.convert_json.outcome == 'success'
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_json_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
|
||||
path: ${{ steps.getVariables.outputs.coverage_report_json }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_json).directory }}
|
||||
path: ${{ fromJson(inputs.coverage_report_json).filename }}
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: 📤 Upload 'Coverage HTML Report' artifact
|
||||
if: inputs.coverage_html_artifact != ''
|
||||
if: inputs.coverage_html_artifact != '' && steps.convert_html.outcome == 'success'
|
||||
continue-on-error: true
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ inputs.coverage_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
|
||||
working-directory: ${{ steps.getVariables.outputs.coverage_report_html_directory }}
|
||||
working-directory: ${{ fromJson(inputs.coverage_report_html).directory }}
|
||||
path: '*'
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: Generate error messages
|
||||
shell: bash
|
||||
run: |
|
||||
exitCode=0
|
||||
if [[ "${{ steps.pytest_bash.outcome }}" == "failure" || "${{ steps.pytest_posh.outcome }}" == "failure" ]]; then
|
||||
printf "❌ pytest: %s\n" "Error in pytest execution."
|
||||
printf "::error title=%s::%s\n" "pytest" "Error in pytest execution."
|
||||
exitCode=1
|
||||
else
|
||||
printf "✅ pytest: No errors.\n"
|
||||
fi
|
||||
|
||||
exit $exitCode
|
||||
|
||||
8
.github/workflows/VerifyDocs.yml
vendored
8
.github/workflows/VerifyDocs.yml
vendored
@@ -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. #
|
||||
@@ -33,7 +33,7 @@ on:
|
||||
python_version:
|
||||
description: 'Python version.'
|
||||
required: false
|
||||
default: '3.12'
|
||||
default: '3.13'
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
@@ -44,10 +44,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: ⏬ Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: 🐍 Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python_version }}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
include: ${{ fromJson(needs.Params.outputs.python_jobs) }}
|
||||
steps:
|
||||
- name: Content creation for ${{ matrix.system }}-${{ matrix.python }}
|
||||
run: echo "${{ matrix.runs-on }}-${{ matrix.python }}" >> artifact.txt
|
||||
run: printf "%s\n" "${{ matrix.runs-on }}-${{ matrix.python }}" >> artifact.txt
|
||||
|
||||
- name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }}
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Package creation
|
||||
run: echo "Package" >> package.txt
|
||||
run: printf "%s\n" "Package" >> package.txt
|
||||
|
||||
- name: 📤 Upload artifact for ${{ matrix.system }}-${{ matrix.python }}
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
|
||||
38
.github/workflows/_Checking_AvailableRunners.yml
vendored
Normal file
38
.github/workflows/_Checking_AvailableRunners.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Testing available GitHub Action Images
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
RunnerTest:
|
||||
name: ${{ matrix.icon }} ${{ matrix.name }}
|
||||
|
||||
runs-on: ${{ matrix.image }}
|
||||
continue-on-error: ${{ matrix.can-fail }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {icon: '🐧', name: 'Ubuntu 22.04 (x86-64)', image: 'ubuntu-22.04', shell: 'bash', can-fail: false}
|
||||
- {icon: '🐧', name: 'Ubuntu 24.04 (x86-64)', image: 'ubuntu-24.04', shell: 'bash', can-fail: false} # latest
|
||||
- {icon: '🍎', name: 'macOS-13 (x86-64)', image: 'macos-13', shell: 'bash', can-fail: false}
|
||||
- {icon: '🍎', name: 'macOS-14 (x86-64)', image: 'macos-14-large', shell: 'bash', can-fail: true } # not in free plan
|
||||
- {icon: '🍎', name: 'macOS-15 (x86-64)', image: 'macos-15-large', shell: 'bash', can-fail: true } # not in free plan
|
||||
- {icon: '🍏', name: 'macOS-13 (aarch64)', image: 'macos-13-xlarge', shell: 'bash', can-fail: true } # not in free plan
|
||||
- {icon: '🍏', name: 'macOS-14 (aarch64)', image: 'macos-14', shell: 'bash', can-fail: false} # latest
|
||||
- {icon: '🍏', name: 'macOS-15 (aarch64)', image: 'macos-15', shell: 'bash', can-fail: false}
|
||||
- {icon: '🪟', name: 'Windows Server 2022', image: 'windows-2022', shell: 'bash', can-fail: false}
|
||||
- {icon: '🪟', name: 'Windows Server 2025', image: 'windows-2025', shell: 'bash', can-fail: false} # latest
|
||||
# Third party images by ARM for aarch64
|
||||
- {icon: '⛄', name: 'Ubuntu 22.04 (aarch64)', image: 'ubuntu-22.04-arm', shell: 'bash', can-fail: false}
|
||||
- {icon: '⛄', name: 'Ubuntu 24.04 (aarch64)', image: 'ubuntu-24.04-arm', shell: 'bash', can-fail: false}
|
||||
- {icon: '🏢', name: 'Windows 11 (arch64)', image: 'windows-11-arm', shell: 'bash', can-fail: false}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
steps:
|
||||
- name: 'uname -a'
|
||||
run: uname -a
|
||||
209
.github/workflows/_Checking_JobTemplates.yml
vendored
209
.github/workflows/_Checking_JobTemplates.yml
vendored
@@ -5,62 +5,71 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@main
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@main
|
||||
with:
|
||||
package_name: pyDummy
|
||||
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: pyDummy
|
||||
python_version_list: "3.9 3.10 3.11 3.12 3.13 pypy-3.9 pypy-3.10"
|
||||
# disable_list: "windows:pypy-3.10"
|
||||
package_name: 'myPackage'
|
||||
python_version_list: '3.9 3.10 3.11 3.12 3.13 3.14 pypy-3.10 pypy-3.11'
|
||||
disable_list: 'windows-arm:pypy-3.10 windows-arm:pypy-3.11'
|
||||
|
||||
PlatformTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: Platform
|
||||
python_version_list: ""
|
||||
system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64"
|
||||
package_name: 'myPackage'
|
||||
name: 'Platform'
|
||||
python_version_list: ''
|
||||
system_list: 'ubuntu ubuntu-arm windows windows-arm macos mingw64 clang64 ucrt64'
|
||||
|
||||
InstallParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
package_name: 'myPackage'
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
python_version_list: ''
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
unittest_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }}
|
||||
# coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
# coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
# coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
# coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }}
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
unittest_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
|
||||
PlatformTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- PlatformTestingParams
|
||||
with:
|
||||
jobs: ${{ needs.PlatformTestingParams.outputs.python_jobs }}
|
||||
jobs: ${{ needs.PlatformTestingParams.outputs.python_jobs }}
|
||||
# tests_directory: ""
|
||||
unittest_directory: platform
|
||||
unittest_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
unittest_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_html }}
|
||||
unittest_directory: platform
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
unittest_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_html }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
coverage_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
|
||||
# Coverage:
|
||||
# uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@main
|
||||
# needs:
|
||||
# - UnitTestingParams
|
||||
# with:
|
||||
# python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
# artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
# secrets:
|
||||
# codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
coverage_xml_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@main
|
||||
@@ -69,55 +78,82 @@ jobs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
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'
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
|
||||
html_report: ${{ needs.ConfigParams.outputs.typing_report_html }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
CodeQuality:
|
||||
uses: pyTooling/Actions/.github/workflows/CheckCodeQuality.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
package_directory: ${{ needs.UnitTestingParams.outputs.package_directory }}
|
||||
artifact: CodeQuality
|
||||
|
||||
DocCoverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@r1
|
||||
uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- 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:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
# - Coverage
|
||||
- PlatformTesting
|
||||
# - UnitTesting
|
||||
# - PlatformTesting
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
|
||||
Install:
|
||||
uses: pyTooling/Actions/.github/workflows/InstallPackage.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- InstallParams
|
||||
- Package
|
||||
with:
|
||||
jobs: ${{ needs.InstallParams.outputs.python_jobs }}
|
||||
wheel: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
package_name: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
- PlatformTesting
|
||||
# - Coverage
|
||||
with:
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
secrets:
|
||||
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
coverage_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
codecov: true
|
||||
codacy: true
|
||||
secrets: inherit
|
||||
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@main
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
- PlatformTesting
|
||||
with:
|
||||
additional_merge_args: '-d "--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit;reduce-depth:pytest.tests.platform"'
|
||||
additional_merge_args: '-d "--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit;reduce-depth:pytest.tests.platform"'
|
||||
testsuite-summary-name: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
merged_junit_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
codecov: true
|
||||
dorny: true
|
||||
secrets: inherit
|
||||
|
||||
# VerifyDocs:
|
||||
# uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@main
|
||||
@@ -135,23 +171,23 @@ jobs:
|
||||
- PublishCoverageResults
|
||||
# - VerifyDocs
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
coverage_report_json_directory: ${{ needs.ConfigParams.outputs.coverage_report_json_directory }}
|
||||
# unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
# coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
unittest_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
|
||||
IntermediateCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/IntermediateCleanUp.yml@r1
|
||||
uses: pyTooling/Actions/.github/workflows/IntermediateCleanUp.yml@main
|
||||
needs:
|
||||
- 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 }}-
|
||||
xml_unittest_artifacts_prefix: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-
|
||||
|
||||
PDFDocumentation:
|
||||
uses: pyTooling/Actions/.github/workflows/LaTeXDocumentation.yml@main
|
||||
@@ -159,48 +195,71 @@ jobs:
|
||||
- UnitTestingParams
|
||||
- Documentation
|
||||
with:
|
||||
document: actions
|
||||
document: 'Actions'
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
pdf_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_pdf }}
|
||||
pdf_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_pdf }}
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@main
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- Documentation
|
||||
# - PDFDocumentation
|
||||
# - Coverage
|
||||
- PDFDocumentation
|
||||
- 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@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
TriggerTaggedRelease:
|
||||
uses: pyTooling/Actions/.github/workflows/TagReleaseCommit.yml@main
|
||||
needs:
|
||||
- Prepare
|
||||
- UnitTesting
|
||||
- PlatformTesting
|
||||
# - Coverage
|
||||
- Install
|
||||
# - 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@main
|
||||
needs:
|
||||
- Prepare
|
||||
- UnitTesting
|
||||
- PlatformTesting
|
||||
- Install
|
||||
# - StaticTypeCheck
|
||||
- Package
|
||||
- PublishToGitHubPages
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
tag: ${{ needs.Prepare.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- ReleasePage
|
||||
# - Package
|
||||
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@main
|
||||
@@ -208,11 +267,10 @@ jobs:
|
||||
- UnitTestingParams
|
||||
- PlatformTestingParams
|
||||
- UnitTesting
|
||||
# - Coverage
|
||||
- StaticTypeCheck
|
||||
- PlatformTesting
|
||||
- Documentation
|
||||
# - PDFDocumentation
|
||||
- PDFDocumentation
|
||||
- PublishTestResults
|
||||
- PublishCoverageResults
|
||||
- PublishToGitHubPages
|
||||
@@ -222,7 +280,6 @@ jobs:
|
||||
remaining: |
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}-*
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_html }}-*
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}-*
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_xml }}-*
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}-*
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}-*
|
||||
@@ -234,9 +291,9 @@ jobs:
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).statictyping_html }}
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_xml }}-*
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).unittesting_html }}-*
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_sqlite }}-*
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_xml }}-*
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_json }}-*
|
||||
${{ fromJson(needs.PlatformTestingParams.outputs.artifact_names).codecoverage_html }}-*
|
||||
|
||||
@@ -8,8 +8,12 @@ jobs:
|
||||
NamespacePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@main
|
||||
with:
|
||||
package_namespace: pyExamples
|
||||
package_name: Extensions
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
codecov: true
|
||||
codacy: true
|
||||
dorny: true
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }}
|
||||
|
||||
93
.github/workflows/_Checking_Nightly.yml
vendored
93
.github/workflows/_Checking_Nightly.yml
vendored
@@ -12,9 +12,9 @@ jobs:
|
||||
steps:
|
||||
- name: 🖉 Build 1
|
||||
run: |
|
||||
echo "Document 1 $(date --utc '+%d.%m.%Y - %H:%M:%S')" > document1.txt
|
||||
echo "Analysis log $(date --utc '+%d.%m.%Y - %H:%M:%S')" > analysis.log
|
||||
echo "Build log $(date --utc '+%d.%m.%Y - %H:%M:%S')" > build.log
|
||||
printf "%s\n" "Document 1 $(date --utc '+%d.%m.%Y - %H:%M:%S')" > document1.txt
|
||||
printf "%s\n" "Analysis log $(date --utc '+%d.%m.%Y - %H:%M:%S')" > analysis.log
|
||||
printf "%s\n" "Build log $(date --utc '+%d.%m.%Y - %H:%M:%S')" > build.log
|
||||
|
||||
- name: 📤 Upload artifact
|
||||
uses: pyTooling/upload-artifact@v4
|
||||
@@ -28,8 +28,8 @@ jobs:
|
||||
|
||||
- name: 🖉 Program
|
||||
run: |
|
||||
echo "Document other $(date --utc '+%d.%m.%Y - %H:%M:%S')" > document1.txt
|
||||
echo "Program $(date --utc '+%d.%m.%Y - %H:%M:%S')" > program.py
|
||||
printf "%s\n" "Document other $(date --utc '+%d.%m.%Y - %H:%M:%S')" > document1.txt
|
||||
printf "%s\n" "Program $(date --utc '+%d.%m.%Y - %H:%M:%S')" > program.py
|
||||
|
||||
- name: 📤 Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -42,49 +42,27 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
NightlyPage:
|
||||
uses: pyTooling/Actions/.github/workflows/NightlyRelease.yml@main
|
||||
uses: ./.github/workflows/PublishReleaseNotes.yml
|
||||
needs:
|
||||
- Build
|
||||
secrets: inherit
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
# attestations: write
|
||||
actions: write
|
||||
with:
|
||||
can-fail: true
|
||||
prerelease: true
|
||||
replacements: |
|
||||
version=4.2.0
|
||||
tool=myTool
|
||||
prog=program
|
||||
nightly_title: "Nightly Release"
|
||||
nightly_description: |
|
||||
This *nightly* release contains all latest and important artifacts created by GHDL's CI pipeline.
|
||||
tag: 4.2.0
|
||||
title: "Nightly Test Release"
|
||||
description: |
|
||||
This *nightly* release contains all latest and important artifacts created by %tool%'s CI pipeline.
|
||||
|
||||
# GHDL %version%
|
||||
# %tool% %version%
|
||||
|
||||
GHDL offers the simulator and synthesis tool for VHDL. GHDL can be build for various backends:
|
||||
* `gcc` - using the GCC compiler framework
|
||||
* `mcode` - in memory code generation
|
||||
* `llvm` - using the LLVM compiler framework
|
||||
* `llvm-jit` - using the LLVM compiler framework, but in memory
|
||||
|
||||
The following asset categories are provided for GHDL:
|
||||
* macOS x64-64 builds as TAR/GZ file
|
||||
* macOS aarch64 builds as TAR/GZ file
|
||||
* Ubuntu 24.04 LTS builds as TAR/GZ file
|
||||
* Windows builds for standalone usage (without MSYS2) as ZIP file
|
||||
* MSYS2 packages as TAR/ZST file
|
||||
|
||||
# pyGHDL %version%
|
||||
|
||||
The Python package `pyGHDL` offers Python binding (`pyGHDL.libghdl`) to a `libghdl` shared library (`*.so`/`*.dll`).
|
||||
In addition to the low-level binding layer, pyGHDL offers:
|
||||
* a Language Server Protocol (LSP) instance for e.g. live code checking by editors
|
||||
* a Code Document Object Model (CodeDOM) based on [pyVHDLModel](https://github.com/VHDL/pyVHDLModel)
|
||||
|
||||
The following asset categories are provided for pyGHDL:
|
||||
* Platform specific Python wheel package for Ubuntu incl. `pyGHDL...so`
|
||||
* Platform specific Python wheel package for Windows incl. `pyGHDL...dll`
|
||||
* %prog%
|
||||
assets: |
|
||||
document: document1.txt: Documentation
|
||||
document: build.log: Logfile - %tool% - %tool%
|
||||
@@ -99,3 +77,46 @@ 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/PublishReleaseNotes.yml
|
||||
needs:
|
||||
- Build
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
can-fail: true
|
||||
replacements: |
|
||||
version=4.2.0
|
||||
tool=myTool
|
||||
prog=program
|
||||
tag: inventory
|
||||
title: "Nightly Test Release with Inventory"
|
||||
description: |
|
||||
This *nightly* release contains all latest and important artifacts created by %tool%'s CI pipeline.
|
||||
|
||||
# %tool% %version%
|
||||
|
||||
* %prog%
|
||||
* inventory.json
|
||||
inventory-json: "inventory.json"
|
||||
inventory-version: 4.2.5
|
||||
inventory-categories: "kind1,kind2"
|
||||
assets: |
|
||||
# artifact: file: labels: asset title
|
||||
document: document1.txt: doc,html: Documentation
|
||||
document: build.log: build,log: Logfile - %tool% - %tool%
|
||||
other: document1.txt: build,SBOM:SBOM - %version%
|
||||
other: %prog%.py: app,binary:Application - %tool% - %version%
|
||||
document:!archive1.zip: Archive 1 - zip
|
||||
document:!archive2.tgz: Archive 2 - tgz
|
||||
document:!archive3.tar.gz: Archive 3 - tar.gz
|
||||
document:!archive4.tzst: Archive 4 - tzst
|
||||
document:!archive5.tar.zst: Archive 5 - tar.zst
|
||||
document:$archive6.tgz: Archive 6 - tgz + dir
|
||||
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
|
||||
|
||||
358
.github/workflows/_Checking_Parameters.yml
vendored
358
.github/workflows/_Checking_Parameters.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: Example
|
||||
python_version_list: "3.11 3.12 pypy-3.9 pypy-3.10"
|
||||
python_version_list: "3.12 3.13 pypy-3.10 pypy-3.11"
|
||||
|
||||
Params_Systems:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
@@ -26,25 +26,25 @@ jobs:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: Example
|
||||
python_version_list: "3.11"
|
||||
python_version_list: "3.12"
|
||||
system_list: "ubuntu windows macos macos-arm"
|
||||
include_list: "ubuntu:3.12 ubuntu:3.13"
|
||||
include_list: "ubuntu:3.13 ubuntu:3.14 ubuntu-arm:3.12"
|
||||
|
||||
Params_Exclude:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: Example
|
||||
python_version_list: "3.12"
|
||||
python_version_list: "3.13"
|
||||
system_list: "ubuntu windows macos macos-arm"
|
||||
exclude_list: "windows:3.12 windows:3.13"
|
||||
exclude_list: "windows:3.13 windows:3.14"
|
||||
|
||||
Params_Disable:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: Example
|
||||
python_version_list: "3.12"
|
||||
python_version_list: "3.13"
|
||||
system_list: "ubuntu windows macos macos-arm"
|
||||
disable_list: "windows:3.12 windows:3.13"
|
||||
disable_list: "windows:3.13 windows:3.14"
|
||||
|
||||
Params_All:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
@@ -55,15 +55,9 @@ jobs:
|
||||
include_list: "windows:3.10 windows:3.11 windows:3.13"
|
||||
exclude_list: "macos:3.12 macos:3.13"
|
||||
|
||||
Params_Check:
|
||||
Params_Check_Default:
|
||||
needs:
|
||||
- Params_Default
|
||||
- Params_PythonVersions
|
||||
- Params_Systems
|
||||
- Params_Include
|
||||
- Params_Exclude
|
||||
- Params_Disable
|
||||
- Params_All
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
@@ -72,7 +66,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
# Params_Default
|
||||
|
||||
- name: Checking results from 'Params_Default'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -82,24 +76,28 @@ jobs:
|
||||
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
expectedSystems = ["ubuntu", "windows", "macos", "macos-arm"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons] + ["mingw64:3.11", "ucrt64:3.11"]
|
||||
expectedSystems = ["ubuntu", "ubuntu-arm", "windows", "windows-arm", "macos", "macos-arm"]
|
||||
excludedJobs = ["windows-arm:3.9", "windows-arm:3.10"]
|
||||
includeJobs = ["mingw64:3.12", "ucrt64:3.12"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_Default.outputs.python_version }}"""
|
||||
@@ -135,7 +133,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_PythonVersions
|
||||
Params_Check_PythonVersions:
|
||||
needs:
|
||||
- Params_PythonVersions
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_PythonVersions'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -144,25 +153,29 @@ jobs:
|
||||
from pyTooling.Common import zipdicts
|
||||
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.11", "3.12", "pypy-3.9", "pypy-3.10"]
|
||||
expectedSystems = ["ubuntu", "windows", "macos", "macos-arm"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons] + ["mingw64:3.11", "ucrt64:3.11"]
|
||||
expectedPythons = ["3.12", "3.13", "pypy-3.10", "pypy-3.11"]
|
||||
expectedSystems = ["ubuntu", "ubuntu-arm", "windows", "windows-arm", "macos", "macos-arm"]
|
||||
excludedJobs = ["windows-arm:pypy-3.10", "windows-arm:pypy-3.11"]
|
||||
includeJobs = ["mingw64:3.12", "ucrt64:3.12"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_PythonVersions.outputs.python_version }}"""
|
||||
@@ -198,7 +211,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_Systems
|
||||
Params_Check_Systems:
|
||||
needs:
|
||||
- Params_Systems
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_Systems'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -209,23 +233,27 @@ jobs:
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
expectedSystems = ["windows"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons] + ["mingw32:3.11", "mingw64:3.11"]
|
||||
excludedJobs = []
|
||||
includeJobs = ["mingw64:3.12", "ucrt64:3.12"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_Systems.outputs.python_version }}"""
|
||||
@@ -261,7 +289,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_Include
|
||||
Params_Check_Include:
|
||||
needs:
|
||||
- Params_Include
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_Include'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -272,23 +311,27 @@ jobs:
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.12"]
|
||||
expectedSystems = ["ubuntu", "windows", "macos", "macos-arm"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons] + ["ubuntu:3.11", "ubuntu:3.12"]
|
||||
excludedJobs = []
|
||||
includeJobs = ["ubuntu:3.13", "ubuntu:3.14", "ubuntu-arm:3.12"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_Include.outputs.python_version }}"""
|
||||
@@ -324,7 +367,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_Exclude
|
||||
Params_Check_Exclude:
|
||||
needs:
|
||||
- Params_Exclude
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_Exclude'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -333,25 +387,29 @@ jobs:
|
||||
from pyTooling.Common import zipdicts
|
||||
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.12"]
|
||||
expectedPythons = ["3.13"]
|
||||
expectedSystems = ["ubuntu", "macos", "macos-arm"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons]
|
||||
excludedJobs = []
|
||||
includeJobs = []
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_Exclude.outputs.python_version }}"""
|
||||
@@ -387,7 +445,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_Disable
|
||||
Params_Check_Disable:
|
||||
needs:
|
||||
- Params_Disable
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_Disable'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -396,30 +465,34 @@ jobs:
|
||||
from pyTooling.Common import zipdicts
|
||||
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.12"]
|
||||
expectedSystems = ["ubuntu", "macos", "macos-arm"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons]
|
||||
expectedPythons = ["3.13"]
|
||||
expectedSystems = ["ubuntu", "windows", "macos", "macos-arm"]
|
||||
excludedJobs = ["windows:3.13"]
|
||||
includeJobs = []
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_Exclude.outputs.python_version }}"""
|
||||
actualPythonJobs = json_loads("""${{ needs.Params_Exclude.outputs.python_jobs }}""".replace("'", '"'))
|
||||
actualArtifactNames = json_loads("""${{ needs.Params_Exclude.outputs.artifact_names }}""".replace("'", '"'))
|
||||
actualPythonVersion = """${{ needs.Params_Disable.outputs.python_version }}"""
|
||||
actualPythonJobs = json_loads("""${{ needs.Params_Disable.outputs.python_jobs }}""".replace("'", '"'))
|
||||
actualArtifactNames = json_loads("""${{ needs.Params_Disable.outputs.artifact_names }}""".replace("'", '"'))
|
||||
errors = 0
|
||||
|
||||
if actualPythonVersion != expectedPythonVersion:
|
||||
@@ -450,7 +523,18 @@ jobs:
|
||||
print(f"All checks PASSED.")
|
||||
exit(errors)
|
||||
|
||||
# Params_All
|
||||
Params_Check_All:
|
||||
needs:
|
||||
- Params_All
|
||||
runs-on: ubuntu-24.04
|
||||
defaults:
|
||||
run:
|
||||
shell: python
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pip install --disable-pip-version-check --break-system-packages pyTooling
|
||||
|
||||
- name: Checking results from 'Params_All'
|
||||
run: |
|
||||
from json import loads as json_loads
|
||||
@@ -461,23 +545,27 @@ jobs:
|
||||
expectedPythonVersion = "3.13"
|
||||
expectedPythons = ["3.12", "3.13"]
|
||||
expectedSystems = ["ubuntu", "macos-arm", "windows"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons] + ["windows:3.10", "windows:3.11", "windows:3.13"]
|
||||
excludedJobs = []
|
||||
includeJobs = ["windows:3.10", "windows:3.11", "windows:3.13"]
|
||||
expectedJobs = [f"{system}:{python}" for system in expectedSystems for python in expectedPythons if f"{system}:{python}" not in excludedJobs] + includeJobs
|
||||
expectedName = "Example"
|
||||
expectedArtifacts = {
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
"unittesting_xml": f"{expectedName}-UnitTestReportSummary-XML",
|
||||
"unittesting_html": f"{expectedName}-UnitTestReportSummary-HTML",
|
||||
"perftesting_xml": f"{expectedName}-PerformanceTestReportSummary-XML",
|
||||
"benchtesting_xml": f"{expectedName}-BenchmarkTestReportSummary-XML",
|
||||
"apptesting_xml": f"{expectedName}-ApplicationTestReportSummary-XML",
|
||||
"codecoverage_sqlite": f"{expectedName}-CodeCoverage-SQLite",
|
||||
"codecoverage_xml": f"{expectedName}-CodeCoverage-XML",
|
||||
"codecoverage_json": f"{expectedName}-CodeCoverage-JSON",
|
||||
"codecoverage_html": f"{expectedName}-CodeCoverage-HTML",
|
||||
"statictyping_cobertura": f"{expectedName}-StaticTyping-Cobertura-XML",
|
||||
"statictyping_junit": f"{expectedName}-StaticTyping-JUnit-XML",
|
||||
"statictyping_html": f"{expectedName}-StaticTyping-HTML",
|
||||
"package_all": f"{expectedName}-Packages",
|
||||
"documentation_html": f"{expectedName}-Documentation-HTML",
|
||||
"documentation_latex": f"{expectedName}-Documentation-LaTeX",
|
||||
"documentation_pdf": f"{expectedName}-Documentation-PDF",
|
||||
}
|
||||
|
||||
actualPythonVersion = """${{ needs.Params_All.outputs.python_version }}"""
|
||||
|
||||
@@ -8,7 +8,12 @@ jobs:
|
||||
SimplePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@main
|
||||
with:
|
||||
package_name: pyDummy
|
||||
package_name: myPackage
|
||||
codecov: true
|
||||
codacy: true
|
||||
dorny: true
|
||||
cleanup: false
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }}
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -15,6 +15,9 @@ coverage.xml
|
||||
/report/unit
|
||||
/tests/*.github
|
||||
|
||||
# bandit
|
||||
/report/bandit
|
||||
|
||||
# setuptools
|
||||
/build/**/*.*
|
||||
/dist/**/*.*
|
||||
@@ -25,8 +28,8 @@ coverage.xml
|
||||
|
||||
# Sphinx
|
||||
doc/_build/
|
||||
doc/pyDummy/**/*.*
|
||||
!doc/pyDummy/index.rst
|
||||
doc/myPackage/**/*.*
|
||||
!doc/myPackage/index.rst
|
||||
|
||||
# BuildTheDocs
|
||||
doc/_theme/**/*.*
|
||||
|
||||
8
.idea/Actions.iml
generated
8
.idea/Actions.iml
generated
@@ -1,7 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/myFramework" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/myPackage" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/doc/_build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/report" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.13" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
# ==================================================================================================================== #
|
||||
# Authors: #
|
||||
# Patrick Lehmann #
|
||||
# Unai Martinez-Corral #
|
||||
# #
|
||||
# ==================================================================================================================== #
|
||||
# Copyright 2020-2024 The pyTooling Authors #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
# SPDX-License-Identifier: Apache-2.0 #
|
||||
# ==================================================================================================================== #
|
||||
name: Pipeline
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
# This job is a workaround for global variables
|
||||
# See https://github.com/actions/runner/issues/480
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@main
|
||||
with:
|
||||
name: ToolName
|
||||
# Optional
|
||||
system_list: 'ubuntu windows msys2 macos'
|
||||
python_version: '3.10'
|
||||
python_version_list: '3.8 3.9 3.10'
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@main
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
jobs: ${{ needs.Params.outputs.python_jobs }}
|
||||
# Optional
|
||||
requirements: '-r tests/requirements.txt'
|
||||
pacboy: >-
|
||||
python-pip:p
|
||||
python-wheel:p
|
||||
python-coverage:p
|
||||
python-lxml:p
|
||||
mingw_requirements: '-r tests/requirements.mingw.txt'
|
||||
tests_directory: 'tests'
|
||||
unittest_directory: 'unit'
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}
|
||||
|
||||
Coverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@main
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
# Optional
|
||||
python_version: ${{ needs..Params.outputs.python_version }}
|
||||
requirements: '-r tests/requirements.txt'
|
||||
tests_directory: 'tests'
|
||||
unittest_directory: 'unit'
|
||||
secrets:
|
||||
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@main
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
commands: |
|
||||
mypy --junit-xml StaticTypingSummary.xml --html-report htmlmypy -p ToolName
|
||||
html_artifact: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
junit_artifact: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_junit }}
|
||||
# Optional
|
||||
python_version: ${{ needs..Params.outputs.python_version }}
|
||||
requirements: '-r tests/requirements.txt'
|
||||
html_report: 'htmlmypy'
|
||||
junit_report: 'StaticTypingSummary.xml'
|
||||
allow_failure: true
|
||||
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@main
|
||||
needs:
|
||||
- UnitTesting
|
||||
- StaticTypeCheck
|
||||
with:
|
||||
# Optional
|
||||
report_files: artifacts/**/*.xml
|
||||
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@main
|
||||
needs:
|
||||
- Params
|
||||
- Coverage
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
# Optional
|
||||
python_version: ${{ needs..Params.outputs.python_version }}
|
||||
requirements: 'wheel'
|
||||
|
||||
Release:
|
||||
uses: pyTooling/Actions/.github/workflows/Release.yml@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- UnitTesting
|
||||
- Coverage
|
||||
- StaticTypeCheck
|
||||
- Package
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@main
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- Params
|
||||
- Release
|
||||
- Package
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
# Optional
|
||||
python_version: ${{ needs..Params.outputs.python_version }}
|
||||
requirements: 'wheel twine'
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
VerifyDocs:
|
||||
uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@main
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
# Optional
|
||||
python_version: ${{ needs..Params.outputs.python_version }}
|
||||
|
||||
BuildTheDocs:
|
||||
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@main
|
||||
needs:
|
||||
- Params
|
||||
- VerifyDocs
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@main
|
||||
needs:
|
||||
- Params
|
||||
- BuildTheDocs
|
||||
- Coverage
|
||||
- StaticTypeCheck
|
||||
with:
|
||||
doc: ${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
# Optional
|
||||
coverage: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
typing: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@main
|
||||
needs:
|
||||
- Params
|
||||
- PublishTestResults
|
||||
- Coverage
|
||||
- StaticTypeCheck
|
||||
- BuildTheDocs
|
||||
- PublishToGitHubPages
|
||||
with:
|
||||
package: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
remaining: |
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-*
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).statictyping_junit }}
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 135 KiB |
111
README.md
111
README.md
@@ -10,52 +10,97 @@ This repository gathers reusable CI tooling for testing, packaging and distribut
|
||||
See [GitHub Actions and GitHub Reusable Workflows](https://pytooling.github.io/Actions/Background.html) for more
|
||||
background information.
|
||||
|
||||
## Reusable workflows
|
||||
## Reusable Actions
|
||||
|
||||
- **Artifacts:**
|
||||
[**pyTooling/upload-artifact**](https://github.com/pyTooling/upload-artifact): The upload-artifact action will
|
||||
preserve file attributes like permissions.
|
||||
|
||||
[**pyTooling/download-artifact**](https://github.com/pyTooling/download-artifact): The download-artifact action will
|
||||
preserve file attributes like permissions.
|
||||
|
||||
## Predefined Docker Images
|
||||
|
||||
- **Documentation:**
|
||||
[**MikTeX**](https://github.com/pyTooling/MikTeX): A predefined MikTeX image based on Debian Bookworm + Python 3.13
|
||||
with specific tools for documentation generation using e.g. Sphinx and related extensions.
|
||||
|
||||
## Reusable Workflows
|
||||
|
||||
This repository provides 10+ *Reusable Workflows* based on the CI pipelines of the repos in this GitHub organisation,
|
||||
[EDA²](https://github.com/edaa-org), [VHDL](https://github.com/vhdl), and others. By combining them, Python packages can
|
||||
be continuously tested and released along with Sphinx documentation sites, to GitHub Releases, GitHub Pages and PyPI.
|
||||
Optionally, coverage and static type check reports can be gathered and integrated into the online documentation.
|
||||
|
||||
[](ExamplePipeline_dark.png)
|
||||
|
||||
[](ExamplePipeline_light.png)
|
||||
[](doc/_static/pyTooling-Actions-SimplePackage.png)
|
||||
|
||||
As shown in the screenshots above, the expected order is:
|
||||
|
||||
- Global:
|
||||
- [Parameters](.github/workflows/Parameters.yml): a workaround for the limitations to handle global variables in
|
||||
GitHub Actions workflows (see [actions/runner#480](https://github.com/actions/runner/issues/480)).
|
||||
It generates outputs with artifact names and job matrices to be used in later running jobs.
|
||||
- Code testing/analysis:
|
||||
- [UnitTesting](.github/workflows/UnitTesting.yml): run unit test with `pytest` using multiple versions of Python, and
|
||||
optionally upload results as XML reports. Configuration options to `pytest` should be given via section
|
||||
`[tool.pytest.ini_options]` in a `pyproject.toml` file.
|
||||
- [CoverageCollection](.github/workflows/CoverageCollection.yml): collect code coverage data (incl. branch coverage)
|
||||
with `pytest`/`pytest-cov`/`coverage.py` using a single version of Python (latest). It generates HTML and Cobertura
|
||||
(XML)reports, upload the HTML report as an artifact, and upload the test results to Codecov and Codacy. Configuration
|
||||
options to `pytest` and `coverage.py` should be given via section `[tool.pytest.ini_options]` and `[tool.coverage.*]`
|
||||
in a `pyproject.toml` file.
|
||||
- [StaticTypeCheck](.github/workflows/StaticTypeCheck.yml): collect static type check result with `mypy`, and
|
||||
optionally upload results as an HTML report.
|
||||
Example `commands`:
|
||||
- **Global:**
|
||||
[**Parameters**](.github/workflows/Parameters.yml): It generates output parameters with artifact names and job matrices
|
||||
to be used in later running jobs.
|
||||
It's a workaround for the limitations to handle global variables in GitHub Actions workflows (see
|
||||
[actions/runner#480](https://github.com/actions/runner/issues/480)).
|
||||
|
||||
[**ExtractConfiguration**](.github/workflows/ExtractConfiguration.yml): extracts configuration values from
|
||||
`pyproject.toml` and exposes configured paths and filenames as job output parameters.
|
||||
- **Predefined pipelines:**
|
||||
[**CompletePipeline**](.github/workflows/CompletePipeline.yml): is a predefined pipeline for typical Python projects
|
||||
using all predefined job templates of pyTooling at once: (unit testing, code coverage, static typing, documentation
|
||||
report generation and publishing, packaging, releasing, ...)
|
||||
- **Code testing/analysis:**
|
||||
[**ApplicationTesting**](.github/workflows/ApplicationTesting.yml): like UnitTesting, but running tests using an
|
||||
installed Python package.
|
||||
|
||||
[**UnitTesting**](.github/workflows/UnitTesting.yml): run unit test with `pytest` using multiple versions of Python, and
|
||||
optionally upload results as XML reports. Configuration options to `pytest` should be given via section
|
||||
`[tool.pytest.ini_options]` in a `pyproject.toml` file.
|
||||
Besides test results, also code coverage data (incl. branch coverage) can be collected using
|
||||
`pytest`/`pytest-cov`/`coverage.py`. Configuration options to `coverage.py` should be given via section
|
||||
`[tool.coverage.*]` in a `pyproject.toml` file.
|
||||
While multiple report formats can be created in the job, it's recommended to use `PublishTestResults` and/or
|
||||
`PublishCoverageResults` to merge results from matrix runs and then generate final reports as XML, JSON or HTML.
|
||||
Finally, reports can be published to GitHub Pages or cloud services like Codecov and Codacy.
|
||||
|
||||
[**StaticTypeCheck**](.github/workflows/StaticTypeCheck.yml): collect static type check result with `mypy`, and
|
||||
optionally upload results as an HTML report.
|
||||
|
||||
[**VerifyDocs**](.github/workflows/VerifyDocs.yml): extract code examples from the README and test these code snippets.
|
||||
- **Packaging and releasing:**
|
||||
[**Package**](.github/workflows/Package.yml): generate source and wheel packages, and upload them as an artifact.
|
||||
|
||||
[**PublishOnPyPI**](.github/workflows/PublishOnPyPI.yml): publish source and wheel packages to PyPI.
|
||||
|
||||
[**PublishTestResults**](.github/workflows/PublishTestResults.yml): publish unit test results through GH action `dorny/test-reporter`.
|
||||
|
||||
[**PublishCoverageResults**](.github/workflows/PublishCoverageResults.yml): publish ucode coverage results.
|
||||
|
||||
[**NightlyRelease**](.github/workflows/NightlyRelease.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.
|
||||
|
||||
[**LaTeXDocumentation**](.github/workflows/LaTeXDocumentation.yml): compile LaTeX documentation to a PDF file using
|
||||
MikTeX.
|
||||
|
||||
[**PublishToGitHubPages**](.github/workflows/PublishToGitHubPages.yml): publish HTML documentation to GitHub Pages.
|
||||
- **Cleanup:**
|
||||
[**IntermediateCleanUp**](.github/workflows/IntermediateCleanUp.yml): delete intermediate artifacts.
|
||||
|
||||
[**ArtifactCleanUp**](.github/workflows/ArtifactCleanUp.yml): delete artifacts.
|
||||
- **⚠ Deprecated ⚠:**
|
||||
[**CoverageCollection**](.github/workflows/CoverageCollection.yml): Use `UnitTesting`, because is can collect code
|
||||
coverage too. This avoids code duplication in job templates.
|
||||
|
||||
[**BuildTheDocs**](.github/workflows/BuildTheDocs.yml): Use `SphinxDocumentation`, `LaTeXDocumentation` and
|
||||
`PublishToGitHubPages`. BuildTheDocs isn't maintained anymore.
|
||||
|
||||
- [VerifyDocs](.github/workflows/VerifyDocs.yml): extract code examples from the README and test these code snippets.
|
||||
- Packaging and releasing:
|
||||
- [Release](.github/workflows/Release.yml): publish GitHub Release.
|
||||
- [Package](.github/workflows/Package.yml): generate source and wheel packages, and upload them as an artifact.
|
||||
- [PublishOnPyPI](.github/workflows/PublishOnPyPI.yml): publish source and wheel packages to PyPI.
|
||||
- [PublishTestResults](.github/workflows/PublishTestResults.yml): publish unit test results through GH action `dorny/test-reporter`.
|
||||
- Documentation:
|
||||
- [BuildTheDocs](.github/workflows/BuildTheDocs.yml): build Sphinx documentation with BuildTheDocs, and upload HTML as
|
||||
an artifact.
|
||||
- [PublishToGitHubPages](.github/workflows/PublishToGitHubPages.yml): publish HTML documentation to GitHub Pages.
|
||||
- Cleanup:
|
||||
- [ArtifactCleanUp](.github/workflows/ArtifactCleanUp.yml): delete artifacts.
|
||||
|
||||
### Example pipeline
|
||||
|
||||
[ExamplePipeline.yml](ExamplePipeline.yml) is an example Workflow which uses all of the Reusable Workflows.
|
||||
ExamplePipeline.yml is an example Workflow which uses all of the Reusable Workflows.
|
||||
Python package/tool developers can copy it into their repos, in order to use al the reusable workflows straightaway.
|
||||
Minimal required modifications are the following:
|
||||
|
||||
|
||||
2
dist/requirements.txt
vendored
2
dist/requirements.txt
vendored
@@ -1,2 +1,2 @@
|
||||
wheel ~= 0.45
|
||||
twine ~= 5.1
|
||||
twine ~= 6.1
|
||||
|
||||
15
doc/Action/Actions.rst
Normal file
15
doc/Action/Actions.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Post-Processing
|
||||
|
||||
* :ref:`ACTION/WithPostStep`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Deprecated
|
||||
|
||||
* :ref:`ACTION/Releaser`
|
||||
@@ -1,8 +1,17 @@
|
||||
.. _ACTION/Releaser:
|
||||
.. index::
|
||||
single: GitHub Action; Releaser
|
||||
|
||||
Releaser
|
||||
########
|
||||
|
||||
.. attention::
|
||||
|
||||
The **Releaser** action is deprecated.
|
||||
|
||||
Use the new GitHub Action workflow template :ref:`JOBTMPL/PublishReleaseNotes` as a replacement with lots of
|
||||
additional features.
|
||||
|
||||
**Releaser** is a Docker GitHub Action written in Python.
|
||||
|
||||
**Releaser** allows to keep a GitHub Release of type pre-release and its artifacts up to date with latest builds.
|
||||
@@ -85,7 +94,7 @@ The following block shows a minimal YAML workflow file:
|
||||
steps:
|
||||
|
||||
# Clone repository
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# Build your application, tool, artifacts, etc.
|
||||
- name: Build
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.. _ACTION/WithPostStep:
|
||||
.. index::
|
||||
single: GitHub Action; WithPostStep
|
||||
|
||||
with-post-step
|
||||
##############
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
.. _ACTION:
|
||||
.. index::
|
||||
single: GitHub Action
|
||||
|
||||
Overview
|
||||
########
|
||||
|
||||
The following 2 actions are provided by **Actions**:
|
||||
|
||||
* :ref:`ACTION/Releaser`
|
||||
* :ref:`ACTION/WithPostStep`
|
||||
.. include:: Actions.rst
|
||||
|
||||
|
||||
.. _ACTION/Instantiation:
|
||||
.. index::
|
||||
single: GitHub Action; Instantiation
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
<JobName>:
|
||||
steps:
|
||||
- ...
|
||||
|
||||
- name: <Name>
|
||||
uses: ./with-post-step
|
||||
with:
|
||||
<Param1>: <Value1>
|
||||
<Param2>: <Value2>
|
||||
|
||||
25
doc/CodeCoverage.rst
Normal file
25
doc/CodeCoverage.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
.. _CODECOV:
|
||||
|
||||
Code Coverage Report
|
||||
####################
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 8
|
||||
|
||||
.. report:code-coverage::
|
||||
:reportid: src
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. report:code-coverage-legend::
|
||||
:reportid: src
|
||||
:style: vertical-table
|
||||
|
||||
----------
|
||||
|
||||
Code coverage report generated with `pytest <https://github.com/pytest-dev/pytest>`__,
|
||||
`Coverage.py <https://github.com/nedbat/coveragepy/tree/master>`__ and visualized by
|
||||
`sphinx-reports <https://github.com/pyTooling/sphinx-reports>`__.
|
||||
24
doc/DocCoverage.rst
Normal file
24
doc/DocCoverage.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
.. _DOCCOV:
|
||||
|
||||
Documentation Coverage Report
|
||||
#############################
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. report:doc-coverage::
|
||||
:reportid: src
|
||||
|
||||
.. grid-item::
|
||||
:columns: 7
|
||||
|
||||
.. report:doc-coverage-legend::
|
||||
:reportid: src
|
||||
:style: vertical-table
|
||||
|
||||
----------
|
||||
|
||||
Documentation coverage generated with `"""docstr-coverage""" <https://github.com/HunterMcGushion/docstr_coverage>`__ and
|
||||
visualized by `sphinx-reports <https://github.com/pyTooling/sphinx-reports>`__.
|
||||
128
doc/Glossary.rst
Normal file
128
doc/Glossary.rst
Normal file
@@ -0,0 +1,128 @@
|
||||
Glossary
|
||||
########
|
||||
|
||||
.. glossary::
|
||||
|
||||
Bandit
|
||||
Bandit is a tool designed to find common security issues in Python code.
|
||||
|
||||
:Source Code: `github.com/PyCQA/bandit/ <https://github.com/PyCQA/bandit/>`__
|
||||
:Package: `pypi.org/project/bandit/ <https://pypi.org/project/bandit/>`__
|
||||
:Documentation: `bandit.readthedocs.io/ <https://bandit.readthedocs.io/>`__
|
||||
|
||||
build
|
||||
A simple, correct Python build frontend.
|
||||
|
||||
:Source Code: `github.com/pypa/build/ <https://github.com/pypa/build/>`__
|
||||
:Package: `pypi.org/project/build/ <https://pypi.org/project/build/>`__
|
||||
:Documentation: `build.pypa.io/ <https://build.pypa.io/>`__
|
||||
|
||||
Codacy
|
||||
.. todo:: Add description of Codacy.
|
||||
|
||||
:Cloud Service: `Codacy.com <https://www.codacy.com/>`__
|
||||
|
||||
CodeCov
|
||||
.. todo:: Add description of CodeCov.
|
||||
|
||||
:Cloud Service: `Codecov.io <https://about.codecov.io/>`__
|
||||
|
||||
Coverage.py
|
||||
The code coverage tool for Python.
|
||||
|
||||
:Source Code: `github.com/nedbat/coveragepy/ <https://github.com/nedbat/coveragepy/>`__
|
||||
:Package: `pypi.org/project/coverage/ <https://pypi.org/project/coverage/>`__
|
||||
:Documentation: `coverage.readthedocs.io/ <https://coverage.readthedocs.io/>`__
|
||||
|
||||
delete-artifact
|
||||
A GitHub Action to deletes artifacts within the workflow run.
|
||||
|
||||
:Source Code: `github.com/GeekyEggo/delete-artifact/ <https://github.com/GeekyEggo/delete-artifact/>`__
|
||||
:Marketplace: `github.com/marketplace/actions/delete-artifact/ <https://github.com/marketplace/actions/delete-artifact/>`__
|
||||
:README: `github.com/GeekyEggo/delete-artifact ⭢ README.md <https://github.com/GeekyEggo/delete-artifact/blob/main/README.md>`__
|
||||
|
||||
docstr_coverage
|
||||
Docstring coverage analysis and rating for Python.
|
||||
|
||||
:Source Code: `github.com/HunterMcGushion/docstr_coverage/ <https://github.com/HunterMcGushion/docstr_coverage/>`__
|
||||
:Package: `pypi.org/project/docstr_coverage/ <https://pypi.org/project/docstr_coverage/>`__
|
||||
:Documentation: `docstr-coverage.readthedocs.io/ <https://docstr-coverage.readthedocs.io/>`__
|
||||
|
||||
gh
|
||||
GitHub’s official command line tool.
|
||||
|
||||
:Source Code: `github.com/cli/cli/ <https://github.com/cli/cli/>`__
|
||||
:Documentation: `cli.github.com/manual/ <https://cli.github.com/manual/>`__
|
||||
|
||||
GitHub Pages
|
||||
GitHub Pages is a static site hosting service that takes HTML, CSS, and JavaScript files straight from a repository
|
||||
on GitHub, optionally runs the files through a build process, and publishes a website.
|
||||
|
||||
:Documentation: https://docs.github.com/en/pages
|
||||
|
||||
interrogate
|
||||
Explain yourself! Interrogate a codebase for docstring coverage.
|
||||
|
||||
:Source Code: `github.com/econchick/interrogate/ <https://github.com/econchick/interrogate/>`__
|
||||
:Package: `pypi.org/project/interrogate/ <https://pypi.org/project/interrogate/>`__
|
||||
:Documentation: `interrogate.readthedocs.io/ <https://interrogate.readthedocs.io/>`__
|
||||
|
||||
MikTeX
|
||||
MiKTeX is a modern TeX distribution for Windows, Linux and macOS.
|
||||
|
||||
:Source Code: `github.com/MiKTeX/miktex/ <https://github.com/MiKTeX/miktex/>`__
|
||||
:Documentation: `miktex.org/ <https://miktex.org/>`__
|
||||
|
||||
mypy
|
||||
Optional static typing for Python.
|
||||
|
||||
:Source Code: `github.com/python/mypy/ <https://github.com/python/mypy/>`__
|
||||
:Package: `pypi.org/project/mypy/ <https://pypi.org/project/mypy/>`__
|
||||
:Documentation: `www.mypy-lang.org/ <https://www.mypy-lang.org/>`__
|
||||
|
||||
pyEDAA.Reports
|
||||
A collection of various (EDA tool-specific) report data formats.
|
||||
|
||||
:Source Code: `github.com/edaa-org/pyEDAA.Reports/ <https://github.com/edaa-org/pyEDAA.Reports/>`__
|
||||
:Package: `pypi.org/project/pyEDAA.Reports/ <https://pypi.org/project/pyEDAA.Reports/>`__
|
||||
:Documentation: `edaa-org.github.io/pyEDAA.Reports/ <https://edaa-org.github.io/pyEDAA.Reports/>`__
|
||||
|
||||
pip
|
||||
The Python package installer.
|
||||
|
||||
:Source Code: `github.com/pypa/pip/ <https://github.com/pypa/pip/>`__
|
||||
:Package: `pypi.org/project/pip/ <https://pypi.org/project/pip/>`__
|
||||
:Documentation: `pip.pypa.io/ <https://pip.pypa.io/>`__
|
||||
|
||||
PyPI
|
||||
Find, install and publish Python packages with the Python Package Index.
|
||||
|
||||
:Cloud Service: `PyPI.org <https://pypi.org/>`__
|
||||
|
||||
pytest
|
||||
The pytest framework makes it easy to write small tests, yet scales to support complex functional testing.
|
||||
|
||||
:Source Code: `github.com/pytest-dev/pytest/ <https://github.com/pytest-dev/pytest/>`__
|
||||
:Package: `pypi.org/project/pytest/ <https://pypi.org/project/pytest/>`__
|
||||
:Documentation: `pytest.org/ <https://pytest.org/>`__
|
||||
|
||||
Sphinx
|
||||
The Sphinx documentation generator.
|
||||
|
||||
:Source Code: `github.com/sphinx-doc/sphinx/ <https://github.com/sphinx-doc/sphinx/>`__
|
||||
:Package: `pypi.org/project/sphinx/ <https://pypi.org/project/sphinx/>`__
|
||||
:Documentation: `www.sphinx-doc.org/ <https://www.sphinx-doc.org/>`__
|
||||
|
||||
Test Reporter
|
||||
Displays test results from popular testing frameworks directly in GitHub.
|
||||
|
||||
:Source Code: `github.com/dorny/test-reporter/ <https://github.com/dorny/test-reporter/>`__
|
||||
:Marketplace: `github.com/marketplace/actions/test-reporter/ <https://github.com/marketplace/actions/test-reporter/>`__
|
||||
:README: `github.com/dorny/test-reporter ⭢ README.md <https://github.com/dorny/test-reporter/blob/main/README.md>`__
|
||||
|
||||
twine
|
||||
Utilities for interacting with PyPI.
|
||||
|
||||
:Source Code: `github.com/pypa/twine/ <https://github.com/pypa/twine/>`__
|
||||
:Package: `pypi.org/project/twine/ <https://pypi.org/project/twine/>`__
|
||||
:Documentation: `twine.readthedocs.io/ <https://twine.readthedocs.io/>`__
|
||||
@@ -36,10 +36,13 @@ to handover input parameters to the template.
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Every Friday at 22:00 - rerun pipeline to check for dependency-based issues
|
||||
- cron: '0 22 * * 5'
|
||||
|
||||
jobs:
|
||||
<InstanceName>:
|
||||
uses: <GitHubOrganization>/<Repository>/.github/workflows/<Template>.yml@v0
|
||||
uses: <GitHubOrganization>/<Repository>/.github/workflows/<Template>.yml@r6
|
||||
with:
|
||||
<Param1>: <Value>
|
||||
|
||||
@@ -57,15 +60,18 @@ Documentation Only (Sphinx)
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Every Friday at 22:00 - rerun pipeline to check for dependency-based issues
|
||||
- cron: '0 22 * * 5'
|
||||
|
||||
jobs:
|
||||
BuildTheDocs:
|
||||
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@r0
|
||||
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@r6
|
||||
with:
|
||||
artifact: Documentation
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r0
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r6
|
||||
needs:
|
||||
- BuildTheDocs
|
||||
with:
|
||||
|
||||
826
doc/JobTemplate/AllInOne/CompletePipeline.rst
Normal file
826
doc/JobTemplate/AllInOne/CompletePipeline.rst
Normal file
@@ -0,0 +1,826 @@
|
||||
.. _JOBTMPL/CompletePipeline:
|
||||
.. index::
|
||||
single: build; CompletePipeline Template
|
||||
single: Bandit; CompletePipeline Template
|
||||
single: CodeCov; CompletePipeline Template
|
||||
single: Codacy; CompletePipeline Template
|
||||
single: Coverage.py; CompletePipeline Template
|
||||
single: docstr_coverage; CompletePipeline Template
|
||||
single: GitHub Pages; CompletePipeline Template
|
||||
single: interrogate; CompletePipeline Template
|
||||
single: MikTeX; CompletePipeline Template
|
||||
single: mypy; CompletePipeline Template
|
||||
single: PyPI; CompletePipeline Template
|
||||
single: pytest; CompletePipeline Template
|
||||
single: pyEDAA.Reports; CompletePipeline Template
|
||||
single: Sphinx; CompletePipeline Template
|
||||
single: Test Reporter; CompletePipeline Template
|
||||
single: twine; CompletePipeline Template
|
||||
single: GitHub Action Reusable Workflow; CompletePipeline Template
|
||||
|
||||
CompletePipeline
|
||||
################
|
||||
|
||||
The ``CompletePipeline`` job template is the combination of almost all job templates offered by pyTooling/Actions in a
|
||||
single workflow template. If fulfills all needs to test, package, document, publish and release Python code from GitHub.
|
||||
It can be used for simple Python packages as well as namespace packages.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
.. grid:: 3
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Testing
|
||||
|
||||
* Run unit tests before packaging using :term:`pytest`.
|
||||
* Run platform tests before packaging using :term:`pytest`.
|
||||
* Run application tests using packaged code on target platform.
|
||||
|
||||
.. rubric:: Code Quality
|
||||
|
||||
* Collect code coverage using :term:`Coverage.py`.
|
||||
* Check documentation coverage using :term:`docstr_coverage` and :term:`interrogate`.
|
||||
* Check static typing closure using :term:`mypy`.
|
||||
* Static Application Security Testing (SAST) using :term:`bandit`
|
||||
|
||||
.. rubric:: Report Handling
|
||||
|
||||
* Merge unit test results into one report using :term:`pyEDAA.Reports`.
|
||||
* Merge code coverage results into one report using :term:`Coverage.py`.
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Documentation
|
||||
|
||||
* Compile documentation using :term:`Sphinx` as HTML and LaTeX.
|
||||
* Translate LaTeX documentation to PDF using :term:`MikTeX`.
|
||||
|
||||
.. rubric:: Publishing Results
|
||||
|
||||
* GitHub Pipeline Summary
|
||||
|
||||
* Publish unittest results using :term:`Test Reporter`.
|
||||
|
||||
* :term:`GitHub Pages`
|
||||
|
||||
* Publish HTML documentation to GitHub Pages.
|
||||
|
||||
* :term:`Codecov`
|
||||
|
||||
* Publish code coverage to CodeCov.
|
||||
* Publish unittest results to CodeCov.
|
||||
|
||||
* :term:`Codacy`
|
||||
|
||||
* Publish code coverage to Codacy.
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Packaging
|
||||
|
||||
* Package as wheel using :term:`build`.
|
||||
* Install wheel on target platform using pip.
|
||||
* Upload to PyPI using :term:`twine`.
|
||||
|
||||
.. rubric:: Releasing
|
||||
|
||||
* Automatic tagging of merge commits on main branch to trigger a tagged pipeline (release pipeline).
|
||||
* Create a release page with text derived from pull request description.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
.. include:: _Behavior.rst
|
||||
|
||||
|
||||
.. topic:: Pipeline Graph
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-SimplePackage.png
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
.. dropdown:: Expand List
|
||||
:animate: fade-in-slide-down
|
||||
:icon: codescan
|
||||
:color: muted
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PrepareJob.yml <JOBTMPL/PrepareJob>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`GitHub command line tool 'gh' <cli/cli>`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/Parameters.yml <JOBTMPL/Parameters>`
|
||||
* :ref:`pyTooling/Actions/.github/workflows/ExtractConfiguration.yml <JOBTMPL/ExtractConfiguration>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`tomli`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/UnitTesting.yml <JOBTMPL/UnitTesting>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`msys2/setup-msys2`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* apt: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/apt` parameter.
|
||||
* homebrew: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/brew` parameter.
|
||||
* MSYS2: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/pacboy` parameter.
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`tomli`
|
||||
* Python packages specified via :ref:`JOBTMPL/UnitTesting/Input/requirements` or
|
||||
:ref:`JOBTMPL/UnitTesting/Input/mingw_requirements` parameter.
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/ApplicationTesting.yml <JOBTMPL/ApplicationTesting>`
|
||||
* :ref:`pyTooling/Actions/.github/workflows/CheckDocumentation.yml <JOBTMPL/CheckDocumentation>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* pip
|
||||
|
||||
* :pypi:`docstr_coverage`
|
||||
* :pypi:`interrogate`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/StaticTypeCheck.yml <JOBTMPL/StaticTypeCheck>`
|
||||
* :ref:`pyTooling/Actions/.github/workflows/Package.yml <JOBTMPL/Package>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`build`
|
||||
* :pypi:`wheel`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PublishTestResults.yml <JOBTMPL/PublishTestResults>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`pyEDAA.Reports`
|
||||
|
||||
* :gh:`dorny/test-reporter`
|
||||
* :gh:`codecov/test-results-action`
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PublishCoverageResults.yml <JOBTMPL/PublishCoverageResults>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`coverage`
|
||||
* :pypi:`tomli`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* :gh:`codecov/codecov-action`
|
||||
* :gh:`codacy/codacy-coverage-reporter-action`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/SphinxDocumentation.yml <JOBTMPL/SphinxDocumentation>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* apt
|
||||
|
||||
* `graphviz <https://graphviz.org/>`__
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* Python packages specified via :ref:`JOBTMPL/SphinxDocumentation/Input/requirements` parameter.
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/LaTeXDocumentation.yml <JOBTMPL/LaTeXDocumentation>`
|
||||
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* :gh:`addnab/docker-run-action`
|
||||
|
||||
* :dockerhub:`pytooling/miktex <pytooling/miktex:sphinx>`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml <JOBTMPL/PublishToGitHubPages>`
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PublishOnPyPI.yml <JOBTMPL/PublishOnPyPI>`
|
||||
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`twine`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/TagReleaseCommit.yml <JOBTMPL/TagReleaseCommit>`
|
||||
|
||||
* :gh:`actions/github-script`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml <JOBTMPL/PublishReleaseNotes>`
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* ``gh`` (GitHub command line interface)
|
||||
* ``jq`` (JSON processing)
|
||||
* apt
|
||||
|
||||
* zstd
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/IntermediateCleanUp.yml <JOBTMPL/IntermediateCleanUp>`
|
||||
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
* :ref:`pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml <JOBTMPL/ArtifactCleanUp>`
|
||||
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``SimplePackage`` job derived from job template ``CompletePipeline``
|
||||
version ``@r6``. It only requires the `package_name` parameter to run a full pipeline suitable for a Python project.
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Simple Package
|
||||
:sync: Simple
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
SimplePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r6
|
||||
with:
|
||||
|
||||
package_name: myPackage
|
||||
|
||||
.. tab-item:: Namespace Package
|
||||
:sync: Namespace
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
NamespacePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Simple Package
|
||||
:sync: Simple
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. tab-item:: Namespace Package
|
||||
:sync: Namespace
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
📂Extension/
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/CompletePipeline/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/package_namespace` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/package_name` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_python_version_list` | no | string | ``'3.9 3.10 3.11 3.12 3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_system_list` | no | string | ``'ubuntu windows macos macos-arm ucrt64'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_include_list` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_exclude_list` | no | string | ``'windows-arm:3.9 windows-arm:3.10'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/unittest_disable_list` | no | string | ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_python_version_list` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_system_list` | no | string | ``'ubuntu windows macos macos-arm ucrt64'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_include_list` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_exclude_list` | no | string | ``'windows-arm:3.9 windows-arm:3.10'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/apptest_disable_list` | no | string | ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/codecov` | no | string | ``'false'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/codacy` | no | string | ``'false'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/dorny` | no | string | ``'false'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Input/cleanup` | no | string | ``'true'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/CompletePipeline/Secrets>`
|
||||
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| Token Name | Required | Type | Default |
|
||||
+===========================================================+==========+==========+==============+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Secret/PYPI_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Secret/CODECOV_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| :ref:`JOBTMPL/CompletePipeline/Secret/CODACY_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/CompletePipeline/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/package_namespace:
|
||||
|
||||
package_namespace
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid Python namespace.
|
||||
:Description: In case the package is a Python namespace package, the name of the library's or package's namespace
|
||||
needs to be specified using this parameter. |br|
|
||||
In case of a simple Python package, this parameter must be specified as an empty string (``''``),
|
||||
which is the default.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Example Instantiation
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
NamespacePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Example Directory Structure
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
📂Extension/
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/package_name:
|
||||
|
||||
package_name
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid Python package name.
|
||||
:Description: In case of a simple Python package, this package's name is specified using this parameter. |br|
|
||||
In case the package is a Python namespace package, the parameter
|
||||
:ref:`JOBTMPL/CompletePipeline/Input/package_namespace` must be specified, too.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Example Instantiation
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
SimplePackage:
|
||||
uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Example Directory Structure
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_python_version:
|
||||
|
||||
unittest_python_version
|
||||
=======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'3.13'``
|
||||
:Possible Values: Any valid Python version conforming to the pattern ``<major>.<minor>`` or ``pypy-<major>.<minor>``. |br|
|
||||
See `actions/python-versions - available Python versions <https://github.com/actions/python-versions>`__
|
||||
and `actions/setup-python - configurable Python versions <https://github.com/actions/setup-python>`__.
|
||||
:Description: The default Python version used for intermediate jobs using Python tools.
|
||||
|
||||
In case :ref:`JOBTMPL/CompletePipeline/Input/unittest_python_version_list` is empty, this default
|
||||
version is used to populate the :ref:`JOBTMPL/CompletePipeline/Input/unittest_python_version_list`
|
||||
parameter.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_python_version_list:
|
||||
|
||||
unittest_python_version_list
|
||||
============================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'3.9 3.10 3.11 3.12 3.13'``
|
||||
:Possible Values: A space separated list of valid Python versions conforming to the pattern ``<major>.<minor>`` or
|
||||
``pypy-<major>.<minor>``.
|
||||
:Description: The list of space-separated Python versions used for unit testing.
|
||||
|
||||
.. include:: ../PythonVersionList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_system_list:
|
||||
|
||||
unittest_system_list
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu windows macos macos-arm mingw64 ucrt64'``
|
||||
:Possible Values: A space separated list of system names.
|
||||
:Description: The list of space-separated systems used for unit testing.
|
||||
|
||||
.. include:: ../SystemList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_include_list:
|
||||
|
||||
unittest_include_list
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be included into the list of unittest
|
||||
variants.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/include_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_exclude_list:
|
||||
|
||||
unittest_exclude_list
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:3.9 windows-arm:3.10'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be excluded from the list of unittest
|
||||
variants.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/exclude_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/unittest_disable_list:
|
||||
|
||||
unittest_disable_list
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be temporarily disabled from the list
|
||||
of unittest variants. |br|
|
||||
Each disabled item creates a warning in the workflow log.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/disable_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_python_version:
|
||||
|
||||
apptest_python_version
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'3.13'``
|
||||
:Possible Values: Any valid Python version conforming to the pattern ``<major>.<minor>`` or ``pypy-<major>.<minor>``. |br|
|
||||
See `actions/python-versions - available Python versions <https://github.com/actions/python-versions>`__
|
||||
and `actions/setup-python - configurable Python versions <https://github.com/actions/setup-python>`__.
|
||||
:Description: The default Python version used for intermediate jobs using Python tools.
|
||||
|
||||
In case :ref:`JOBTMPL/CompletePipeline/Input/apptest_python_version_list` is empty, this default
|
||||
version is used to populate the :ref:`JOBTMPL/CompletePipeline/Input/apptest_python_version_list`
|
||||
parameter.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_python_version_list:
|
||||
|
||||
apptest_python_version_list
|
||||
===========================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: A space separated list of valid Python versions conforming to the pattern ``<major>.<minor>`` or
|
||||
``pypy-<major>.<minor>```.
|
||||
:Description: The list of space-separated Python versions used for application testing.
|
||||
|
||||
As this list is empty by default, the value is derived from
|
||||
:ref:`JOBTMPL/CompletePipeline/Input/apptest_python_version`.
|
||||
|
||||
.. include:: ../PythonVersionList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_system_list:
|
||||
|
||||
apptest_system_list
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu windows macos macos-arm mingw64 ucrt64'``
|
||||
:Possible Values: A space separated list of system names.
|
||||
:Description: The list of space-separated systems used for application testing.
|
||||
|
||||
.. include:: ../SystemList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_include_list:
|
||||
|
||||
apptest_include_list
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be included into the list of
|
||||
application test variants.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/include_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_exclude_list:
|
||||
|
||||
apptest_exclude_list
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:3.9 windows-arm:3.10'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be excluded from the list of
|
||||
application test variants.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/exclude_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/apptest_disable_list:
|
||||
|
||||
apptest_disable_list
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be temporarily disabled from the list
|
||||
of application test variants. |br|
|
||||
Each disabled item creates a warning in the workflow log.
|
||||
|
||||
For more details see :ref:`JOBTMPL/Parameters/Input/disable_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/codecov:
|
||||
|
||||
codecov
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *true*, publish merged code coverage results and a merged unit test summary to CodeCov. |br|
|
||||
Secret :ref:`JOBTMPL/CompletePipeline/Secret/CODECOV_TOKEN` must be set.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/codacy:
|
||||
|
||||
codacy
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *true*, publish merged code coverage results to Codacy. |br|
|
||||
Secret :ref:`JOBTMPL/CompletePipeline/Secret/CODACY_TOKEN` must be set.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/dorny:
|
||||
|
||||
dorny
|
||||
=====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *true*, publish a merged unit test summary as pipeline result.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Input/cleanup:
|
||||
|
||||
cleanup
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'true'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *false*, do not remove intermediate artifacts. |br|
|
||||
This might help debugging artifact handovers between jobs.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
The workflow template uses the following secrets to publish results to other services.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Secret/PYPI_TOKEN:
|
||||
|
||||
PYPI_TOKEN
|
||||
==========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish and upload packages on :term:`PyPI`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Secret/CODECOV_TOKEN:
|
||||
|
||||
CODECOV_TOKEN
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish code coverage and unit test results to :term:`CodeCov`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Secret/CODACY_TOKEN:
|
||||
|
||||
CODACY_TOKEN
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish code coverage results to :term:`Codacy`.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/CompletePipeline/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
The following optimizations can be used to reduce the template's runtime.
|
||||
|
||||
.. todo::
|
||||
|
||||
CompletePipeline::Optimizations Needs a list of optimizations.
|
||||
16
doc/JobTemplate/AllInOne/_Behavior.rst
Normal file
16
doc/JobTemplate/AllInOne/_Behavior.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
1. Infer information from ``${{ github.ref }}`` variable.
|
||||
2. Extract Python project settings from :file:`pyproject.toml`.
|
||||
3. Compute job matrix based on system, Python version, environment, ... for job variants.
|
||||
4. Run unit tests using pytest and collect code coverage.
|
||||
5. Run platform tests using pytest and collect code coverage.
|
||||
6. Run application tests using pytest.
|
||||
7. Package code as wheel.
|
||||
8. Check documentation coverage using docstr_coverage and interrogate.
|
||||
9. Verify type annotation using static typing analysis using mypy.
|
||||
10. Merge unit test results and code coverage results.
|
||||
11. Generate HTML and LaTeX documentations using Sphinx.
|
||||
12. Translate LaTeX documentation to PDF using MikTeX.
|
||||
13. Publish unit test and code coverage results to cloud services.
|
||||
14. Publish documentation to GitHub Pages.
|
||||
15. Publish wheel to PyPI.
|
||||
16. Create a GitHub release page and upload release assets.
|
||||
32
doc/JobTemplate/AllInOne/index.rst
Normal file
32
doc/JobTemplate/AllInOne/index.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
.. _JOBTMPL/AllInOne:
|
||||
|
||||
All-In-One
|
||||
##########
|
||||
|
||||
The category *all-in-one* provides workflow templates implementing all necessary steps (jobs) for testing and publishing
|
||||
a Python project. It utilizes allmost all of ``pyTooling/Acion``'s workflow templates.
|
||||
|
||||
Such a all-in-one workflow template covers:
|
||||
|
||||
* unit testing
|
||||
* code coverage collections
|
||||
* documentation checking
|
||||
* pulishing of unit test and code coverage results
|
||||
* merging of test reports
|
||||
* packaging as wheel
|
||||
* publishing wheels to PyPI
|
||||
* documentation generation via Sphinx and Miktex
|
||||
* automatic tagging of release commits
|
||||
* releasing
|
||||
|
||||
.. topic:: Provides *all-in-one* workflow templates
|
||||
|
||||
* :ref:`JOBTMPL/CompletePipeline` - Use all of ``pyTooling/Acion``'s workflow templates by instantiation of a single
|
||||
workflow template.
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-SimplePackage.png
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
CompletePipeline
|
||||
@@ -1,90 +0,0 @@
|
||||
.. _JOBTMPL/ArtifactCleanup:
|
||||
|
||||
ArtifactCleanUp
|
||||
###############
|
||||
|
||||
This job removes artifacts used to exchange data from job to job.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Delete the package artifact if the current pipeline run was not a tagged run.
|
||||
2. Delete all remaining artifacts if given as a parameter.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
The simplest variant just uses the artifact name for the package.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@r0
|
||||
with:
|
||||
package: Package
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
- UnitTesting
|
||||
- BuildTheDocs
|
||||
- PublishToGitHubPages
|
||||
- PublishTestResults
|
||||
with:
|
||||
package: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
remaining: |
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-*
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
package
|
||||
=======
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| package | yes | string | — — — — |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Artifacts to be removed on not tagged runs.
|
||||
|
||||
|
||||
remaining
|
||||
=========
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| remaining | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Artifacts to be removed unconditionally.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
@@ -1,75 +0,0 @@
|
||||
.. _JOBTMPL/BuildTheDocs:
|
||||
|
||||
BuildTheDocs
|
||||
############
|
||||
|
||||
This jobs compiles the documentation written in ReStructured Text with Sphinx using BuildTheDocs.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository.
|
||||
2. Build the documentation.
|
||||
3. Upload the HTML documentation as an artifact.
|
||||
4. Publish the HTML documentation to GitHub Pages.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`buildthedocs/btd`
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
BuildTheDocs:
|
||||
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@r0
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
BuildTheDocs:
|
||||
uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| artifact | optional | string | ``""`` |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the documentation artifact.
|
||||
|
||||
If no artifact name is given, the job directly publishes the documentation's HTML content to GitHub Pages.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
157
doc/JobTemplate/Cleanup/ArtifactCleanup.rst
Normal file
157
doc/JobTemplate/Cleanup/ArtifactCleanup.rst
Normal file
@@ -0,0 +1,157 @@
|
||||
.. _JOBTMPL/ArtifactCleanup:
|
||||
.. index::
|
||||
single: delete-artifact; ArtifactCleanUp Template
|
||||
single: GitHub Action Reusable Workflow; ArtifactCleanUp Template
|
||||
|
||||
ArtifactCleanUp
|
||||
###############
|
||||
|
||||
This job removes artifacts which were used to exchange data between jobs.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Delete artifacts from pipeline.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Delete the package artifact if the current pipeline run was not a tagged run.
|
||||
2. Delete all remaining artifacts if given as a parameter.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-ArtifactCleanup.png
|
||||
:width: 350px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
The simplest variant just uses the artifact name for the package.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@r6
|
||||
with:
|
||||
package: Package
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ArtifactCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
- UnitTesting
|
||||
- BuildTheDocs
|
||||
- PublishToGitHubPages
|
||||
- PublishTestResults
|
||||
with:
|
||||
package: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
remaining: |
|
||||
${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}-*
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/IntermediateCleanUp`
|
||||
``IntermediateCleanUp`` is used to remove intermediate artifacts like unit test artifacts for each job variant
|
||||
after test results have been merged into a single file.
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/ArtifactCleanup/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================+
|
||||
| :ref:`JOBTMPL/ArtifactCleanup/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ArtifactCleanup/Input/package` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ArtifactCleanup/Input/remaining` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/ArtifactCleanup/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/ArtifactCleanup/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Input/package:
|
||||
|
||||
package
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Multi-line string accepting any valid artifact name per line.
|
||||
:Description: Artifacts to be removed on not tagged runs.
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Input/remaining:
|
||||
|
||||
remaining
|
||||
=========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Multi-line string accepting any valid artifact name per line.
|
||||
:Description: Versi
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/ArtifactCleanup/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
141
doc/JobTemplate/Cleanup/IntermediateCleanup.rst
Normal file
141
doc/JobTemplate/Cleanup/IntermediateCleanup.rst
Normal file
@@ -0,0 +1,141 @@
|
||||
.. _JOBTMPL/IntermediateCleanUp:
|
||||
.. index::
|
||||
single: delete-artifact; IntermediateCleanUp Template
|
||||
single: GitHub Action Reusable Workflow; IntermediateCleanUp Template
|
||||
|
||||
IntermediateCleanUp
|
||||
###################
|
||||
|
||||
The ``IntermediateCleanUp`` job template is used to remove intermediate artifacts like unit test artifacts for each job
|
||||
variant after test results have been merged into a single file.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Delete artifacts from pipeline.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Delete all SQLite code coverage artifacts if given as a parameter.
|
||||
2. Delete all JUnit XML report artifacts if given as a parameter.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-IntermediateCleanUp.png
|
||||
:width: 400px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``Params`` job derived from job template ``Parameters`` version ``@r6``. It only
|
||||
requires a `name` parameter to create the artifact names.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
IntermediateCleanUp:
|
||||
uses: pyTooling/Actions/.github/workflows/IntermediateCleanUp.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- PublishCoverageResults
|
||||
- PublishTestResults
|
||||
if: success() || failure()
|
||||
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 }}-
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/ArtifactCleanup`
|
||||
``ArtifactCleanup`` is used to remove artifacts like unit test report artifacts after artifact's content has been
|
||||
(post-)processed or published.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/IntermediateCleanUp/Inputs>`
|
||||
|
||||
+----------------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+============================================================================+==========+==========+===================================================+
|
||||
| :ref:`JOBTMPL/IntermediateCleanUp/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+----------------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/IntermediateCleanUp/Input/sqlite_coverage_artifacts_prefix` | no | string | ``''`` |
|
||||
+----------------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
| :ref:`JOBTMPL/IntermediateCleanUp/Input/xml_unittest_artifacts_prefix` | no | string | ``''`` |
|
||||
+----------------------------------------------------------------------------+----------+----------+---------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/IntermediateCleanUp/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/IntermediateCleanUp/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Input/sqlite_coverage_artifacts_prefix:
|
||||
|
||||
sqlite_coverage_artifacts_prefix
|
||||
================================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name including ``*``.
|
||||
:Description: Prefix for SQLite coverage artifacts to be removed.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Input/xml_unittest_artifacts_prefix:
|
||||
|
||||
xml_unittest_artifacts_prefix
|
||||
=============================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name including ``*``.
|
||||
:Description: Prefix for XML unittest artifacts to be removed.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/IntermediateCleanUp/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
28
doc/JobTemplate/Cleanup/index.rst
Normal file
28
doc/JobTemplate/Cleanup/index.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
.. _JOBTMPL/Cleanup:
|
||||
|
||||
Cleanup
|
||||
#######
|
||||
|
||||
The category *cleanup* provides workflow templates implementing artifact cleanups (removals) from pipelines.
|
||||
|
||||
Running lots of unit testing, platform testing and application testing variants (operating system |times| Python version
|
||||
|times| environment) creates dozens to hundrets of artifacts (unit test report, code coverage report, ...). This
|
||||
consumes pipeline storage which can be freed up. Moreover, it's unclear which artifacts contain the final unit test and
|
||||
code coverage reports. Thus, it's benefitial, to remove intermediate artifacts after merging reports into one summary
|
||||
report.
|
||||
|
||||
.. topic:: Intermediate cleanups
|
||||
|
||||
* :ref:`JOBTMPL/IntermediateCleanup` - remove intermediate artifacts after merging reports into one summary report.
|
||||
|
||||
|
||||
.. topic:: Final cleanups
|
||||
|
||||
* :ref:`JOBTMPL/ArtifactCleanup` - remove artifacts after publising results and creating release assets.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
IntermediateCleanup
|
||||
ArtifactCleanup
|
||||
@@ -1,170 +0,0 @@
|
||||
.. _JOBTMPL/CodeCoverage:
|
||||
|
||||
CoverageCollection
|
||||
##################
|
||||
|
||||
This jobs runs the specified unit tests with activated code coverage collection (incl. branch coverage).
|
||||
|
||||
It uses pytest, pytest-cov and coverage.py in a single job run, thus it uses one fixed Python version (usually latest).
|
||||
It generates HTML and Cobertura reports (XML), then it uploads the HTML report as an artifact and the jUnit test results
|
||||
(XML) to `Codecov <https://about.codecov.io/>`__ and `Codacy <https://www.codacy.com/>`__.
|
||||
|
||||
Configuration options to ``pytest`` and ``coverage.py`` should be given via sections ``[tool.pytest.ini_options]`` and
|
||||
``[tool.coverage.*]`` in a ``pyproject.toml`` file.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository
|
||||
2. Setup Python and install dependencies
|
||||
3. Extract configuration from ``pyproject.toml`` or ``.coveragerc``.
|
||||
4. Run unit tests and collect code coverage
|
||||
5. Convert coverage data to a Cobertura XML file
|
||||
6. Convert coverage data to a HTML report
|
||||
7. Upload HTML report as an artifact
|
||||
8. Publish Cobertura file to CodeCov
|
||||
9. Publish Cobertura file to Codacy
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
* A CodeCov account was created.
|
||||
* A Codacy account was created.
|
||||
|
||||
**Requirements:**
|
||||
|
||||
Setup a secret (e.g. ``codacy_token``) in GitHub to handover the Codacy project token to the job.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`actions/upload-artifact`
|
||||
* :gh:`codecov/codecov-action`
|
||||
* :gh:`codacy/codacy-coverage-reporter-action`
|
||||
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Coverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r0
|
||||
with:
|
||||
artifact: Coverage
|
||||
secrets:
|
||||
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Coverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
secrets:
|
||||
codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| python_version | optional | string | 3.11 |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Python version used for running unit tests.
|
||||
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
+----------------+----------+----------+-------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+===============================+
|
||||
| requirements | optional | string | ``-r tests/requirements.txt`` |
|
||||
+----------------+----------+----------+-------------------------------+
|
||||
|
||||
Python dependencies to be installed through pip.
|
||||
|
||||
|
||||
tests_directory
|
||||
===============
|
||||
|
||||
+-----------------+----------+----------+-----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=================+==========+==========+===========+
|
||||
| tests_directory | optional | string | ``tests`` |
|
||||
+-----------------+----------+----------+-----------+
|
||||
|
||||
Path to the directory containing tests (test working directory).
|
||||
|
||||
|
||||
unittest_directory
|
||||
==================
|
||||
|
||||
+--------------------+----------+----------+-----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+====================+==========+==========+===========+
|
||||
| unittest_directory | optional | string | ``unit`` |
|
||||
+--------------------+----------+----------+-----------+
|
||||
|
||||
Path to the directory containing unit tests (relative to tests_directory).
|
||||
|
||||
|
||||
coverage_config
|
||||
===============
|
||||
|
||||
+-----------------+----------+----------+--------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=================+==========+==========+====================+
|
||||
| coverage_config | optional | string | ``pyproject.toml`` |
|
||||
+-----------------+----------+----------+--------------------+
|
||||
|
||||
Path to the ``.coveragerc`` file. Use ``pyproject.toml`` by default.
|
||||
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| artifact | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the coverage artifact.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
codacy_token
|
||||
============
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Secret Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| codacy_token | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Token to push result to codacy.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
10
doc/JobTemplate/Deprecated/BuildTheDocs.rst
Normal file
10
doc/JobTemplate/Deprecated/BuildTheDocs.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
.. _JOBTMPL/BuildTheDocs:
|
||||
|
||||
BuildTheDocs
|
||||
############
|
||||
|
||||
.. attention::
|
||||
|
||||
The ``BuildTheDocs`` job template is deprecated.
|
||||
|
||||
See :ref:`JOBTMPL/SphinxDocumentation` and :ref:`JOBTMPL/LaTeXDocumentation`.
|
||||
10
doc/JobTemplate/Deprecated/CoverageCollection.rst
Normal file
10
doc/JobTemplate/Deprecated/CoverageCollection.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
.. _JOBTMPL/CoverageCollection:
|
||||
|
||||
CoverageCollection
|
||||
##################
|
||||
|
||||
.. attention::
|
||||
|
||||
The ``CoverageCollection`` job template is deprecated.
|
||||
|
||||
See :ref:`JOBTMPL/UnitTesting` and :ref:`JOBTMPL/PublishCoverageResults`.
|
||||
10
doc/JobTemplate/Deprecated/NightlyRelease.rst
Normal file
10
doc/JobTemplate/Deprecated/NightlyRelease.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
.. _JOBTMPL/NightlyRelease:
|
||||
|
||||
NightlyRelease
|
||||
##############
|
||||
|
||||
.. attention::
|
||||
|
||||
The ``NightlyRelease`` job template is deprecated.
|
||||
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes`.
|
||||
20
doc/JobTemplate/Deprecated/index.rst
Normal file
20
doc/JobTemplate/Deprecated/index.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
.. _JOBTMPL/Deprecated:
|
||||
|
||||
Deprecated
|
||||
##########
|
||||
|
||||
The category *deprecated* collects outdated job templates:
|
||||
|
||||
:ref:`JOBTMPL/CoverageCollection`
|
||||
replaced by :ref:`JOBTMPL/UnitTesting`
|
||||
:ref:`JOBTMPL/NightlyRelease`
|
||||
replaced by :ref:`JOBTMPL/PublishReleaseNotes`
|
||||
:ref:`JOBTMPL/BuildTheDocs`
|
||||
replaced by :ref:`JOBTMPL/SphinxDocumentation` and :ref:`JOBTMPL/LaTeXDocumentation`
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
CoverageCollection
|
||||
NightlyRelease
|
||||
BuildTheDocs
|
||||
188
doc/JobTemplate/Documentation/LaTeXDocumentation.rst
Normal file
188
doc/JobTemplate/Documentation/LaTeXDocumentation.rst
Normal file
@@ -0,0 +1,188 @@
|
||||
.. _JOBTMPL/LaTeXDocumentation:
|
||||
.. index::
|
||||
single: MikTeX; LaTeXDocumentation Template
|
||||
single: GitHub Action Reusable Workflow; LaTeXDocumentation Template
|
||||
|
||||
LaTeXDocumentation
|
||||
##################
|
||||
|
||||
The ``LaTeXDocumentation`` job template downloads an artifact containing a LaTeX document and translates to a PDF file
|
||||
using MikTeX.
|
||||
|
||||
The translation process uses ``latexmk`` for handling multiple passes. The default LaTeX processor is ``xelatex``, but
|
||||
can be switched by a parameter.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Translate a LaTeX document to PDF.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Download the LaTeX artifact.
|
||||
2. Build the PDF using ``latexmk``.
|
||||
3. Upload the generated PDF as an artifact.
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* :gh:`addnab/docker-run-action`
|
||||
|
||||
* :dockerhub:`pytooling/miktex <pytooling/miktex:sphinx>`
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
Documentation:
|
||||
uses: pyTooling/Actions/.github/workflows/SphinxDocumentation.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
|
||||
PDFDocumentation:
|
||||
uses: pyTooling/Actions/.github/workflows/LaTeXDocumentation.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- Documentation
|
||||
with:
|
||||
document: pyEDAA.ProjectModel
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
pdf_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_pdf }}
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/LaTeXDocumentation/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/LaTeXDocumentation/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/LaTeXDocumentation/Input/latex_artifact` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/LaTeXDocumentation/Input/document` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/LaTeXDocumentation/Input/processor` | no | string | ``'xelatex'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/LaTeXDocumentation/Input/pdf_artifact` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/LaTeXDocumentation/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/LaTeXDocumentation/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Input/latex_artifact:
|
||||
|
||||
latex_artifact
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the LaTeX document to translate.
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Input/document:
|
||||
|
||||
document
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid document name.
|
||||
:Description: Name of the LaTeX document
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Input/processor:
|
||||
|
||||
processor
|
||||
=========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'xelatex'``
|
||||
:Possible Values: Any supported LaTeX processor supported by MikTeX and ``latexmk``.
|
||||
:Description: Name of the used LaTeX processor.
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Input/pdf_artifact:
|
||||
|
||||
pdf_artifact
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the generated PDF document.
|
||||
:Optimization:
|
||||
.. hint::
|
||||
|
||||
If this parameter is empty, no PDF file will be generated and no artifact will be uploaded.
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/LaTeXDocumentation/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
The following optimizations can be used to reduce the template's runtime.
|
||||
|
||||
Disable PDF generation and PDF artifact
|
||||
If parameter :ref:`JOBTMPL/LaTeXDocumentation/Input/pdf_artifact` is empty, no PDF will be generated and uploaded.
|
||||
178
doc/JobTemplate/Documentation/PublishToGitHubPages.rst
Normal file
178
doc/JobTemplate/Documentation/PublishToGitHubPages.rst
Normal file
@@ -0,0 +1,178 @@
|
||||
.. _JOBTMPL/PublishToGitHubPages:
|
||||
.. index::
|
||||
single: GitHub Pages; PublishToGitHubPages Template
|
||||
single: GitHub Action Reusable Workflow; PublishToGitHubPages Template
|
||||
|
||||
PublishToGitHubPages
|
||||
####################
|
||||
|
||||
This job template publishes HTML content from artifacts of other jobs to GitHub Pages.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
tbd
|
||||
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Download artifacts.
|
||||
3. Push HTML files to branch ``gh-pages``.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishToGitHubPages.png
|
||||
:width: 500px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Simple Example
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
BuildTheDocs:
|
||||
# ...
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r6
|
||||
needs:
|
||||
- BuildTheDocs
|
||||
with:
|
||||
doc: Documentation
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Complex Example
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
- BuildTheDocs
|
||||
- Coverage
|
||||
- StaticTypeCheck
|
||||
with:
|
||||
doc: ${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
coverage: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
typing: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PublishToGitHubPages/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/PublishToGitHubPages/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishToGitHubPages/Input/doc` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishToGitHubPages/Input/coverage` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishToGitHubPages/Input/typing` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PublishToGitHubPages/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PublishToGitHubPages/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Input/doc:
|
||||
|
||||
doc
|
||||
===
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the documentation artifact containing the HTML website.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Input/coverage:
|
||||
|
||||
coverage
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the coverage artifact containing the HTML coverage report, which will be integrated as a
|
||||
subdirectory.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Input/typing:
|
||||
|
||||
typing
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the type checking artifact containing the HTML type checker report, which will be integrated
|
||||
as a subdirectory.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishToGitHubPages/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
327
doc/JobTemplate/Documentation/SphinxDocumentation.rst
Normal file
327
doc/JobTemplate/Documentation/SphinxDocumentation.rst
Normal file
@@ -0,0 +1,327 @@
|
||||
.. _JOBTMPL/SphinxDocumentation:
|
||||
.. index::
|
||||
single: Sphinx; SphinxDocumentation Template
|
||||
single: GitHub Action Reusable Workflow; SphinxDocumentation Template
|
||||
|
||||
SphinxDocumentation
|
||||
###################
|
||||
|
||||
The ``SphinxDocumentation`` job template compiles the ReStructured Text documentation using :term:`Sphinx` to an HTML
|
||||
website and a LaTeX documentation. This LaTeX document can be translated using e.g. :term:`MikTeX` to a PDF file.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Build documentation using Sphinx as HTML and upload as artifact. |br|
|
||||
(see :ref:`JOBTMPL/SphinxDocumentation/Input/html_artifact`).
|
||||
* Build documentation using Sphinx as LaTeX and upload as artifact. |br|
|
||||
(see :ref:`JOBTMPL/SphinxDocumentation/Input/latex_artifact`).
|
||||
|
||||
* Workaround `sphinx-doc/sphinx#13189 <https://github.com/sphinx-doc/sphinx/issues/13189>`__
|
||||
* Workaround `sphinx-doc/sphinx#13190 <https://github.com/sphinx-doc/sphinx/issues/13190>`__
|
||||
|
||||
* Optionally: download code coverage artifact (JSON format) given by :ref:`JOBTMPL/SphinxDocumentation/Input/coverage_json_artifact`.
|
||||
* Optionally: download unit test report artifact (XML format) given by :ref:`JOBTMPL/SphinxDocumentation/Input/unittest_xml_artifact`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Install system dependencies.
|
||||
3. Setup Python environment and install Python dependencies.
|
||||
4. Download optional artifacts for integration of further reports into the documentation.
|
||||
5. Build the HTML documentation using Sphinx.
|
||||
6. Build the LaTeX documentation using Sphinx.
|
||||
|
||||
1. Apply LaTeX workaround I.
|
||||
2. Apply LaTeX workaround II.
|
||||
|
||||
7. Upload the HTML and LaTeX artifacts.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-SphinxDocumentation.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* apt
|
||||
|
||||
* `graphviz <https://graphviz.org/>`__
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* Python packages specified via :ref:`JOBTMPL/SphinxDocumentation/Input/requirements` parameter.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
Documentation:
|
||||
uses: pyTooling/Actions/.github/workflows/SphinxDocumentation.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
python_version: ${{ needs.UnitTestingParams.outputs.python_version }}
|
||||
html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_html }}
|
||||
latex_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).documentation_latex }}
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/SphinxDocumentation/Inputs>`
|
||||
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=========================================================================+==========+================+===================================================================+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/requirements` | no | string | ``'-r doc/requirements.txt'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/doc_directory` | no | string | ``'doc'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/coverage_json_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/coverage_report_json` | no | string (JSON) | :jsoncode:`{"directory": "report/coverage"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/unittest_xml_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/unittest_xml` | no | string (JSON) | :jsoncode:`{"directory": "report/unit"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/html_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/SphinxDocumentation/Input/latex_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/SphinxDocumentation/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/SphinxDocumentation/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/requirements:
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'-r doc/requirements.txt'``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'Sphinx sphinx_rtd_theme sphinxcontrib-mermaid'``.
|
||||
:Description: Python dependencies to be installed through *pip*.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/doc_directory:
|
||||
|
||||
doc_directory
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'doc'``
|
||||
:Possible Values: Any valid directory or sub-directory.
|
||||
:Description: Directory where the Sphinx documentation is located.
|
||||
|
||||
.. attention::
|
||||
|
||||
When this parameter gets changed, :ref:`JOBTMPL/SphinxDocumentation/Input/requirements` needs to be
|
||||
adjusted as well.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/coverage_json_artifact:
|
||||
|
||||
coverage_json_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the code coverage report in JSON format.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/coverage_report_json:
|
||||
|
||||
coverage_report_json
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage JSON report will be extracted from
|
||||
:ref:`artifact <JOBTMPL/SphinxDocumentation/Input/coverage_json_artifact>`.
|
||||
:Description: Directory as JSON object where the code coverage JSON report will be extracted. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
Documentation:
|
||||
uses: pyTooling/Actions/.github/workflows/SphinxDocumentation.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/unittest_xml_artifact:
|
||||
|
||||
unittest_xml_artifact
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the unittest XML report summary in XML format.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/unittest_xml:
|
||||
|
||||
unittest_xml
|
||||
============
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/unit",
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the unittest JUnit XML report will be extracted from
|
||||
:ref:`artifact <JOBTMPL/SphinxDocumentation/Input/unittest_xml_artifact>`.
|
||||
:Description: Directory as JSON object where the unittest JUnit XML report will be extracted. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
Documentation:
|
||||
uses: pyTooling/Actions/.github/workflows/SphinxDocumentation.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
unittest_xml: ${{ needs.ConfigParams.outputs.unittest_xml }}
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/html_artifact:
|
||||
|
||||
html_artifact
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the generated HTML website.
|
||||
:Optimization:
|
||||
.. hint::
|
||||
|
||||
If this parameter is empty, no HTML website will be generated and no artifact will be uploaded.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Input/latex_artifact:
|
||||
|
||||
latex_artifact
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the generated LaTeX document and resource files (e.g., images).
|
||||
:Optimization:
|
||||
.. hint::
|
||||
|
||||
If this parameter is empty, no LaTeX document will be generated and no artifact will be uploaded.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/SphinxDocumentation/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
The following optimizations can be used to reduce the template's runtime.
|
||||
|
||||
Disable HTML website generation and HTML artifact
|
||||
If parameter :ref:`JOBTMPL/SphinxDocumentation/Input/html_artifact` is empty, no HTML website will be generated and
|
||||
uploaded.
|
||||
Disable LaTeX document generation and LaTeX artifact
|
||||
If parameter :ref:`JOBTMPL/SphinxDocumentation/Input/latex_artifact` is empty, no LaTeX document will be generated and
|
||||
uploaded.
|
||||
17
doc/JobTemplate/Documentation/index.rst
Normal file
17
doc/JobTemplate/Documentation/index.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
.. _JOBTMPL/Documentation:
|
||||
|
||||
Documentation
|
||||
#############
|
||||
|
||||
The category *documentation* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/SphinxDocumentation` - Translate ReStructured Text to HTML and LaTeX using Sphinx.
|
||||
* :ref:`JOBTMPL/LaTeXDocumentation` - Translate LaTeX to PDF using MikTeX.
|
||||
* :ref:`JOBTMPL/PublishToGitHubPages` - Upload HTML content to GitHub Pages.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
SphinxDocumentation
|
||||
LaTeXDocumentation
|
||||
PublishToGitHubPages
|
||||
@@ -1,106 +0,0 @@
|
||||
.. _JOBTMPL/Package:
|
||||
|
||||
Package
|
||||
#######
|
||||
|
||||
This job packages the Python source code as a source package (``*.tar.gz``) and wheel package (``*.whl``) and uploads it
|
||||
as an artifact.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository
|
||||
2. Setup Python and install dependencies
|
||||
3. Package Python sources:
|
||||
|
||||
* If parameter ``requirements`` is empty, use ``build`` package and run ``python build``.
|
||||
* If parameter ``requirements`` is ``no-isolation``, use ``build`` package in *no-isolation* mode and run
|
||||
``python build``.
|
||||
* If parameter ``requirements`` is non-empty, use ``setuptools`` package and run ``python setup.py``.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@r0
|
||||
with:
|
||||
artifact: Package
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
- Coverage
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
requirements: -r build/requirements.txt
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| python_version | optional | string | 3.11 |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Python version.
|
||||
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| requirements | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Python dependencies to be installed through pip; if empty, use pyproject.toml through build.
|
||||
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| artifact | yes | string | — — — — |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Name of the package artifact.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
184
doc/JobTemplate/Package/InstallPackage.rst
Normal file
184
doc/JobTemplate/Package/InstallPackage.rst
Normal file
@@ -0,0 +1,184 @@
|
||||
.. _JOBTMPL/InstallPackage:
|
||||
.. index::
|
||||
single: pip; InstallPackage Template
|
||||
single: GitHub Action Reusable Workflow; InstallPackage Template
|
||||
|
||||
InstallPackage (beta)
|
||||
#####################
|
||||
|
||||
The ``InstallPackage`` job template takes a generated Python package and installs it on the target platform. Afterwards
|
||||
the installation is verified. This aims for packaging and dependency mistakes in the package.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Install generated Python package on the target platform.
|
||||
* Verify the installed package's version.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
* Download Python package as artifact.
|
||||
* Prepare the Python environment.
|
||||
* Install the Python package using :term:`pip`.
|
||||
* Read out and verify the package version.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-InstallPackage.png
|
||||
:width: 500px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`msys2/setup-msys2`
|
||||
* :gh:`actions/setup-python`
|
||||
* pip
|
||||
|
||||
* :pypi:`pip`
|
||||
* :pypi:`wheel`
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``Install`` job derived from job template ``InstallPackage`` version
|
||||
`@r6`. It installs the Python package on various platforms using a precomputed job-matrix created by job
|
||||
``InstallParams``. This job uses the same ``Parameters`` job template as job ``UnitTestingParams``, which was used to
|
||||
define parameters for the packaging job ``Package``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
InstallParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
python_version_list: ''
|
||||
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
|
||||
Install:
|
||||
uses: pyTooling/Actions/.github/workflows/InstallPackage.yml@r6
|
||||
needs:
|
||||
- UnitTestingParams
|
||||
- InstallParams
|
||||
- Package
|
||||
with:
|
||||
jobs: ${{ needs.InstallParams.outputs.python_jobs }}
|
||||
wheel: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
|
||||
package_name: ${{ needs.UnitTestingParams.outputs.package_fullname }}
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/InstallPackage/Inputs>`
|
||||
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=========================================================================+==========+==========+===================================================================================================================================+
|
||||
| :ref:`JOBTMPL/InstallPackage/Input/jobs` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/InstallPackage/Input/wheel` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/InstallPackage/Input/package_name` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/InstallPackage/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/InstallPackage/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Input/jobs:
|
||||
|
||||
jobs
|
||||
====
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: A JSON string with an array of dictionaries with the following key-value pairs:
|
||||
|
||||
:sysicon: icon to display
|
||||
:system: name of the system
|
||||
:runs-on: virtual machine image and base operating system
|
||||
:runtime: name of the runtime environment if not running natively on the VM image
|
||||
:shell: name of the shell
|
||||
:pyicon: icon for CPython or pypy
|
||||
:python: Python version
|
||||
:envname: full name of the selected environment
|
||||
:Description: A JSON encoded job matrix to run multiple Python job variations.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Input/wheel:
|
||||
|
||||
wheel
|
||||
=====
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: The artifact containing the packaged Python code as wheel.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Input/package_name:
|
||||
|
||||
package_name
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid Python package, subpackage or module name.
|
||||
:Description: The package or module containing the version information as a string in ``__version__``.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/InstallPackage/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
175
doc/JobTemplate/Package/Package.rst
Normal file
175
doc/JobTemplate/Package/Package.rst
Normal file
@@ -0,0 +1,175 @@
|
||||
.. _JOBTMPL/Package:
|
||||
.. index::
|
||||
single: build; Package Template
|
||||
single: GitHub Action Reusable Workflow; Package Template
|
||||
|
||||
Package
|
||||
#######
|
||||
|
||||
This job packages the Python source code as a source package (``*.tar.gz``) and wheel package (``*.whl``) and uploads it
|
||||
as an artifact.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Package source code as wheel and source distribution.
|
||||
* Support packaging using :pypi:`build` (recommended) or :pypi:`setuptools`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Setup Python and install dependencies.
|
||||
3. Package Python sources:
|
||||
|
||||
* If parameter :ref:`JOBTMPL/Package/Input/requirements` is empty, use :pypi:`build` for packaging and execute
|
||||
``python -m build ...``.
|
||||
* If parameter :ref:`JOBTMPL/Package/Input/requirements` is ``no-isolation``, use :pypi:`build` for packaging in
|
||||
*no-isolation* mode executing ``python -m build --no-isolation ...``.
|
||||
* If parameter :ref:`JOBTMPL/Package/Input/requirements` is non-empty, use :pypi:`setuptools` for package and
|
||||
execute ``python setup.py ...``.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-Package.png
|
||||
:width: 500px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`build`
|
||||
* :pypi:`wheel`
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@r6
|
||||
with:
|
||||
artifact: Package
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Package:
|
||||
uses: pyTooling/Actions/.github/workflows/Package.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
requirements: -r build/requirements.txt
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/Package/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/Package/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Package/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Package/Input/requirements` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Package/Input/artifact` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/Package/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/Package/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/Package/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Input/requirements:
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'build wheel'``.
|
||||
:Behavior: If the value is an empty string, :pypi:`build` is used for packaging. |br|
|
||||
if the value is ``no-isolation``, :pypi:`build` is used in *no-isolation* mode for packaging. |br|
|
||||
otherwise, a list of requirements is assumed and :pypi:`setuptools` is used for packaging.
|
||||
:Description: Python dependencies to be installed through *pip*.
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Input/artifact:
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the packaged Python code.
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/Package/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
210
doc/JobTemplate/Package/PublishOnPyPI.rst
Normal file
210
doc/JobTemplate/Package/PublishOnPyPI.rst
Normal file
@@ -0,0 +1,210 @@
|
||||
.. _JOBTMPL/PublishOnPyPI:
|
||||
.. index::
|
||||
single: PyPI; PublishOnPyPI Template
|
||||
single: twine; PublishOnPyPI Template
|
||||
single: GitHub Action Reusable Workflow; PublishOnPyPI Template
|
||||
|
||||
PublishOnPyPI
|
||||
#############
|
||||
|
||||
Publish a wheel (``*.whl``) packages and/or source (``*.tar.gz``) package to :term:`PyPI`.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Publish a Python package to :term:`PyPI`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Download package artifact
|
||||
2. Publish source package(s) (``*.tar.gz``)
|
||||
3. Publish wheel package(s) (``*.whl``)
|
||||
4. Delete the artifact
|
||||
|
||||
.. topic:: Preconditions
|
||||
|
||||
1. A PyPI account was created and the package name is either not occupied or the user has access rights for that
|
||||
package.
|
||||
2. An access token was generated at PyPI, which can be used for uploading packages.
|
||||
3. A secret (e.g. ``PYPI_TOKEN``) was setup in GitHub Actions to handover the PyPI token to the pipeline.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishOnPyPI.png
|
||||
:width: 500px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`twine`
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
The following example demonstrates how to publish the artifact named ``Package`` to PyPI on every pipeline run triggered
|
||||
by a Git tag. A secret is forwarded from GitHub secrets to a job secret.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
# ...
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@r6
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
with:
|
||||
artifact: Package
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
In this more complex example, the job depends on a parameter creation (``Params``) and packaging job (``Package``). The
|
||||
used Python version is overwritten by a parameter calculated in the ``Params`` jobs. Also the artifact name is managed
|
||||
by that job. Finally, the list of requirements is overwritten to load a list of requirements from ``dist/requirements.txt``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
# ...
|
||||
|
||||
Package:
|
||||
# ...
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@r6
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- Params
|
||||
- Package
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
requirements: -r dist/requirements.txt
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/Package`
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PublishOnPyPI/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/PublishOnPyPI/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishOnPyPI/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishOnPyPI/Input/requirements` | no | string | ``'wheel twine'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishOnPyPI/Input/artifact` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PublishOnPyPI/Secrets>`
|
||||
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| Token Name | Required | Type | Default |
|
||||
+===========================================================+==========+==========+==============+
|
||||
| :ref:`JOBTMPL/PublishOnPyPI/Secret/PYPI_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PublishOnPyPI/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Input/requirements:
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'wheel twine'``.
|
||||
:Description: Python dependencies to be installed through *pip*.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Input/artifact:
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the packaged Python package(s).
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Secret/PYPI_TOKEN:
|
||||
|
||||
PYPI_TOKEN
|
||||
==========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish and upload packages on :term:`PyPI`.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishOnPyPI/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
17
doc/JobTemplate/Package/index.rst
Normal file
17
doc/JobTemplate/Package/index.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
.. _JOBTMPL/Packaging:
|
||||
|
||||
Packaging
|
||||
#########
|
||||
|
||||
The category *packaging* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/Package` - Package Python packages and modules as wheel.
|
||||
* :ref:`JOBTMPL/InstallPackage` - Install Python package (wheel) on target platforms.
|
||||
* :ref:`JOBTMPL/PublishOnPyPI` - Upload Python package (wheel) to PyPI.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
Package
|
||||
InstallPackage
|
||||
PublishOnPyPI
|
||||
@@ -1,413 +0,0 @@
|
||||
.. _JOBTMPL/Parameters:
|
||||
|
||||
Parameters
|
||||
##########
|
||||
|
||||
The ``Parameters`` job template is a workaround for the limitations of GitHub Actions to handle global variables in
|
||||
GitHub Actions workflows (see `actions/runner#480 <https://github.com/actions/runner/issues/480>`__.
|
||||
|
||||
It generates output parameters with artifact names and a job matrix to be used in later running jobs.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
.. todo:: Parameters:Behavior Needs documentation.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
*None*
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
The following instantiation example creates a job `Params` derived from job template `Parameters` version `r0`. It only
|
||||
requires a `name` parameter to create the artifact names.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
The following instantiation example creates 3 jobs from the same template, but with differing input parameters. The
|
||||
first job `UnitTestingParams` might be used to create a job matrix of unit tests. It creates the cross of default
|
||||
systems (Windows, Ubuntu, macOS, MinGW64, UCRT64) and the given list of Python versions including some mypy versions. In
|
||||
addition a list of excludes (marked as :deletion:`deletions`) and includes (marked as :addition:`additions`) is handed
|
||||
over resulting in the following combinations:
|
||||
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| Version | 3.8 🔴 | 3.9 🟠 | 3.10 🟡 | 3.11 🟢 | 3.12 🟢 | 3.13.a1 🟣 | pypy-3.8 🔴 | pypy-3.9 🟠 | pypy-3.10 🟡 |
|
||||
+============+=============+=============+==============+==============+=========================+============+=============+==============================+===============================+
|
||||
| Windows 🧊 | windows:3.8 | windows:3.9 | windows:3.10 | windows:3.11 | | | | :deletion:`windows:pypy-3.9` | :deletion:`windows:pypy-3.10` |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| Ubuntu 🐧 | ubuntu:3.8 | ubuntu:3.9 | ubuntu:3.10 | ubuntu:3.11 | :addition:`ubuntu:3.12` | | | ubuntu:pypy-3.9 | ubuntu:pypy-3.10 |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| macOS 🍎 | macos:3.8 | macos:3.9 | macos:3.10 | macos:3.11 | :addition:`macos:3.12` | | | macos:pypy-3.9 | macos:pypy-3.10 |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| MSYS 🟪 | | | | | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| MinGW32 ⬛ | | | | | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| MinGW64 🟦 | | | | mingw64:3.11 | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| Clang32 🟫 | | | | | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| Clang64 🟧 | | | | | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
| UCRT64 🟨 | | | | | | | | | |
|
||||
+------------+-------------+-------------+--------------+--------------+-------------------------+------------+-------------+------------------------------+-------------------------------+
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
python_version_list: "3.8 3.9 3.10 3.11 pypy-3.9 pypy-3.10"
|
||||
include_list: "ubuntu:3.12 macos:3.12"
|
||||
exclude_list: "windows:pypy-3.9 windows:pypy-3.10"
|
||||
|
||||
PerformanceTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
python_version_list: "3.11 3.12"
|
||||
system_list: "ubuntu windows macos"
|
||||
|
||||
PlatformTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@dev
|
||||
with:
|
||||
name: pyTooling
|
||||
python_version_list: "3.12"
|
||||
system_list: "ubuntu windows macos mingw32 mingw64 clang64 ucrt64"
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
name
|
||||
====
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| name | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
The name of the library or package.
|
||||
|
||||
It's used to create artifact names.
|
||||
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| python_version | optional | string | ``3.12`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Python version to be used for all jobs requiring a single Python version.
|
||||
|
||||
|
||||
python_version_list
|
||||
===================
|
||||
|
||||
+----------------------+----------+----------+----------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+======================+==========+==========+============================+
|
||||
| python_version_list | optional | string | ``3.8 3.9 3.10 3.11 3.12`` |
|
||||
+----------------------+----------+----------+----------------------------+
|
||||
|
||||
Space separated list of CPython versions and/or mypy version to run tests with.
|
||||
|
||||
**Possible values:**
|
||||
|
||||
* ``3.7``, ``3.8``, ``3.9``, ``3.10`` , ``3.11``, ``3.12``, ``3.13``
|
||||
* ``pypy-3.7``, ``pypy-3.8``, ``pypy-3.9``, ``pypy-3.10``
|
||||
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| Icon | Version | Maintained until | Comments |
|
||||
+======+===========+==================+=========================================+
|
||||
| ⚫ | 3.7 | 2023.06.27 | :red:`outdated` |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🔴 | 3.8 | 2024.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🟠 | 3.9 | 2025.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🟡 | 3.10 | 2026.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🟢 | 3.11 | 2027.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🟢 | 3.12 | 2028.10 | :green:`latest` |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| 🟣 | 3.13 | 2029.10 | Python 3.13 alpha (or RC) will be used. |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| ⟲⚫ | pypy-3.7 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| ⟲🔴 | pypy-3.8 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| ⟲🟠 | pypy-3.9 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
| ⟲🟡 | pypy-3.10 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------+
|
||||
|
||||
|
||||
system_list
|
||||
===========
|
||||
|
||||
+----------------+----------+----------+-----------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=========================================+
|
||||
| system_list | optional | string | ``ubuntu windows macos mingw64 ucrt64`` |
|
||||
+----------------+----------+----------+-----------------------------------------+
|
||||
|
||||
Space separated list of systems to run tests on.
|
||||
|
||||
**Possible values:**
|
||||
|
||||
* Native systems: ``ubuntu``, ``windows``, ``macos``
|
||||
* MSYS2: ``msys``, ``mingw32``, ``mingw64``, ``clang32``, ``clang64``, ``ucrt64``
|
||||
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| Icon | System | Used version | Comments |
|
||||
+======+===========+==============================+=================================================================+
|
||||
| 🧊 | Windows | Windows Server 2022 (latest) | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🐧 | Ubuntu | Ubuntu 22.04 (LTS) (latest) | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🍎 | macOS | macOS Monterey 12 (latest) | While this marked latest, macOS Ventura 13 is already provided. |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟪 | MSYS | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| ⬛ | MinGW32 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟦 | MinGW64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟫 | Clang32 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟧 | Clang64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟨 | UCRT64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
|
||||
Source: `Images provided by GitHub <https://github.com/actions/runner-images>`__
|
||||
|
||||
include_list
|
||||
============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| include_list | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Space separated list of ``system:python`` items to be included into the list of test.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
include_list: "ubuntu:3.11 macos:3.11"
|
||||
|
||||
|
||||
exclude_list
|
||||
============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| exclude_list | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Space separated list of ``system:python`` items to be excluded from the list of test.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
exclude_list: "windows:pypy-3.8 windows:pypy-3.9"
|
||||
|
||||
|
||||
disable_list
|
||||
============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| disable_list | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Space separated list of ``system:python`` items to be temporarily disabled from the list of test.
|
||||
|
||||
Each disabled item creates a warning in the workflow log:
|
||||
|
||||
.. image:: /_static/GH_Workflow_DisabledJobsWarnings.png
|
||||
:scale: 80 %
|
||||
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
disable_list: "windows:3.10 windows:3.11"
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
A single string parameter representing the default Python version that should be used across multiple jobs in the same
|
||||
pipeline.
|
||||
|
||||
Such a parameter is needed as a workaround, because GitHub Actions doesn't support proper handling of global pipeline
|
||||
variables. Thus, this job is used to compute an output parameter that can be reused in other jobs.
|
||||
|
||||
**Usage Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
CodeCoverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
|
||||
python_jobs
|
||||
===========
|
||||
|
||||
A list of dictionaries containing a job description.
|
||||
|
||||
A job description contains the following key-value pairs:
|
||||
|
||||
* ``sysicon`` - icon to display
|
||||
* ``system`` - name of the system
|
||||
* ``runs-on`` - virtual machine image and base operating system
|
||||
* ``runtime`` - name of the runtime environment if not running natively on the VM image
|
||||
* ``shell`` - name of the shell
|
||||
* ``pyicon`` - icon for CPython or pypy
|
||||
* ``python`` - Python version
|
||||
* ``envname`` - full name of the selected environment
|
||||
|
||||
**Usage Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@dev
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
jobs: ${{ needs.Params.outputs.python_jobs }}
|
||||
|
||||
This list can be unpacked with ``fromJson(...)`` in a job ``strategy:matrix:include``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
UnitTesting:
|
||||
name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Unit Tests using Python ${{ matrix.python }}
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include: ${{ fromJson(inputs.jobs) }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
steps:
|
||||
- name: 🐍 Setup Python ${{ matrix.python }}
|
||||
if: matrix.system != 'msys2'
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
|
||||
artifact_names
|
||||
==============
|
||||
|
||||
A dictionary of artifact names sharing a common prefix.
|
||||
|
||||
The supported artifacts are:
|
||||
|
||||
* ``unittesting_xml`` - UnitTesting XML summary report
|
||||
* ``unittesting_html`` - UnitTesting HTML summary report
|
||||
* ``codecoverage_sqlite`` - Code Coverage internal database (SQLite)
|
||||
* ``codecoverage_json`` - Code Coverage JSON report
|
||||
* ``codecoverage_xml`` - Code Coverage XML report
|
||||
* ``codecoverage_html`` - Code Coverage HTML report
|
||||
* ``statictyping_html`` - Static Type Checking HTML report
|
||||
* ``package_all`` - Packaged Python project (multiple formats)
|
||||
* ``documentation_pdf`` - Documentation in PDF format
|
||||
* ``documentation_html`` - Documentation in HTML format
|
||||
|
||||
**Usage Example:**
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
Coverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@dev
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
|
||||
|
||||
Params
|
||||
======
|
||||
|
||||
.. attention:: ``Params`` is deprecated.
|
||||
|
||||
* ``params['unittesting']`` |rarr| ``artifact_names['unittesting_xml']``
|
||||
* ``params['coverage']`` |rarr| ``artifact_names['codecoverage_xml']``
|
||||
* ``params['typing']`` |rarr| ``artifact_names['statictyping_html']``
|
||||
* ``params['package']`` |rarr| ``artifact_names['package_all']``
|
||||
* ``params['doc']`` |rarr| ``artifact_names['documentation_html']``
|
||||
462
doc/JobTemplate/Publish/PublishCoverageResults.rst
Normal file
462
doc/JobTemplate/Publish/PublishCoverageResults.rst
Normal file
@@ -0,0 +1,462 @@
|
||||
.. _JOBTMPL/PublishCoverageResults:
|
||||
.. index::
|
||||
single: CodeCov; PublishCoverageResults Template
|
||||
single: Codacy; PublishCoverageResults Template
|
||||
single: Coverage.py; PublishCoverageResults Template
|
||||
single: GitHub Action Reusable Workflow; PublishCoverageResults Template
|
||||
|
||||
PublishCoverageResults
|
||||
######################
|
||||
|
||||
The ``PublishCoverageResults`` job template downloads artifacts provided by :ref:`JOBTMPL/UnitTesting` containing code
|
||||
coverage databases created by :term:`Coverage.py`. These databases are then merged and converted into various output
|
||||
formats like Cobertura XML, JSON or HTML. These outputs are either uploaded as a new artifact or can be published to
|
||||
cloud services like :term:`CodeCov` or :term:`Codacy`.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Merge SQLite code coverage databases generated by Coverage.py into a single
|
||||
SQLite database.
|
||||
* Convert SQLite database to Cobertura XML format.
|
||||
* Convert SQLite database to Coverage.py JSON format.
|
||||
* Convert SQLite database to HTML code coverage report.
|
||||
* Publish code coverage at CodeCov.
|
||||
* Publish code coverage as Codacy.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Download artifact matching the :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_artifacts_pattern`.
|
||||
3. Install Python dependencies especially :pypi:`coverage`.
|
||||
4. Rename SQLite database files within artifact download directory to match the required filename pattern for
|
||||
Coverage.py's merge operation.
|
||||
5. Report code coverage as table into job log.
|
||||
6. Convert code coverage to Cobertura XML format.
|
||||
7. Convert code coverage to JSON format.
|
||||
8. Convert code coverage to HTML report (website).
|
||||
9. Upload merged SQLite database as artifact.
|
||||
10. Upload Cobertura XML file as artifact.
|
||||
11. Upload JSON file as artifact.
|
||||
12. Upload HTML report as artifact.
|
||||
13. Publish Cobertura report to CodeCov.
|
||||
14. Publish Cobertura report to Codacy.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishCoverageResults.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`coverage`
|
||||
* :pypi:`tomli`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* :gh:`codecov/codecov-action`
|
||||
* :gh:`codacy/codacy-coverage-reporter-action`
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
- UnitTesting
|
||||
with:
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
coverage_json_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_json }}
|
||||
coverage_html_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_html }}
|
||||
codecov: 'true'
|
||||
codacy: 'true'
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PublishCoverageResults/Inputs>`
|
||||
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=============================================================================+==========+================+==========================================================================================================================+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_artifacts_pattern` | no | string | ``'*-CodeCoverage-SQLite-*'`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_config` | no | string | ``'pyproject.toml'`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_report_xml` | no | string (JSON) | :jsoncode:`{"directory": "report/coverage", "filename": "coverage.xml", "fullpath": "report/coverage/coverage.xml"}` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_report_json` | no | string (JSON) | :jsoncode:`{"directory": "report/coverage", "filename": "coverage.json", "fullpath": "report/coverage/coverage.json"}` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_report_html` | no | string (JSON) | :jsoncode:`{"directory": "report/coverage/html"}` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_sqlite_artifact` | no | string | ``''`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_xml_artifact` | no | string | ``''`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_json_artifact` | no | string | ``''`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_html_artifact` | no | string | ``''`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/codecov` | no | string | ``'false'`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Input/codacy` | no | string | ``'false'`` |
|
||||
+-----------------------------------------------------------------------------+----------+----------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PublishCoverageResults/Secrets>`
|
||||
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| Token Name | Required | Type | Default |
|
||||
+===========================================================+==========+==========+==============+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Secret/CODECOV_TOKEN`| no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| :ref:`JOBTMPL/PublishCoverageResults/Secret/CODACY_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PublishCoverageResults/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_artifacts_pattern:
|
||||
|
||||
coverage_artifacts_pattern
|
||||
==========================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'*-CodeCoverage-SQLite-*'``
|
||||
:Possible Values: Any valid artifact matching pattern using fixed text and ``*`` characters.
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_config:
|
||||
|
||||
coverage_config
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'pyproject.toml'``
|
||||
:Possible Values: Any valid path to a :file:`pyproject.toml` file. |br|
|
||||
Alternatively, path to a :file:`.coveragerc` file (deprecated).
|
||||
:Description: Path to a Python project configuration file for extraction of project settings.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Extracted values from :file:`pyproject.toml`
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.pytest]
|
||||
junit_xml = "report/unit/UnittestReportSummary.xml"
|
||||
|
||||
[tool.pyedaa-reports]
|
||||
junit_xml = "report/unit/unittest.xml"
|
||||
|
||||
[tool.coverage.xml]
|
||||
output = "report/coverage/coverage.xml"
|
||||
|
||||
[tool.coverage.json]
|
||||
output = "report/coverage/coverage.json"
|
||||
|
||||
[tool.coverage.html]
|
||||
directory = "report/coverage/html"
|
||||
title="Code Coverage of pyDummy"
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_report_xml:
|
||||
|
||||
coverage_report_xml
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.xml",
|
||||
"fullpath": "reports/coverage/coverage.xml"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in Cobertura XML format will be
|
||||
saved.
|
||||
:filename: Filename of the generated Cobertura XML report. |br|
|
||||
Any valid XML filename.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the code coverage report in Cobertura XML format
|
||||
will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_report_json:
|
||||
|
||||
coverage_report_json
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.json",
|
||||
"fullpath": "reports/coverage/coverage.json"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in Coverage.py's JSON format
|
||||
will be saved.
|
||||
:filename: Filename of the generated Coverage.py JSON report. |br|
|
||||
Any valid JSON filename.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the code coverage report in Coverage.py's JSON
|
||||
format will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_report_html:
|
||||
|
||||
coverage_report_html
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage/html"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in HTML format will be saved.
|
||||
:Description: Directory as JSON object where the code coverage report in HTML format will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
PublishCoverageResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishCoverageResults.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_sqlite_artifact:
|
||||
|
||||
coverage_sqlite_artifact
|
||||
========================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the merged SQLite code coverage database.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_xml_artifact:
|
||||
|
||||
coverage_xml_artifact
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the merged code coverage report as Cobertura XML file.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_json_artifact:
|
||||
|
||||
coverage_json_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the merged code coverage report as Coverage.py JSON file.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/coverage_html_artifact:
|
||||
|
||||
coverage_html_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'report/coverage/html'``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the merged code coverage report as HTML report.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/codecov:
|
||||
|
||||
codecov
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *true*, publish code coverage results to CodeCov.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Input/codacy:
|
||||
|
||||
codacy
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: If *true*, publish code coverage results to Codacy.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
The workflow template uses the following secrets to publish results to other services.
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Secret/CODECOV_TOKEN:
|
||||
|
||||
CODECOV_TOKEN
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish code coverage and unit test results to :term:`CodeCov`.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Secret/CODACY_TOKEN:
|
||||
|
||||
CODACY_TOKEN
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish code coverage results to :term:`Codacy`.
|
||||
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishCoverageResults/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
The following optimizations can be used to reduce the template's runtime.
|
||||
|
||||
Disable code coverage SQLite database artifact upload
|
||||
If parameter :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_sqlite_artifact` is empty, the collected code coverage database
|
||||
(SQLlite format) wont be uploaded as an artifact.
|
||||
Disable code coverage report conversion to the Cobertura XML format.
|
||||
If parameter :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_xml_artifact` is empty, no Cobertura XML file will be generated
|
||||
from code coverage report. As no Cobertura XML file exists, no code coverage XML artifact will be uploaded.
|
||||
Disable code coverage report conversion to the *Coverage.py* JSON format.
|
||||
If parameter :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_json_artifact` is empty, no *Coverage.py* JSON file will be
|
||||
generated from code coverage report. As no JSON file exists, no code coverage JSON artifact will be uploaded.
|
||||
Disable code coverage report conversion to an HTML website.
|
||||
If parameter :ref:`JOBTMPL/PublishCoverageResults/Input/coverage_html_artifact` is empty, no coverage report HTML report will be
|
||||
generated from code coverage report. As no HTML report exists, no code coverage HTML artifact will be uploaded.
|
||||
|
||||
.. todo:: PublishCoverageResults:: Disable publishing to codecov and codacy. |br| If upload is enabled, XML will be always generated.
|
||||
344
doc/JobTemplate/Publish/PublishTestResults.rst
Normal file
344
doc/JobTemplate/Publish/PublishTestResults.rst
Normal file
@@ -0,0 +1,344 @@
|
||||
.. _JOBTMPL/PublishTestResults:
|
||||
.. index::
|
||||
single: CodeCov; PublishTestResults Template
|
||||
single: pyEDAA.Reports; PublishTestResults Template
|
||||
single: Test Reporter; PublishTestResults Template
|
||||
single: GitHub Action Reusable Workflow; PublishTestResults Template
|
||||
|
||||
PublishTestResults
|
||||
##################
|
||||
|
||||
This job downloads all matching JUnit report artifacts, merged the reports into one single report and then publishes the
|
||||
JUnit test summary reports to multiple services for visualization and longterm statistical tracking.
|
||||
|
||||
Supported services are:
|
||||
|
||||
* GitHub Actions job results using :term:`Test Reporter`
|
||||
* :term:`Codecov`
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Merge multiple JUnit XML reports generated by pytest into a single JUnit XML report.
|
||||
* Publish unit test results to currently running pipeline as job result.
|
||||
* Publish unit test results to CodeCov.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository
|
||||
2. Download multiple artifacts containing test report summaries in JUnit XML format conforming to an artifact name
|
||||
pattern (see :ref:`JOBTMPL/PublishTestResults/Input/unittest_artifacts_pattern`) for limiting the number of
|
||||
downloaded artifacts and the hereby generated traffic.
|
||||
3. Rename the found JUnit XML files.
|
||||
4. Merge all found JUnit XML files using :term:`pyEDAA.Reports` into a new JUnit XML file. |br|
|
||||
Optionally, apply certain transformation and cleanup operations to the JUnit report structure.
|
||||
5. Publish test results as a markdown report page to GitHub Actions using :term:`Test Reporter`.
|
||||
6. Publish test results to :term:`Codecov` using :gh:`codecov/test-results-action`.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Job Steps
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishTestResults.png
|
||||
:width: 500px
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Generated Dorny Report below Pipeline Graph
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishTestResults-Dorny.png
|
||||
:width: 500px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* pip
|
||||
|
||||
* :pypi:`pyEDAA.Reports`
|
||||
|
||||
* :gh:`dorny/test-reporter`
|
||||
* :gh:`codecov/test-results-action`
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@r6
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
CodeCoverage:
|
||||
# ...
|
||||
|
||||
UnitTesting:
|
||||
# ...
|
||||
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@r6
|
||||
needs:
|
||||
- CodeCoverage
|
||||
- UnitTesting
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PublishTestResults/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+=====================================================================+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/unittest_artifacts_pattern` | no | string | ``'*-UnitTestReportSummary-XML-*'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/merged_junit_filename` | no | string | ``'Unittesting.xml'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/merged_junit_artifact` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/merge-input-dialect` | no | string | ``'pyTest-JUnit'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/merge-output-dialect` | no | string | ``'pyTest-JUnit'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/additional_merge_args` | no | string | ``'"--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit"'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/testsuite-summary-name` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/publish` | no | string | ``'true'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/report_title` | no | string | ``'Unit Test Results'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/dorny` | no | string | ``'true'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/codecov` | no | string | ``'false'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Input/codecov_flags` | no | string | ``'unittest'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+---------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PublishTestResults/Secrets>`
|
||||
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
| Token Name | Required | Type | Default |
|
||||
+===========================================================+==========+==========+==============+
|
||||
| :ref:`JOBTMPL/PublishTestResults/Secret/CODECOV_TOKEN` | no | string | — — — — |
|
||||
+-----------------------------------------------------------+----------+----------+--------------+
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PublishTestResults/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/unittest_artifacts_pattern:
|
||||
|
||||
unittest_artifacts_pattern
|
||||
==========================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'*-UnitTestReportSummary-XML-*'``
|
||||
:Possible Values: Any valid artifact matching pattern using fixed text and ``*`` characters.
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/merged_junit_filename:
|
||||
|
||||
merged_junit_filename
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'Unittesting.xml'``
|
||||
:Possible Values: Any valid filename suitable for a JUnit XML report.
|
||||
:Description: The filename for the merged JUnit report in XML format. |br|
|
||||
See :ref:`JOBTMPL/PublishTestResults/Input/merge-output-dialect` for the used JUnit dialect in the
|
||||
merged report file.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/merged_junit_artifact:
|
||||
|
||||
merged_junit_artifact
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description:
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/merge-input-dialect:
|
||||
|
||||
merge-input-dialect
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'pyTest-JUnit'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/merge-output-dialect:
|
||||
|
||||
merge-output-dialect
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'pyTest-JUnit'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/additional_merge_args:
|
||||
|
||||
additional_merge_args
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'"--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit"'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/testsuite-summary-name:
|
||||
|
||||
testsuite-summary-name
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/publish:
|
||||
|
||||
publish
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'true'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/report_title:
|
||||
|
||||
report_title
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'Unit Test Results'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/dorny:
|
||||
|
||||
dorny
|
||||
=====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'true'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/codecov:
|
||||
|
||||
codecov
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Input/codecov_flags:
|
||||
|
||||
codecov_flags
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'unittest'``
|
||||
:Possible Values: tbd
|
||||
:Description: tbd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Secret/CODECOV_TOKEN:
|
||||
|
||||
CODECOV_TOKEN
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: — — — —
|
||||
:Description: The token to publish unit test results on :term:`CodeCov`.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishTestResults/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
15
doc/JobTemplate/Publish/index.rst
Normal file
15
doc/JobTemplate/Publish/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. _JOBTMPL/Publish:
|
||||
|
||||
Publish
|
||||
#######
|
||||
|
||||
The category *publish* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/PublishTestResults`- Merge and publish unit test results.
|
||||
* :ref:`JOBTMPL/PublishCoverageResults` - Merge and publish code coverage results.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
PublishTestResults
|
||||
PublishCoverageResults
|
||||
@@ -1,139 +0,0 @@
|
||||
.. _JOBTMPL/PyPI:
|
||||
|
||||
PublishOnPyPI
|
||||
#############
|
||||
|
||||
Publish a source (``*.tar.gz``) package and/or wheel (``*.whl``) packages to `PyPI <https://pypi.org/>`__.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Download package artifact
|
||||
2. Publish source package(s) (``*.tar.gz``)
|
||||
3. Publish wheel package(s) (``*.whl``)
|
||||
4. Delete the artifact
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
A PyPI account was created and the package name is either not occupied or the user has access rights for that package.
|
||||
|
||||
**Requirements:**
|
||||
|
||||
Setup a secret (e.g. ``PYPI_TOKEN``) in GitHub to handover the PyPI token to the job.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`geekyeggo/delete-artifact`
|
||||
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
The following example demonstrates how to publish the artifact named ``Package`` to PyPI on every pipeline run triggered
|
||||
by a Git tag. A secret is forwarded from GitHub secrets to a job secret.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
# ...
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@r0
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
with:
|
||||
artifact: Package
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
In this more complex example, the job depends on a parameter creation (``Params``) and packaging job (``Package``). The
|
||||
used Python version is overwritten by a parameter calculated in the ``Params`` jobs. Also the artifact name is managed
|
||||
by that job. Finally, the list of requirements is overwritten to load a list of requirements from ``dist/requirements.txt``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
# ...
|
||||
|
||||
Package:
|
||||
# ...
|
||||
|
||||
PublishOnPyPI:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@r0
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- Params
|
||||
- Package
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
requirements: -r dist/requirements.txt
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).package_all }}
|
||||
secrets:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| python_version | optional | string | ``3.11`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Python version used for uploading the package contents via `twine` to PyPI.
|
||||
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
+----------------+----------+----------+-----------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================+
|
||||
| requirements | optional | string | ``wheel twine`` |
|
||||
+----------------+----------+----------+-----------------+
|
||||
|
||||
List of requirements to be installed for uploading the package contents to PyPI.
|
||||
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| artifact | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the artifact containing the package(s).
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
PYPI_TOKEN
|
||||
==========
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Secret Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| PYPI_TOKEN | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
The token to access the package at PyPI for uploading new data.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
@@ -1,88 +0,0 @@
|
||||
.. _JOBTMPL/PublishTestResults:
|
||||
|
||||
PublishTestResults
|
||||
##################
|
||||
|
||||
This job downloads all artifacts and uploads jUnit XML reports as a Markdown page to GitHub Actions to visualize the
|
||||
results a an item in the job list. For publishing, :gh:`dorny/test-reporter` is used.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository
|
||||
2. Download (all) artifacts
|
||||
3. Publish test results as a markdown report page to GitHub Actions.
|
||||
|
||||
.. note::
|
||||
|
||||
The :gh:`actions/download-artifact` does not support wildcards to specify a subset of artifacts for downloading.
|
||||
Thus, all artifacts need to be downloaded.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/download-artifact`
|
||||
* :gh:`dorny/test-reporter`
|
||||
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@r0
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
CodeCoverage:
|
||||
# ...
|
||||
|
||||
UnitTesting:
|
||||
# ...
|
||||
|
||||
PublishTestResults:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@r0
|
||||
needs:
|
||||
- CodeCoverage
|
||||
- UnitTesting
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
report_files
|
||||
============
|
||||
|
||||
+----------------+----------+----------+---------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================================+
|
||||
| report_files | optional | string | ``artifacts/**/*.xml`` |
|
||||
+----------------+----------+----------+---------------------------------+
|
||||
|
||||
Pattern of jUnit report files to publish as Markdown.
|
||||
|
||||
The parameter can be a comma separated list. Wildcards are supported.
|
||||
|
||||
.. hint::
|
||||
|
||||
All artifacts are downloaded into directory ``artifacts``, thus the pattern should include this directory as a
|
||||
prefix.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
@@ -1,106 +0,0 @@
|
||||
.. _JOBTMPL/PublishToGitHubPages:
|
||||
|
||||
PublishToGitHubPages
|
||||
####################
|
||||
|
||||
This job publishes HTML content from artifacts of other jobs to GitHub Pages.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository.
|
||||
2. Download artifacts.
|
||||
3. Push HTML files to branch ``gh-pages``.
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
BuildTheDocs:
|
||||
# ...
|
||||
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r0
|
||||
needs:
|
||||
- BuildTheDocs
|
||||
with:
|
||||
doc: Documentation
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
PublishToGitHubPages:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
- BuildTheDocs
|
||||
- Coverage
|
||||
- StaticTypeCheck
|
||||
with:
|
||||
doc: ${{ fromJson(needs.Params.outputs.artifact_names).documentation_html }}
|
||||
coverage: ${{ fromJson(needs.Params.outputs.artifact_names).codecoverage_html }}
|
||||
typing: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
doc
|
||||
===
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| doc | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the documentation artifact.
|
||||
|
||||
|
||||
coverage
|
||||
========
|
||||
|
||||
+----------------+----------+----------+-----------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================+
|
||||
| coverage | optional | string | ``""`` |
|
||||
+----------------+----------+----------+-----------------+
|
||||
|
||||
Name of the coverage artifact.
|
||||
|
||||
|
||||
typing
|
||||
======
|
||||
|
||||
+----------------+----------+----------+-----------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================+
|
||||
| typing | optional | string | ``""`` |
|
||||
+----------------+----------+----------+-----------------+
|
||||
|
||||
Name of the typing artifact.
|
||||
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
32
doc/JobTemplate/PythonVersionList.rst
Normal file
32
doc/JobTemplate/PythonVersionList.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
.. rubric:: Possible values
|
||||
|
||||
* ``3.8``, ``3.9``, ``3.10`` , ``3.11``, ``3.12``, ``3.13``, ``3.14``
|
||||
* ``pypy-3.7``, ``pypy-3.8``, ``pypy-3.9``, ``pypy-3.10``, ``pypy-3.11``
|
||||
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| Icon | Version | Maintained until | Comments |
|
||||
+======+===========+==================+===============================================+
|
||||
| ⚫ | 3.8 | 2024.10 | :red:`outdated` |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🔴 | 3.9 | 2025.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🟠 | 3.10 | 2026.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🟡 | 3.11 | 2027.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🟢 | 3.12 | 2028.10 | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🟢 | 3.13 | 2029.10 | :green:`latest CPython` |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| 🟣 | 3.14 | 2030.10 | Python 3.14 alpha, beta (or RC) will be used. |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| ⟲⚫ | pypy-3.7 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| ⟲⚫ | pypy-3.8 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| ⟲🔴 | pypy-3.9 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| ⟲🟠 | pypy-3.10 | ????.?? | |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
| ⟲🟡 | pypy-3.11 | ????.?? | :green:`latest PyPy` |
|
||||
+------+-----------+------------------+-----------------------------------------------+
|
||||
150
doc/JobTemplate/Quality/CheckDocumentation.rst
Normal file
150
doc/JobTemplate/Quality/CheckDocumentation.rst
Normal file
@@ -0,0 +1,150 @@
|
||||
.. _JOBTMPL/CheckDocumentation:
|
||||
.. index::
|
||||
single: docstr_coverage; CheckDocumentation Template
|
||||
single: interrogate; CheckDocumentation Template
|
||||
single: GitHub Action Reusable Workflow; CheckDocumentation Template
|
||||
|
||||
CheckDocumentation
|
||||
##################
|
||||
|
||||
The ``CheckDocumentation`` job checks the level of documentation coverage for Python files.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Check documentation coverage in Python code using :pypi:`docstr_coverage`.
|
||||
* Check documentation coverage in Python code using :pypi:`interrogate`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Setup Python environment and install dependencies.
|
||||
3. Run ``docstr_coverage``.
|
||||
4. Run ``interrogate``.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-CheckDocumentation.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* pip
|
||||
|
||||
* :pypi:`docstr_coverage`
|
||||
* :pypi:`interrogate`
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``Params`` job derived from job template ``Parameters`` version ``@r6``. It only
|
||||
requires a `name` parameter to create the artifact names.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
DocCoverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CheckDocumentation.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
directory: ${{ needs.ConfigParams.outputs.package_directory }}
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/ExtractConfiguration`
|
||||
``ExtractConfiguration`` is usually used to compute the path to the package's source code directory.
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/CheckDocumentation/Inputs>`
|
||||
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=========================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/CheckDocumentation/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CheckDocumentation/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CheckDocumentation/Input/directory` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/CheckDocumentation/Input/fail_under` | no | string | ``'80'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/CheckDocumentation/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/CheckDocumentation/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Input/directory:
|
||||
|
||||
directory
|
||||
=========
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid directory or sub-directory.
|
||||
:Description: Directory where the Python code is located.
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Input/fail_under:
|
||||
|
||||
fail_under
|
||||
==========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'80'``
|
||||
:Possible Values: Any valid percentage from 0 to 100 encoded as string.
|
||||
:Description: A minimum percentage level for good documentation. If the documentation coverage is below this level,
|
||||
the coverage is considered a fail.
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/CheckDocumentation/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
365
doc/JobTemplate/Quality/StaticTypeCheck.rst
Normal file
365
doc/JobTemplate/Quality/StaticTypeCheck.rst
Normal file
@@ -0,0 +1,365 @@
|
||||
.. _JOBTMPL/StaticTypeCheck:
|
||||
.. index::
|
||||
single: mypy; StaticTypeCheck Template
|
||||
single: GitHub Action Reusable Workflow; StaticTypeCheck Template
|
||||
|
||||
StaticTypeCheck
|
||||
###############
|
||||
|
||||
This job template runs a static type check using :term:`mypy` and collects the results. These results can be converted
|
||||
to a HTML report and uploaded as an artifact.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Run static type check using :term:`mypy`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository
|
||||
2. Setup Python and install dependencies
|
||||
3. Run type checking.
|
||||
4. Upload type checking report as an artifact
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-StaticTypeCheck.png
|
||||
:width: 400px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* pip
|
||||
|
||||
* Python packages specified via :ref:`JOBTMPL/StaticTypeCheck/Input/requirements`.
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
This example runs mypy for the Python package ``myPackage`` according to the configuration stored in
|
||||
:file:`pyproject.toml`. It prints a report into the job's log. In addition is generates a report in HTML format into the
|
||||
directory ``report/typing``.
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r6
|
||||
with:
|
||||
cobertura_artifact: 'TypeChecking-Cobertura'
|
||||
junit_artifact: 'TypeChecking-JUnit'
|
||||
html_artifact: 'TypeChecking-HTML'
|
||||
|
||||
.. grid-item::
|
||||
:columns: 6
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.mypy]
|
||||
packages = ["myPackage"]
|
||||
strict = true
|
||||
pretty = true
|
||||
|
||||
html_report = "report/typing/html"
|
||||
junit_xml = "report/typing/StaticTypingSummary.xml"
|
||||
cobertura_xml_report = "report/typing"
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
To ease the handling of mypy parameters stored in :file:`pyproject.toml`, the :ref:`JOBTMPL/ExtractConfiguration` is
|
||||
used to extract the set configuration parameters for later usage. Similarly, :ref:`JOBTMPL/Parameters` is used to
|
||||
precompute the artifact's name.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
junit_report: ${{ needs.ConfigParams.outputs.typing_report_junit }}
|
||||
junit_artifact: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_junit }}
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/StaticTypeCheck/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+================+==========================================================================================================================================+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/requirements` | no | string | ``'-r tests/requirements.txt'`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/mypy_options` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/cobertura_report` | no | string (JSON) | :jsoncode:`{"fullpath": "report/typing/cobertura.xml", "directory": "report/typing", "filename": "cobertura.xml"}` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/junit_report` | no | string (JSON) | :jsoncode:`{"fullpath": "report/typing/StaticTypingSummary.xml", "directory": "report/typing", "filename": "StaticTypingSummary.xml"}` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/html_report` | no | string (JSON) | :jsoncode:`{"directory": "report/typing/html"}` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/cobertura_artifact` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/junit_artifact` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/StaticTypeCheck/Input/html_artifact` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------------+------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/StaticTypeCheck/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/StaticTypeCheck/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/requirements:
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'-r tests/requirements.txt'``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'mypy lxml'``.
|
||||
:Description: Python dependencies to be installed through *pip*.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/mypy_options:
|
||||
|
||||
mypy_options
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid command line options for :term:`mypy`.
|
||||
:Description: Additional options handed over to mypy as ``mypy ${mypy_options}``.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/cobertura_report:
|
||||
|
||||
cobertura_report
|
||||
================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing",
|
||||
"filename": "cobertura.xml",
|
||||
"fullpath": "reports/typing/cobertura.xml"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the type checking report in Cobertura XML format will be
|
||||
saved.
|
||||
:filename: Filename of the generated type checking report in Cobertura XML format. |br|
|
||||
Currently, this filename is hardcoded within :term:`mypy` as :file:`cobertura.xml`.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the type checking report in Cobertura XML format
|
||||
will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
cobertura_report: ${{ needs.ConfigParams.outputs.statictyping_cobertura }}
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/junit_report:
|
||||
|
||||
junit_report
|
||||
============
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing",
|
||||
"filename": "StaticTypingSummary.xml",
|
||||
"fullpath": "reports/typing/StaticTypingSummary.xml"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the type checking report in JUnit XML format will be
|
||||
saved.
|
||||
:filename: Filename of the generated type checking report in JUnit XML format. |br|
|
||||
Any valid file name for mypy's JUnit XML report.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the type checking report in JUnit XML format
|
||||
will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
junit_report: ${{ needs.ConfigParams.outputs.statictyping_junit }}
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/html_report:
|
||||
|
||||
html_report
|
||||
===========
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing/html"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the type checking report in HTML format will be saved.
|
||||
:Description: Directory as JSON object where the type checking report in HTML format will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
html_report: ${{ needs.ConfigParams.outputs.statictyping_html }}
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/cobertura_artifact:
|
||||
|
||||
cobertura_artifact
|
||||
==================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the Cobertura XML report.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/junit_artifact:
|
||||
|
||||
junit_artifact
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the JUnit XML report.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Input/html_artifact:
|
||||
|
||||
html_artifact
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the HTML report.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/StaticTypeCheck/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
6
doc/JobTemplate/Quality/VerifyDocs.rst
Normal file
6
doc/JobTemplate/Quality/VerifyDocs.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. _JOBTMPL/VerifyDocs:
|
||||
|
||||
VerifyDocs (idea)
|
||||
#################
|
||||
|
||||
.. todo:: VerifyDocs:: Needs documentation.
|
||||
17
doc/JobTemplate/Quality/index.rst
Normal file
17
doc/JobTemplate/Quality/index.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
.. _JOBTMPL/Quality:
|
||||
|
||||
Quality
|
||||
#######
|
||||
|
||||
The category *quality* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/VerifyDocs` - Verify code snippets in documentations for correctness.
|
||||
* :ref:`JOBTMPL/CheckDocumentation` - Check documentation coverage in Python modules.
|
||||
* :ref:`JOBTMPL/StaticTypeCheck` - Check type annotations using mypy.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
VerifyDocs
|
||||
StaticTypeCheck
|
||||
CheckDocumentation
|
||||
@@ -1,96 +0,0 @@
|
||||
.. _JOBTMPL/GitHubReleasePage:
|
||||
|
||||
Release
|
||||
#######
|
||||
|
||||
This job creates a Release Page on GitHub.
|
||||
|
||||
**Release Template in Markdown**:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
**Automated Release created on: ${{ steps.getVariables.outputs.datetime }}**
|
||||
|
||||
# New Features
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Changes
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Bug Fixes
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Documentation
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
# Unit Tests
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
----------
|
||||
# Related Issues and Pull-Requests
|
||||
|
||||
* tbd
|
||||
* tbd
|
||||
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Extract information from environment variables provided by GitHub Actions.
|
||||
2. Create a Release Page on GitHub
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/create-release` (unmaintained)
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Release:
|
||||
uses: pyTooling/Actions/.github/workflows/Release.yml@r0
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Release:
|
||||
uses: pyTooling/Actions/.github/workflows/Release.yml@r0
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
needs:
|
||||
- Package
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
This job template needs no input parameters.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
580
doc/JobTemplate/Release/PublishReleaseNotes.rst
Normal file
580
doc/JobTemplate/Release/PublishReleaseNotes.rst
Normal file
@@ -0,0 +1,580 @@
|
||||
.. _JOBTMPL/PublishReleaseNotes:
|
||||
.. index::
|
||||
single: gh; PublishReleaseNotes Template
|
||||
single: GitHub Action Reusable Workflow; PublishReleaseNotes Template
|
||||
|
||||
PublishReleaseNotes
|
||||
###################
|
||||
|
||||
This template creates a GitHub Release Page and uploads assets to that page.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Assembly a release description from various sources:
|
||||
|
||||
* Description file in the repository.
|
||||
* Description via job template parameter.
|
||||
* Description from associated pull-request.
|
||||
|
||||
* Download artifact and upload selected files as assets to the release page.
|
||||
* Add an inventory file in JSON format as asset to each release.
|
||||
* Replace placeholders with variable contents.
|
||||
* Override the release's title.
|
||||
* Create draft releases.
|
||||
* Create pre-release release.
|
||||
* Create nightly/rolling releases.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Install dependencies.
|
||||
3. Check if it's a full release or nightly release (rolling release).
|
||||
4. Delete old release.
|
||||
5. Assemble release notes.
|
||||
6. Create a new or recreate the release page as draft.
|
||||
7. Attach files from artifacts as assets:
|
||||
|
||||
1. Download artifact
|
||||
2. Optionally, create compressed archives of that content.
|
||||
3. Upload assets to release page.
|
||||
|
||||
8. Remove draft state from new release page.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PublishReleaseNotes.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* ``gh`` (GitHub command line interface)
|
||||
* ``jq`` (JSON processing)
|
||||
* apt
|
||||
|
||||
* zstd
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@r6
|
||||
|
||||
Release:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@r6
|
||||
needs:
|
||||
- Prepare
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
tag: ${{ needs.Prepare.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/ReleaseNotes:
|
||||
|
||||
Release Notes
|
||||
*************
|
||||
|
||||
Providing a release description (a.k.a release page content) can be achieved from various sources. These sources can
|
||||
also be combined to a single description. Moreover, the resulting description can contain placeholders which can be
|
||||
replaced by values provided via parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements`.
|
||||
|
||||
Description text from file in the repository
|
||||
The job template's parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file` provides a way to read a
|
||||
predefined content from a file within the repository. This allows sharing the same text between nightly releases and
|
||||
full releases.
|
||||
|
||||
.. note::
|
||||
|
||||
This file can't be computed/modified at pipeline runtime, because a fixed Git commit is checked out for this job
|
||||
template run.
|
||||
Descriptions text from pipeline parameter
|
||||
The job template's parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/description` provides a way to either hard code
|
||||
a release description in YAML code, or connect a GitHub Action variable ``${{ ... }}`` to that parameter.
|
||||
|
||||
The content is available in replacement variable ``%%DESCRIPTION%%``.
|
||||
Description text from associated PullRequest
|
||||
If an associated pull-request can be identified for a merge-commit, the pull-requests description can be used as a
|
||||
release description.
|
||||
|
||||
The content is available in replacement variable ``%%PULLREQUEST%%``.
|
||||
Additional text from :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer`
|
||||
Additionally, a footer text is provided.
|
||||
|
||||
The content is available in replacement variable ``%%FOOTER%%``.
|
||||
|
||||
.. topic:: Order of Processing
|
||||
|
||||
1. If :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file` exists and is not empty, it will serve as the main
|
||||
description. If the description contains ``%%...%%`` placeholders, these placeholders will be replaced
|
||||
accordingly. If description contains ``%...%`` placeholders, replacement rules provided by
|
||||
:ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` will be applied.
|
||||
2. If :ref:`JOBTMPL/PublishReleaseNotes/Input/description` is not empty, it will serve as the main description. If
|
||||
the description contains ``%%...%%`` placeholders, these placeholders will be replaced accordingly. If description
|
||||
contains ``%...%`` placeholders, replacement rules provided by :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements`
|
||||
will be applied.
|
||||
3. If the associated pull-request exists and is not empty, it's description will serve as the main description. If
|
||||
the description contains ``%%...%%`` placeholders, these placeholders will be replaced accordingly. If description
|
||||
contains ``%...%`` placeholders, replacement rules provided by :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements`
|
||||
will be applied.
|
||||
4. Otherwise, an error is raised.
|
||||
|
||||
.. topic:: Replacements
|
||||
|
||||
``%%DESCRIPTION%%``
|
||||
Replaces the placeholder with the content from :ref:`JOBTMPL/PublishReleaseNotes/Input/description`.
|
||||
``%%PULLREQUEST%%``, ``%%PULLREQUEST+0%%``, ``%%PULLREQUEST+1%%``, ``%%PULLREQUEST+2%%``, ``%%PULLREQUEST+3%%``
|
||||
Replaces the content by the associated pull-requests description text.
|
||||
|
||||
If an indentation level +N (``+1``, ``+2``, ``+3``) is specified, headlines in the pull-request description will be
|
||||
moved by N levels down.
|
||||
``%%FOOTER%%``
|
||||
Replaces the placeholder with the content from :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer`.
|
||||
``%%gh_server%%``
|
||||
Replaced by the GitHub server URL. |br|
|
||||
The value is derived from ``${{ github.server_url }}``.
|
||||
``%%gh_workflow_name%%``
|
||||
Replaced by the workflow name. |br|
|
||||
The value is derived from ``${{ github.workflow }}``.
|
||||
``%%gh_owner%%``
|
||||
Replaced by the repository owner, which is either the name of a GitHub organisation or a GitHub user account. |br|
|
||||
The value is derived from ``${{ github.repository_owner }}``.
|
||||
``%%gh_repo%%``
|
||||
Replaced by the repository name. |br|
|
||||
The value is derived from ``${{ github.repository }}`` by splitting namespace and repository name into the
|
||||
``${repo}`` variable.
|
||||
``%%gh_owner_repo%%``
|
||||
Replaced by the repository slug, which is either the name of a GitHub organisation or a GitHub user account
|
||||
followed by the repository name concatenated by the slash character. |br|
|
||||
The value is derived from ``${{ github.repository }}``.
|
||||
``%%gh_pages%%``
|
||||
Replaced by the URL to the associated GitHub Pages webspace. |br|
|
||||
The value is formatted as ``https://${{ github.repository_owner }}.github.io/${repo}``.
|
||||
``%%gh_runid%%``
|
||||
Replaced by the pipelines ID. |br|
|
||||
The value is derived from ``${{ github.run_id }}``
|
||||
``%%gh_actor%%``
|
||||
Replaced by the actor (user or bot), who launched the pipeline. |br|
|
||||
The value is derived from ``${{ github.actor }}``.
|
||||
``%%gh_sha%%``
|
||||
Replaced by the associated commit's SHA. |br|
|
||||
The value is derived from ``${{ github.sha }}``
|
||||
``%%date%%``
|
||||
Replaced by the current date. |br|
|
||||
The value is formatted as ``$(date '+%Y-%m-%d')``.
|
||||
``%%time%%``
|
||||
Replaced by the current date. |br|
|
||||
The value is formatted as ``$(date '+%H:%M:%S %Z')``.
|
||||
``%%datetime%%``
|
||||
Replaced by the current date. |br|
|
||||
The value is formatted as ``$(date '+%Y-%m-%d %H:%M:%S %Z')``.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
.. todo::
|
||||
|
||||
* GHDL - uses description_file and description
|
||||
* pyTooling - uses pullrequest
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Assets:
|
||||
|
||||
Assets
|
||||
******
|
||||
|
||||
.. todo::
|
||||
|
||||
PublishReleaseNotes::Assets Describe artifact to asset transformation
|
||||
|
||||
Format: ``artifact:file:title``
|
||||
|
||||
See also: :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements`
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Inventory:
|
||||
|
||||
Inventory
|
||||
*********
|
||||
|
||||
.. todo::
|
||||
|
||||
PublishReleaseNotes::Inventory Describe how inventory files are created.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PublishReleaseNotes/Inputs>`
|
||||
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=========================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/ubuntu_image` | no | string | ``'ubuntu-24.04'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/release_branch` | no | string | ``'main'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/mode` | no | string | ``'release'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/tag` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/title` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/description` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer` | no | string | see parameter details |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/draft` | no | boolean | ``false`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/prerelease` | no | boolean | ``false`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/latest` | no | boolean | ``false`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/assets` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/inventory-json` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/inventory-version` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/inventory-categories` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/tarball-name` | no | string | ``'__pyTooling_upload_artifact__.tar'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PublishReleaseNotes/Input/can-fail` | no | boolean | ``false`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PublishReleaseNotes/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PublishReleaseNotes/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/ubuntu_image:
|
||||
|
||||
ubuntu_image
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: usually no
|
||||
:Default Value: ``'ubuntu-24.04'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
for available Ubuntu image versions.
|
||||
:Description: Name of the Ubuntu image used to run a job.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/release_branch:
|
||||
|
||||
release_branch
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'main'``
|
||||
:Possible Values: Any valid Git branch name.
|
||||
:Description: Name of the branch containing releases.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/mode:
|
||||
|
||||
mode
|
||||
====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'release'``
|
||||
:Possible Values: ``'release'``, ``'nightly'``
|
||||
:Description: The release mode, which is either *nightly* (a.k.a *rolling* release) or *release*.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/tag:
|
||||
|
||||
tag
|
||||
===
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid Git tag name.
|
||||
:Description: Name of the release (tag).
|
||||
:Condition: It must match an existing tag name in the repository.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/title:
|
||||
|
||||
title
|
||||
=====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid string suitable for a release title (headline).
|
||||
:Description: If this parameter is not empty, the releases title is set, which overrides the default title inferred
|
||||
from the associated tag name.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/description:
|
||||
|
||||
description
|
||||
===========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid (multi-line) Markdown string.
|
||||
:Description: The description of the release usually used to render the *release notes*. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/description_file:
|
||||
|
||||
description_file
|
||||
================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid Markdown file. |br|
|
||||
Suggested value: :file:`.github/ReleaseDescription.md`.
|
||||
:Description: Path to a Markdown file used for the release description. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/description_footer:
|
||||
|
||||
description_footer
|
||||
==================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block::
|
||||
|
||||
|
||||
--------
|
||||
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
|
||||
:Possible Values: Any valid (multi-line) Markdown text.
|
||||
:Description: A footer added to the description. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/draft:
|
||||
|
||||
draft
|
||||
=====
|
||||
|
||||
:Type: :red:`boolean`
|
||||
:Required: no
|
||||
:Default Value: ``false``
|
||||
:Possible Values: ``false``, ``true``
|
||||
:Description: If *true*, the release is kept in *draft* state.
|
||||
|
||||
.. note::
|
||||
|
||||
GitHub doesn't send e-mail notifications to subscribed users for draft releases.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/prerelease:
|
||||
|
||||
prerelease
|
||||
==========
|
||||
|
||||
:Type: :red:`boolean`
|
||||
:Required: no
|
||||
:Default Value: ``false``
|
||||
:Possible Values: ``false``, ``true``
|
||||
:Description: If *true*, the release is marked as a *pre-release*.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/latest:
|
||||
|
||||
latest
|
||||
======
|
||||
|
||||
:Type: :red:`boolean`
|
||||
:Required: no
|
||||
:Default Value: ``false``
|
||||
:Possible Values: ``false``, ``true``
|
||||
:Description: If *true*, the release is marked as *latest release*.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/replacements:
|
||||
|
||||
replacements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid multi-line string of format ``search=replace`` patterns.
|
||||
:Description: The given replacements are used to replace placeholders in :ref:`JOBTMPL/PublishReleaseNotes/Input/description`,
|
||||
:ref:`JOBTMPL/PublishReleaseNotes/Input/description_file`, :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer`. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details.
|
||||
:Example: The following example replaces the placeholder ``%version%`` with the actual version number (inferred
|
||||
from tag name by :ref:`JOBTMPL/PrepareJob`.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ReleasePage:
|
||||
uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@r6
|
||||
needs:
|
||||
- Prepare
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
tag: ${{ needs.Prepare.outputs.version }}
|
||||
description: |
|
||||
# myPackage %version%
|
||||
|
||||
This is the latest release of myPackage.
|
||||
replacements: |
|
||||
version=${{ needs.Prepare.outputs.version }}
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/assets:
|
||||
|
||||
assets
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid multi-line string containing artifact to asset transformations. |br|
|
||||
The ``artifact:file:title`` format is explained at :ref:`JOBTMPL/PublishReleaseNotes/Assets`
|
||||
:Description: Each line describes which artifacts to download and extract as well as which extracted file to upload
|
||||
as a release asset. The files title can be changed. |br|
|
||||
Replacement rules from parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` can be used,
|
||||
too. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/Assets` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/inventory-json:
|
||||
|
||||
inventory-json
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid JSON filename. |br|
|
||||
Suggested value: :file:`inventory.json`.
|
||||
:Description: If this parameter is not empty, an inventory of all assets will be created and attached as a JSON file
|
||||
to the release. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/inventory-version:
|
||||
|
||||
inventory-version
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid version string.
|
||||
:Description: If this parameter is not empty, the version field in the inventory JSON is set to this value. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details.
|
||||
|
||||
.. hint::
|
||||
|
||||
Especially for *nightly*/*rolling* releases, the used Git tag is a name rather then a version
|
||||
number. Therefore, a version number must be provided thus a nightly release can be identified as
|
||||
``vX.Y.Z``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/inventory-categories:
|
||||
|
||||
inventory-categories
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: A colon separated list of identifiers used as category names in an inventory JSON.
|
||||
:Description: For decoding hierarchy levels (categories) in an inventory JSON, the hierarchy of categories can be
|
||||
added to the inventoy JSON. |br|
|
||||
See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/tarball-name:
|
||||
|
||||
tarball-name
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'__pyTooling_upload_artifact__.tar'``
|
||||
:Possible Values: Any valid name for a tarball file.
|
||||
:Description:
|
||||
.. todo:: PublishReleaseNotes::tarball-name Needs documentation.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Input/can-fail:
|
||||
|
||||
can-fail
|
||||
========
|
||||
|
||||
:Type: :red:`boolean`
|
||||
:Required: no
|
||||
:Default Value: ``false``
|
||||
:Possible Values: ``false``, ``true``
|
||||
:Description:
|
||||
.. todo:: PublishReleaseNotes::can-fail Needs documentation.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Output/release-page:
|
||||
|
||||
release-page
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Description: Returns the URL to the release page.
|
||||
:Example: ``tbd``
|
||||
|
||||
|
||||
.. _JOBTMPL/PublishReleaseNotes/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
198
doc/JobTemplate/Release/TagReleaseCommit.rst
Normal file
198
doc/JobTemplate/Release/TagReleaseCommit.rst
Normal file
@@ -0,0 +1,198 @@
|
||||
.. _JOBTMPL/TagReleaseCommit:
|
||||
.. index::
|
||||
single: gh; TagReleaseCommit Template
|
||||
single: GitHub Action Reusable Workflow; TagReleaseCommit Template
|
||||
|
||||
TagReleaseCommit
|
||||
################
|
||||
|
||||
The ``TagReleaseCommit`` job template creates a tag at the commit currently used by the pipeline run and then it
|
||||
triggers a new pipeline run for that tag, a.k.a *tag pipeline* or *release pipeline*.
|
||||
|
||||
.. note::
|
||||
|
||||
When the *tag pipeline* is launched, the pipeline is displayed in GitHub Actions with the name in the YAML file. In
|
||||
contrast, when a tag is manually added and pushed via Git on command line, the tag name is displayed.
|
||||
|
||||
Currently, no command, API or similar is known to add a tag and trigger a matching pipeline run, where the pipeline
|
||||
is named like the used tag. Thus, currently this job template has a slightly different behavior compared to manual
|
||||
tagging and pushing a tag to GitHub.
|
||||
|
||||
In addition, GitHub doesn't support *project access token*, thus there is no solution to create a user independent
|
||||
token to emulate a manual push operation.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Tag the current pipeline's commit.
|
||||
* Trigger a new pipeline run for this new tag.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Tag the current commit with a tag named like :ref:`JOBTMPL/TagReleaseCommit/Input/version`.
|
||||
2. Trigger a pipeline run for the new tag.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-TagReleaseCommit.png
|
||||
:width: 350px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/github-script`
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example depicts three jobs within a bigger pipeline. The ``prepare`` job derived from job
|
||||
template ``PrepareJob`` version ``@r6`` figures out if a pipeline runs for a release merge-commit, for a tag or any
|
||||
other reason. Its outputs are used to either run a ``TriggerTaggedRelease`` job derived from job template
|
||||
``TagReleaseCommit`` version ``@r6``, or alternatively run the ``ReleasePage`` job derived from job template
|
||||
``PublishReleaseNotes`` version ``@r6``.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@r6
|
||||
|
||||
# Other pipeline jobs
|
||||
|
||||
TriggerTaggedRelease:
|
||||
uses: pyTooling/Actions/.github/workflows/TagReleaseCommit.yml@r6
|
||||
needs:
|
||||
- Prepare
|
||||
if: needs.Prepare.outputs.is_release_commit == 'true' && github.event_name != 'schedule'
|
||||
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@r6
|
||||
needs:
|
||||
- Prepare
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
with:
|
||||
tag: ${{ needs.Prepare.outputs.version }}
|
||||
secrets: inherit
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/TagReleaseCommit/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/TagReleaseCommit/Input/ubuntu_image` | no | string | ``'ubuntu-24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/TagReleaseCommit/Input/version` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/TagReleaseCommit/Input/auto_tag` | yes | string | — — — — |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/TagReleaseCommit/Input/workflow` | no | string | ``'Pipeline.yml'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/TagReleaseCommit/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/TagReleaseCommit/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Input/ubuntu_image:
|
||||
|
||||
ubuntu_image
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu-24.04'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
for available Ubuntu image versions.
|
||||
:Description: Name of the Ubuntu image used to run this job.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Input/version:
|
||||
|
||||
version
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: Any valid Git tag name.
|
||||
:Description: The version string to be used for tagging.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Input/auto_tag:
|
||||
|
||||
auto_tag
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: ``'false'``, ``'true'```
|
||||
:Description: If *true*, tag the current commit.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Input/workflow:
|
||||
|
||||
workflow
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'Pipeline.yml'``
|
||||
:Possible Values: Any valid GitHub Action pipeline filename.
|
||||
:Description: Github Action pipeline (workflow) to trigger after tag creation.
|
||||
|
||||
.. note::
|
||||
|
||||
Compared to manual tagging and pushing a tag, where a pipeline is triggered automatically, here a
|
||||
pipeline must be trigger separately by API. Therefore the pipeline doesn't run with the name of the
|
||||
tag, but with the name specified within the workflow YAML file.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/TagReleaseCommit/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
15
doc/JobTemplate/Release/index.rst
Normal file
15
doc/JobTemplate/Release/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. _JOBTMPL/Release:
|
||||
|
||||
Release
|
||||
#######
|
||||
|
||||
The category *release* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/TagReleaseCommit` - Automatically tag current commit in Git using the associate pull-requests title.
|
||||
* :ref:`JOBTMPL/PublishReleaseNotes` - Create GitHub release page and upload release assets.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
TagReleaseCommit
|
||||
PublishReleaseNotes
|
||||
877
doc/JobTemplate/Setup/ExtractConfiguration.rst
Normal file
877
doc/JobTemplate/Setup/ExtractConfiguration.rst
Normal file
@@ -0,0 +1,877 @@
|
||||
.. _JOBTMPL/ExtractConfiguration:
|
||||
.. index::
|
||||
single: GitHub Action Reusable Workflow; ExtractConfiguration Template
|
||||
|
||||
ExtractConfiguration
|
||||
####################
|
||||
|
||||
The ``ExtractConfiguration`` job template extracts Python project settings from :file:`pyproject.toml` and shares the
|
||||
values via output parameters with other jobs. Thus, only a single centralized implementation is needed to avoid code
|
||||
duplications within jobs.
|
||||
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Extract the unittest report file in pytest's JUnit XML format as directory name, filename and full path from
|
||||
:file:`pyproject.toml`.
|
||||
* Extract the merged unittest XML report file as directory name, filename and full path from :file:`pyproject.toml`.
|
||||
* Extract code coverage report in HTML format as directory from :file:`pyproject.toml`.
|
||||
* Extract code coverage report file in Cobertura XML format as directory name, filename and full path from
|
||||
:file:`pyproject.toml`.
|
||||
* Extract code coverage report file in Coverage.py's JSON format as directory name, filename and full path from
|
||||
:file:`pyproject.toml`.
|
||||
* Extract static typing report file in Cobertura XML format as directory name, filename and full path from
|
||||
:file:`pyproject.toml`.
|
||||
* Extract static typing report file in JUnit XML format as directory name, filename and full path from
|
||||
:file:`pyproject.toml`.
|
||||
* Extract static typing report in HTML format as directory name from :file:`pyproject.toml`.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Install Python dependencies.
|
||||
3. Compute the full package name and the package source directory.
|
||||
4. Read :file:`pyproject.toml` and extract settings for:
|
||||
|
||||
* :term:`Coverage.py`
|
||||
* :term:`mypy`
|
||||
* :term:`pyEDAA.Reports`
|
||||
* :term:`pytest`
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-ExtractConfiguration.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`tomli`
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``ConfigParams`` job derived from job template ``ExtractConfiguration``
|
||||
version ``@r6``. It requires no special parameters to extract unit test (pytest) and code coverage (Coverage.py)
|
||||
settings.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/UnitTesting`
|
||||
``UnitTesting`` is usually
|
||||
:ref:`JOBTMPL/StaticTypeCheck`
|
||||
xxx
|
||||
:ref:`JOBTMPL/CheckDocumentation`
|
||||
xxx
|
||||
:ref:`JOBTMPL/InstallPackage`
|
||||
xxx
|
||||
:ref:`JOBTMPL/PublishCoverageResults`
|
||||
xxx
|
||||
:ref:`JOBTMPL/PublishTestResults`
|
||||
xxx
|
||||
:ref:`JOBTMPL/SphinxDocumentation`
|
||||
xxx
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/ExtractConfiguration/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Input/coverage_config` | no | string | ``'pyproject.toml'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/ExtractConfiguration/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/ExtractConfiguration/Outputs>`
|
||||
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| Result Name | Type | Description |
|
||||
+=================================================================================+================+===================================================================+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/unittest_report_xml` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/unittest_merged_report_xml` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/coverage_report_html` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/coverage_report_xml` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/coverage_report_json` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/typing_report_cobertura` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/typing_report_junit` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/ExtractConfiguration/Output/typing_report_html` | string (JSON) | |
|
||||
+---------------------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Input/python_version:
|
||||
|
||||
.. include:: ../_python_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Input/coverage_config:
|
||||
|
||||
coverage_config
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'pyproject.toml'``
|
||||
:Possible Values: Any valid path to a :file:`pyproject.toml` file. |br|
|
||||
Alternatively, path to a :file:`.coveragerc` file (deprecated).
|
||||
:Description: Path to a Python project configuration file for extraction of project settings.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Extracted values from :file:`pyproject.toml`
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.coverage.xml]
|
||||
output = "report/coverage/coverage.xml"
|
||||
|
||||
[tool.coverage.json]
|
||||
output = "report/coverage/coverage.json"
|
||||
|
||||
[tool.coverage.html]
|
||||
directory = "report/coverage/html"
|
||||
title="Code Coverage of myPackage"
|
||||
|
||||
[tool.mypy]
|
||||
html_report = "report/typing/html"
|
||||
junit_xml = "report/typing/StaticTypingSummary.xml"
|
||||
cobertura_xml_report = "report/typing"
|
||||
|
||||
[tool.pyedaa-reports]
|
||||
junit_xml = "report/unit/unittest.xml"
|
||||
|
||||
[tool.pytest]
|
||||
junit_xml = "report/unit/UnittestReportSummary.xml"
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/unittest_report_xml:
|
||||
|
||||
unittest_report_xml
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the unit
|
||||
test's report XML file created by :term:`pytest` in JUnit XML format.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the unittest XML report file will be created. |br|
|
||||
Example: :file:`reports/unit`
|
||||
:filename: Contains the filename of the unittest XML report file. |br|
|
||||
Example: :file:`UnittestReportSummary.xml`
|
||||
:fullpath: Contains the path where the unittest XML report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/unit/UnittestReportSummary.xml`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`pytest`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.pytest]
|
||||
junit_xml = "report/unit/UnittestReportSummary.xml"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/unit",
|
||||
"filename": "UnittestReportSummary.xml",
|
||||
"fullpath": "reports/unit/UnittestReportSummary.xml"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.unittest_report_xml).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.unittest_report_xml).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.unittest_report_xml).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/unittest_merged_report_xml:
|
||||
|
||||
unittest_merged_report_xml
|
||||
==========================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the merged
|
||||
unittest report file in JUnit XML format created by :term:`pyEDAA.Reports`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the merged unittest XML report file will be created. |br|
|
||||
Example: :file:`reports/unit`
|
||||
:filename: Contains the filename of the merged unittest XML report file. |br|
|
||||
Example: :file:`unittest.xml`
|
||||
:fullpath: Contains the path where the merged unittest XML report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/unit/unittest.xml`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`pyEDAA.Reports`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.pyedaa-reports]
|
||||
junit_xml = "report/unit/unittest.xml"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/unit",
|
||||
"filename": "unittest.xml",
|
||||
"fullpath": "reports/unit/unittest.xml"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.unittest_merged_report_xml }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.unittest_merged_report_xml).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.unittest_merged_report_xml).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.unittest_merged_report_xml).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/coverage_report_html:
|
||||
|
||||
coverage_report_html
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory and the full path, where the code coverage
|
||||
HTML report will be generated by :term:`Coverage.py`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the code coverage report in HTML format will be created. |br|
|
||||
Example: :file:`report/coverage/html`
|
||||
:fullpath: Contains the path where the code coverage report in HTML format will be created. |br|
|
||||
This is the same as the previous JSON field. |br|
|
||||
Example: :file:`report/coverage/html`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`Coverage.py`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.coverage.html]
|
||||
directory = "report/coverage/html"
|
||||
title="Code Coverage of pyDummy"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "report/coverage/html",
|
||||
"fullpath": "report/coverage/html"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_html).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_html).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.coverage_report_html).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/coverage_report_xml:
|
||||
|
||||
coverage_report_xml
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the code
|
||||
coverage XML report file in Cobertura XML format created by :term:`Coverage.py`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the code coverage XML report file will be created. |br|
|
||||
Example: :file:`reports/unit`
|
||||
:filename: Contains the filename of the code coverage XML report file. |br|
|
||||
Example: :file:`unittest.xml`
|
||||
:fullpath: Contains the path where the code coverage XML report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/unit/unittest.xml`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`Coverage.py`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.coverage.xml]
|
||||
output = "report/coverage/coverage.xml"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.xml",
|
||||
"fullpath": "reports/coverage/coverage.xml"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_xml).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_xml).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.coverage_report_xml).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/coverage_report_json:
|
||||
|
||||
coverage_report_json
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the code
|
||||
coverage JSON report file created by :term:`Coverage.py`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the code coverage JSON report file will be created. |br|
|
||||
Example: :file:`reports/unit`
|
||||
:filename: Contains the filename of the code coverage JSON report file. |br|
|
||||
Example: :file:`unittest.json`
|
||||
:fullpath: Contains the path where the code coverage JSON report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/unit/unittest.json`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`Coverage.py`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.coverage.json]
|
||||
output = "report/coverage/coverage.json"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.json",
|
||||
"fullpath": "reports/coverage/coverage.json"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_json).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.coverage_report_json).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.coverage_report_json).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/typing_report_cobertura:
|
||||
|
||||
typing_report_cobertura
|
||||
=======================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the static
|
||||
type checking report file in Cobertura format created by :term:`mypy`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the type checking XML report file will be created. |br|
|
||||
Example: :file:`reports/typing`
|
||||
:filename: Contains the filename of the type checking XML report file. |br|
|
||||
Example: :file:`cobertura.xml`
|
||||
:fullpath: Contains the path where the type checking XML report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/typing/cobertura.xml`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`mypy`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.mypy]
|
||||
cobertura_xml_report = "report/typing"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing",
|
||||
"filename": "cobertura.xml",
|
||||
"fullpath": "reports/typing/cobertura.xml"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.typing_report_cobertura }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.typing_report_cobertura).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.typing_report_cobertura).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.typing_report_cobertura).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/typing_report_junit:
|
||||
|
||||
typing_report_junit
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the static
|
||||
type checking report file in JUnit XML format created by :term:`mypy`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the static typing JUnit XML report file will be created. |br|
|
||||
Example: :file:`reports/typing`
|
||||
:filename: Contains the filename of the static typing JUnit XML report file. |br|
|
||||
Example: :file:`StaticTypingSummary.xml`
|
||||
:fullpath: Contains the path where the cstatic typing JUnit XML report file will be created. |br|
|
||||
This is the concatenation of both previous JSON fields. |br|
|
||||
Example: :file:`reports/typing/StaticTypingSummary.xml`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`mypy`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.mypy]
|
||||
junit_xml = "report/typing/StaticTypingSummary.xml"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing",
|
||||
"filename": "StaticTypingSummary.xml",
|
||||
"fullpath": "reports/typing/StaticTypingSummary.xml"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.typing_report_junit }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.typing_report_junit).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.typing_report_junit).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.typing_report_junit).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Output/typing_report_html:
|
||||
|
||||
typing_report_html
|
||||
==================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a string in JSON format containing the directory, the filename and the fullpath to the static
|
||||
type checking report in HTML format created by :term:`mypy`.
|
||||
|
||||
The JSON object contains these fields:
|
||||
|
||||
:directory: Contains the directory where the static typing HTML report will be created. |br|
|
||||
Example: :file:`reports/typing/html`
|
||||
:fullpath: Contains the path where the static typing HTML report will be created. |br|
|
||||
This is the same as the previous JSON field. |br|
|
||||
Example: :file:`reports/typing/html`
|
||||
:pyproject.toml: Matching :file:`pyproject.toml` configuration for tool :term:`mypy`.
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.mypy]
|
||||
html_report = "report/typing/html"
|
||||
:Example:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/typing/html",
|
||||
"fullpath": "reports/typing/html"
|
||||
}
|
||||
:Usage:
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Forwarding complete JSON object
|
||||
:sync: ForwardParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: ${{ needs.ConfigParams.outputs.typing_report_html }}
|
||||
|
||||
.. tab-item:: Assembling new JSON object
|
||||
:sync: AssembleParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
report: >-
|
||||
{ "dir": "${{ fromJson(needs.ConfigParams.outputs.typing_report_html).directory }}",
|
||||
"file": "${{ fromJson(needs.ConfigParams.outputs.typing_report_html).filename }}"
|
||||
}
|
||||
|
||||
.. tab-item:: Using single field from JSON object
|
||||
:sync: SingleFieldFromParam
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
OtherJob:
|
||||
uses: some/path/to/a/template@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
fullpath: ${{ fromJson(needs.ConfigParams.outputs.typing_report_html).fullpath }}
|
||||
|
||||
|
||||
.. _JOBTMPL/ExtractConfiguration/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
780
doc/JobTemplate/Setup/Parameters.rst
Normal file
780
doc/JobTemplate/Setup/Parameters.rst
Normal file
@@ -0,0 +1,780 @@
|
||||
.. _JOBTMPL/Parameters:
|
||||
.. index::
|
||||
single: GitHub Action Reusable Workflow; Parameters Template
|
||||
|
||||
Parameters
|
||||
##########
|
||||
|
||||
The ``Parameters`` job template is a workaround for the limitations of GitHub Actions to handle global variables in
|
||||
GitHub Actions workflows (see `actions/runner#480 <https://github.com/actions/runner/issues/480>`__).
|
||||
|
||||
It generates output parameters containing a list of artifact names and a job matrix to be used in later-running jobs.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Generate artifact names for various artifacts.
|
||||
* Generate a matrix of job combinations as a JSON string made from:
|
||||
|
||||
* systems (Ubuntu, macOS, Windows)
|
||||
* architecture (x64-64, aarch64)
|
||||
* Python versions (3.9, 3.10, ..., 3.13),
|
||||
* Python implementation (CPython, PyPy), and
|
||||
* environments (Native, MinGW64, UCRT64, ...).
|
||||
|
||||
* Provide a (default) Python version for other jobs.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Delay job execution by :ref:`JOBTMPL/Parameters/Input/pipeline-delay` seconds.
|
||||
2. Compute job matrix using an embedded Python script.
|
||||
3. Assemble artifact names using a common prefix derived from Python namespace and package name.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-Parameters.png
|
||||
:width: 1000px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* Python from base-system.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
The following instantiation example creates a ``Params`` job derived from job template ``Parameters`` version
|
||||
``@r6``. It only requires a :ref:`JOBTMPL/Parameters/Input/package_name` parameter to create the artifact names.
|
||||
|
||||
.. grid-item::
|
||||
:columns: 7
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
jobs: ${{ needs.Params.outputs.python_jobs }}
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
The following instantiation example creates 3 jobs from the same template, but with differing input parameters.
|
||||
|
||||
The first ``UnitTestingParams`` job might be used to create a job matrix of unit tests. It creates the cross of
|
||||
default systems (Windows, Ubuntu, macOS, macOS-ARM, MinGW64, UCRT64) and the given list of Python versions
|
||||
including some mypy versions. In addition a list of excludes (marked as :deletion:`deletions`) and includes
|
||||
(marked as :addition:`additions`) is handed over resulting in the following combinations.
|
||||
|
||||
The second ``PerformanceTestingParams`` job might be used to create a job matrix for performance tests. Here a
|
||||
pipeline might be limited to the latest two Python versions on a selected list of platforms.
|
||||
|
||||
The third ``PlatformTestingParams`` job might be used to create a job matrix for platform compatibility tests.
|
||||
Here a pipeline might be limited to the latest Python version, but all available platforms.
|
||||
|
||||
.. grid-item::
|
||||
:columns: 7
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
python_version_list: '3.9 3.10 3.11 3.12 pypy-3.10 pypy-3.11'
|
||||
system_list: 'ubuntu windows macos macos-arm mingw64 ucrt64'
|
||||
include_list: 'ubuntu:3.13 macos:3.13 macos-arm:3.13'
|
||||
exclude_list: 'windows:pypy-3.10 windows:pypy-3.11'
|
||||
|
||||
PerformanceTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
python_version_list: '3.12 3.13'
|
||||
system_list: 'ubuntu windows macos macos-arm'
|
||||
|
||||
PlatformTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
python_version_list: '3.13'
|
||||
system_list: 'ubuntu windows macos macos-arm mingw32 mingw64 clang64 ucrt64'
|
||||
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Version | 3.9 🔴 | 3.10 🟠 | 3.11 🟡 | 3.12 🟢 | 3.13 🟢 | 3.14.b1 🟣 | pypy-3.9 🔴 | pypy-3.10 🟠 | pypy-3.11 🟡 |
|
||||
+================================+================+=================+=================+=================+============================+============+=============+===============================+===============================+
|
||||
| Ubuntu 🐧 | ubuntu:3.9 | ubuntu:3.10 | ubuntu:3.11 | ubuntu:3.12 | :addition:`ubuntu:3.13` | | | ubuntu:pypy-3.10 | ubuntu:pypy-3.11 |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| macOS (x86-64) 🍎 | macos:3.9 | macos:3.10 | macos:3.11 | macos:3.12 | :addition:`macos:3.13` | | | macos:pypy-3.10 | macos:pypy-3.11 |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| macOS (aarch64) 🍏 | macos-arm:3.9 | macos-arm:3.10 | macos-arm:3.11 | macos-arm:3.12 | :addition:`macos-arm:3.13` | | | macos:pypy-3.10 | macos:pypy-3.11 |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 | windows:3.9 | windows:3.10 | windows:3.11 | windows:3.12 | | | | :deletion:`windows:pypy-3.10` | :deletion:`windows:pypy-3.11` |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + MSYS 🟪 | | | | | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + MinGW32 ⬛ | | | | | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + MinGW64 🟦 | | | | mingw64:3.12 | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + Clang32 🟫 | | | | | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + Clang64 🟧 | | | | | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
| Windows Server 🪟 + UCRT64 🟨 | | | | ucrt64:3.12 | | | | | |
|
||||
+--------------------------------+----------------+-----------------+-----------------+-----------------+----------------------------+------------+-------------+-------------------------------+-------------------------------+
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/Parameters/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/Parameters/Input/ubuntu_image_version` | no | string | ``'24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/name` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/package_namespace` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/package_name` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/python_version` | no | string | ``'3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/python_version_list` | no | string | ``'3.9 3.10 3.11 3.12 3.13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/system_list` | no | string | ``'ubuntu windows macos macos-arm mingw64 ucrt64'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/include_list` | no | string | ``''`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/exclude_list` | no | string | ``'windows-arm:3.9 windows-arm:3.10'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/disable_list` | no | string | ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/ubuntu_image` | no | string | ``'ubuntu-24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/ubuntu_arm_image` | no | string | ``'ubuntu-24.04-arm'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/windows_image` | no | string | ``'windows-2025'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/windows_arm_image` | no | string | ``'windows-11-arm'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/macos_intel_image` | no | string | ``'macos-13'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/macos_arm_image` | no | string | ``'macos-15'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Input/pipeline-delay` | no | number | ``0`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/Parameters/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/Parameters/Outputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| Result Name | Type | Description |
|
||||
+=====================================================================+================+===================================================================+
|
||||
| :ref:`JOBTMPL/Parameters/Output/python_version` | string | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Output/package_fullname` | string | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Output/package_directory` | string | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Output/artifact_basename` | string | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Output/artifact_names` | string (JSON) | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/Parameters/Output/python_jobs` | string (JSON) | |
|
||||
+---------------------------------------------------------------------+----------------+-------------------------------------------------------------------+
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/ubuntu_image_version:
|
||||
|
||||
.. include:: ../_ubuntu_image_version.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/name:
|
||||
|
||||
name
|
||||
====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Prefix used to generate artifact names. Usually, the name of the Python package. |br|
|
||||
In case this parameter is an empty string, the artifact prefix is derived from :ref:`JOBTMPL/Parameters/Input/package_name`
|
||||
if the package is a simple Python package, **or** from :ref:`JOBTMPL/Parameters/Input/package_namespace`
|
||||
and :ref:`JOBTMPL/Parameters/Input/package_name`, if the package is a Python namespace package.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/package_namespace:
|
||||
|
||||
package_namespace
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid Python namespace.
|
||||
:Description: In case the package is a Python namespace package, the name of the library's or package's namespace
|
||||
needs to be specified using this parameter. |br|
|
||||
In case of a simple Python package, this parameter must be specified as an empty string (``''``),
|
||||
which is the default. |br|
|
||||
This parameter is used to derive :ref:`JOBTMPL/Parameters/Input/name`, if it's an empty string.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Example Instantiation
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_namespace: myFramework
|
||||
package_name: Extension
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Example Directory Structure
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
📂Extension/
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/package_name:
|
||||
|
||||
package_name
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid Python package name.
|
||||
:Description: In case of a simple Python package, this package's name is specified using this parameter. |br|
|
||||
In case the package is a Python namespace package, the parameter
|
||||
:ref:`JOBTMPL/Parameters/Input/package_namespace` must be specified, too. |br|
|
||||
This parameter is used to derive :ref:`JOBTMPL/Parameters/Input/name`, if it's an empty string.
|
||||
:Example:
|
||||
.. grid:: 2
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. rubric:: Example Instantiation
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Pipeline
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
.. grid-item::
|
||||
:columns: 4
|
||||
|
||||
.. rubric:: Example Directory Structure
|
||||
|
||||
.. code-block::
|
||||
|
||||
📂ProjectRoot/
|
||||
📂myFramework/
|
||||
📦SubPackage/
|
||||
🐍__init__.py
|
||||
🐍SubModuleA.py
|
||||
🐍__init__.py
|
||||
🐍ModuleB.py
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/python_version:
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'3.13'``
|
||||
:Possible Values: Any valid Python version conforming to the pattern ``<major>.<minor>`` or ``pypy-<major>.<minor>``. |br|
|
||||
See `actions/python-versions - available Python versions <https://github.com/actions/python-versions>`__
|
||||
and `actions/setup-python - configurable Python versions <https://github.com/actions/setup-python>`__.
|
||||
:Description: Python version used as default for other jobs requiring a single Python version. |br|
|
||||
In case :ref:`JOBTMPL/Parameters/Input/python_version_list` is an empty string, this version is used
|
||||
to populate the version list.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/python_version_list:
|
||||
|
||||
python_version_list
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'3.9 3.10 3.11 3.12 3.13'``
|
||||
:Possible Values: A space separated list of valid Python versions conforming to the pattern ``<major>.<minor>`` or
|
||||
``pypy-<major>.<minor>``. |br|
|
||||
See `actions/python-versions - available Python versions <https://github.com/actions/python-versions>`__
|
||||
and `actions/setup-python - configurable Python versions <https://github.com/actions/setup-python>`__.
|
||||
:Description: The list of space-separated Python versions used for Python variation testing.
|
||||
|
||||
.. include:: ../PythonVersionList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/system_list:
|
||||
|
||||
system_list
|
||||
===========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu windows macos macos-arm mingw64 ucrt64'``
|
||||
:Possible Values: A space separated list of system names.
|
||||
:Description: The list of space-separated systems used for application testing.
|
||||
|
||||
.. include:: ../SystemList.rst
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/include_list:
|
||||
|
||||
include_list
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be included into the list of test
|
||||
variants.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
include_list: "ubuntu:3.11 macos:3.11"
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/exclude_list:
|
||||
|
||||
exclude_list
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:3.9 windows-arm:3.10'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be excluded from the list of test
|
||||
variants.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
exclude_list: "windows:pypy-3.8 windows:pypy-3.9"
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/disable_list:
|
||||
|
||||
disable_list
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-arm:pypy-3.10 windows-arm:pypy-3.11'``
|
||||
:Possible Values: A space separated list of ``<system>:<python_version>`` tuples.
|
||||
:Description: List of space-separated ``<system>:<python_version>`` tuples to be temporarily disabled from the list
|
||||
of test variants. |br|
|
||||
Each disabled item creates a warning in the workflow log.
|
||||
:Warning Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
disable_list: "windows:3.10 windows:3.11"
|
||||
|
||||
.. image:: ../../_static/GH_Workflow_DisabledJobsWarnings.png
|
||||
:width: 400px
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/ubuntu_image:
|
||||
|
||||
ubuntu_image
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu-24.04'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
for available Ubuntu image versions.
|
||||
:Description: Name of the Ubuntu x86-64 image and version used to run a Ubuntu jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/ubuntu_arm_image:
|
||||
|
||||
ubuntu_arm_image
|
||||
================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu-24.04-arm'``
|
||||
:Possible Values: See `actions/partner-runner-images - Available Images <https://github.com/actions/partner-runner-images?tab=readme-ov-file#available-images>`__
|
||||
for available Ubuntu ARM image versions.
|
||||
:Description: Name of the Ubuntu aarch64 image and version used to run a Ubuntu ARM jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/windows_image:
|
||||
|
||||
windows_image
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-2025'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
:Description: Name of the Windows Server x86-64 image and version used to run a Windows jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/windows_arm_image:
|
||||
|
||||
windows_arm_image
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'windows-11-arm'``
|
||||
:Possible Values: See `actions/partner-runner-images - Available Images <https://github.com/actions/partner-runner-images?tab=readme-ov-file#available-images>`__
|
||||
:Description: Name of the Windows aarch64 image and version used to run a Windows ARM jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/macos_intel_image:
|
||||
|
||||
macos_intel_image
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'macos-13'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
:Description: Name of the macOS x86-64 image and version used to run a macOS Intel jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/macos_arm_image:
|
||||
|
||||
macos_arm_image
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'macos-15'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
:Description: Name of the macOS aarch64 image and version used to run a macOS ARM jobs when selected via :ref:`JOBTMPL/Parameters/Input/system_list`.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Input/pipeline-delay:
|
||||
|
||||
pipeline-delay
|
||||
==============
|
||||
|
||||
:Type: number
|
||||
:Required: no
|
||||
:Default Value: ``0``
|
||||
:Possible Values: Any integer number.
|
||||
:Description: Slow down this job, to delay the startup of the GitHub Action pipline.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/python_version:
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'3.13'``
|
||||
:Possible Values: Any valid Python version conforming to the pattern ``<major>.<minor>`` or ``pypy-<major>.<minor>``.
|
||||
:Description: Returns
|
||||
|
||||
A single string parameter representing the default Python version that should be used across multiple jobs in the same
|
||||
pipeline.
|
||||
|
||||
Such a parameter is needed as a workaround, because GitHub Actions doesn't support proper handling of global pipeline
|
||||
variables. Thus, this job is used to compute an output parameter that can be reused in other jobs.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
CodeCoverage:
|
||||
uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/package_fullname:
|
||||
|
||||
package_fullname
|
||||
================
|
||||
|
||||
:Type: string
|
||||
:Description: Returns the full package name composed from :ref:`JOBTMPL/Parameters/Input/package_namespace`
|
||||
and :ref:`JOBTMPL/Parameters/Input/package_name`.
|
||||
:Example: ``myFramework.Extension``
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/package_directory:
|
||||
|
||||
package_directory
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Description: Returns the full package path composed from :ref:`JOBTMPL/Parameters/Input/package_namespace`
|
||||
and :ref:`JOBTMPL/Parameters/Input/package_name`.
|
||||
:Example: ``myFramework/Extension``
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/artifact_basename:
|
||||
|
||||
artifact_basename
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Description: Returns the basename (prefix) of all :ref:`artifact names <JOBTMPL/Parameters/Output/artifact_names>` |br|.
|
||||
The basename is either :ref:`JOBTMPL/Parameters/Input/name` if set, otherwise its
|
||||
:ref:`JOBTMPL/Parameters/Output/package_fullname`.
|
||||
:Example: ``myFramework.Extension``
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/artifact_names:
|
||||
|
||||
artifact_names
|
||||
==============
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a JSON dictionary of artifact names sharing a common prefix (see :ref:`JOBTMPL/Parameters/Input/name`). |br|
|
||||
As artifacts are handed from jo to job, a consistent naming scheme is advised to avoid duplications
|
||||
and naming artifacts by hand. This technique solves again the problem of global variables in GitHub
|
||||
Action YAMl files and the need for assigning the same value (here artifact name) to multiple jobs
|
||||
templates.
|
||||
|
||||
The supported artifacts are:
|
||||
|
||||
:unittesting_xml: UnitTesting XML summary report
|
||||
:unittesting_html: UnitTesting HTML summary report
|
||||
:perftesting_xml: PerformanceTesting XML summary report
|
||||
:benchtesting_xml: Benchmarking XML summary report
|
||||
:apptesting_xml: ApplicationTesting XML summary report
|
||||
:codecoverage_sqlite: Code Coverage internal database (SQLite)
|
||||
:codecoverage_xml: Code Coverage Cobertura XML report
|
||||
:codecoverage_json: Code Coverage Coverage.py JSON report
|
||||
:codecoverage_html: Code Coverage HTML report
|
||||
:statictyping_cobertura: Static Type Checking Cobertura XML report
|
||||
:statictyping_junit: Static Type Checking JUnit XML report
|
||||
:statictyping_html: Static Type Checking HTML report
|
||||
:package_all: Packaged Python project (multiple formats)
|
||||
:documentation_html: Documentation in HTML format
|
||||
:documentation_latex: Documentation in LaTeX format
|
||||
:documentation_pdf: Documentation in PDF format
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
name: pyTooling
|
||||
|
||||
Coverage:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
unittest_xml_artifact: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting_xml }}
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Output/python_jobs:
|
||||
|
||||
python_jobs
|
||||
===========
|
||||
|
||||
:Type: string (JSON)
|
||||
:Description: Returns a JSON array of job descriptions, wherein each job description is a dictionary providing the
|
||||
following key-value pairs:
|
||||
|
||||
:sysicon: icon to display
|
||||
:system: name of the system
|
||||
:runs-on: virtual machine image and base operating system
|
||||
:runtime: name of the runtime environment if not running natively on the VM image
|
||||
:shell: name of the shell
|
||||
:pyicon: icon for CPython or pypy
|
||||
:python: Python version
|
||||
:envname: full name of the selected environment
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
name: pyDummy
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
jobs: ${{ needs.Params.outputs.python_jobs }}
|
||||
:Usage: The generated JSON array can be unpacked using the ``fromJson(...)`` function in a job's matrix
|
||||
``strategy:matrix:include`` like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
name: Unit Testing (Matrix)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobs:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
UnitTesting:
|
||||
name: ${{ matrix.sysicon }} ${{ matrix.pyicon }} Unit Tests using Python ${{ matrix.python }}
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
strategy:
|
||||
matrix:
|
||||
include: ${{ fromJson(inputs.jobs) }}
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
steps:
|
||||
- name: 🐍 Setup Python ${{ matrix.python }}
|
||||
if: matrix.system != 'msys2'
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
:Debugging: The job prints debugging information like system |times| Python version |times| environment
|
||||
combinations as well as the generated JSON array in the job's log.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{"sysicon": "🐧", "system": "ubuntu", "runs-on": "ubuntu-24.04", "runtime": "native", "shell": "bash", "pyicon": "🔴", "python": "3.9", "envname": "Linux (x86-64)" },
|
||||
{"sysicon": "🐧", "system": "ubuntu", "runs-on": "ubuntu-24.04", "runtime": "native", "shell": "bash", "pyicon": "🟠", "python": "3.10", "envname": "Linux (x86-64)" },
|
||||
{"sysicon": "🐧", "system": "ubuntu", "runs-on": "ubuntu-24.04", "runtime": "native", "shell": "bash", "pyicon": "🟡", "python": "3.11", "envname": "Linux (x86-64)" },
|
||||
{"sysicon": "🐧", "system": "ubuntu", "runs-on": "ubuntu-24.04", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.12", "envname": "Linux (x86-64)" },
|
||||
{"sysicon": "🐧", "system": "ubuntu", "runs-on": "ubuntu-24.04", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.13", "envname": "Linux (x86-64)" },
|
||||
{"sysicon": "🪟", "system": "windows", "runs-on": "windows-2025", "runtime": "native", "shell": "pwsh", "pyicon": "🔴", "python": "3.9", "envname": "Windows (x86-64)" },
|
||||
{"sysicon": "🪟", "system": "windows", "runs-on": "windows-2025", "runtime": "native", "shell": "pwsh", "pyicon": "🟠", "python": "3.10", "envname": "Windows (x86-64)" },
|
||||
{"sysicon": "🪟", "system": "windows", "runs-on": "windows-2025", "runtime": "native", "shell": "pwsh", "pyicon": "🟡", "python": "3.11", "envname": "Windows (x86-64)" },
|
||||
{"sysicon": "🪟", "system": "windows", "runs-on": "windows-2025", "runtime": "native", "shell": "pwsh", "pyicon": "🟢", "python": "3.12", "envname": "Windows (x86-64)" },
|
||||
{"sysicon": "🪟", "system": "windows", "runs-on": "windows-2025", "runtime": "native", "shell": "pwsh", "pyicon": "🟢", "python": "3.13", "envname": "Windows (x86-64)" },
|
||||
{"sysicon": "🍎", "system": "macos", "runs-on": "macos-13", "runtime": "native", "shell": "bash", "pyicon": "🔴", "python": "3.9", "envname": "macOS (x86-64)" },
|
||||
{"sysicon": "🍎", "system": "macos", "runs-on": "macos-13", "runtime": "native", "shell": "bash", "pyicon": "🟠", "python": "3.10", "envname": "macOS (x86-64)" },
|
||||
{"sysicon": "🍎", "system": "macos", "runs-on": "macos-13", "runtime": "native", "shell": "bash", "pyicon": "🟡", "python": "3.11", "envname": "macOS (x86-64)" },
|
||||
{"sysicon": "🍎", "system": "macos", "runs-on": "macos-13", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.12", "envname": "macOS (x86-64)" },
|
||||
{"sysicon": "🍎", "system": "macos", "runs-on": "macos-13", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.13", "envname": "macOS (x86-64)" },
|
||||
{"sysicon": "🍏", "system": "macos-arm", "runs-on": "macos-15", "runtime": "native", "shell": "bash", "pyicon": "🔴", "python": "3.9", "envname": "macOS (aarch64)" },
|
||||
{"sysicon": "🍏", "system": "macos-arm", "runs-on": "macos-15", "runtime": "native", "shell": "bash", "pyicon": "🟠", "python": "3.10", "envname": "macOS (aarch64)" },
|
||||
{"sysicon": "🍏", "system": "macos-arm", "runs-on": "macos-15", "runtime": "native", "shell": "bash", "pyicon": "🟡", "python": "3.11", "envname": "macOS (aarch64)" },
|
||||
{"sysicon": "🍏", "system": "macos-arm", "runs-on": "macos-15", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.12", "envname": "macOS (aarch64)" },
|
||||
{"sysicon": "🍏", "system": "macos-arm", "runs-on": "macos-15", "runtime": "native", "shell": "bash", "pyicon": "🟢", "python": "3.13", "envname": "macOS (aarch64)" },
|
||||
{"sysicon": "🪟🟦", "system": "msys2", "runs-on": "windows-2025", "runtime": "MINGW64", "shell": "msys2 {0}", "pyicon": "🟢", "python": "3.12", "envname": "Windows+MSYS2 (x86-64) - MinGW64"},
|
||||
{"sysicon": "🪟🟨", "system": "msys2", "runs-on": "windows-2025", "runtime": "UCRT64", "shell": "msys2 {0}", "pyicon": "🟢", "python": "3.12", "envname": "Windows+MSYS2 (x86-64) - UCRT64" }
|
||||
]
|
||||
|
||||
|
||||
.. _JOBTMPL/Parameters/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
|
||||
Nontheless, the generated output :ref:`JOBTMPL/Parameters/Output/python_jobs` is influenced by many input parameters
|
||||
generating :math:`N^2` many Python job combinations, which in turn will influence the overall pipeline runtime and how many
|
||||
jobs (parallel VMs) are needed to execute the matrix.
|
||||
|
||||
.. hint::
|
||||
|
||||
Some VM images (macOS, Windows) have parallelism limitations and run slower then Ubuntu-based jobs. Additionally,
|
||||
environments like MSYS2 require an additional setup time increasing a jobs runtime significantly.
|
||||
464
doc/JobTemplate/Setup/PrepareJob.rst
Normal file
464
doc/JobTemplate/Setup/PrepareJob.rst
Normal file
@@ -0,0 +1,464 @@
|
||||
.. _JOBTMPL/PrepareJob:
|
||||
.. index::
|
||||
single: GitHub Action Reusable Workflow; PrepareJob Template
|
||||
|
||||
PrepareJob
|
||||
##########
|
||||
|
||||
The ``PrepareJob`` template is a workaround for the limitations of GitHub Actions to handle global variables in GitHub
|
||||
Actions workflows (see `actions/runner#480 <https://github.com/actions/runner/issues/480>`__) as well as providing basic
|
||||
string operations (see GitHub Action's `limited set of functions <https://docs.github.com/en/actions/reference/workflows-and-actions/expressions#functions>`__).
|
||||
|
||||
The job template generates various output parameters derived from
|
||||
`${{ github }} context <https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#github-context>`__.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Provide branch name or tag name from ``${{ github.ref }}`` variable.
|
||||
* Check if pipeline is a branch, tag or pull-request pipeline.
|
||||
* Check if a commit is a merge commit.
|
||||
* Check if a commit is a release commit.
|
||||
* Check if a tag is a nightly tag (rolling release tag).
|
||||
* Check if a tag is a release tag.
|
||||
* Find associated pull-request (PR) for a merge commit/release commit.
|
||||
* Provide a version from tag name or pull-request name.
|
||||
|
||||
.. note::
|
||||
|
||||
Due to GitHub Action's broken type system and missing implicit type conversions in YAML files, *boolean* values need
|
||||
to be returned as *string* values otherwise type compatibility and comparison are broken. This also requires all
|
||||
inputs to be *string* parameters, otherwise step's, job's or template's output cannot be assigned to a template's
|
||||
input.
|
||||
|
||||
**Problems:**
|
||||
|
||||
1. Scripts (Bash, Python, ...) return results as strings. There is no option or operation provided by GitHub Actions
|
||||
to convert outputs of ``printf`` to a ``boolean`` in the YAML file.
|
||||
2. Unlike job template inputs, outputs have no type information. These are all considered *string* values. Again no
|
||||
implicit or explicit type conversion is provided.
|
||||
3. While inputs might be defined as ``boolean`` and a matching default can be set as a *boolean* value (e.g.,
|
||||
``false``), a connected variable from ``${{ needs }}`` context will either cause a typing error or a later
|
||||
comparison will not work as expected. Either the comparison works with ``inputs.param == false`` for the default
|
||||
value, **or** it works with a value from ``${{ needs }}`` context, which is a string ``inputs.param == 'false'``.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Classify ``${{ github.ref }}`` into branch, tag or pull-request.
|
||||
3. Compute output parameters.
|
||||
4. Find associated pull-request.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-PrepareJob.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`GitHub command line tool 'gh' <cli/cli>`
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``Prepare`` job derived from job template ``PrepareJob`` version ``@r6``.
|
||||
In a default usecase, no input parameters need to be specified for the job template assuming a main-branch and
|
||||
release-branch called ``main``, a development-branch called ``dev``, as well as semantic versioning for tags and
|
||||
pull-request titles.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Prepare:
|
||||
uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@r6
|
||||
|
||||
<ReleaseJob>:
|
||||
needs:
|
||||
- Prepare
|
||||
if: needs.Prepare.outputs.is_release_tag == 'true'
|
||||
...
|
||||
with:
|
||||
version: ${{ needs.Prepare.outputs.version }}
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/TagReleaseCommit`
|
||||
``PrepareJob`` is usually used to identify if a pipeline's commit is a merge commit created by a pull-request. If
|
||||
so, this commit can be tagged automatically to trigger a release pipeline (tag pipeline) for the same commit
|
||||
resulting in a full release (PyPI, GitHub Pages, GitHub Release, ...).
|
||||
:ref:`JOBTMPL/PublishReleaseNotes`
|
||||
``PrepareJob`` is usually used to identify if a tag pipeline is a release pipeline.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/PrepareJob/Inputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=====================================================================+==========+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/ubuntu_image` | no | string | ``'ubuntu-24.04'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/main_branch` | no | string | ``'main'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/development_branch` | no | string | ``'dev'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/release_branch` | no | string | ``'main'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/nightly_tag_pattern` | no | string | ``'nightly'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern` | no | string | ``'(v|r)?[0-9]+(\.[0-9]+){0,2}(-(dev|alpha|beta|rc)([0-9]*))?'`` |
|
||||
+---------------------------------------------------------------------+----------+----------+-------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/PrepareJob/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/PrepareJob/Outputs>`
|
||||
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| Result Name | Type | Description |
|
||||
+=====================================================================+==========+===================================================================+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/on_main_branch` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/on_dev_branch` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/on_release_branch` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/is_regular_commit` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/is_merge_commit` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/is_release_commit` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/is_nightly_tag` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/is_release_tag` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/ref_kind` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/branch` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/tag` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/version` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/pr_title` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/PrepareJob/Output/pr_number` | string | |
|
||||
+---------------------------------------------------------------------+----------+-------------------------------------------------------------------+
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/ubuntu_image:
|
||||
|
||||
ubuntu_image
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'ubuntu-24.04'``
|
||||
:Possible Values: See `actions/runner-images - Available Images <https://github.com/actions/runner-images?tab=readme-ov-file#available-images>`__
|
||||
for available Ubuntu image versions.
|
||||
:Description: Name of the Ubuntu image used to run this job.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/main_branch:
|
||||
|
||||
main_branch
|
||||
===========
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'main'``
|
||||
:Possible Values: Any valid branch name.
|
||||
:Description: Name of the main branch.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/development_branch:
|
||||
|
||||
development_branch
|
||||
==================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'dev'``
|
||||
:Possible Values: Any valid branch name.
|
||||
:Description: Name of the development branch.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/release_branch:
|
||||
|
||||
release_branch
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'main'``
|
||||
:Possible Values: Any valid branch name.
|
||||
:Description: Name of the branch containing releases.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/nightly_tag_pattern:
|
||||
|
||||
nightly_tag_pattern
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'nightly'``
|
||||
:Possible Values: Any valid regular expression. |br|
|
||||
Suggested alternative values: ``latest``, ``rolling``
|
||||
:Description: Name of the tag used for rolling releases, a.k.a nightly builds.
|
||||
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Input/release_tag_pattern:
|
||||
|
||||
release_tag_pattern
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'(v|r)?[0-9]+(\.[0-9]+){0,2}(-(dev|alpha|beta|rc)([0-9]*))?'``
|
||||
:Possible Values: Any valid regular expression.
|
||||
:Description: A regular expression describing a pattern for identifying a release tag.
|
||||
|
||||
The default pattern matches on a `semantic version number <https://semver.org/>`__ separated by dots.
|
||||
It supports up to 3 digit groups. It accepts an optional ``v`` or ``r`` prefix. Optionally, a postfix
|
||||
of ``dev``, ``alpha``, ``beta`` or ``rc`` separated by a hyphen can be appended. If needed, the
|
||||
postfix can have a digit group.
|
||||
|
||||
**Matching tag names as releases:**
|
||||
|
||||
* ``v1``, ``r1``
|
||||
* ``1``, ``1.1``, ``1.1.1``
|
||||
* ``v1.2.8-dev``
|
||||
* ``v3.13.5-alpha2``
|
||||
* ``v4.7.22-beta3``
|
||||
* ``v10.2-rc1``
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/on_main_branch:
|
||||
|
||||
on_main_branch
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is on :ref:`main branch <JOBTMPL/PrepareJob/Input/main_branch>`,
|
||||
otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/on_dev_branch:
|
||||
|
||||
on_dev_branch
|
||||
=============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is on :ref:`development branch <JOBTMPL/PrepareJob/Input/development_branch>`,
|
||||
otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/on_release_branch:
|
||||
|
||||
on_release_branch
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is on :ref:`release branch <JOBTMPL/PrepareJob/Input/release_branch>`,
|
||||
otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/is_regular_commit:
|
||||
|
||||
is_regular_commit
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is not a :ref:`merge commit <JOBTMPL/PrepareJob/Output/is_merge_commit>`
|
||||
nor :ref:`release commit <JOBTMPL/PrepareJob/Output/is_release_commit>`, otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/is_merge_commit:
|
||||
|
||||
is_merge_commit
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is on :ref:`main branch <JOBTMPL/PrepareJob/Input/main_branch>`
|
||||
or :ref:`development branch <JOBTMPL/PrepareJob/Input/development_branch>` and has more than one
|
||||
parent (merge commit), otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/is_release_commit:
|
||||
|
||||
is_release_commit
|
||||
=================
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline's commit is on :ref:`release branch <JOBTMPL/PrepareJob/Input/release_branch>`
|
||||
and has more than one parent (merge commit), otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/is_nightly_tag:
|
||||
|
||||
is_nightly_tag
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline is a tag pipeline for a commit on :ref:`release branch <JOBTMPL/PrepareJob/Input/release_branch>`
|
||||
and the tag's name matches the :ref:`nightly tag pattern <JOBTMPL/PrepareJob/Input/nightly_tag_pattern>`,
|
||||
otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/is_release_tag:
|
||||
|
||||
is_release_tag
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'false'``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns ``'true'`` if the pipeline is a tag pipeline for a commit on :ref:`release branch <JOBTMPL/PrepareJob/Input/release_branch>`
|
||||
and the tag's name matches the :ref:`release tag pattern <JOBTMPL/PrepareJob/Input/release_tag_pattern>`,
|
||||
otherwise return ``'false'``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/ref_kind:
|
||||
|
||||
ref_kind
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``'unknown'``
|
||||
:Possible Values: ``'branch'``, ``'tag'``, ``'pullrequest'``, ``'unknown'``
|
||||
:Description: Returns ``'branch'`` if pipeline's commit is on a branch or returns ``'tag'`` if the pipeline runs for
|
||||
a tagged commit, otherwise returns ``'unknown'`` in case of an internal error.
|
||||
|
||||
If the kind is a branch, the branch name is available in the job's :ref:`JOBTMPL/PrepareJob/Output/branch`
|
||||
result. |br|
|
||||
If the kind is a tag, the tags name is available in the job's :ref:`JOBTMPL/PrepareJob/Output/tag`
|
||||
result. |br|
|
||||
If the kind is a pull-request, the pull request's id is available in the job's :ref:`JOBTMPL/PrepareJob/Output/pr_number`
|
||||
result. |br|
|
||||
Moreover, if the tag matches the :ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`, the extracted
|
||||
version is available in the job's :ref:`JOBTMPL/PrepareJob/Output/version` result.
|
||||
|
||||
.. note::
|
||||
|
||||
GitHub doesn't provide standalone branch or tag information, but provides the variable
|
||||
``${{ github.ref }}`` specifying the currently active reference (branch, tag, pull, ...). This job
|
||||
template parses the context's variable and derives if a pipeline runs for a commit on a branch or a
|
||||
tagged commit.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/branch:
|
||||
|
||||
branch
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid branch name.
|
||||
:Description: Returns the branch's name the pipeline's commit is associated to, if :ref:`JOBTMPL/PrepareJob/Output/ref_kind`
|
||||
is ``'branch'``, otherwise returns an empty string ``''``.
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/tag:
|
||||
|
||||
tag
|
||||
===
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid tag name.
|
||||
:Description: Returns the tag's name the pipeline's commit is associated to, if :ref:`JOBTMPL/PrepareJob/Output/ref_kind`
|
||||
is ``'tag'``, otherwise returns an empty string ``''``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/version:
|
||||
|
||||
version
|
||||
=======
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid version matching :ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`.
|
||||
:Description: In case the pipeline runs for a tag, it returns the tag's name, if the name matches
|
||||
:ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`, otherwise returns an empty string ``''``. |br|
|
||||
In case the pipeline runs for a branch, then the commit is checked if it's a
|
||||
:ref:`merge commit <JOBTMPL/PrepareJob/Output/is_merge_commit>` and corresponding pull-request (PR) is
|
||||
searched. When a matching PR can be located and it's title matches
|
||||
:ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`, then this title is returned as a version,
|
||||
otherwise it returns an empty string ``''``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/pr_title:
|
||||
|
||||
pr_title
|
||||
========
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``''``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns the associated pull-request's title, if the pipeline's commit is a
|
||||
:ref:`merge commit <JOBTMPL/PrepareJob/Output/is_merge_commit>` and the located pull-request's title
|
||||
for this commit matches :ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`, otherwise returns an
|
||||
empty string ``''``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Output/pr_number:
|
||||
|
||||
pr_number
|
||||
=========
|
||||
|
||||
:Type: string
|
||||
:Default Value: ``''``
|
||||
:Possible Values: ``'true'``, ``'false'``
|
||||
:Description: Returns the associated pull-request's number, if the pipeline's commit is a
|
||||
:ref:`merge commit <JOBTMPL/PrepareJob/Output/is_merge_commit>` and the located pull-request's title
|
||||
for this commit matches :ref:`JOBTMPL/PrepareJob/Input/release_tag_pattern`, otherwise returns an
|
||||
empty string ``''``.
|
||||
|
||||
|
||||
.. _JOBTMPL/PrepareJob/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
This template offers no optimizations (reduced job runtime).
|
||||
21
doc/JobTemplate/Setup/index.rst
Normal file
21
doc/JobTemplate/Setup/index.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
.. _JOBTMPL/Setup:
|
||||
|
||||
Pipeline Setup
|
||||
##############
|
||||
|
||||
The category *pipeline setup* provides workflow templates implementing preparation steps suitable for every pipeline.
|
||||
|
||||
* :ref:`JOBTMPL/Parameters` - Compute a matrix of (operating system |times| Python version |times| environment)
|
||||
combinations for unit testing, platform testing or application testing and provide the result as a JSON string via
|
||||
pipeline outputs.
|
||||
* :ref:`JOBTMPL/PrepareJob` - Check GitHub Action environment variables and commits to provide precomputed variables as
|
||||
pipeline outputs.
|
||||
* :ref:`JOBTMPL/ExtractConfiguration` - Extract configuration settings from :file:`pyproject.toml` and provide settings
|
||||
as pipeline outputs.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
PrepareJob
|
||||
Parameters
|
||||
ExtractConfiguration
|
||||
@@ -1,182 +0,0 @@
|
||||
.. _JOBTMPL/StaticTypeChecking:
|
||||
|
||||
StaticTypeCheck
|
||||
###############
|
||||
|
||||
This job runs a static type check using mypy and collects the results. These results can be converted to a HTML report
|
||||
and then uploaded as an artifact.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository
|
||||
2. Setup Python and install dependencies
|
||||
3. Run type checking command(s).
|
||||
4. Upload type checking report as an artifact
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r0
|
||||
with:
|
||||
commands: |
|
||||
touch pyTooling/__init__.py
|
||||
mypy --html-report htmlmypy -p pyTooling
|
||||
report: 'htmlmypy'
|
||||
artifact: TypeChecking
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
StaticTypeCheck:
|
||||
uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
python_version: ${{ needs.Params.outputs.python_version }}
|
||||
commands: |
|
||||
touch pyTooling/__init__.py
|
||||
mypy --html-report htmlmypy -p pyTooling
|
||||
report: 'htmlmypy'
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).statictyping_html }}
|
||||
|
||||
Commands
|
||||
========
|
||||
|
||||
Example ``commands``:
|
||||
|
||||
1. Regular package
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
commands: mypy --html-report htmlmypy -p ToolName
|
||||
|
||||
|
||||
2. Parent namespace package
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
commands: |
|
||||
touch Parent/__init__.py
|
||||
mypy --html-report htmlmypy -p ToolName
|
||||
|
||||
3. Child namespace package
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
commands: |
|
||||
cd Parent
|
||||
mypy --html-report ../htmlmypy -p ToolName
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
python_version
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+-----------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================+
|
||||
| python_version | optional | string | ``3.11`` |
|
||||
+----------------+----------+----------+-----------------+
|
||||
|
||||
Python version.
|
||||
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
+----------------+----------+----------+-------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+===============================+
|
||||
| requirements | optional | string | ``-r tests/requirements.txt`` |
|
||||
+----------------+----------+----------+-------------------------------+
|
||||
|
||||
Python dependencies to be installed through pip.
|
||||
|
||||
|
||||
commands
|
||||
========
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| commands | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Commands to run the static type checks.
|
||||
|
||||
|
||||
html_report
|
||||
===========
|
||||
|
||||
+----------------+----------+----------+-----------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================+
|
||||
| report | optional | string | ``htmlmypy`` |
|
||||
+----------------+----------+----------+-----------------+
|
||||
|
||||
HTML output directory to upload as an artifact.
|
||||
|
||||
|
||||
junit_report
|
||||
============
|
||||
|
||||
+----------------+----------+----------+-----------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=============================+
|
||||
| report | optional | string | ``StaticTypingSummary.xml`` |
|
||||
+----------------+----------+----------+-----------------------------+
|
||||
|
||||
junit file to upload as an artifact.
|
||||
|
||||
|
||||
html_artifact
|
||||
=============
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| html_artifact | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the typing artifact (HTML report).
|
||||
|
||||
|
||||
junit_artifact
|
||||
==============
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| junit_artifact | optional | string | ``""`` |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
Name of the typing junit artifact (junit XML).
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
30
doc/JobTemplate/SystemList.rst
Normal file
30
doc/JobTemplate/SystemList.rst
Normal file
@@ -0,0 +1,30 @@
|
||||
.. rubric:: Possible values
|
||||
|
||||
* Native systems: ``ubuntu``, ``windows``, ``macos``
|
||||
* MSYS2: ``msys``, ``mingw32``, ``mingw64``, ``clang32``, ``clang64``, ``ucrt64``
|
||||
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| Icon | System | Used version | Comments |
|
||||
+======+===========+==============================+=================================================================+
|
||||
| 🪟 | Windows | Windows Server 2025 (latest) | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🐧 | Ubuntu | Ubuntu 24.04 (LTS) (latest) | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🍎 | macOS | macOS Ventura 13 (latest) | While this marked latest, macOS Ventura 13 is already provided. |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🍏 | macOS-arm | macOS Sonoma 14 (latest) | While this marked latest, macOS Ventura 13 is already provided. |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟪 | MSYS | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| ⬛ | MinGW32 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟦 | MinGW64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟫 | Clang32 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟧 | Clang64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
| 🟨 | UCRT64 | | |
|
||||
+------+-----------+------------------------------+-----------------------------------------------------------------+
|
||||
|
||||
Source: `Images provided by GitHub <https://github.com/actions/runner-images>`__
|
||||
77
doc/JobTemplate/Templates.rst
Normal file
77
doc/JobTemplate/Templates.rst
Normal file
@@ -0,0 +1,77 @@
|
||||
.. grid:: 5
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: All-In-One
|
||||
|
||||
* :ref:`JOBTMPL/CompletePipeline` |br| |br| |br| |br|
|
||||
|
||||
.. rubric:: Pipeline Setup
|
||||
|
||||
* :ref:`JOBTMPL/Parameters`
|
||||
* :ref:`JOBTMPL/PrepareJob`
|
||||
* :ref:`JOBTMPL/ExtractConfiguration`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Documentation
|
||||
|
||||
* :ref:`JOBTMPL/CheckDocumentation`
|
||||
* :ref:`JOBTMPL/SphinxDocumentation`
|
||||
* :ref:`JOBTMPL/LaTeXDocumentation`
|
||||
|
||||
.. #* :ref:`JOBTMPL/VerifyDocs`
|
||||
|
||||
.. rubric:: Unit Tests, Code Coverage
|
||||
|
||||
* :ref:`JOBTMPL/ApplicationTesting`
|
||||
* :ref:`JOBTMPL/UnitTesting`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Code Quality
|
||||
|
||||
* :ref:`JOBTMPL/StaticTypeCheck`
|
||||
* *code formatting (planned)*
|
||||
* *coding style (planned)*
|
||||
* *code linting (planned)*
|
||||
|
||||
.. rubric:: Build and Packaging
|
||||
|
||||
* :ref:`JOBTMPL/Package`
|
||||
* :ref:`JOBTMPL/InstallPackage`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Publishing
|
||||
|
||||
* :ref:`JOBTMPL/PublishOnPyPI`
|
||||
* :ref:`JOBTMPL/PublishTestResults`
|
||||
* :ref:`JOBTMPL/PublishCoverageResults`
|
||||
* :ref:`JOBTMPL/PublishToGitHubPages`
|
||||
|
||||
.. rubric:: Releasing
|
||||
|
||||
* :ref:`JOBTMPL/PublishReleaseNotes`
|
||||
* :ref:`JOBTMPL/TagReleaseCommit`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: Cleanup
|
||||
|
||||
* :ref:`JOBTMPL/IntermediateCleanup`
|
||||
* :ref:`JOBTMPL/ArtifactCleanup`
|
||||
|
||||
.. grid-item::
|
||||
:columns: 2
|
||||
|
||||
.. rubric:: :ref:`JOBTMPL/Deprecated`
|
||||
|
||||
* :ref:`JOBTMPL/CoverageCollection`
|
||||
* :ref:`JOBTMPL/NightlyRelease`
|
||||
* :ref:`JOBTMPL/BuildTheDocs`
|
||||
6
doc/JobTemplate/Testing/ApplicationTesting.rst
Normal file
6
doc/JobTemplate/Testing/ApplicationTesting.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. _JOBTMPL/ApplicationTesting:
|
||||
|
||||
ApplicationTesting (idea)
|
||||
#########################
|
||||
|
||||
.. todo:: ApplicationTesting:: Needs documentation.
|
||||
756
doc/JobTemplate/Testing/UnitTesting.rst
Normal file
756
doc/JobTemplate/Testing/UnitTesting.rst
Normal file
@@ -0,0 +1,756 @@
|
||||
.. _JOBTMPL/UnitTesting:
|
||||
.. index::
|
||||
single: pytest; UnitTesting Template
|
||||
single: Coverage.py; UnitTesting Template
|
||||
single: GitHub Action Reusable Workflow; UnitTesting Template
|
||||
|
||||
UnitTesting
|
||||
###########
|
||||
|
||||
This template runs multiple jobs from a matrix as a cross of Python versions and systems. The summary report in junit
|
||||
XML format is optionally uploaded as an artifact.
|
||||
|
||||
Configuration options to :term:`pytest` should be given via section ``[tool.pytest.ini_options]`` in a
|
||||
``pyproject.toml`` file.
|
||||
|
||||
.. topic:: Features
|
||||
|
||||
* Execute unit tests using :term:`pytest`.
|
||||
|
||||
* Provide unit test results as JUnit XML file (pyTest XML dialect).
|
||||
|
||||
* Collect code coverage using :term:`Coverage.py`.
|
||||
|
||||
* Provide code coverage results as pytest SQLite database.
|
||||
* Provide code coverage results as Cobertura XML file.
|
||||
* Provide code coverage results as pytest JSON file.
|
||||
* Provide code coverage results as HTML report.
|
||||
|
||||
.. topic:: Behavior
|
||||
|
||||
1. Checkout repository.
|
||||
2. Setup environment and install dependencies (``apt``, ``homebrew``, ``pacman``, ...).
|
||||
3. Setup Python and install dependencies (:term:`pip`).
|
||||
4. Run instructions from ``*_before_script`` parameter.
|
||||
5. Run unit tests using *pytest* and if enabled in combination with *Coverage.py*.
|
||||
6. Convert gathered results to other formats.
|
||||
7. Upload results (test reports, code coverage reports, ...) as an artifacts.
|
||||
|
||||
.. topic:: Job Execution
|
||||
|
||||
.. image:: ../../_static/pyTooling-Actions-UnitTesting.png
|
||||
:width: 600px
|
||||
|
||||
.. topic:: Dependencies
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`msys2/setup-msys2`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`pyTooling/download-artifact`
|
||||
|
||||
* :gh:`actions/download-artifact`
|
||||
|
||||
* :gh:`pyTooling/upload-artifact`
|
||||
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
* apt: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/apt` parameter.
|
||||
* homebrew: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/brew` parameter.
|
||||
* MSYS2: Packages specified via :ref:`JOBTMPL/UnitTesting/Input/pacboy` parameter.
|
||||
* pip
|
||||
|
||||
* :pypi:`wheel`
|
||||
* :pypi:`tomli`
|
||||
* Python packages specified via :ref:`JOBTMPL/UnitTesting/Input/requirements` or
|
||||
:ref:`JOBTMPL/UnitTesting/Input/mingw_requirements` parameter.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Instantiation:
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
The following instantiation example creates a ``UnitTesting`` job derived from job template ``UnitTesting`` version
|
||||
`@r6`. For providing the job matrix as a JSON string, the :ref:`JOBTMPL/Parameters` job template is used. Additionally,
|
||||
the job needs configuration settings, which are stored in :file:`pyproject.toml`. Instead of duplicating these settings,
|
||||
the :ref:`JOBTMPL/ExtractConfiguration` job template is used to extract these settings.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTestingParams:
|
||||
uses: pyTooling/Actions/.github/workflows/Parameters.yml@r6
|
||||
with:
|
||||
package_name: myPackage
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
- UnitTestingParams
|
||||
with:
|
||||
jobs: ${{ needs.UnitTestingParams.outputs.python_jobs }}
|
||||
requirements: '-r tests/unit/requirements.txt'
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
unittest_xml_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).unittesting_xml }}
|
||||
coverage_sqlite_artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).codecoverage_sqlite }}
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`JOBTMPL/Parameters`
|
||||
``Parameters`` is usually used to pre-compute the job matrix as a JSON string with all system |times| environment
|
||||
|times| Python version combinations.
|
||||
:ref:`JOBTMPL/PublishTestResults`
|
||||
``PublishTestResults`` can be used to merge all JUnit test reports into one file.
|
||||
:ref:`JOBTMPL/PublishCoverageResults`
|
||||
``PublishCoverageResults`` can be used to merge all code coverage reports into one file.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Parameters:
|
||||
|
||||
Parameter Summary
|
||||
*****************
|
||||
|
||||
.. # |unittest_report_xml| code-block:: json
|
||||
|
||||
{ "directory": "report/unit",
|
||||
"filename": "TestReportSummary.xml",
|
||||
"fullpath": "report/unit/TestReportSummary.xml"
|
||||
}
|
||||
|
||||
|
||||
.. rubric:: Goto :ref:`input parameters <JOBTMPL/UnitTesting/Inputs>`
|
||||
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=========================================================================+==========+==========+===================================================================================================================================+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/jobs` | yes | string | — — — — |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/apt` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/brew` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/pacboy` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/requirements` | no | string | ``'-r tests/requirements.txt'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/mingw_requirements` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/macos_before_script` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/macos_arm_before_script` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/ubuntu_before_script` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/mingw64_before_script` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/ucrt64_before_script` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/root_directory` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/tests_directory` | no | string | ``'tests'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/unittest_directory` | no | string | ``'unit'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/unittest_report_xml` | no | string | :jsoncode:`{"directory": "report/unit", "filename": "TestReportSummary.xml", "fullpath": "report/unit/TestReportSummary.xml"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_config` | no | string | ``'pyproject.toml'`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_report_xml` | no | string | :jsoncode:`{"directory": "report/coverage", "filename": "coverage.xml", "fullpath": "report/coverage/coverage.xml"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_report_json` | no | string | :jsoncode:`{"directory": "report/coverage", "filename": "coverage.json", "fullpath": "report/coverage/coverage.json"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_report_html` | no | string | :jsoncode:`{"directory": "report/coverage"}` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/unittest_xml_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/unittest_html_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_sqlite_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_xml_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_json_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
| :ref:`JOBTMPL/UnitTesting/Input/coverage_html_artifact` | no | string | ``''`` |
|
||||
+-------------------------------------------------------------------------+----------+----------+-----------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
.. rubric:: Goto :ref:`secrets <JOBTMPL/UnitTesting/Secrets>`
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
.. rubric:: Goto :ref:`output parameters <JOBTMPL/UnitTesting/Outputs>`
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Inputs:
|
||||
|
||||
Input Parameters
|
||||
****************
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/jobs:
|
||||
|
||||
jobs
|
||||
====
|
||||
|
||||
:Type: string
|
||||
:Required: yes
|
||||
:Default Value: — — — —
|
||||
:Possible Values: A JSON string with an array of dictionaries with the following key-value pairs:
|
||||
|
||||
:sysicon: icon to display
|
||||
:system: name of the system
|
||||
:runs-on: virtual machine image and base operating system
|
||||
:runtime: name of the runtime environment if not running natively on the VM image
|
||||
:shell: name of the shell
|
||||
:pyicon: icon for CPython or pypy
|
||||
:python: Python version
|
||||
:envname: full name of the selected environment
|
||||
:Description: A JSON encoded job matrix to run multiple Python job variations.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/apt:
|
||||
|
||||
apt
|
||||
===
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``apt install``. |br|
|
||||
Packages are specified as a space separated list like ``'graphviz curl gzip'``.
|
||||
:Description: Additional Ubuntu system dependencies to be installed through *apt*.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
UnitTests:
|
||||
...
|
||||
with:
|
||||
apt: >-
|
||||
graphviz
|
||||
curl
|
||||
gzip
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/brew:
|
||||
|
||||
brew
|
||||
====
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``brew install``. |br|
|
||||
Packages are specified as a space separated list.
|
||||
:Description: Additional macOS system dependencies to be installed through *brew*.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/pacboy:
|
||||
|
||||
pacboy
|
||||
======
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``pacboy``. |br|
|
||||
Packages are specified as a space separated list like ``'python-lxml:p python-numpy:p'``.
|
||||
:Description: Additional MSYS2 system dependencies to be installed through *pacboy* (*pacman*). |br|
|
||||
Usually, Python packages start with ``python-``. The suffix ``:p`` ensures pacboy figures out the
|
||||
correct package repository prefix for MinGW64, UCRT64, ...
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, a dedicated workflow step reads the :ref:`JOBTMPL/UnitTesting/Input/requirements` file
|
||||
for Python and compares requested packages with a list of packages that should be installed through
|
||||
*pacman*/*pacboy* compared to installation via *pip*. These are mainly core packages or packages
|
||||
with embedded C code. |br|
|
||||
The list of identified packages is handed over to *pacboy* for preinstallation. Otherwise *pip*
|
||||
will later raise an error. |br|
|
||||
The packages listed by this parameter will be installed in addition to the identified packages.
|
||||
|
||||
.. attention::
|
||||
|
||||
Ensure your Python requirements match the available version from MSYS2 packages list, otherwise
|
||||
if your :file:`requirements.txt` requests a newer version then provided by MSYS2, such a dependency
|
||||
will fail.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
UnitTests:
|
||||
...
|
||||
with:
|
||||
pacboy: >-
|
||||
python-lxml:p
|
||||
:Packages: The following list of Python packages is identified to be installed via *pacboy*:
|
||||
|
||||
* :ucrt64:`python-coverage` |rarr| :pypi:`coverage`
|
||||
* :ucrt64:`igraph` |rarr| :pypi:`igraph`
|
||||
* :ucrt64:`python-lxml` |rarr| :pypi:`lxml`
|
||||
* :ucrt64:`python-markupsafe` |rarr| :pypi:`markupsafe`
|
||||
* :ucrt64:`python-numpy` |rarr| :pypi:`numpy`
|
||||
* :ucrt64:`python-pip` |rarr| :pypi:`pip`
|
||||
* :ucrt64:`python-pyaml` |rarr| :pypi:`pyaml`
|
||||
* :ucrt64:`python-ruamel-yaml` |rarr| :pypi:`ruamel-yaml`
|
||||
* :ucrt64:`python-wheel` |rarr| :pypi:`wheel`
|
||||
* :ucrt64:`python-tomli` |rarr| :pypi:`tomli`
|
||||
* :ucrt64:`python-types-pyyaml` |rarr| :pypi:`types.pyyaml`
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/requirements:
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'-r tests/requirements.txt'``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'coverage pytest'``.
|
||||
:Description: Python dependencies to be installed through *pip*.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/mingw_requirements:
|
||||
|
||||
mingw_requirements
|
||||
==================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid list of parameters for ``pip install``. |br|
|
||||
Either a requirements file can be referenced using ``'-r path/to/requirements.txt'``, or a list of
|
||||
packages can be specified using a space separated list like ``'coverage pytest'``.
|
||||
:Description: Override Python dependencies to be installed through *pip* in MSYS2 (MinGW64/UCRT64) only.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/macos_before_script:
|
||||
|
||||
macos_before_script
|
||||
===================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid *Bash* instructions as single-line or multi-line string suitable for macOS (Intel platform).
|
||||
:Description: These optional *Bash* instructions for macOS are executed after setting up the environment and
|
||||
installing the platform specific dependencies and before running the unit test.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/macos_arm_before_script:
|
||||
|
||||
macos_arm_before_script
|
||||
=======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid *Bash* instructions as single-line or multi-line string suitable for macOS (ARM platform).
|
||||
:Description: These optional *Bash* instructions for macOS are executed after setting up the environment and
|
||||
installing the platform specific dependencies and before running the unit test.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/ubuntu_before_script:
|
||||
|
||||
ubuntu_before_script
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid *Bash* instructions as single-line or multi-line string suitable for Ubuntu.
|
||||
:Description: These optional *Bash* instructions for Ubuntu are executed after setting up the environment and
|
||||
installing the platform specific dependencies and before running the unit test.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/mingw64_before_script:
|
||||
|
||||
mingw64_before_script
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid *Bash* instructions as single-line or multi-line string suitable for MinGW64 on Windows.
|
||||
:Description: These optional *Bash* instructions for MinGW64 on Windows are executed after setting up the
|
||||
environment and installing the platform specific dependencies and before running the unit test.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/ucrt64_before_script:
|
||||
|
||||
ucrt64_before_script
|
||||
====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid *Bash* instructions as single-line or multi-line string suitable for UCRT64 on Windows.
|
||||
:Description: These optional *Bash* instructions for UCRT64 on Windows are executed after setting up the
|
||||
environment and installing the platform specific dependencies and before running the unit test.
|
||||
|
||||
.. hint::
|
||||
|
||||
The next parameters allow running different test kinds (unit tests, performance tests, platform tests, ...) with the
|
||||
same job template, but isolated in sub-directories, thus pytest only discovers a subset of tests. The following code
|
||||
blocks showcase how the job template uses these parameters and how it relates to a proposed directory structure.
|
||||
|
||||
.. grid:: 3
|
||||
|
||||
.. grid-item::
|
||||
:columns: 5
|
||||
|
||||
.. card:: Relation between :ref:`JOBTMPL/UnitTesting/Input/root_directory`, :ref:`JOBTMPL/UnitTesting/Input/tests_directory` and :ref:`JOBTMPL/UnitTesting/Input/unittest_directory`
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd <RepositoryRoot>
|
||||
cd ${root_directory}
|
||||
|
||||
python -m \
|
||||
pytest -raP \
|
||||
--color=yes ..... \
|
||||
"${tests_directory}/${unittest_directory}"
|
||||
|
||||
.. grid-item::
|
||||
:columns: 3
|
||||
|
||||
.. card:: Directory Structure
|
||||
|
||||
.. code-block::
|
||||
|
||||
<RepositoryRoot>/
|
||||
doc/
|
||||
myPackage/
|
||||
__init__.py
|
||||
tests/
|
||||
unit/
|
||||
myTests.py
|
||||
|
||||
.. grid-item::
|
||||
:columns: 3
|
||||
|
||||
.. card:: Example for Default Values
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd <RepositoryRoot>
|
||||
cd .
|
||||
|
||||
python -m \
|
||||
pytest -raP \
|
||||
--color=yes ..... \
|
||||
"tests/unit"
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/root_directory:
|
||||
|
||||
root_directory
|
||||
==============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``''``
|
||||
:Possible Values: Any valid directory or sub-directory.
|
||||
:Description: Working directory for running tests. |br|
|
||||
Usually, this is the repository's root directory. Tests are called relatively from here. See
|
||||
:ref:`JOBTMPL/UnitTesting/Input/tests_directory` and :ref:`JOBTMPL/UnitTesting/Input/unittest_directory`.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/tests_directory:
|
||||
|
||||
tests_directory
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'tests'``
|
||||
:Possible Values: Any valid directory or sub-directory.
|
||||
:Description: Path to the directory containing tests (relative from :ref:`JOBTMPL/UnitTesting/Input/root_directory`).
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/unittest_directory:
|
||||
|
||||
unittest_directory
|
||||
==================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'unit'``
|
||||
:Possible Values: Any valid directory or sub-directory.
|
||||
:Description: Path to the directory containing unit tests (relative from :ref:`JOBTMPL/UnitTesting/Input/tests_directory`).
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/unittest_report_xml:
|
||||
|
||||
unittest_report_xml
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/unit",
|
||||
"filename": "UnittestReportSummary.xml",
|
||||
"fullpath": "reports/unit/UnittestReportSummary.xml"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the unittest summary report in XML format will be saved.
|
||||
:filename: Filename of the generated JUnit XML report. |br|
|
||||
Any valid filename accepted by ``pytest ... --junitxml=${unittest_report_xml}``.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the unittest summary report in XML format will
|
||||
be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
unittest_report_xml: ${{ needs.ConfigParams.outputs.unittest_report_xml }}
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_config:
|
||||
|
||||
coverage_config
|
||||
===============
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Default Value: ``'pyproject.toml'``
|
||||
:Possible Values: TBD
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_report_xml:
|
||||
|
||||
coverage_report_xml
|
||||
===================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.xml",
|
||||
"fullpath": "reports/coverage/coverage.xml"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in Cobertura XML format will be
|
||||
saved.
|
||||
:filename: Filename of the generated Cobertura XML report. |br|
|
||||
Any valid XML filename.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the code coverage report in Cobertura XML format
|
||||
will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_xml: ${{ needs.ConfigParams.outputs.coverage_report_xml }}
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_report_json:
|
||||
|
||||
coverage_report_json
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage",
|
||||
"filename": "coverage.json",
|
||||
"fullpath": "reports/coverage/coverage.json"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in Coverage.py's JSON format
|
||||
will be saved.
|
||||
:filename: Filename of the generated Coverage.py JSON report. |br|
|
||||
Any valid JSON filename.
|
||||
:fullpath: The concatenation of both previous fields using the ``/`` separator.
|
||||
:Description: Directory, filename and fullpath as JSON object where the code coverage report in Coverage.py's JSON
|
||||
format will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_json: ${{ needs.ConfigParams.outputs.coverage_report_json }}
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_report_html:
|
||||
|
||||
coverage_report_html
|
||||
====================
|
||||
|
||||
:Type: string (JSON)
|
||||
:Required: no
|
||||
:Default Value:
|
||||
.. code-block:: json
|
||||
|
||||
{ "directory": "reports/coverage/html"
|
||||
}
|
||||
:Possible Values: Any valid JSON string containing a JSON object with fields:
|
||||
|
||||
:directory: Directory or sub-directory where the code coverage report in HTML format will be saved.
|
||||
:Description: Directory as JSON object where the code coverage report in HTML format will be saved. |br|
|
||||
This path is configured in :file:`pyproject.toml` and can be extracted by
|
||||
:ref:`JOBTMPL/ExtractConfiguration`.
|
||||
:Example:
|
||||
.. code-block:: yaml
|
||||
|
||||
ConfigParams:
|
||||
uses: pyTooling/Actions/.github/workflows/ExtractConfiguration.yml@r6
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r6
|
||||
needs:
|
||||
- ConfigParams
|
||||
with:
|
||||
...
|
||||
coverage_report_html: ${{ needs.ConfigParams.outputs.coverage_report_html }}
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/unittest_xml_artifact:
|
||||
|
||||
unittest_xml_artifact
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the unittest report summary in XML format.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/unittest_html_artifact:
|
||||
|
||||
unittest_html_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the unittest report in HTML format.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_sqlite_artifact:
|
||||
|
||||
coverage_sqlite_artifact
|
||||
========================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the code coverage report as SQLite database.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_xml_artifact:
|
||||
|
||||
coverage_xml_artifact
|
||||
=====================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the code coverage report in XML format.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_json_artifact:
|
||||
|
||||
coverage_json_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the code coverage report in JSON format.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Input/coverage_html_artifact:
|
||||
|
||||
coverage_html_artifact
|
||||
======================
|
||||
|
||||
:Type: string
|
||||
:Required: no
|
||||
:Possible Values: Any valid artifact name.
|
||||
:Description: Name of the artifact containing the code coverage report in HTML format.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Secrets:
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Outputs:
|
||||
|
||||
Outputs
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
|
||||
|
||||
.. _JOBTMPL/UnitTesting/Optimizations:
|
||||
|
||||
Optimizations
|
||||
*************
|
||||
|
||||
The following optimizations can be used to reduce the template's runtime.
|
||||
|
||||
Disable unit test XML generation
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/unittest_xml_artifact` is empty, no unit test summary report will be
|
||||
generated and no JUnit XML artifact will be uploaded.
|
||||
Disabled code coverage collection
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/coverage_config` is empty, no code coverage will be collected.
|
||||
Disable code coverage SQLite database artifact upload
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/coverage_sqlite_artifact` is empty, the collected code coverage database
|
||||
(SQLlite format) wont be uploaded as an artifact.
|
||||
Disable code coverage report conversion to the Cobertura XML format.
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/coverage_xml_artifact` is empty, no Cobertura XML file will be generated
|
||||
from code coverage report. As no Cobertura XML file exists, no code coverage XML artifact will be uploaded.
|
||||
Disable code coverage report conversion to the *Coverage.py* JSON format.
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/coverage_json_artifact` is empty, no *Coverage.py* JSON file will be
|
||||
generated from code coverage report. As no JSON file exists, no code coverage JSON artifact will be uploaded.
|
||||
Disable code coverage report conversion to an HTML website.
|
||||
If parameter :ref:`JOBTMPL/UnitTesting/Input/coverage_html_artifact` is empty, no coverage report HTML report will be
|
||||
generated from code coverage report. As no HTML report exists, no code coverage HTML artifact will be uploaded.
|
||||
15
doc/JobTemplate/Testing/index.rst
Normal file
15
doc/JobTemplate/Testing/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. _JOBTMPL/Testing:
|
||||
|
||||
Testing
|
||||
#######
|
||||
|
||||
The category *testing* provides workflow templates implementing
|
||||
|
||||
* :ref:`JOBTMPL/UnitTesting` - Run unit tests and collect code coverage.
|
||||
* :ref:`JOBTMPL/ApplicationTesting` - Run application tests.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
UnitTesting
|
||||
ApplicationTesting
|
||||
@@ -1,159 +0,0 @@
|
||||
.. _JOBTMPL/UnitTesting:
|
||||
|
||||
UnitTesting
|
||||
###########
|
||||
|
||||
This template runs multiple jobs from a matrix as a cross of Python versions and systems. The summary report in junit
|
||||
XML format is optionally uploaded as an artifact.
|
||||
|
||||
Configuration options to ``pytest`` should be given via section ``[tool.pytest.ini_options]`` in a ``pyproject.toml``
|
||||
file.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
1. Checkout repository
|
||||
2. Setup Python and install dependencies
|
||||
3. Run unit tests using ``pytest``.
|
||||
4. Upload junit test summary as an artifact
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
* :gh:`actions/checkout`
|
||||
* :gh:`msys2/setup-msys2`
|
||||
* :gh:`actions/setup-python`
|
||||
* :gh:`actions/upload-artifact`
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
jobs:
|
||||
Params:
|
||||
# ...
|
||||
|
||||
UnitTesting:
|
||||
uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r0
|
||||
needs:
|
||||
- Params
|
||||
with:
|
||||
jobs: ${{ needs.Params.outputs.python_jobs }}
|
||||
artifact: ${{ fromJson(needs.Params.outputs.artifact_names).unittesting }}
|
||||
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
TBD
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
jobs
|
||||
====
|
||||
|
||||
+----------------+----------+----------+--------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==============+
|
||||
| jobs | yes | string | — — — — |
|
||||
+----------------+----------+----------+--------------+
|
||||
|
||||
JSON list with environment fields, telling the system and Python versions to run tests with.
|
||||
|
||||
|
||||
requirements
|
||||
============
|
||||
|
||||
+----------------+----------+----------+---------------------------------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+=================================+
|
||||
| requirements | optional | string | ``-r tests/requirements.txt`` |
|
||||
+----------------+----------+----------+---------------------------------+
|
||||
|
||||
Python dependencies to be installed through pip.
|
||||
|
||||
|
||||
pacboy
|
||||
======
|
||||
|
||||
+----------------+----------+----------+-----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+===========+
|
||||
| pacboy | optional | string | ``""`` |
|
||||
+----------------+----------+----------+-----------+
|
||||
|
||||
Additional MSYS2 dependencies to be installed through pacboy (pacman).
|
||||
|
||||
Internally, a workflow step reads the requirements file for Python and compares requested packages with a list of
|
||||
packages that should be installed through pacman/pacboy compared to installation via pip. These are mainly core packages
|
||||
or packages with embedded C code.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
pacboy: >-
|
||||
python-lxml:p
|
||||
|
||||
|
||||
mingw_requirements
|
||||
==================
|
||||
|
||||
+--------------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+====================+==========+==========+==========+
|
||||
| mingw_requirements | optional | string | ``""`` |
|
||||
+--------------------+----------+----------+----------+
|
||||
|
||||
Override Python dependencies to be installed through pip on MSYS2 (MINGW64) only.
|
||||
|
||||
|
||||
tests_directory
|
||||
===============
|
||||
|
||||
+-----------------+----------+----------+-----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+=================+==========+==========+===========+
|
||||
| tests_directory | optional | string | ``tests`` |
|
||||
+-----------------+----------+----------+-----------+
|
||||
|
||||
Path to the directory containing tests (test working directory).
|
||||
|
||||
|
||||
unittest_directory
|
||||
==================
|
||||
|
||||
+--------------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+====================+==========+==========+==========+
|
||||
| unittest_directory | optional | string | ``unit`` |
|
||||
+--------------------+----------+----------+----------+
|
||||
|
||||
Path to the directory containing unit tests (relative to tests_directory).
|
||||
|
||||
|
||||
artifact
|
||||
========
|
||||
|
||||
+----------------+----------+----------+----------+
|
||||
| Parameter Name | Required | Type | Default |
|
||||
+================+==========+==========+==========+
|
||||
| artifact | optional | string | ``""`` |
|
||||
+----------------+----------+----------+----------+
|
||||
|
||||
Generate unit test report with junitxml and upload results as an artifact.
|
||||
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
@@ -1,42 +0,0 @@
|
||||
.. _JOBTMPL/VerifyDocumentation:
|
||||
|
||||
VerifyDocs
|
||||
##########
|
||||
|
||||
This job extracts code examples from the README and tests these code snippets.
|
||||
|
||||
**Behavior:**
|
||||
|
||||
TBD
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
TBD
|
||||
|
||||
Instantiation
|
||||
*************
|
||||
|
||||
Simple Example
|
||||
==============
|
||||
|
||||
.. todo:: VerifyDocs:SimpleExample Needs documentation.
|
||||
|
||||
Complex Example
|
||||
===============
|
||||
|
||||
.. todo:: VerifyDocs:ComplexExample Needs documentation.
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
.. todo:: VerifyDocs:Parameters Needs documentation.
|
||||
|
||||
Secrets
|
||||
*******
|
||||
|
||||
This job template needs no secrets.
|
||||
|
||||
Results
|
||||
*******
|
||||
|
||||
This job template has no output parameters.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user