@@ -40,6 +40,52 @@ stages:
4040 - if : $CI_COMMIT_BRANCH == "main"
4141 - if : $CI_PIPELINE_SOURCE == "web"
4242
43+ # File pattern anchors for different job types
44+ .python-quality-files : &python-quality-files
45+ - " src/**/*.py"
46+ - " tests/**/*.py"
47+ - " noxfile.py"
48+ - " pyproject.toml"
49+ - " .ruff.toml"
50+ - " pyrightconfig.json"
51+ - " .gitlab-ci.yml"
52+
53+ .python-typecheck-files : &python-typecheck-files
54+ - " src/**/*.py"
55+ - " tests/**/*.py"
56+ - " noxfile.py"
57+ - " pyproject.toml"
58+ - " pyrightconfig.json"
59+ - " .gitlab-ci.yml"
60+
61+ .python-security-files : &python-security-files
62+ - " src/**/*.py"
63+ - " tests/**/*.py"
64+ - " noxfile.py"
65+ - " pyproject.toml"
66+ - " bandit.yml"
67+ - " .gitlab-ci.yml"
68+
69+ .python-test-files : &python-test-files
70+ - " src/**/*.py"
71+ - " tests/**/*.py"
72+ - " noxfile.py"
73+ - " pyproject.toml"
74+ - " .coveragerc"
75+ - " .gitlab-ci.yml"
76+
77+ .docs-files : &docs-files
78+ - " docs/**/*"
79+ - " src/**/*.py"
80+ - " noxfile.py"
81+ - " pyproject.toml"
82+ - " .gitlab-ci.yml"
83+
84+ .rust-files : &rust-files
85+ - " rust/**/*.rs"
86+ - " Cargo.toml"
87+ - " .gitlab-ci.yml"
88+
4389# Base job template for Python quality checks
4490.quality-job : &quality-job
4591 stage : quality
@@ -55,19 +101,17 @@ quality-python:
55101 << : *quality-job
56102 script :
57103 - uvx nox -t quality
58- changes :
59- - " src/**/*.py"
60- - " tests/**/*.py"
61- - " noxfile.py"
62- - " pyproject.toml"
63- - " .ruff.toml"
64- - " pyrightconfig.json"
65- - " .gitlab-ci.yml"
104+ rules :
105+ - if : $CI_PIPELINE_SOURCE == "merge_request_event"
106+ changes : *python-quality-files
107+ - if : $CI_COMMIT_BRANCH == "main"
108+ changes : *python-quality-files
109+ - if : $CI_PIPELINE_SOURCE == "web"
110+ changes : *python-quality-files
66111
67112typecheck-python :
68113 stage : typecheck
69114 << : *uv-cache
70- << : *on-merge-requests-and-main
71115 parallel :
72116 matrix :
73117 - PYTHON_VERSION : ["3.9", "3.10", "3.11", "3.12", "3.13"]
@@ -78,37 +122,35 @@ typecheck-python:
78122 - uvx nox -s typecheck-$PYTHON_VERSION
79123 after_script :
80124 - uv cache prune --ci
81- changes :
82- - " src/**/*.py "
83- - " tests/**/*.py "
84- - " noxfile.py "
85- - " pyproject.toml "
86- - " pyrightconfig.json "
87- - " .gitlab-ci.yml "
125+ rules :
126+ - if : $CI_PIPELINE_SOURCE == "merge_request_event "
127+ changes : *python-typecheck-files
128+ - if : $CI_COMMIT_BRANCH == "main "
129+ changes : *python-typecheck-files
130+ - if : $CI_PIPELINE_SOURCE == "web "
131+ changes : *python-typecheck-files
88132
89133# Security Checks
90134security-python :
91135 stage : security
92136 << : *uv-cache
93- << : *on-merge-requests-and-main
94137 script :
95138 - uvx nox -s security-python
96139 after_script :
97140 - uv cache prune --ci
98141 allow_failure : true
99- changes :
100- - " src/**/*.py "
101- - " tests/**/*.py "
102- - " noxfile.py "
103- - " pyproject.toml "
104- - " bandit.yml "
105- - " .gitlab-ci.yml "
142+ rules :
143+ - if : $CI_PIPELINE_SOURCE == "merge_request_event "
144+ changes : *python-security-files
145+ - if : $CI_COMMIT_BRANCH == "main "
146+ changes : *python-security-files
147+ - if : $CI_PIPELINE_SOURCE == "web "
148+ changes : *python-security-files
106149
107150# Python Tests - Using GitLab Matrix Strategy
108151test-python :
109152 stage : test
110153 << : *uv-cache
111- << : *on-merge-requests-and-main
112154 parallel :
113155 matrix :
114156 - PYTHON_VERSION : ["3.9", "3.10", "3.11", "3.12", "3.13"]
@@ -127,18 +169,17 @@ test-python:
127169 - tests/results/
128170 - coverage.xml
129171 expire_in : 5 days
130- changes :
131- - " src/**/*.py "
132- - " tests/**/*.py "
133- - " noxfile.py "
134- - " pyproject.toml "
135- - " .coveragerc "
136- - " .gitlab-ci.yml "
172+ rules :
173+ - if : $CI_PIPELINE_SOURCE == "merge_request_event "
174+ changes : *python-test-files
175+ - if : $CI_COMMIT_BRANCH == "main "
176+ changes : *python-test-files
177+ - if : $CI_PIPELINE_SOURCE == "web "
178+ changes : *python-test-files
137179
138180# Cross-platform testing with macOS (GitLab.com SaaS runners)
139181test-python-macos :
140182 stage : test
141- << : *on-merge-requests-and-main
142183 tags :
143184 - saas-macos-medium-m1
144185 before_script :
@@ -156,18 +197,17 @@ test-python-macos:
156197 - tests/results/
157198 - coverage.xml
158199 expire_in : 5 days
159- changes :
160- - " src/**/*.py "
161- - " tests/**/*.py "
162- - " noxfile.py "
163- - " pyproject.toml "
164- - " .coveragerc "
165- - " .gitlab-ci.yml "
200+ rules :
201+ - if : $CI_PIPELINE_SOURCE == "merge_request_event "
202+ changes : *python-test-files
203+ - if : $CI_COMMIT_BRANCH == "main "
204+ changes : *python-test-files
205+ - if : $CI_PIPELINE_SOURCE == "web "
206+ changes : *python-test-files
166207
167208# Cross-platform testing with Windows (GitLab.com SaaS runners)
168209test-python-windows :
169210 stage : test
170- << : *on-merge-requests-and-main
171211 tags :
172212 - saas-windows-medium-amd64
173213 before_script :
@@ -185,24 +225,26 @@ test-python-windows:
185225 - tests/results/
186226 - coverage.xml
187227 expire_in : 5 days
188- changes :
189- - " src/**/*.py "
190- - " tests/**/*.py "
191- - " noxfile.py "
192- - " pyproject.toml "
193- - " .coveragerc "
194- - " .gitlab-ci.yml "
228+ rules :
229+ - if : $CI_PIPELINE_SOURCE == "merge_request_event "
230+ changes : *python-test-files
231+ - if : $CI_COMMIT_BRANCH == "main "
232+ changes : *python-test-files
233+ - if : $CI_PIPELINE_SOURCE == "web "
234+ changes : *python-test-files
195235
196236{% if cookiecutter.add_rust_extension == 'y' -%}
197237# Rust-specific jobs (conditional on rust extension flag)
198238.rust-job : &rust-job
199239 image : rust:latest
200240 stage : quality
201- << : *on-merge-requests-and-main
202- changes :
203- - " rust/**/*.rs"
204- - " Cargo.toml"
205- - " .gitlab-ci.yml"
241+ rules :
242+ - if : $CI_PIPELINE_SOURCE == "merge_request_event"
243+ changes : *rust-files
244+ - if : $CI_COMMIT_BRANCH == "main"
245+ changes : *rust-files
246+ - if : $CI_PIPELINE_SOURCE == "web"
247+ changes : *rust-files
206248
207249format-rust :
208250 << : *rust-job
@@ -261,13 +303,13 @@ build-docs:
261303 paths :
262304 - docs/_build/html/
263305 expire_in : 5 days
264- << : *on-merge-requests-and-main
265- changes :
266- - " docs/**/* "
267- - " src/**/*.py "
268- - " noxfile.py "
269- - " pyproject.toml "
270- - " .gitlab-ci.yml "
306+ rules :
307+ - if : $CI_PIPELINE_SOURCE == "merge_request_event"
308+ changes : *docs-files
309+ - if : $CI_COMMIT_BRANCH == "main "
310+ changes : *docs-files
311+ - if : $CI_PIPELINE_SOURCE == "web "
312+ changes : *docs-files
271313
272314# Documentation build (GitLab Pages - fallback/mirror)
273315pages :
@@ -284,11 +326,7 @@ pages:
284326 expire_in : 30 days
285327 rules :
286328 - if : $CI_COMMIT_BRANCH == "main"
287- changes :
288- - " docs/**/*"
289- - " src/**/*.py"
290- - " noxfile.py"
291- - " pyproject.toml"
329+ changes : *docs-files
292330
293331# Test Release Job (TestPyPI)
294332test-release-python :
0 commit comments