chg: ci: Only run relevant CI jobs based on the changes

Trigger selected CI jobs on MR automatically only if there are related
code changes. Otherwise, offer an option to run the jobs manually in
MRs. For other sources, like schedules, tags etc., execute the jobs as
usual.

Merge branch 'nicki/ci-restrict-rules-changes' into 'main'

See merge request isc-projects/bind9!10987
This commit is contained in:
Nicki Křížek 2025-09-18 15:27:02 +02:00
commit e5a417a8a6
6 changed files with 135 additions and 35 deletions

2
.gitattributes vendored
View file

@ -29,7 +29,7 @@ dangerfile.py export-ignore
/tests/bench/names.csv export-ignore
/util/** export-ignore
/util/bindkeys.pl -export-ignore
/util/check-make-install.in -export-ignore
/util/check-make-install.sh.in -export-ignore
/util/dtrace.sh -export-ignore
/util/meson.build -export-ignore
/util/meson-system-test-init.sh -export-ignore

2
.gitignore vendored
View file

@ -65,7 +65,7 @@ timestamp
# Gets generated by Build Ear (bear)
/compile_commands.commands.json
/tsan
/util/check-make-install
/util/check-make-install.sh
/INSTALL
doc/man/dnssec-cds.8in
doc/man/dnssec-checkds.8in

View file

@ -273,19 +273,73 @@ stages:
### Job Templates
.rule_mr_code: &rule_mr_code
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
- '**/meson.build'
.rule_mr_shell: &rule_mr_shell
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.sh'
- '**/*.sh.in'
- 'bin/tests/system/org.isc.bind.system'
.rule_mr_python: &rule_mr_python
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.py'
.rule_mr_manual: &rule_mr_manual
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
when: manual # only run on MR if requested
allow_failure: true # don't block the pipeline or the pipeline result
.rule_tag: &rule_tag
- if: '$CI_COMMIT_TAG != null'
.rule_source_other_than_mr: &rule_source_other_than_mr
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
.rule_source_all: &rule_source_all
- if: '$CI_PIPELINE_SOURCE =~ /^(api|merge_request_event|pipeline|schedule|trigger|web)$/'
.api-pipelines-schedules-tags-triggers-web-triggering-rules: &api_pipelines_schedules_tags_triggers_web_triggering_rules
rules:
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
- if: '$CI_COMMIT_TAG != null'
- *rule_tag
- *rule_source_other_than_mr
.default-triggering-rules_list: &default_triggering_rules_list
- if: '$CI_PIPELINE_SOURCE =~ /^(api|merge_request_event|pipeline|schedule|trigger|web)$/'
- if: '$CI_COMMIT_TAG != null'
- *rule_tag
- *rule_source_all
.default-triggering-rules: &default_triggering_rules
rules:
- *default_triggering_rules_list
.code-triggering-rules: &code_triggering_rules
rules:
- *rule_mr_code
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
.shell-triggering-rules: &shell_triggering_rules
rules:
- *rule_mr_shell
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
.python-triggering-rules: &python_triggering_rules
rules:
- *rule_mr_python
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
.precheck: &precheck_job
<<: *default_triggering_rules
<<: *base_image
@ -373,7 +427,7 @@ stages:
- meson compile -C build system-test-dependencies
- test -z "${NO_BUILD_TEST_PREREQ}" && ninja -C build meson-test-prereq
- test -z "${RUN_MESON_INSTALL}" || meson install -C build --destdir=$INSTALL_PATH
- test -z "${RUN_MESON_INSTALL}" || DESTDIR="${INSTALL_PATH}" sh build/util/check-make-install
- test -z "${RUN_MESON_INSTALL}" || DESTDIR="${INSTALL_PATH}" sh build/util/check-make-install.sh
#- test -z "${CROSS_COMPILATION}" || grep -F -A 1 "checking whether we are cross compiling" config.log | grep -q "result.*yes"
- test -z "${CROSS_COMPILATION}" || file build/lib/dns/gen | grep -F -q "ELF 64-bit LSB"
#- test -z "${CROSS_COMPILATION}" || ( ! git ls-files -z --others --exclude lib/dns/gen | xargs -0 file | grep "ELF 64-bit LSB" )
@ -400,8 +454,17 @@ stages:
stage: performance
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
- &shotgun_rule_mr_manual
if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
when: manual # don't run on each MR unless requested
allow_failure: true
- &shotgun_rule_tag
if: '$CI_COMMIT_TAG != null'
variables:
@ -521,6 +584,7 @@ stages:
- find build/man/ -maxdepth 2 -name "*.[0-9]" -exec mandoc -T lint "{}" \; | ( ! grep -v -e "skipping paragraph macro. sp after" -e "unknown font, skipping request. ft C" -e "input text line longer than 80 bytes" )
.respdiff: &respdiff_job
<<: *code_triggering_rules
stage: system
before_script:
- *configure
@ -561,6 +625,7 @@ misc:
black:
<<: *precheck_job
<<: *python_triggering_rules
needs: []
script:
- black $(git ls-files '*.py')
@ -574,6 +639,7 @@ black:
vulture:
<<: *precheck_job
<<: *python_triggering_rules
needs: []
script:
- vulture --exclude "*ans.py,conftest.py,isctest" --ignore-names "pytestmark,reconfigure_policy,setup_filters" bin/tests/system/
@ -603,6 +669,16 @@ ci-orphaned-anchors:
clang-format:
<<: *precheck_job
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
- '**/.clang-format'
- '**/.clang-format.headers'
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
needs: []
script:
- if [ -r .clang-format ]; then "${CLANG_FORMAT}" -i -style=file $(git ls-files '*.c' '*.h'); fi
@ -616,13 +692,29 @@ clang-format:
coccinelle:
<<: *precheck_job
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
- 'cocci/**'
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
needs: []
script:
- util/check-cocci
- util/check-cocci.sh
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
meson-format:
<<: *precheck_job
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/meson.build'
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
needs: []
script:
- git ls-files "*meson.build" | xargs muon-meson fmt -i
@ -651,6 +743,7 @@ doctest:
pylint:
<<: *precheck_job
<<: *python_triggering_rules
needs: []
variables:
PYTHONPATH: "${CI_PROJECT_DIR}/bin/tests/system"
@ -670,6 +763,7 @@ reuse:
shfmt:
<<: *precheck_job
<<: *shell_triggering_rules
needs: []
script:
- shfmt -w -i 2 -ci -bn . $(find . -name "*.sh.in")
@ -692,12 +786,14 @@ danger:
checkbashisms:
<<: *precheck_job
<<: *shell_triggering_rules
needs: []
script:
- checkbashisms $(find . -path './.git' -prune -o -type f -exec sh -c 'head -n 1 "{}" | grep -qsF "#!/bin/sh"' \; -print)
mypy:
<<: *precheck_job
<<: *python_triggering_rules
stage: precheck
script:
- mypy "bin/tests/system/isctest/"
@ -1677,7 +1773,6 @@ coverity:
respdiff:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *base_image
variables:
CC: gcc
@ -1690,7 +1785,6 @@ respdiff:
respdiff:asan:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *base_image
variables:
CC: gcc
@ -1703,7 +1797,6 @@ respdiff:asan:
respdiff:tsan:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *tsan_debian_trixie_amd64_image
variables:
CC: "${CLANG}"
@ -1720,7 +1813,6 @@ respdiff:tsan:
respdiff-third-party:
<<: *respdiff_job
<<: *default_triggering_rules
<<: *base_image
variables:
CC: gcc
@ -1734,7 +1826,6 @@ respdiff-third-party:
.respdiff-recent-named: &respdiff_recent_named
<<: *respdiff_job
<<: *base_image
<<: *default_triggering_rules
needs:
- job: ci-variables
artifacts: true
@ -1777,12 +1868,8 @@ shotgun:dot:
variables:
SHOTGUN_SCENARIO: dot
SHOTGUN_TRAFFIC_MULTIPLIER: 5
rules: &shotgun_rules_manual_mr
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
when: manual # don't run on each MR unless requested
allow_failure: true
rules:
- *shotgun_rule_mr_manual
- *shotgun_rule_tag
- *shotgun_rule_other
@ -1792,7 +1879,10 @@ shotgun:doh-get:
SHOTGUN_SCENARIO: doh-get
SHOTGUN_TRAFFIC_MULTIPLIER: 2
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX: 0.4 # bump from the default due to increased tail-end jitter
rules: *shotgun_rules_manual_mr
rules:
- *shotgun_rule_mr_manual
- *shotgun_rule_tag
- *shotgun_rule_other
generate-stress-test-configs:
<<: *base_image
@ -1809,6 +1899,16 @@ generate-stress-test-configs:
stress-test-child-pipeline:
<<: *default_triggering_rules
stage: performance
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
when: manual # don't run on each MR unless requested
allow_failure: true
- if: '$CI_COMMIT_TAG != null'
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
trigger:
include:
- artifact: stress-test-configs.yml

