3434 required : false
3535 default : ' '
3636 type : string
37- requirements :
38- description : ' Python dependencies to be installed through pip .'
37+ apt :
38+ description : ' Ubuntu dependencies to be installed through apt .'
3939 required : false
40- default : ' -r ./requirements.txt'
40+ default : ' '
41+ type : string
42+ brew :
43+ description : ' macOS dependencies to be installed through brew.'
44+ required : false
45+ default : ' '
4146 type : string
4247 pacboy :
4348 description : ' MSYS2 dependencies to be installed through pacboy (pacman).'
4449 required : false
4550 default : " "
4651 type : string
52+ requirements :
53+ description : ' Python dependencies to be installed through pip.'
54+ required : false
55+ default : ' -r ./requirements.txt'
56+ type : string
4757 mingw_requirements :
4858 description : ' Override Python dependencies to be installed through pip on MSYS2 (MINGW64) only.'
4959 required : false
5060 default : ' '
5161 type : string
62+ macos_before_script :
63+ description : ' Scripts to execute before pytest on macOS (Intel).'
64+ required : false
65+ default : ' '
66+ type : string
67+ macos_arm_before_script :
68+ description : ' Scripts to execute before pytest on macOS (ARM).'
69+ required : false
70+ default : ' '
71+ type : string
72+ ubuntu_before_script :
73+ description : ' Scripts to execute before pytest on Ubuntu.'
74+ required : false
75+ default : ' '
76+ type : string
77+ windows_before_script :
78+ description : ' Scripts to execute before pytest on Windows (x64-64).'
79+ required : false
80+ default : ' '
81+ type : string
82+ windows_arm_before_script :
83+ description : ' Scripts to execute before pytest on Windows (aarch64).'
84+ required : false
85+ default : ' '
86+ type : string
87+ mingw64_before_script :
88+ description : ' Scripts to execute before pytest on Windows (x64-64) within MSYS2 MinGW64.'
89+ required : false
90+ default : ' '
91+ type : string
92+ ucrt64_before_script :
93+ description : ' Scripts to execute before pytest on Windows (x64-64) within MSYS2 UCRT64.'
94+ required : false
95+ default : ' '
96+ type : string
5297 root_directory :
5398 description : ' Working directory for running tests.'
5499 required : false
64109 required : false
65110 default : ' app'
66111 type : string
112+ apptest_report_xml :
113+ description : ' JSON object describing the path where to save the application test summary report XML.'
114+ required : false
115+ default : >-
116+ { "directory": "report/app",
117+ "filename": "TestReportSummary.xml",
118+ "fullpath": "report/app/TestReportSummary.xml"
119+ }
120+ type : string
67121 apptest_xml_artifact :
68122 description : " Generate application test report with junitxml and upload results as an artifact."
69123 required : false
70124 default : ' '
71125 type : string
126+ unittest_html_artifact :
127+ description : " Generate application test report with html and upload results as an artifact."
128+ required : false
129+ default : ' '
130+ type : string
72131
73132jobs :
74133 ApplicationTesting :
75- name : ${{ matrix.sysicon }} ${{ matrix.pyicon }} Application Tests using Python ${{ matrix.python }}
134+ name : ${{ matrix.sysicon }} ${{ matrix.pyicon }} Application Tests - Python ${{ matrix.python }}
76135 runs-on : ${{ matrix.runs-on }}
77136
78137 strategy :
@@ -87,12 +146,20 @@ jobs:
87146 steps :
88147 - name : ⏬ Checkout repository
89148 uses : actions/checkout@v7
149+ # with:
150+ # lfs: true
151+ # submodules: true
90152
91- - name : 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job
92- uses : pyTooling/download-artifact@v8
93- with :
94- name : ${{ inputs.wheel }}
95- path : install
153+ # Package Manager steps
154+ - name : 🔧 Install homebrew dependencies on macOS
155+ if : ( matrix.system == 'macos' || matrix.system == 'macos-arm' ) && inputs.brew != ''
156+ run : brew install ${{ inputs.brew }}
157+
158+ - name : 🔧 Install apt dependencies on Ubuntu
159+ if : ( matrix.system == 'ubuntu' || matrix.system == 'ubuntu-arm' ) && inputs.apt != ''
160+ run : |
161+ sudo apt-get update
162+ sudo apt-get install -y --no-install-recommends ${{ inputs.apt }}
96163
97164 # TODO: extract step to an Action so package, so code can be shared with UnitTesting.yml
98165 - name : Compute path to requirements file
@@ -259,7 +326,43 @@ jobs:
259326 python -m pip install --disable-pip-version-check --break-system-packages ${{ steps.requirements.outputs.requirements }}
260327 fi
261328
262- # TODO: Before scripts?
329+ # Before scripts
330+
331+ - name : 🍎 macOS (Intel) before scripts
332+ if : matrix.system == 'macos' && inputs.macos_before_script != ''
333+ run : ${{ inputs.macos_before_script }}
334+
335+ - name : 🍏 macOS (ARM) before scripts
336+ if : matrix.system == 'macos-arm' && inputs.macos_arm_before_script != ''
337+ run : ${{ inputs.macos_arm_before_script }}
338+
339+ - name : 🐧 Ubuntu before scripts
340+ if : ( matrix.system == 'ubuntu' || matrix.system == 'ubuntu-arm' ) && inputs.ubuntu_before_script != ''
341+ run : ${{ inputs.ubuntu_before_script }}
342+
343+ - name : 🪟 Windows (x86-64) before scripts
344+ if : matrix.system == 'windows' && inputs.windows_before_script != ''
345+ run : ${{ inputs.windows_before_script }}
346+
347+ - name : 🏢 Windows (aarch64) before scripts
348+ if : matrix.system == 'windows-arm' && inputs.windows_arm_before_script != ''
349+ run : ${{ inputs.windows_arm_before_script }}
350+
351+ - name : 🪟🟦 Windows (x86-64) + MinGW64 before scripts
352+ if : matrix.system == 'msys2' && matrix.runtime == 'MINGW64' && inputs.mingw64_before_script != ''
353+ run : ${{ inputs.mingw64_before_script }}
354+
355+ - name : 🪟🟨 Windows (x86-64) + UCRT64 before scripts
356+ if : matrix.system == 'msys2' && matrix.runtime == 'UCRT64' && inputs.ucrt64_before_script != ''
357+ run : ${{ inputs.ucrt64_before_script }}
358+
359+ # Install package
360+
361+ - name : 📥 Download artifacts '${{ inputs.wheel }}' from 'Package' job
362+ uses : pyTooling/download-artifact@v8
363+ with :
364+ name : ${{ inputs.wheel }}
365+ path : install
263366
264367 - name : 🔧 Install wheel from artifact (Ubuntu/macOS)
265368 if : ( matrix.system != 'windows' && matrix.system != 'windows-arm' )
@@ -274,34 +377,26 @@ jobs:
274377# Run pytests
275378
276379 - name : ✅ Run application tests (Ubuntu/macOS)
380+ id : pytest_bash
277381 if : ( matrix.system != 'windows' && matrix.system != 'windows-arm' )
278382 run : |
279383 export ENVIRONMENT_NAME="${{ matrix.envname }}"
280384
281385 cd "${{ inputs.root_directory || '.' }}"
282386 [ -n '${{ inputs.apptest_xml_artifact }}' ] && PYTEST_ARGS='--junitxml=report/unit/TestReportSummary.xml' || unset PYTEST_ARGS
283- if [ -n '${{ inputs.coverage_config }}' ]; then
284- printf "%s\n" "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
285- coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
286- else
287- printf "%s\n" "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
288- python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
289- fi
387+ printf "%s\n" "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
388+ python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
290389
291390 - name : ✅ Run application tests (Windows)
391+ id : pytest_posh
292392 if : ( matrix.system == 'windows' || matrix.system == 'windows-arm' )
293393 run : |
294394 $env:ENVIRONMENT_NAME = "${{ matrix.envname }}"
295395
296396 cd "${{ inputs.root_directory || '.' }}"
297397 $PYTEST_ARGS = if ("${{ inputs.apptest_xml_artifact }}") { "--junitxml=report/unit/TestReportSummary.xml" } else { "" }
298- if ("${{ inputs.coverage_config }}") {
299- Write-Host "coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
300- coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
301- } else {
302- Write-Host "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
303- python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
304- }
398+ Write-Host "python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}"
399+ python -m pytest -raP $PYTEST_ARGS --color=yes ${{ inputs.tests_directory || '.' }}/${{ inputs.apptest_directory }}
305400
306401# Upload artifacts
307402
@@ -310,7 +405,31 @@ jobs:
310405 uses : pyTooling/upload-artifact@v7
311406 with :
312407 name : ${{ inputs.apptest_xml_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
313- working-directory : report/unit
314- path : TestReportSummary.xml
408+ working-directory : ${{ fromJson(inputs.unittest_report_xml).directory }}
409+ path : ${{ fromJson(inputs.unittest_report_xml).filename }}
315410 if-no-files-found : error
316411 retention-days : 1
412+
413+ # - name: 📤 Upload 'Application Tests HTML Report' artifact
414+ # if: inputs.apptest_html_artifact != ''
415+ # continue-on-error: true
416+ # uses: pyTooling/upload-artifact@v7
417+ # with:
418+ # name: ${{ inputs.apptest_html_artifact }}-${{ matrix.system }}-${{ matrix.runtime }}-${{ matrix.python }}
419+ # path: ${{ inputs.apptest_report_html_directory }}
420+ # if-no-files-found: error
421+ # retention-days: 1
422+
423+ - name : Generate error messages
424+ shell : bash
425+ run : |
426+ exitCode=0
427+ if [[ "${{ steps.pytest_bash.outcome }}" == "failure" || "${{ steps.pytest_posh.outcome }}" == "failure" ]]; then
428+ printf "❌ pytest: %s\n" "Error in pytest execution."
429+ printf "::error title=%s::%s\n" "pytest" "Error in pytest execution."
430+ exitCode=1
431+ else
432+ printf "✅ pytest: No errors.\n"
433+ fi
434+
435+ exit $exitCode
0 commit comments