1- # ADO pipeline that runs the msal Python test suite.
2- # Unit tests run first (no secrets); E2E tests run after, with the MSID Lab
3- # certificate fetched from Key Vault. Triggered on every push to the
4- # working branch .
1+ # ADO pipeline for the msal Python test suite.
2+ # Two stages → two GitHub checks (Unit tests, E2E tests). Each stage uses
3+ # one job that loops the supported Python matrix internally so the GitHub
4+ # check count stays small .
55
66trigger :
77 branches :
88 include :
99 - 4gust/ado-pipeline
10- pr : none
10+ - dev
11+
12+ pr :
13+ branches :
14+ include :
15+ - dev
16+ drafts : false
1117
1218stages :
1319
@@ -18,54 +24,85 @@ stages:
1824 displayName : ' Unit tests'
1925 jobs :
2026 - job : Pytest
21- displayName : ' pytest (unit)'
27+ displayName : ' pytest (unit, all Python versions )'
2228 pool :
2329 vmImage : ubuntu-22.04
24- strategy :
25- matrix :
26- Python39 :
27- python.version : ' 3.9'
28- Python310 :
29- python.version : ' 3.10'
30- Python311 :
31- python.version : ' 3.11'
32- Python312 :
33- python.version : ' 3.12'
34- Python313 :
35- python.version : ' 3.13'
36- Python314 :
37- python.version : ' 3.14'
30+ timeoutInMinutes : 30
3831 steps :
3932 - task : UsePythonVersion@0
40- displayName : ' Use Python $(python.version)'
41- inputs :
42- versionSpec : ' $(python.version)'
43-
44- - script : |
45- python -m pip install --upgrade pip
46- pip install -r requirements.txt
47- pip install pytest pytest-azurepipelines
48- displayName: 'Install Python dependencies'
33+ displayName : ' Use Python 3.9'
34+ inputs : { versionSpec: '3.9' }
35+ - task : UsePythonVersion@0
36+ displayName : ' Use Python 3.10'
37+ inputs : { versionSpec: '3.10' }
38+ - task : UsePythonVersion@0
39+ displayName : ' Use Python 3.11'
40+ inputs : { versionSpec: '3.11' }
41+ - task : UsePythonVersion@0
42+ displayName : ' Use Python 3.12'
43+ inputs : { versionSpec: '3.12' }
44+ - task : UsePythonVersion@0
45+ displayName : ' Use Python 3.13'
46+ inputs : { versionSpec: '3.13' }
47+ - task : UsePythonVersion@0
48+ displayName : ' Use Python 3.14'
49+ inputs : { versionSpec: '3.14' }
4950
5051 - bash : |
52+ set -uo pipefail
5153 mkdir -p test-results
52- set -o pipefail
53- pytest -vv \
54- --junitxml=test-results/junit.xml \
55- --ignore=tests/test_e2e.py \
56- --ignore=tests/test_e2e_manual.py \
57- --ignore=tests/test_fmi_e2e.py \
58- 2>&1 | tee test-results/pytest.log
59- displayName: 'Run pytest (unit only)'
54+ OVERALL_RC=0
55+
56+ for V in 3.9 3.10 3.11 3.12 3.13 3.14; do
57+ echo "============================================================"
58+ echo " Unit tests · Python ${V}"
59+ echo "============================================================"
60+
61+ PY="python${V}"
62+ if ! command -v "$PY" >/dev/null; then
63+ echo "##vso[task.logissue type=error]${PY} not on PATH"
64+ OVERALL_RC=1
65+ continue
66+ fi
67+
68+ "$PY" -m venv ".venv-${V}"
69+ # shellcheck disable=SC1090
70+ source ".venv-${V}/bin/activate"
71+
72+ python -m pip install --upgrade pip
73+ pip install -r requirements.txt
74+ pip install pytest pytest-azurepipelines
75+
76+ set -o pipefail
77+ pytest -vv \
78+ --junitxml="test-results/junit-unit-${V}.xml" \
79+ --ignore=tests/test_e2e.py \
80+ --ignore=tests/test_e2e_manual.py \
81+ --ignore=tests/test_fmi_e2e.py \
82+ 2>&1 | tee "test-results/pytest-unit-${V}.log"
83+ RC=$?
84+ set +o pipefail
85+
86+ deactivate
87+
88+ if [ $RC -ne 0 ]; then
89+ echo "Python ${V}: unit pytest exited ${RC}"
90+ OVERALL_RC=1
91+ fi
92+ done
93+
94+ exit $OVERALL_RC
95+ displayName: 'Run pytest (unit, all Python versions)'
6096
6197 - task : PublishTestResults@2
6298 displayName : ' Publish JUnit test results'
6399 condition : succeededOrFailed()
64100 inputs :
65101 testResultsFormat : ' JUnit'
66- testResultsFiles : ' test-results/junit.xml'
102+ testResultsFiles : ' test-results/junit-unit-* .xml'
67103 failTaskOnFailedTests : true
68- testRunTitle : ' Unit tests · Python $(python.version)'
104+ testRunTitle : ' Unit tests'
105+ mergeTestResults : true
69106
70107# ─────────────────────────────────────────────────────────────────────────────
71108# Stage 2 · E2E tests — runs only if unit tests pass. Fetches the MSID Lab
@@ -78,34 +115,29 @@ stages:
78115 condition : succeeded()
79116 jobs :
80117 - job : Pytest
81- displayName : ' pytest (E2E)'
118+ displayName : ' pytest (E2E, all Python versions )'
82119 pool :
83120 vmImage : ubuntu-22.04
84- strategy :
85- matrix :
86- Python39 :
87- python.version : ' 3.9'
88- Python310 :
89- python.version : ' 3.10'
90- Python311 :
91- python.version : ' 3.11'
92- Python312 :
93- python.version : ' 3.12'
94- Python313 :
95- python.version : ' 3.13'
96- Python314 :
97- python.version : ' 3.14'
121+ timeoutInMinutes : 60
98122 steps :
99123 - task : UsePythonVersion@0
100- displayName : ' Use Python $(python.version)'
101- inputs :
102- versionSpec : ' $(python.version)'
103-
104- - script : |
105- python -m pip install --upgrade pip
106- pip install -r requirements.txt
107- pip install pytest pytest-azurepipelines
108- displayName: 'Install Python dependencies'
124+ displayName : ' Use Python 3.9'
125+ inputs : { versionSpec: '3.9' }
126+ - task : UsePythonVersion@0
127+ displayName : ' Use Python 3.10'
128+ inputs : { versionSpec: '3.10' }
129+ - task : UsePythonVersion@0
130+ displayName : ' Use Python 3.11'
131+ inputs : { versionSpec: '3.11' }
132+ - task : UsePythonVersion@0
133+ displayName : ' Use Python 3.12'
134+ inputs : { versionSpec: '3.12' }
135+ - task : UsePythonVersion@0
136+ displayName : ' Use Python 3.13'
137+ inputs : { versionSpec: '3.13' }
138+ - task : UsePythonVersion@0
139+ displayName : ' Use Python 3.14'
140+ inputs : { versionSpec: '3.14' }
109141
110142 - task : AzureKeyVault@2
111143 displayName : ' Fetch MSID Lab certificate from Key Vault'
@@ -130,13 +162,48 @@ stages:
130162 LAB_AUTH_B64: $(LabAuth)
131163
132164 - bash : |
165+ set -uo pipefail
133166 mkdir -p test-results
134- set -o pipefail
135- pytest -vv \
136- --junitxml=test-results/junit.xml \
137- tests/test_e2e.py tests/test_fmi_e2e.py \
138- 2>&1 | tee test-results/pytest.log
139- displayName: 'Run pytest (E2E only)'
167+ OVERALL_RC=0
168+
169+ for V in 3.9 3.10 3.11 3.12 3.13 3.14; do
170+ echo "============================================================"
171+ echo " E2E tests · Python ${V}"
172+ echo "============================================================"
173+
174+ PY="python${V}"
175+ if ! command -v "$PY" >/dev/null; then
176+ echo "##vso[task.logissue type=error]${PY} not on PATH"
177+ OVERALL_RC=1
178+ continue
179+ fi
180+
181+ "$PY" -m venv ".venv-${V}"
182+ # shellcheck disable=SC1090
183+ source ".venv-${V}/bin/activate"
184+
185+ python -m pip install --upgrade pip
186+ pip install -r requirements.txt
187+ pip install pytest pytest-azurepipelines
188+
189+ set -o pipefail
190+ pytest -vv \
191+ --junitxml="test-results/junit-e2e-${V}.xml" \
192+ tests/test_e2e.py tests/test_fmi_e2e.py \
193+ 2>&1 | tee "test-results/pytest-e2e-${V}.log"
194+ RC=$?
195+ set +o pipefail
196+
197+ deactivate
198+
199+ if [ $RC -ne 0 ]; then
200+ echo "Python ${V}: e2e pytest exited ${RC}"
201+ OVERALL_RC=1
202+ fi
203+ done
204+
205+ exit $OVERALL_RC
206+ displayName: 'Run pytest (E2E, all Python versions)'
140207 env:
141208 LAB_APP_CLIENT_CERT_PFX_PATH: $(LAB_APP_CLIENT_CERT_PFX_PATH)
142209
@@ -145,9 +212,10 @@ stages:
145212 condition : succeededOrFailed()
146213 inputs :
147214 testResultsFormat : ' JUnit'
148- testResultsFiles : ' test-results/junit.xml'
215+ testResultsFiles : ' test-results/junit-e2e-* .xml'
149216 failTaskOnFailedTests : true
150- testRunTitle : ' E2E tests · Python $(python.version)'
217+ testRunTitle : ' E2E tests'
218+ mergeTestResults : true
151219
152220 - bash : rm -f "$(Agent.TempDirectory)/lab-auth.pfx"
153221 displayName : ' Remove lab certificate from agent'
0 commit comments