View file

@ -18,26 +18,26 @@ install_dir="${DESTDIR}@prefix@"
named_binary_path="${install_dir}/sbin/named"
if [ ! -x "${named_binary_path}" ]; then
echo "ERROR: ${named_binary_path} does not exist or is not executable"
status=1
echo "ERROR: ${named_binary_path} does not exist or is not executable"
status=1
fi
named_man_page_path="${install_dir}/share/man/man8/named.8"
if [ ! -f "${named_man_page_path}" ]; then
echo "ERROR: ${named_man_page_path} does not exist"
status=1
echo "ERROR: ${named_man_page_path} does not exist"
status=1
fi
if [ -n "${DESTDIR}" ]; then
for expected_subdir in bin lib sbin share; do
echo "${install_dir}/${expected_subdir}" >> "${abs_builddir}/expected_dirs"
done
find "${install_dir}" -maxdepth 1 -mindepth 1 -type d | sort > "${abs_builddir}/existing_dirs"
if ! diff -u "${abs_builddir}/expected_dirs" "${abs_builddir}/existing_dirs"; then
echo "ERROR: Contents of DESTDIR do not match expectations"
status=1
fi
rm -f "${abs_builddir}/expected_dirs" "${abs_builddir}/existing_dirs"
for expected_subdir in bin lib sbin share; do
echo "${install_dir}/${expected_subdir}" >>"${abs_builddir}/expected_dirs"
done
find "${install_dir}" -maxdepth 1 -mindepth 1 -type d | sort >"${abs_builddir}/existing_dirs"
if ! diff -u "${abs_builddir}/expected_dirs" "${abs_builddir}/existing_dirs"; then
echo "ERROR: Contents of DESTDIR do not match expectations"
status=1
fi
rm -f "${abs_builddir}/expected_dirs" "${abs_builddir}/existing_dirs"
fi
exit $status

View file

@ -10,8 +10,8 @@
# information regarding copyright ownership.
configure_file(
input: 'check-make-install.in',
output: 'check-make-install',
input: 'check-make-install.sh.in',
output: 'check-make-install.sh',
configuration: {
'abs_builddir': meson.project_build_root(),
'abs_top_srcdir': meson.project_source_root(),