Skip to content

Commit 6b0d8a4

Browse files
ci(pr): gate builds on changed-files and broaden safe exclusions (#1118)
## Summary Reduces PR CI time by skipping build jobs when no downstream test or doc consumer needs them, and by excluding more files that never affect builds or tests. **Build gating (\`if:\`):** - \`conda-cpp-build\`: \`test_cpp ∨ test_python_conda ∨ build_docs\` - \`conda-python-build\`: \`test_python_conda ∨ build_docs\` - All 5 \`wheel-build-*\`: \`test_python_wheels\` **New exclusions (applied to all 4 changed-file groups):** - \`**/*.md\` (docs are \`.rst\`), \`LICENSE\`, \`.gitattributes\`, \`.gitignore\`, \`.clang-format\`, \`.github/release.yml\` - \`ci/thirdparty-testing/**\` (only invoked by \`nightly.yaml\`) - \`.github/workflows/*.yaml\` files not reachable from \`pr.yaml\` (\`build.yaml\`, \`nightly.yaml\`, \`cloud_ci.yaml\`, etc.) — \`self_hosted_service_test.yaml\` is deliberately kept ## Safety Each group still begins with \`'**'\` (include everything). \`!\` lines only remove paths, so any new file that isn't explicitly excluded triggers full CI — fail-closed default preserved. ## Expected impact | PR touches only… | Before | After | |---|---|---| | Markdown / LICENSE / .clang-format | full build+test matrix | \`checks\` only | | \`ci/thirdparty-testing/**.sh\` | full build+test matrix | \`checks\` only | | Nightly-only workflow files | full build+test matrix | \`checks\` only | | \`notebooks/**\` or \`docs/**/*.rst\` | full matrix | skips 5 wheel builds + wheel tests | | \`cpp/**\` or \`python/**\` | unchanged | unchanged | Authors: - Ramakrishnap (https://github.com/rgsl888prabhu) Approvers: - James Lamb (https://github.com/jameslamb) URL: #1118
1 parent baeab76 commit 6b0d8a4

1 file changed

Lines changed: 139 additions & 54 deletions

File tree

.github/workflows/pr.yaml

Lines changed: 139 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -117,29 +117,48 @@ jobs:
117117
build_docs:
118118
- '**'
119119
- '!.ai/**'
120+
- '!.clang-format'
120121
- '!.coderabbit.yaml'
121-
- '!AGENTS.md'
122-
- '!.github/CODE_OF_CONDUCT.md'
122+
- '!.gitattributes'
123+
- '!.github/.ai/**'
124+
- '!.github/.coderabbit_review_guide.md'
123125
- '!.github/CODEOWNERS'
126+
- '!.github/CODE_OF_CONDUCT.md'
124127
- '!.github/ISSUE_TEMPLATE/**'
125128
- '!.github/PULL_REQUEST_TEMPLATE.md'
126129
- '!.github/SECURITY.md'
127-
- '!.github/.ai/**'
128-
- '!.github/.coderabbit_review_guide.md'
129130
- '!.github/agents/**'
130131
- '!.github/copy-pr-bot.yaml'
131132
- '!.github/ops-bot.yaml'
133+
- '!.github/release.yml'
134+
- '!.github/workflows/build.yaml'
135+
- '!.github/workflows/build_images.yaml'
136+
- '!.github/workflows/build_test_publish_images.yaml'
137+
- '!.github/workflows/cloud_ci.yaml'
138+
- '!.github/workflows/inactivity_reminder.yaml'
139+
- '!.github/workflows/issue_automation.yaml'
140+
- '!.github/workflows/nightly.yaml'
141+
- '!.github/workflows/test.yaml'
142+
- '!.github/workflows/test_images.yaml'
143+
- '!.github/workflows/trigger-breaking-change-alert.yaml'
144+
- '!.gitignore'
132145
- '!.pre-commit-config.yaml'
146+
- '!AGENTS.md'
147+
- '!CHANGELOG.md'
148+
- '!CONTRIBUTING.md'
149+
- '!LICENSE'
150+
- '!README.md'
133151
- '!ci/build_wheel*.sh'
134152
- '!ci/check_style.sh'
135153
- '!ci/release/**'
136-
- '!ci/run_ctests.sh'
137154
- '!ci/run_*.pytests.sh'
155+
- '!ci/run_ctests.sh'
138156
- '!ci/test_cpp*.sh'
139157
- '!ci/test_notebooks.sh'
140158
- '!ci/test_python.sh'
141159
- '!ci/test_self_hosted_service.sh'
142160
- '!ci/test_wheel*.sh'
161+
- '!ci/thirdparty-testing/**'
143162
- '!container-builder/**'
144163
- '!helmchart/**'
145164
- '!ngc/**'
@@ -149,22 +168,41 @@ jobs:
149168
- '!utilities/**'
150169
test_cpp:
151170
- '**'
152-
- '!CONTRIBUTING.md'
153-
- '!README.md'
171+
- '!**/*.md'
154172
- '!.ai/**'
173+
- '!.clang-format'
174+
- '!.claude-plugin/**'
155175
- '!.coderabbit.yaml'
156-
- '!AGENTS.md'
157-
- '!.github/CODE_OF_CONDUCT.md'
176+
- '!.cursor-plugin/**'
177+
- '!.gitattributes'
178+
- '!.github/.ai/**'
179+
- '!.github/.coderabbit_review_guide.md'
158180
- '!.github/CODEOWNERS'
181+
- '!.github/CODE_OF_CONDUCT.md'
159182
- '!.github/ISSUE_TEMPLATE/**'
160183
- '!.github/PULL_REQUEST_TEMPLATE.md'
161184
- '!.github/SECURITY.md'
162-
- '!.github/.ai/**'
163-
- '!.github/.coderabbit_review_guide.md'
164185
- '!.github/agents/**'
165186
- '!.github/copy-pr-bot.yaml'
166187
- '!.github/ops-bot.yaml'
188+
- '!.github/release.yml'
189+
- '!.github/workflows/build.yaml'
190+
- '!.github/workflows/build_images.yaml'
191+
- '!.github/workflows/build_test_publish_images.yaml'
192+
- '!.github/workflows/cloud_ci.yaml'
193+
- '!.github/workflows/inactivity_reminder.yaml'
194+
- '!.github/workflows/issue_automation.yaml'
195+
- '!.github/workflows/nightly.yaml'
196+
- '!.github/workflows/test.yaml'
197+
- '!.github/workflows/test_images.yaml'
198+
- '!.github/workflows/trigger-breaking-change-alert.yaml'
199+
- '!.gitignore'
167200
- '!.pre-commit-config.yaml'
201+
- '!AGENTS.md'
202+
- '!CONTRIBUTING.md'
203+
- '!LICENSE'
204+
- '!README.md'
205+
- '!agents/**'
168206
- '!ci/build_docs.sh'
169207
- '!ci/build_python.sh'
170208
- '!ci/build_wheel*.sh'
@@ -173,117 +211,154 @@ jobs:
173211
- '!ci/test_python.sh'
174212
- '!ci/test_self_hosted_service.sh'
175213
- '!ci/test_wheel*.sh'
214+
- '!ci/thirdparty-testing/**'
215+
- '!ci/utils/sync_skills_version.sh'
216+
- '!ci/utils/validate_skills.sh'
176217
- '!container-builder/**'
177218
- '!docs/**'
219+
- '!gemini-extension.json'
178220
- '!helmchart/**'
179221
- '!img/**'
180222
- '!ngc/**'
181223
- '!notebooks/**'
182224
- '!python/**'
225+
- '!skills/**/SKILL.md'
226+
- '!skills/**/resources/**'
183227
- '!sonar-project.properties'
184228
- '!sonarqube/**'
185229
- '!ucf/**'
186230
- '!utilities/**'
187-
- '!skills/**/SKILL.md'
188-
- '!skills/**/resources/**'
189-
- '!ci/utils/validate_skills.sh'
190-
- '!ci/utils/sync_skills_version.sh'
191-
- '!agents/**'
192-
- '!.cursor-plugin/**'
193-
- '!.claude-plugin/**'
194-
- '!gemini-extension.json'
195231
test_python_conda:
196232
- '**'
197-
- '!CONTRIBUTING.md'
198-
- '!README.md'
233+
- '!**/*.md'
199234
- '!.ai/**'
235+
- '!.clang-format'
236+
- '!.claude-plugin/**'
200237
- '!.coderabbit.yaml'
201-
- '!AGENTS.md'
202-
- '!.github/CODE_OF_CONDUCT.md'
238+
- '!.cursor-plugin/**'
239+
- '!.gitattributes'
240+
- '!.github/.ai/**'
241+
- '!.github/.coderabbit_review_guide.md'
203242
- '!.github/CODEOWNERS'
243+
- '!.github/CODE_OF_CONDUCT.md'
204244
- '!.github/ISSUE_TEMPLATE/**'
205245
- '!.github/PULL_REQUEST_TEMPLATE.md'
206246
- '!.github/SECURITY.md'
207-
- '!.github/.ai/**'
208-
- '!.github/.coderabbit_review_guide.md'
209247
- '!.github/agents/**'
210248
- '!.github/copy-pr-bot.yaml'
211249
- '!.github/ops-bot.yaml'
250+
- '!.github/release.yml'
251+
- '!.github/workflows/build.yaml'
252+
- '!.github/workflows/build_images.yaml'
253+
- '!.github/workflows/build_test_publish_images.yaml'
254+
- '!.github/workflows/cloud_ci.yaml'
255+
- '!.github/workflows/inactivity_reminder.yaml'
256+
- '!.github/workflows/issue_automation.yaml'
257+
- '!.github/workflows/nightly.yaml'
258+
- '!.github/workflows/test.yaml'
259+
- '!.github/workflows/test_images.yaml'
260+
- '!.github/workflows/trigger-breaking-change-alert.yaml'
261+
- '!.gitignore'
212262
- '!.pre-commit-config.yaml'
263+
- '!AGENTS.md'
264+
- '!CONTRIBUTING.md'
265+
- '!LICENSE'
266+
- '!README.md'
267+
- '!agents/**'
213268
- '!ci/build_docs.sh'
214269
- '!ci/build_wheel*.sh'
215270
- '!ci/check_style.sh'
216271
- '!ci/release/**'
217272
- '!ci/test_self_hosted_service.sh'
218273
- '!ci/test_wheel*.sh'
274+
- '!ci/thirdparty-testing/**'
275+
- '!ci/utils/sync_skills_version.sh'
276+
- '!ci/utils/validate_skills.sh'
219277
- '!container-builder/**'
220278
- '!docs/**'
279+
- '!gemini-extension.json'
221280
- '!helmchart/**'
222281
- '!img/**'
223282
- '!ngc/**'
224283
- '!notebooks/**'
284+
- '!skills/**/SKILL.md'
285+
- '!skills/**/resources/**'
225286
- '!sonar-project.properties'
226287
- '!sonarqube/**'
227288
- '!ucf/**'
228289
- '!utilities/**'
229-
- '!skills/**/SKILL.md'
230-
- '!skills/**/resources/**'
231-
- '!ci/utils/validate_skills.sh'
232-
- '!ci/utils/sync_skills_version.sh'
233-
- '!agents/**'
234-
- '!.cursor-plugin/**'
235-
- '!.claude-plugin/**'
236-
- '!gemini-extension.json'
237290
test_python_wheels:
238291
- '**'
239-
- '!CONTRIBUTING.md'
240-
- '!README.md'
292+
- '!**/*.md'
241293
- '!.ai/**'
294+
- '!.clang-format'
295+
- '!.claude-plugin/**'
242296
- '!.coderabbit.yaml'
243-
- '!AGENTS.md'
244-
- '!.github/CODE_OF_CONDUCT.md'
297+
- '!.cursor-plugin/**'
298+
- '!.gitattributes'
299+
- '!.github/.ai/**'
300+
- '!.github/.coderabbit_review_guide.md'
245301
- '!.github/CODEOWNERS'
302+
- '!.github/CODE_OF_CONDUCT.md'
246303
- '!.github/ISSUE_TEMPLATE/**'
247304
- '!.github/PULL_REQUEST_TEMPLATE.md'
248305
- '!.github/SECURITY.md'
249-
- '!.github/.ai/**'
250-
- '!.github/.coderabbit_review_guide.md'
251306
- '!.github/agents/**'
252307
- '!.github/copy-pr-bot.yaml'
253308
- '!.github/ops-bot.yaml'
309+
- '!.github/release.yml'
310+
- '!.github/workflows/build.yaml'
311+
- '!.github/workflows/build_images.yaml'
312+
- '!.github/workflows/build_test_publish_images.yaml'
313+
- '!.github/workflows/cloud_ci.yaml'
314+
- '!.github/workflows/inactivity_reminder.yaml'
315+
- '!.github/workflows/issue_automation.yaml'
316+
- '!.github/workflows/nightly.yaml'
317+
- '!.github/workflows/test.yaml'
318+
- '!.github/workflows/test_images.yaml'
319+
- '!.github/workflows/trigger-breaking-change-alert.yaml'
320+
- '!.gitignore'
254321
- '!.pre-commit-config.yaml'
322+
- '!AGENTS.md'
323+
- '!CONTRIBUTING.md'
324+
- '!LICENSE'
325+
- '!README.md'
326+
- '!agents/**'
255327
- '!ci/build_cpp.sh'
256328
- '!ci/build_docs.sh'
257329
- '!ci/build_python.sh'
258330
- '!ci/check_style.sh'
259331
- '!ci/release/**'
260332
- '!ci/run_ctests.sh'
261333
- '!ci/test_python.sh'
334+
- '!ci/thirdparty-testing/**'
335+
- '!ci/utils/sync_skills_version.sh'
336+
- '!ci/utils/validate_skills.sh'
262337
- '!conda/**'
263338
- '!container-builder/**'
339+
- '!gemini-extension.json'
264340
- '!helmchart/**'
265341
- '!img/**'
266342
- '!ngc/**'
267343
- '!notebooks/**'
344+
- '!skills/**/SKILL.md'
345+
- '!skills/**/resources/**'
268346
- '!sonar-project.properties'
269347
- '!sonarqube/**'
270348
- '!ucf/**'
271349
- '!utilities/**'
272-
- '!skills/**/SKILL.md'
273-
- '!skills/**/resources/**'
274-
- '!ci/utils/validate_skills.sh'
275-
- '!ci/utils/sync_skills_version.sh'
276-
- '!agents/**'
277-
- '!.cursor-plugin/**'
278-
- '!.claude-plugin/**'
279-
- '!gemini-extension.json'
280350
checks:
281351
secrets: inherit
282352
uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@main
283353
with:
284354
enable_check_generated_files: false
285355
conda-cpp-build:
286-
needs: [checks, compute-matrix-filters]
356+
needs: [checks, compute-matrix-filters, changed-files]
357+
# Consumed by conda-cpp-tests, conda-python-build, and (transitively) docs-build.
358+
if: >-
359+
fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp ||
360+
fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda ||
361+
fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs
287362
secrets: inherit
288363
uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@main
289364
with:
@@ -306,7 +381,11 @@ jobs:
306381
script-env-secret-3-key: CUOPT_AWS_SECRET_ACCESS_KEY
307382
script-env-secret-3-value: ${{ secrets.CUOPT_AWS_SECRET_ACCESS_KEY }}
308383
conda-python-build:
309-
needs: [conda-cpp-build, compute-matrix-filters]
384+
needs: [conda-cpp-build, compute-matrix-filters, changed-files]
385+
# Consumed by conda-python-tests and docs-build.
386+
if: >-
387+
fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda ||
388+
fromJSON(needs.changed-files.outputs.changed_file_groups).build_docs
310389
secrets: inherit
311390
uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@main
312391
with:
@@ -343,7 +422,9 @@ jobs:
343422
container_image: "rapidsai/ci-conda:26.06-latest"
344423
script: "ci/build_docs.sh"
345424
wheel-build-cuopt-mps-parser:
346-
needs: compute-matrix-filters
425+
needs: [compute-matrix-filters, changed-files]
426+
# All wheel-build-* jobs feed the wheel test jobs, so they gate on the same group.
427+
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels
347428
secrets: inherit
348429
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main
349430
with:
@@ -355,7 +436,8 @@ jobs:
355436
# need 1 build per Python version and arch (but CUDA version doesn't matter so choose the latest)
356437
matrix_filter: ${{ needs.compute-matrix-filters.outputs.mps_parser_filter }}
357438
wheel-build-libcuopt:
358-
needs: [wheel-build-cuopt-mps-parser, compute-matrix-filters]
439+
needs: [wheel-build-cuopt-mps-parser, compute-matrix-filters, changed-files]
440+
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels
359441
secrets: inherit
360442
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main
361443
with:
@@ -366,7 +448,8 @@ jobs:
366448
build_type: pull-request
367449
script: ci/build_wheel_libcuopt.sh
368450
wheel-build-cuopt:
369-
needs: [wheel-build-cuopt-mps-parser, wheel-build-libcuopt, compute-matrix-filters]
451+
needs: [wheel-build-cuopt-mps-parser, wheel-build-libcuopt, compute-matrix-filters, changed-files]
452+
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels
370453
secrets: inherit
371454
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main
372455
with:
@@ -391,7 +474,8 @@ jobs:
391474
script-env-secret-3-key: CUOPT_AWS_SECRET_ACCESS_KEY
392475
script-env-secret-3-value: ${{ secrets.CUOPT_AWS_SECRET_ACCESS_KEY }}
393476
wheel-build-cuopt-server:
394-
needs: [checks, compute-matrix-filters]
477+
needs: [checks, compute-matrix-filters, changed-files]
478+
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels
395479
secrets: inherit
396480
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main
397481
with:
@@ -403,7 +487,8 @@ jobs:
403487
# Only need 1 package per CUDA major version. This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version".
404488
matrix_filter: ${{ needs.compute-matrix-filters.outputs.cuopt_server_filter }}
405489
wheel-build-cuopt-sh-client:
406-
needs: compute-matrix-filters
490+
needs: [compute-matrix-filters, changed-files]
491+
if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_wheels
407492
secrets: inherit
408493
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@main
409494
with:

0 commit comments

Comments
 (0)