bind9/.gitlab-ci.yml
Michał Kępień 67c9c118ba Use "git push --force-with-lease" for autorebases
If a merge request is merged to an autorebased branch while it is
getting rebased, the "git push -f" command at the end of the autorebase
job will cause the contents of that merge request to be silently deleted
from Git history even though the merge request will still be (correctly)
shown as "merged" by GitLab.

Use "git push --force-with-lease" instead to prevent force-pushing the
rebased version of the branch if it is pushed to after its pre-rebase
version is fetched by the autorebase job.  Report such an event
accordingly.  For simplicity, no retries are attempted as the problem is
expected to be resolved by the next autorebase and the chances of this
scenario happening in practice are already low to begin with.

(cherry picked from commit f5a7671107)
2026-04-30 20:35:21 +00:00

2737 lines
85 KiB
YAML

variables:
# Not normally needed, but may be if some script uses `apt-get install`.
DEBIAN_FRONTEND: noninteractive
# Locale settings do not affect the build, but might affect tests.
LC_ALL: C
# automated commits will inherit identification from pipeline trigger
GIT_AUTHOR_NAME: "$GITLAB_USER_NAME (GitLab job $CI_JOB_ID)"
GIT_AUTHOR_EMAIL: "$GITLAB_USER_EMAIL"
GIT_COMMITTER_NAME: "$GIT_AUTHOR_NAME"
GIT_COMMITTER_EMAIL: "$GIT_AUTHOR_EMAIL"
CI_REGISTRY_IMAGE: registry.gitlab.isc.org/isc-projects/images/bind9
CCACHE_DIR: "/ccache"
GIT_DEPTH: 1
GIT_CLEAN_FLAGS: -ffdxq
# The following values may be overwritten in GitLab's CI/CD Variables Settings.
BUILD_PARALLEL_JOBS: 6
TEST_PARALLEL_JOBS: 4
CONFIGURE: ./configure
CLANG_VERSION: 22
CLANG: "clang-${CLANG_VERSION}"
SCAN_BUILD: "scan-build-${CLANG_VERSION}"
LLVM_SYMBOLIZER: "/usr/lib/llvm-${CLANG_VERSION}/bin/llvm-symbolizer"
CLANG_FORMAT: "clang-format-${CLANG_VERSION}"
CFLAGS_COMMON: -fno-omit-frame-pointer -fno-optimize-sibling-calls -O1 -g -Wall -Wextra
# Pass run-time flags to AddressSanitizer to get core dumps on error.
ASAN_OPTIONS: abort_on_error=1:disable_coredump=0:unmap_shadow_on_exit=1
ASAN_SYMBOLIZER_PATH: "${LLVM_SYMBOLIZER}"
TSAN_OPTIONS_COMMON: "disable_coredump=0 second_deadlock_stack=1 atexit_sleep_ms=1000 history_size=7 log_exe_name=true log_path=tsan"
TSAN_SUPPRESSIONS: "suppressions=${CI_PROJECT_DIR}/.tsan-suppress"
TSAN_OPTIONS_DEBIAN: "${TSAN_OPTIONS_COMMON} ${TSAN_SUPPRESSIONS} external_symbolizer_path=${LLVM_SYMBOLIZER}"
TSAN_OPTIONS_FEDORA: "${TSAN_OPTIONS_COMMON} ${TSAN_SUPPRESSIONS} external_symbolizer_path=/usr/bin/llvm-symbolizer"
UBSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:disable_coredump=0"
AM_COLOR_TESTS: always
WITHOUT_READLINE: "--without-readline"
WITH_READLINE: "--with-readline"
WITH_READLINE_EDITLINE: "--with-readline=editline"
WITH_READLINE_LIBEDIT: "--with-readline=libedit"
WITH_READLINE_READLINE: "--with-readline=readline"
INSTALL_PATH: "${CI_PROJECT_DIR}/.local"
# In multithreaded unit tests, abort on the first failure
CMOCKA_TEST_ABORT: 1
# Disable pytest's "cacheprovider" plugin to prevent it from creating
# cross-testrun files as there is no need to use that feature in CI.
PYTEST_ADDOPTS: "-p no:cacheprovider"
HYPOTHESIS_PROFILE: "ci"
# Some jobs may clean up the build artifacts unless this is set to 0.
CLEAN_BUILD_ARTIFACTS_ON_SUCCESS: 1
# DNS Shotgun performance testing defaults
SHOTGUN_ROUNDS: 1
SHOTGUN_DURATION: 120
# allow unlimited improvements against baseline
SHOTGUN_EVAL_THRESHOLD_CPU_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_RCODE_MAX: '+inf'
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN: '-inf'
# Even though there's only one job per runtime environment, the GitLab
# "instance" executor insists on cloning the Git repository to a path that
# contains a variable number from zero to the "maximum concurrent instances
# count" allowed on the GitLab Runner. See the "0" directory in this example
# path: /home/ec2-user/builds/t1_4FZzvz/0/isc-projects/bind9/.git/.
#
# This is not a problem for isolated jobs like "stress" tests that depend on
# no other jobs. However, it is a problem for jobs that need other jobs'
# artifacts. For example, a system test job that has its Git repo cloned to
# the "/1/" sub-path will fail if it downloads build job artifacts that have
# ./configure output files with "/0/" in its sub-path recorded.
GIT_CLONE_PATH_INSTANCE_EXECUTOR: "/home/ec2-user/builds/${CI_PROJECT_PATH}/"
default:
# Allow all running CI jobs to be automatically canceled when a new
# version of a branch is pushed.
#
# See: https://docs.gitlab.com/ee/ci/pipelines/settings.html#auto-cancel-redundant-pipelines
interruptible: true
# AWS can interrupt the spot instance anytime, so let's retry the job when
# the interruption event happens to avoid a pipeline failure.
retry:
max: 2
when:
- runner_system_failure
workflow:
# Prevent jobs marked with "interruptible: false" that have not yet been
# started from getting canceled when a newer pipeline is created for the same
# branch. This setting was added to enable "iterative autorebases" to work
# correctly with `resource_group`. Without this setting, pending rebase jobs
# waiting for a resource group would get canceled by the "git push" operation
# at the end of a prior rebase job belonging to the same resource group.
auto_cancel:
on_new_commit: interruptible
stages:
- autoconf
- quick-checks
- other-checks
- build
- unit
- system
- performance
- docs
- postmerge
- release
### Runner Tag Templates
# AlmaLinux autoscaling GitLab Runners on AWS EC2 (amd64)
.almalinux-8fips-amd64-image: &almalinux_8fips_amd64_image
tags:
- almalinux-8
- amd64
- autoscaler
- aws
- fips
- shell
.almalinux-9fips-amd64-image: &almalinux_9fips_amd64_image
tags:
- almalinux-9
- amd64
- autoscaler
- aws
- fips
- shell
.almalinux-10fips-amd64-image: &almalinux_10fips_amd64_image
tags:
- almalinux-10
- amd64
- autoscaler
- aws
- fips
- shell
# Autoscaling GitLab Runner on AWS EC2 (amd64)
.linux-amd64: &linux_amd64
tags:
- linux
- aws
- runner-manager
- amd64
# Autoscaling GitLab Runner on AWS EC2 (arm64)
.linux-arm64: &linux_arm64
tags:
- linux
- aws
- runner-manager
- aarch64
.freebsd-autoscaler-13-amd64-tags: &freebsd_autoscaler_13_amd64_tags
tags:
- amd64
- autoscaler
- aws
- bsd-stress-test-1
- shell
- stress-test
.freebsd-autoscaler-14-amd64-tags: &freebsd_autoscaler_14_amd64_tags
tags:
- amd64
- autoscaler
- aws
- bsd-stress-test-2
- shell
- stress-test
.freebsd-autoscaler-15-amd64-tags: &freebsd_autoscaler_15_amd64_tags
tags:
- amd64
- autoscaler
- aws
- bsd-stress-test-3
- shell
- stress-test
### Docker Image Templates
# Alpine Linux
.alpine-3.23-amd64: &alpine_3_23_amd64_image
image: "$CI_REGISTRY_IMAGE:alpine-3.23-amd64"
<<: *linux_amd64
# AlmaLinux
.almalinux-8-amd64: &almalinux_8_amd64_image
image: "$CI_REGISTRY_IMAGE:almalinux-8-amd64"
<<: *linux_amd64
.almalinux-9-amd64: &almalinux_9_amd64_image
image: "$CI_REGISTRY_IMAGE:almalinux-9-amd64"
<<: *linux_amd64
.almalinux-10-amd64: &almalinux_10_amd64_image
image: "$CI_REGISTRY_IMAGE:almalinux-10-amd64"
<<: *linux_amd64
# Debian
.debian-bookworm-amd64: &debian_bookworm_amd64_image
image: "$CI_REGISTRY_IMAGE:debian-bookworm-amd64"
<<: *linux_amd64
.debian-trixie-amd64: &debian_trixie_amd64_image
image: "$CI_REGISTRY_IMAGE:debian-trixie-amd64"
<<: *linux_amd64
.tsan-debian-trixie-amd64: &tsan_debian_trixie_amd64_image
image: "$CI_REGISTRY_IMAGE:tsan-debian-trixie-amd64"
<<: *linux_amd64
.debian-trixie-amd64cross32: &debian_trixie_amd64cross32_image
image: "$CI_REGISTRY_IMAGE:debian-trixie-amd64cross32"
<<: *linux_amd64
.debian-sid-amd64: &debian_sid_amd64_image
image: "$CI_REGISTRY_IMAGE:debian-sid-amd64"
<<: *linux_amd64
# openSUSE Tumbleweed
.tumbleweed-latest-amd64: &tumbleweed_latest_amd64_image
image: "$CI_REGISTRY_IMAGE:tumbleweed-latest-amd64"
<<: *linux_amd64
# Fedora
.tsan-fedora-43-amd64: &tsan_fedora_43_amd64_image
image: "$CI_REGISTRY_IMAGE:tsan-fedora-43-amd64"
<<: *linux_amd64
.fedora-43-amd64: &fedora_43_amd64_image
image: "$CI_REGISTRY_IMAGE:fedora-43-amd64"
<<: *linux_amd64
.fedora-43-arm64: &fedora_43_arm64_image
image: "$CI_REGISTRY_IMAGE:fedora-43-arm64"
<<: *linux_arm64
# Ubuntu
.ubuntu-jammy-amd64: &ubuntu_jammy_amd64_image
image: "$CI_REGISTRY_IMAGE:ubuntu-jammy-amd64"
<<: *linux_amd64
.ubuntu-noble-amd64: &ubuntu_noble_amd64_image
image: "$CI_REGISTRY_IMAGE:ubuntu-noble-amd64"
<<: *linux_amd64
# Base image
# This is a meta image that is used as a base for non-specific jobs
.base: &base_image
<<: *debian_trixie_amd64_image
### 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'
- 'bin/tests/system/custom-test-driver'
.rule_mr_python: &rule_mr_python
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.py'
.rule_mr_system_tests: &rule_mr_system_tests
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- 'bin/tests/system/**/*'
.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_PROJECT_NAMESPACE == "isc-private" && $CI_COMMIT_TAG != null'
.rule_tag_open_source: &rule_tag_open_source
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_COMMIT_TAG != null && $CI_COMMIT_TAG !~ /-S/'
.rule_tag_open_source_maintenance: &rule_tag_open_source_maintenance
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_COMMIT_TAG != null && $CI_COMMIT_TAG !~ /-S/ && $RELEASE_TYPE != "security"'
.rule_tag_security: &rule_tag_security
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_COMMIT_TAG != null && $RELEASE_TYPE == "security"'
.rule_tag_security_or_subscription: &rule_tag_security_or_subscription
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_COMMIT_TAG != null && ($RELEASE_TYPE == "security" || $CI_COMMIT_TAG =~ /-S/)'
.rule_source_other_than_mr: &rule_source_other_than_mr
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/ && $REBASE_ONLY != "1"'
.rule_source_all: &rule_source_all
- if: '$CI_PIPELINE_SOURCE =~ /^(api|merge_request_event|pipeline|schedule|trigger|web)$/ && $REBASE_ONLY != "1"'
.rule_private_security_branch: &rule_private_security_branch
- if: '$CI_COMMIT_BRANCH =~ /^security-(main|bind-9\.[1-9][0-9])$/ && $CI_PROJECT_PATH == "isc-private/bind9" && $REBASE_ONLY != "1"'
.api-pipelines-schedules-tags-triggers-web-triggering-rules: &api_pipelines_schedules_tags_triggers_web_triggering_rules
rules:
- *rule_tag
- *rule_source_other_than_mr
.default-triggering-rules_list: &default_triggering_rules_list
- *rule_tag
- *rule_source_all
- *rule_private_security_branch
.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
- *rule_private_security_branch
.shell-triggering-rules: &shell_triggering_rules
rules:
- *rule_mr_shell
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
- *rule_private_security_branch
.python-triggering-rules: &python_triggering_rules
rules:
- *rule_mr_python
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
- *rule_private_security_branch
.extra-system-tests-triggering-rules: &extra_system_tests_triggering_rules
rules:
- *rule_tag
- *rule_source_other_than_mr
- *rule_mr_system_tests
.quick-check: &quick_checks_job
<<: *default_triggering_rules
<<: *base_image
stage: quick-checks
needs: []
tags:
- smalljob
.other-check: &other_checks_job
<<: *default_triggering_rules
<<: *base_image
stage: other-checks
needs: []
.autoconf: &autoconf_job
<<: *default_triggering_rules
<<: *base_image
stage: autoconf
tags:
- smalljob
script:
- autoreconf -fi
artifacts:
untracked: true
.configure: &configure
- ${CONFIGURE}
--disable-maintainer-mode
--enable-developer
--enable-option-checking=fatal
--enable-dnstap
--enable-dnsrps
--with-cmocka
--with-libxml2
--with-json-c
--enable-leak-detection
$EXTRA_CONFIGURE
|| (test -s config.log && cat config.log; exit 1)
.git-clone-bind9-qa: &git_clone_bind9-qa
- git clone --depth 1 https://gitlab.isc.org/isc-projects/bind9-qa.git "$CI_PROJECT_DIR"/bind9-qa
# change directory to the workspace before including this
.find_python: &find_python
- PYTHON="$(cat bin/tests/system/isctest/vars/.ac_vars/PYTHON)"
- test -x "$PYTHON"
.find_pytest: &find_pytest
- PYTEST="$(cat bin/tests/system/isctest/vars/.ac_vars/PYTEST)"
- test -x "$PYTEST"
.parse_tsan: &parse_tsan
- *find_python
- find -name 'tsan.*' -exec "$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/parse_tsan.py {} \;
.check_readline_setup: &check_readline_setup
- if [[ -n "${WITHOUT_READLINE}" ]]; then
! grep "^#define HAVE_READLINE" config.h;
elif [[ -n "${WITH_READLINE}" ]]; then
grep -e "^#define HAVE_READLINE_READLINE"
-e "^#define HAVE_READLINE_LIBEDIT"
-e "^#define HAVE_READLINE_EDITLINE" config.h;
elif [[ -n "${WITH_READLINE_EDITLINE}" ]]; then
grep "^#define HAVE_READLINE_EDITLINE" config.h;
elif [[ -n "${WITH_READLINE_LIBEDIT}" ]]; then
grep "^#define HAVE_READLINE_LIBEDIT" config.h;
elif [[ -n "${WITH_READLINE_READLINE}" ]]; then
grep "^#define HAVE_READLINE_READLINE" config.h;
fi
.list_installed_package_versions: &list_installed_package_versions
- echo -e "\e[0Ksection_start:`date +%s`:installed_packages_section[collapsed=true]\r\e[0KHeader of the installed packages collapsible section"
- ( pip3 list || pip list || echo "no pip" ) 2>/dev/null
- for cmd in "apk info --verbose" "dpkg-query --show --showformat='\${Package}-\${Version}\n'" "pkg info --quiet" "rpm -qa | sort"; do
eval "$cmd" 2>/dev/null && break;
done || true
- echo -e "\e[0Ksection_end:`date +%s`:installed_packages_section\r\e[0K"
# Unpack release tarball and continue work in the extracted directory.
.unpack_release_tarball: &unpack_release_tarball
- tar --extract --file bind-*.tar.xz
- rm -f bind-*.tar.xz
- cd bind-*
.fips-feature-test: &fips_feature_test
- if bin/tests/system/feature-test --have-fips-mode; then
if [ "$(cat /proc/sys/crypto/fips_enabled)" = "1" ]; then
echo "FIPS is enabled";
else
echo "FIPS is disabled";
exit 1;
fi
fi
.build: &build_job
<<: *default_triggering_rules
stage: build
before_script:
- test -w "${CCACHE_DIR}" && export PATH="/usr/lib/ccache:${PATH}"
- test -n "${OUT_OF_TREE_WORKSPACE}" && mkdir "${OUT_OF_TREE_WORKSPACE}" && cd "${OUT_OF_TREE_WORKSPACE}"
- *list_installed_package_versions
script:
- *configure
- *check_readline_setup
- make -j${BUILD_PARALLEL_JOBS:-1} -k all V=1
- test -z "${RUN_MAKE_INSTALL}" || make DESTDIR="${INSTALL_PATH}" install
- test -z "${RUN_MAKE_INSTALL}" || DESTDIR="${INSTALL_PATH}" sh util/check-make-install.sh
- if [[ "${CFLAGS}" == *"-fsanitize=address"* ]]; then ( ! grep -F AddressSanitizer config.log ); fi
- 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 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" )
- if test -z "${OUT_OF_TREE_WORKSPACE}" && test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
- bin/named/named -V
- *fips_feature_test
needs:
- job: autoreconf
artifacts: true
artifacts:
untracked: true
when: always
.setup_interfaces: &setup_interfaces
- if [ "$(id -u)" -eq "0" ]; then
sh -x bin/tests/system/ifconfig.sh up;
else
sudo sh -x bin/tests/system/ifconfig.sh up;
fi
.display_pytest_failures: &display_pytest_failures
- awk '/^=+ FAILURES =+/{flag=1;next}/^=+.*=+$/{flag=0}flag' bin/tests/system/pytest.out.txt || true
- awk '/^=+ ERRORS =+/{flag=1;next}/^=+.*=+$/{flag=0}flag' bin/tests/system/pytest.out.txt || true
.shotgun: &shotgun_job
<<: *base_image
stage: performance
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
SHOTGUN_ROUNDS: 5
when: manual # don't run on each MR unless requested
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
SHOTGUN_ROUNDS: 5
WEEKDAY: "1" # run only on Monday mornings
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|trigger|web)$/ && $REBASE_ONLY != "1"'
variables:
SHOTGUN_ROUNDS: 5
when: manual
allow_failure: true
script:
- if [ -n "$WEEKDAY" ] && [ "$(date +%w)" != "$WEEKDAY" ]; then exit 0; fi # if WEEKDAY is set, only run on those days
- if [ -z "$BASELINE" ]; then export BASELINE=$BIND_BASELINE_VERSION; fi # this dotenv variable can't be set in the rules section, because rules are evaluated before any jobs run
- PIPELINE_ID=$(curl -s -X POST --fail
-F "token=$CI_JOB_TOKEN"
-F ref=main
-F "variables[SHOTGUN_TEST_VERSION]=['$CI_COMMIT_REF_NAME', '$BASELINE']"
-F "variables[SHOTGUN_DURATION]=300"
-F "variables[SHOTGUN_ROUNDS]=$SHOTGUN_ROUNDS"
-F "variables[SHOTGUN_TRAFFIC_MULTIPLIER]=$SHOTGUN_TRAFFIC_MULTIPLIER"
-F "variables[SHOTGUN_SCENARIO]=$SHOTGUN_SCENARIO"
-F "variables[SHOTGUN_EVAL_THRESHOLD_CPU_MIN]=$SHOTGUN_EVAL_THRESHOLD_CPU_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_CPU_MAX]=$SHOTGUN_EVAL_THRESHOLD_CPU_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN]=$SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_MEMORY_MAX]=$SHOTGUN_EVAL_THRESHOLD_MEMORY_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_RCODE_MIN]=$SHOTGUN_EVAL_THRESHOLD_RCODE_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_RCODE_MAX]=$SHOTGUN_EVAL_THRESHOLD_RCODE_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MAX]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MAX"
https://gitlab.isc.org/api/v4/projects/188/trigger/pipeline | jq .id)
- *git_clone_bind9-qa
- >
"$CI_PROJECT_DIR"/bind9-qa/ci/wait_shotgun.py ${WEEKDAY:+--notify} $PIPELINE_ID
needs:
- job: ci-variables
artifacts: true
timeout: 2h
.system_test_common: &system_test_job
<<: *default_triggering_rules
stage: system
before_script:
- test -n "${OUT_OF_TREE_WORKSPACE}" && cp -r bin/tests/system/* "${OUT_OF_TREE_WORKSPACE}/bin/tests/system/" && cd "${OUT_OF_TREE_WORKSPACE}"
- *setup_interfaces
# This script needs to: 1) fail if the system tests fail, 2) fail if
# the junit.xml file is broken, 3) produce the junit.xml file even if
# the system tests fail. Therefore, $RET is used to "cache" the
# result of running pytest as interrupting the script immediately when
# system tests fail would make checking the contents of the junit.xml
# file impossible (GitLab Runner uses "set -o pipefail").
script:
- *fips_feature_test
- *find_pytest
- *find_python
- *git_clone_bind9-qa
- ( if [ "${CI_DISPOSABLE_ENVIRONMENT}" = "true" ]; then sleep 3000; "$PYTHON" "${CI_PROJECT_DIR}/bind9-qa/ci/get_running_system_tests.py"; fi ) &
- cd bin/tests/system
- RET=0
- >
("$PYTEST" --junit-xml="$CI_PROJECT_DIR"/junit_pytest.xml -n "$TEST_PARALLEL_JOBS" | tee pytest.out.txt) || RET=1
- >
"$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/postprocess_junit_files.py "$CI_PROJECT_DIR"/junit_pytest.xml --output "$CI_PROJECT_DIR"/junit.xml
- (exit $RET)
- '( ! grep -F "grep: warning:" pytest.out.txt )'
- test "$CLEAN_BUILD_ARTIFACTS_ON_SUCCESS" -eq 0 || ( cd ../../.. && make clean >/dev/null 2>&1 )
after_script:
- test -n "${OUT_OF_TREE_WORKSPACE}" && cd "${OUT_OF_TREE_WORKSPACE}"
- *display_pytest_failures
artifacts:
untracked: true
exclude:
- "**/__pycache__/**/*"
when: always
reports:
junit: junit.xml
.system_test_make_check: &system_test_make_check_job
<<: *system_test_job
# This script needs to: 1) fail if the system tests fail, 2) fail if
# the junit.xml file is broken, 3) produce the junit.xml file even if
# the system tests fail. Therefore, $RET is used to "cache" the
# result of "make check" as interrupting the script immediately when
# system tests fail would prevent the junit.xml file from being
# produced.
script:
- cd bin/tests/system
- RET=0
# With pytest 9.0, there's the following error in pytest_ignore_collect():
# The (path: py.path.local) argument is deprecated, please use (collection_path: pathlib.Path).
# This should be fixed before pytest 9.1, when it becomes ineffective.
- if pytest --version | grep -F "pytest 9.0" >/dev/null; then echo "filterwarnings = ignore::pytest.PytestRemovedIn9Warning" >> pytest.ini; fi
- make -j${TEST_PARALLEL_JOBS:-1} check || RET=$?
- cd "$CI_PROJECT_DIR"
- *find_python
- >
"$PYTHON" bin/tests/convert_trs_to_junit.py . > "$CI_PROJECT_DIR"/junit_system.xml
- *git_clone_bind9-qa
- >
"$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/postprocess_junit_files.py "$CI_PROJECT_DIR"/junit_system.xml --output "$CI_PROJECT_DIR"/junit.xml
- (exit $RET)
after_script:
- cat bin/tests/system/test-suite.log || true
.system_test_tsan: &system_test_tsan_job
<<: *system_test_job
after_script:
- *display_pytest_failures
- find bin/tests/system -name "*dig.*" | xargs grep "error" || true
- *parse_tsan
.unit_test_common: &unit_test_job
<<: *default_triggering_rules
stage: unit
before_script:
- test -n "${OUT_OF_TREE_WORKSPACE}" && cd "${OUT_OF_TREE_WORKSPACE}"
# This script needs to: 1) fail if the unit tests fail, 2) fail if the
# junit.xml file is broken, 3) produce the junit.xml file even if the
# unit tests fail. Therefore, $RET is used to "cache" the result of
# "make unit" as interrupting the script immediately when unit tests
# fail would prevent the junit.xml file from being produced.
script:
- *fips_feature_test
- RET=0
- make -j${TEST_PARALLEL_JOBS:-1} -k unit V=1 || RET=$?
- *find_python
- *git_clone_bind9-qa
- >
"$PYTHON" "$CI_PROJECT_DIR"/bin/tests/convert_trs_to_junit.py . > "$CI_PROJECT_DIR"/junit_unit.xml
- >
"$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/postprocess_junit_files.py "$CI_PROJECT_DIR"/junit_unit.xml --output "$CI_PROJECT_DIR"/junit.xml
- (exit $RET)
- test "$CLEAN_BUILD_ARTIFACTS_ON_SUCCESS" -eq 0 || make clean >/dev/null 2>&1
artifacts:
untracked: true
when: always
reports:
junit: junit.xml
.unit_test_tsan: &unit_test_tsan_job
<<: *unit_test_job
after_script:
- *parse_tsan
.docs: &docs_job
variables:
DOC_MAKE_TARGET: doc
stage: docs
script:
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} -k ${DOC_MAKE_TARGET} V=1
- find doc/man/ -maxdepth 1 -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:
- autoreconf -fi
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} V=1
- *setup_interfaces
- *git_clone_bind9-qa
- cd "$CI_PROJECT_DIR"/bind9-qa/respdiff
needs: []
artifacts:
paths:
- bind9-qa/respdiff
exclude:
- bind9-qa/respdiff/rspworkdir/data.mdb # Exclude a 10 GB file.
untracked: true
when: always
### Job Definitions
# Jobs in the quick-checks stage
autoreconf:
<<: *autoconf_job
misc:
<<: *quick_checks_job
script:
- sh util/checklibs.sh > checklibs.out
- sh util/check-categories.sh
- sh util/check-gitignore.sh
- sh util/check-trailing-whitespace.sh
- if git grep SYSTEMTESTTOP -- ':!.gitlab-ci.yml'; then echo 'Please use relative paths instead of $SYSTEMTESTTOP.'; exit 1; fi
- bash util/unused-headers.sh
# Check dangling symlinks in the repository
- if find . -xtype l | grep .; then exit 1; fi
artifacts:
paths:
- checklibs.out
when: on_failure
black:
<<: *quick_checks_job
<<: *python_triggering_rules
script:
- black $(git ls-files '*.py')
- git diff > black.patch
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
artifacts:
paths:
- black.patch
expire_in: "1 week"
when: on_failure
vulture:
<<: *quick_checks_job
<<: *python_triggering_rules
script:
- vulture
ci-variables:
<<: *quick_checks_job
script:
- export BIND_BASELINE_BRANCH="$(sed -n -E "s|^m4_define\(\[bind_VERSION_MINOR\], ([0-9]+)\)dnl$|\1|p" configure.ac)"
# When testing a .0 release, compare it against the previous development
# release (e.g., 9.19.0 and 9.18.0 should both be compared against 9.17.22).
- if [ "$(sed -n -E "s|^m4_define\(\[bind_VERSION_PATCH\], ([0-9]+)\)dnl$|\1|p" configure.ac)" = "0" ]; then export BIND_BASELINE_BRANCH=$((BIND_BASELINE_BRANCH - 1 - (BIND_BASELINE_BRANCH % 2))); fi
- BIND_BASELINE_VERSION="$(curl -s "https://gitlab.isc.org/api/v4/projects/1/repository/tags?search=^v9.${BIND_BASELINE_BRANCH}&order_by=version" | jq -r ".[0].name")"
- echo "BIND_BASELINE_VERSION=$BIND_BASELINE_VERSION" >> ci_vars.env
needs:
- job: autoreconf
artifacts: true
artifacts:
reports:
dotenv: ci_vars.env
ci-orphaned-anchors:
<<: *quick_checks_job
script:
- *git_clone_bind9-qa
- >
"$CI_PROJECT_DIR"/bind9-qa/ci-orphaned-anchors/check_orphaned_anchors_ci.py .gitlab-ci.yml
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- .gitlab-ci.yml
clang-format:
<<: *quick_checks_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
- *rule_private_security_branch
script:
- if [ -r .clang-format ]; then "${CLANG_FORMAT}" -i -style=file $(git ls-files '*.c' '*.h'); fi
- git diff > clang-format.patch
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
artifacts:
paths:
- clang-format.patch
expire_in: "1 week"
when: on_failure
doctest:
<<: *quick_checks_job
# This script needs to: 1) fail if the doctest fails, 2) fail if
# the junit.xml file is broken, 3) produce the junit.xml file even if
# the doctest fails. Therefore, $RET is used to "cache" the
# result of running pytest as interrupting the script immediately when
# a doctest fails would make checking the contents of the junit.xml
# file impossible (GitLab Runner uses "set -o pipefail").
script:
- *configure
- *find_python
- *find_pytest
- export TOP_BUILDDIR=$(cat bin/tests/system/isctest/vars/.ac_vars/TOP_BUILDDIR)
- cd bin/tests/system/isctest
- RET=0
- >
"$PYTEST" --noconftest --doctest-modules --junit-xml="$CI_PROJECT_DIR/junit_doctest.xml" || RET=1
- *git_clone_bind9-qa
- >
"$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/postprocess_junit_files.py "$CI_PROJECT_DIR/junit_doctest.xml" --output "$CI_PROJECT_DIR/junit.xml"
- (exit $RET)
needs:
- job: autoreconf
artifacts: true
artifacts:
reports:
junit:
- junit.xml
pylint:
<<: *quick_checks_job
<<: *python_triggering_rules
script:
- pylint $(git ls-files '*.py')
ruff:
<<: *quick_checks_job
<<: *python_triggering_rules
script:
- ruff check
reuse:
<<: *quick_checks_job
image:
name: docker.io/fsfe/reuse:latest
entrypoint: [""]
script:
- reuse lint
shfmt:
<<: *quick_checks_job
<<: *shell_triggering_rules
script:
- shfmt -w -i 2 -ci -bn . $(find . -name "*.sh.in")
- git diff > shfmt.patch
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
artifacts:
paths:
- shfmt.patch
expire_in: "1 week"
when: on_failure
danger:
<<: *quick_checks_job
script:
- pip install git+https://gitlab.isc.org/isc-projects/hazard.git
- hazard
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
mypy:
<<: *quick_checks_job
<<: *python_triggering_rules
script:
- mypy "bin/tests/system/isctest/"
linkcheck:
<<: *quick_checks_job
script:
# Some domains tested by linkchecker may think that we connect to them too
# often and will refuse connection or reply with and error code, which
# makes this job fail. Let's check links only on Wednesdays.
- if [ "$(date +%w)" != "3" ]; then exit 0; fi
- pushd doc/arm/ > /dev/null && sphinx-build -b linkcheck . linkcheck_output/
artifacts:
paths:
- doc/arm/linkcheck_output/
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
generate-stress-test-configs:
<<: *quick_checks_job
script:
- *git_clone_bind9-qa
- >
"$CI_PROJECT_DIR"/bind9-qa/stress/generate_stress_test_configs.py > stress-test-configs.yml
artifacts:
paths:
- stress-test-configs.yml
generate-tsan-stress-test-configs:
<<: *quick_checks_job
script:
- *git_clone_bind9-qa
- >
"$CI_PROJECT_DIR"/bind9-qa/stress/generate_tsan_stress_jobs.py > tsan-stress-test-configs.yml
artifacts:
paths:
- tsan-stress-test-configs.yml
when: manual
# Jobs in the other-checks stage
checkbashisms:
<<: *other_checks_job
<<: *shell_triggering_rules
script:
- checkbashisms $(find . -path './.git' -prune -o -type f -exec sh -c 'head -n 1 "{}" | grep -qsF "#!/bin/sh"' \; -print)
coccinelle:
<<: *other_checks_job
rules:
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
changes:
- '**/*.c'
- '**/*.h'
- 'cocci/**'
- 'util/check-cocci.sh'
- *rule_mr_manual
- *rule_tag
- *rule_source_other_than_mr
- *rule_private_security_branch
script:
- util/check-cocci.sh
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; exit 1; fi
# Jobs for scan-build builds on Debian 13 "trixie" (amd64)
.scan_build: &scan_build
- ${SCAN_BUILD} --html-title="BIND 9 ($CI_COMMIT_SHORT_SHA)"
--keep-cc
--status-bugs
--keep-going
-o scan-build.reports make -j${BUILD_PARALLEL_JOBS:-1} all V=1
scan-build:
<<: *other_checks_job
variables:
CC: "${CLANG}"
CFLAGS: "${CFLAGS_COMMON}"
CONFIGURE: "${SCAN_BUILD} ./configure"
EXTRA_CONFIGURE: "--with-libidn2"
before_script:
- *list_installed_package_versions
script:
- *configure
- *scan_build
needs:
- job: autoreconf
artifacts: true
artifacts:
paths:
- scan-build.reports/
when: on_failure
# Coverity Scan analysis upload
.coverity_prep: &coverity_prep
- curl --output /tmp/cov-analysis-linux64.md5 https://scan.coverity.com/download/linux64
--form project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN
--form md5=1
- curl --output /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64
--form project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN
- test "$(md5sum /tmp/cov-analysis-linux64.tgz | awk '{ print $1 }')" = "$(cat /tmp/cov-analysis-linux64.md5)"
- tar --extract --gzip --file=/tmp/cov-analysis-linux64.tgz --directory=/tmp
- test -d /tmp/cov-analysis-linux64-*
.coverity_build: &coverity_build
- /tmp/cov-analysis-linux64-*/bin/cov-build --dir /tmp/cov-int sh -c 'make -j${BUILD_PARALLEL_JOBS:-1} -k all V=1'
- tar --create --gzip --file=/tmp/cov-int.tar.gz --directory /tmp cov-int
- curl -v https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN
--form email=bind-changes@isc.org
--form file=@/tmp/cov-int.tar.gz
--form version="$(git rev-parse --short HEAD)"
--form description="$(git rev-parse --short HEAD) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID" 2>&1
| tee curl-response.txt
- grep -q 'Build successfully submitted' curl-response.txt
coverity:
<<: *other_checks_job
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og"
EXTRA_CONFIGURE: "--with-libidn2"
script:
- *coverity_prep
- *configure
- *coverity_build
after_script:
- mv -v /tmp/cov-int.tar.gz ${CI_PROJECT_DIR}/
needs:
- job: autoreconf
artifacts: true
artifacts:
paths:
- curl-response.txt
- cov-int.tar.gz
expire_in: "1 week"
when: on_failure
rules:
- if: '$COVERITY_SCAN_PROJECT_NAME != null && $COVERITY_SCAN_TOKEN != null'
# git fsck operates over the whole repository and is sufficient to schedule it
# only in one branch, preferably "main". GitLab's clone strategy prevents us
# from using the "bind9" repo clone; we need to clone it ourselves.
fsck:
<<: *other_checks_job
variables:
GIT_STRATEGY: none
script:
- git clone https://gitlab.isc.org/isc-projects/bind9.git bind9-full-clone
- cd bind9-full-clone/
- git fsck
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
tarball-create:
<<: *build_job
<<: *base_image
script:
- ./configure --enable-maintainer-mode
- make maintainer-clean
- autoreconf -fi
- ./configure --enable-maintainer-mode
- make -j${BUILD_PARALLEL_JOBS:-1} all V=1
- if test "$(git status --porcelain | grep -Ev '\?\?' | wc -l)" -gt "0"; then git status --short; git diff > diff.patch; exit 1; fi
- make -j${BUILD_PARALLEL_JOBS:-1} dist V=1
artifacts:
paths:
- diff.patch
- bind-*.tar.xz
when: always
needs:
- job: autoreconf
artifacts: true
# Jobs for doc builds on Debian 13 "trixie" (amd64)
changelog:
<<: *base_image
<<: *docs_job
rules:
- if: '$CI_MERGE_REQUEST_TITLE =~ /\s(dev|usr|pkg):/'
variables:
DOC_MAKE_TARGET: html
before_script:
- echo -e "$CI_MERGE_REQUEST_TITLE\n" > commitmsg
- sed -i 's/^Draft:\s*//' commitmsg
- echo -e "$CI_MERGE_REQUEST_DESCRIPTION" >> commitmsg
- git commit --allow-empty -F commitmsg
- export CHANGELOG=$(ls doc/changelog/changelog-9.* | sort --version-sort | tail -n 1)
- printf "\n" >> $CHANGELOG
- ./contrib/gitchangelog/gitchangelog.py HEAD^..HEAD >> $CHANGELOG
after_script:
- git diff
needs:
- job: autoreconf
artifacts: true
artifacts:
untracked: true
docs:
<<: *default_triggering_rules
<<: *base_image
<<: *docs_job
before_script:
- *list_installed_package_versions
needs:
- job: autoreconf
artifacts: true
artifacts:
untracked: true
docs:tarball:
<<: *default_triggering_rules
<<: *base_image
<<: *docs_job
before_script:
- *unpack_release_tarball
needs:
- job: tarball-create
artifacts: true
# Job detecting named.conf breakage introduced since the previous point release
cross-version-config-tests:
stage: system
<<: *base_image
<<: *default_triggering_rules
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
# Disable option checking to prevent problems with new default options in
# the &configure anchor.
EXTRA_CONFIGURE: "--disable-option-checking"
script:
- *configure
- *setup_interfaces
- make -j${BUILD_PARALLEL_JOBS:-1}
- *find_python
- *find_pytest
- git clone --branch "${BIND_BASELINE_VERSION}" --depth 1 https://gitlab.isc.org/isc-projects/bind9.git "bind-${BIND_BASELINE_VERSION}"
- cd "bind-${BIND_BASELINE_VERSION}"
- autoreconf -fi
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1}
# The cross-version-config-tests job would fail when a system test is
# removed from the upcoming release. To avoid this, remove the system test
# also from the $BIND_BASELINE_VERSION.
- find bin/tests/system/ -mindepth 1 -maxdepth 1 -type d -exec sh -c 'test -e ../"$0" || rm -rfv -- "$0"' {} \;
- cd bin/tests/system
# System tests that employ binary drivers will fail on ABI change and
# should not be run.
- rm -r dlzexternal
- rm -r dyndb
# Run the setup phase of all system tests in the most recently tagged BIND 9
# release using the binaries built for the current BIND 9 version. This
# intends to detect obvious backward compatibility issues with the latter.
- sed -i "s|f\"{AC_VARS\['TOP_BUILDDIR'\]}|\"$CI_PROJECT_DIR|g" isctest/vars/basic.py
# This script needs to: 1) fail if the tests fail, 2) fail if
# the junit.xml file is broken, 3) produce the junit.xml file even if
# the tests fail. Therefore, $RET is used to "cache" the
# result of running pytest as interrupting the script immediately when
# system tests fail would make checking the contents of the junit.xml
# file impossible (GitLab Runner uses "set -o pipefail").
- RET=0
- >
"$PYTEST" --setup-only --junit-xml="$CI_PROJECT_DIR"/junit_pytest.xml -n "${TEST_PARALLEL_JOBS:-1}" || RET=1
- *git_clone_bind9-qa
- >
"$PYTHON" "$CI_PROJECT_DIR"/bind9-qa/ci/postprocess_junit_files.py "$CI_PROJECT_DIR"/junit_pytest.xml --output "$CI_PROJECT_DIR"/junit.xml
- (exit $RET)
needs:
- job: autoreconf
artifacts: true
- job: ci-variables
artifacts: true
artifacts:
reports:
junit: junit.xml
paths:
- bind-*
- junit.xml
untracked: true
expire_in: "1 day"
when: always
# Jobs for regular GCC builds on Alpine Linux 3.23 (amd64)
gcc:alpine3.23:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "${WITHOUT_READLINE}"
<<: *alpine_3_23_amd64_image
<<: *build_job
system:gcc:alpine3.23:amd64:
<<: *alpine_3_23_amd64_image
<<: *system_test_job
needs:
- job: gcc:alpine3.23:amd64
artifacts: true
unit:gcc:alpine3.23:amd64:
<<: *alpine_3_23_amd64_image
<<: *unit_test_job
needs:
- job: gcc:alpine3.23:amd64
artifacts: true
# Jobs for regular GCC builds on Alma Linux 8 (amd64)
gcc:almalinux8:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2"
<<: *almalinux_8_amd64_image
<<: *build_job
system:gcc:almalinux8:amd64:
<<: *almalinux_8_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
needs:
- job: gcc:almalinux8:amd64
artifacts: true
unit:gcc:almalinux8:amd64:
<<: *almalinux_8_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:almalinux8:amd64
artifacts: true
# Jobs for regular GCC builds on Alma Linux 9 (amd64)
gcc:almalinux9:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --disable-developer"
<<: *almalinux_9_amd64_image
<<: *build_job
system:gcc:almalinux9:amd64:
<<: *almalinux_9_amd64_image
<<: *system_test_job
needs:
- job: gcc:almalinux9:amd64
artifacts: true
unit:gcc:almalinux9:amd64:
<<: *almalinux_9_amd64_image
<<: *unit_test_job
needs:
- job: gcc:almalinux9:amd64
artifacts: true
# Jobs for regular GCC builds on Alma Linux 10 (amd64)
gcc:almalinux10:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2"
<<: *almalinux_10_amd64_image
<<: *build_job
system:gcc:almalinux10:amd64:
<<: *almalinux_10_amd64_image
<<: *system_test_job
needs:
- job: gcc:almalinux10:amd64
artifacts: true
unit:gcc:almalinux10:amd64:
<<: *almalinux_10_amd64_image
<<: *unit_test_job
needs:
- job: gcc:almalinux10:amd64
artifacts: true
# Jobs for scheduled GCC builds on AlmaLinux 8 & 9 FIPS-aware images with FIPS
# mode in BIND 9 enabled
gcc:8fips:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --enable-fips-mode --disable-tracing"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
<<: *almalinux_8fips_amd64_image
<<: *build_job
system:gcc:8fips:amd64:
<<: *almalinux_8fips_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:8fips:amd64
artifacts: true
unit:gcc:8fips:amd64:
<<: *almalinux_8fips_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:8fips:amd64
artifacts: true
gcc:9fips:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --enable-fips-mode --disable-leak-detection --disable-tracing"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
<<: *almalinux_9fips_amd64_image
<<: *build_job
system:gcc:9fips:amd64:
<<: *almalinux_9fips_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:9fips:amd64
artifacts: true
unit:gcc:9fips:amd64:
<<: *almalinux_9fips_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:9fips:amd64
artifacts: true
gcc:10fips:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --enable-fips-mode --disable-leak-detection --disable-tracing"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
<<: *almalinux_10fips_amd64_image
<<: *build_job
system:gcc:10fips:amd64:
<<: *almalinux_10fips_amd64_image
<<: *system_test_job
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:10fips:amd64
artifacts: true
unit:gcc:10fips:amd64:
<<: *almalinux_10fips_amd64_image
<<: *unit_test_job
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: gcc:10fips:amd64
artifacts: true
gcc:tarball:nosphinx:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --disable-developer"
RUN_MAKE_INSTALL: 1
<<: *almalinux_9_amd64_image
<<: *build_job
before_script:
- *list_installed_package_versions
- (! command -v sphinx-build >/dev/null)
- *unpack_release_tarball
needs:
- job: tarball-create
artifacts: true
# Jobs for regular GCC builds on Debian 12 "bookworm" (amd64)
gcc:bookworm:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -DOPENSSL_API_COMPAT=10100"
# See https://gitlab.isc.org/isc-projects/bind9/-/issues/3444
EXTRA_CONFIGURE: "--without-jemalloc --disable-leak-detection"
<<: *debian_bookworm_amd64_image
<<: *build_job
system:gcc:bookworm:amd64:
<<: *debian_bookworm_amd64_image
<<: *system_test_job
# Set up environment variables that allow the "keyfromlabel" system test to be run
variables:
OPENSSL_CONF: "/var/tmp/etc/openssl.cnf"
SOFTHSM2_CONF: "/var/tmp/softhsm2/softhsm2.conf"
needs:
- job: gcc:bookworm:amd64
artifacts: true
unit:gcc:bookworm:amd64:
<<: *debian_bookworm_amd64_image
<<: *unit_test_job
needs:
- job: gcc:bookworm:amd64
artifacts: true
# Jobs for RBT zone- & cache-enabled GCC builds on Debian 13 "trixie" (amd64)
gcc:trixie:rbt:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2 --with-zonedb=rbt --with-cachedb=rbt"
<<: *debian_trixie_amd64_image
<<: *build_job
system:gcc:trixie:rbt:amd64:
<<: *debian_trixie_amd64_image
<<: *system_test_job
needs:
- job: gcc:trixie:rbt:amd64
artifacts: true
unit:gcc:trixie:rbt:amd64:
<<: *debian_trixie_amd64_image
<<: *unit_test_job
needs:
- job: gcc:trixie:rbt:amd64
artifacts: true
# Jobs for regular GCC builds on Debian 13 "trixie" (amd64)
gcc:trixie:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} --coverage -O0"
# Tracing needs to be disabled otherwise gcovr fails
EXTRA_CONFIGURE: "--with-libidn2 ${WITH_READLINE_LIBEDIT} --disable-tracing"
RUN_MAKE_INSTALL: 1
<<: *debian_trixie_amd64_image
<<: *build_job
system:gcc:trixie:amd64:
<<: *debian_trixie_amd64_image
<<: *system_test_job
variables:
CI_ENABLE_LONG_TESTS: 1
CLEAN_BUILD_ARTIFACTS_ON_SUCCESS: 0
TZ: Australia/Sydney
# using artifacts from unit test job is required for gcov
needs:
- job: unit:gcc:trixie:amd64
artifacts: true
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
CI_ENABLE_LIVE_INTERNET_TESTS: 1
- *default_triggering_rules_list
unit:gcc:trixie:amd64:
<<: *debian_trixie_amd64_image
<<: *unit_test_job
variables:
CI_ENABLE_LONG_TESTS: 1
CLEAN_BUILD_ARTIFACTS_ON_SUCCESS: 0
needs:
- job: gcc:trixie:amd64
artifacts: true
# Build job for cross-compiled GCC builds on 64-bit Debian 13 "trixie"
# (amd64) with 32-bit BIND 9.
gcc:trixie:amd64cross32:
variables:
CFLAGS: "${CFLAGS_COMMON}"
CROSS_COMPILATION: 1
EXTRA_CONFIGURE: "--build=x86_64-linux-gnu --host=i686-linux-gnu --with-libidn2 ${WITH_READLINE_LIBEDIT}"
<<: *debian_trixie_amd64cross32_image
<<: *build_job
# Jobs for strict OpenSSL 3.x (no deprecated) GCC builds on Debian "trixie" (amd64)
# Run with pkcs11-provider tests
gcc:ossl3:trixie:amd64:
<<: *debian_trixie_amd64_image
<<: *build_job
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -O3 -DOPENSSL_NO_DEPRECATED=1 -DOPENSSL_API_COMPAT=30000"
# See https://gitlab.isc.org/isc-projects/bind9/-/issues/3444
EXTRA_CONFIGURE: "--without-jemalloc --disable-leak-detection"
GNUMAKEFLAGS: "--shuffle=reverse"
RUN_MAKE_INSTALL: 1
system:gcc:ossl3:trixie:amd64:
# Set up environment variables to run pkcs11-provider based system tests
variables:
OPENSSL_CONF: "/var/tmp/etc/openssl-provider.cnf"
SOFTHSM2_CONF: "/var/tmp/softhsm2/softhsm2.conf"
<<: *debian_trixie_amd64_image
<<: *system_test_job
needs:
- job: gcc:ossl3:trixie:amd64
artifacts: true
unit:gcc:ossl3:amd64:
<<: *debian_trixie_amd64_image
<<: *unit_test_job
needs:
- job: gcc:ossl3:trixie:amd64
artifacts: true
# Jobs for regular GCC builds on Debian "sid" (amd64)
# Also tests configration option: --without-lmdb.
gcc:sid:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -O3"
EXTRA_CONFIGURE: "--with-libidn2 --without-lmdb ${WITH_READLINE}"
<<: *debian_sid_amd64_image
<<: *build_job
system:gcc:sid:amd64:
<<: *debian_sid_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
needs:
- job: gcc:sid:amd64
artifacts: true
unit:gcc:sid:amd64:
<<: *debian_sid_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:sid:amd64
artifacts: true
# Job for out-of-tree GCC build on Debian 13 "trixie" (amd64)
# Also tests configration option: --with-lmdb.
gcc:out-of-tree:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og"
CONFIGURE: "${CI_PROJECT_DIR}/configure"
EXTRA_CONFIGURE: "--with-libidn2 --with-lmdb"
RUN_MAKE_INSTALL: 1
OUT_OF_TREE_WORKSPACE: workspace
<<: *base_image
<<: *build_job
system:gcc:out-of-tree:
variables:
OUT_OF_TREE_WORKSPACE: workspace
needs:
- job: gcc:out-of-tree
artifacts: true
<<: *base_image
<<: *system_test_job
unit:gcc:out-of-tree:
variables:
OUT_OF_TREE_WORKSPACE: workspace
needs:
- job: gcc:out-of-tree
artifacts: true
<<: *base_image
<<: *unit_test_job
# Jobs for tarball GCC builds on Debian 13 "trixie" (amd64)
gcc:tarball:
variables:
CC: gcc
EXTRA_CONFIGURE: "--with-libidn2"
RUN_MAKE_INSTALL: 1
<<: *base_image
<<: *build_job
before_script:
- *list_installed_package_versions
- *unpack_release_tarball
needs:
- job: tarball-create
artifacts: true
system:gcc:tarball:
<<: *base_image
<<: *system_test_job
before_script:
- cd bind-*
- *setup_interfaces
after_script:
- cd bind-*
- *display_pytest_failures
needs:
- job: gcc:tarball
artifacts: true
unit:gcc:tarball:
<<: *base_image
<<: *unit_test_job
before_script:
- cd bind-*
needs:
- job: gcc:tarball
artifacts: true
# Jobs for debug GCC builds on openSUSE Tumbleweed (amd64)
gcc:tumbleweed:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -DDEBUG"
# NOTE: Testing DNSRPS-enabled builds currently requires an
# operating system with glibc 2.34+. This requirement will go away
# once the DNSRPS dynamic loading code gets reworked to use libuv's
# dlopen() API.
#
# NOTE: This does *not* enable testing of the DNSRPS feature itself.
# Doing that requires a DNSRPS provider library to be present on the
# test host.
EXTRA_CONFIGURE: "--enable-dnsrps --enable-dnsrps-dl --with-libidn2 --without-gssapi ${WITH_READLINE_READLINE}"
GNUMAKEFLAGS: "--shuffle=random"
<<: *tumbleweed_latest_amd64_image
<<: *build_job
system:gcc:tumbleweed:amd64:
<<: *tumbleweed_latest_amd64_image
<<: *system_test_make_check_job
needs:
- job: gcc:tumbleweed:amd64
artifacts: true
unit:gcc:tumbleweed:amd64:
<<: *tumbleweed_latest_amd64_image
<<: *unit_test_job
needs:
- job: gcc:tumbleweed:amd64
artifacts: true
# Jobs for regular GCC builds on Ubuntu 22.04 Jammy Jellyfish (amd64)
gcc:jammy:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--disable-geoip --with-libidn2 --disable-doh --disable-dnstap --without-cmocka --without-gssapi"
<<: *ubuntu_jammy_amd64_image
<<: *build_job
system:gcc:jammy:amd64:
<<: *ubuntu_jammy_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
needs:
- job: gcc:jammy:amd64
artifacts: true
unit:gcc:jammy:amd64:
<<: *ubuntu_jammy_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:jammy:amd64
artifacts: true
# Jobs for regular GCC builds on Ubuntu 24.04 Noble Numbat (amd64)
gcc:noble:amd64:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "--with-libidn2"
<<: *ubuntu_noble_amd64_image
<<: *build_job
system:gcc:noble:amd64:
<<: *ubuntu_noble_amd64_image
<<: *system_test_job
needs:
- job: gcc:noble:amd64
artifacts: true
unit:gcc:noble:amd64:
<<: *ubuntu_noble_amd64_image
<<: *unit_test_job
needs:
- job: gcc:noble:amd64
artifacts: true
# Jobs for ASAN builds on Fedora 43 (amd64)
gcc:asan:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -fsanitize=address,undefined"
LDFLAGS: "-fsanitize=address,undefined"
EXTRA_CONFIGURE: "--with-libidn2 --without-jemalloc"
<<: *fedora_43_amd64_image
<<: *build_job
system:gcc:asan:
variables:
LSAN_OPTIONS: "suppressions=$CI_PROJECT_DIR/suppr-lsan.txt"
<<: *fedora_43_amd64_image
<<: *system_test_job
needs:
- job: gcc:asan
artifacts: true
unit:gcc:asan:
<<: *fedora_43_amd64_image
<<: *unit_test_job
needs:
- job: gcc:asan
artifacts: true
clang:asan:
variables:
CC: ${CLANG}
CFLAGS: "${CFLAGS_COMMON} -fsanitize=address,undefined"
LDFLAGS: "-fsanitize=address,undefined"
EXTRA_CONFIGURE: "--with-libidn2 --without-jemalloc"
<<: *base_image
<<: *build_job
system:clang:asan:
<<: *base_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
needs:
- job: clang:asan
artifacts: true
unit:clang:asan:
<<: *base_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: clang:asan
artifacts: true
# Jobs for TSAN builds on Fedora 43 (amd64)
gcc:tsan:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Wno-stringop-overread -ggdb -O2 -fsanitize=thread"
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
<<: *tsan_fedora_43_amd64_image
<<: *build_job
system:gcc:tsan:
variables:
TSAN_OPTIONS: "${TSAN_OPTIONS_FEDORA}"
<<: *tsan_fedora_43_amd64_image
<<: *system_test_tsan_job
<<: *extra_system_tests_triggering_rules
needs:
- job: gcc:tsan
artifacts: true
unit:gcc:tsan:
variables:
TSAN_OPTIONS: "${TSAN_OPTIONS_FEDORA}"
<<: *tsan_fedora_43_amd64_image
<<: *unit_test_tsan_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: gcc:tsan
artifacts: true
clang:tsan:
<<: *tsan_debian_trixie_amd64_image
<<: *build_job
variables:
CC: "${CLANG}"
CFLAGS: "${CFLAGS_COMMON} -ggdb -O2 -fsanitize=thread"
# -Wl,--disable-new-dtags ensures that Clang creates valid TSAN reports
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
system:clang:tsan:
variables:
TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}"
<<: *tsan_debian_trixie_amd64_image
<<: *system_test_tsan_job
needs:
- job: clang:tsan
artifacts: true
unit:clang:tsan:
variables:
TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}"
<<: *tsan_debian_trixie_amd64_image
<<: *unit_test_tsan_job
needs:
- job: clang:tsan
artifacts: true
tsan:stress:
<<: *default_triggering_rules
stage: system
variables:
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
trigger:
include:
- artifact: tsan-stress-test-configs.yml
job: generate-tsan-stress-test-configs
needs:
- job: generate-tsan-stress-test-configs
artifacts: true
- job: gcc:tsan
artifacts: true
- job: clang:tsan
artifacts: true
# Jobs for Clang builds on Debian 13 "trixie" (amd64)
clang:trixie:amd64:
variables:
CC: ${CLANG}
CFLAGS: "${CFLAGS_COMMON}"
RUN_MAKE_INSTALL: 1
<<: *debian_trixie_amd64_image
<<: *build_job
system:clang:trixie:amd64:
<<: *debian_trixie_amd64_image
<<: *system_test_job
<<: *extra_system_tests_triggering_rules
needs:
- job: clang:trixie:amd64
artifacts: true
unit:clang:trixie:amd64:
<<: *debian_trixie_amd64_image
<<: *unit_test_job
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
needs:
- job: clang:trixie:amd64
artifacts: true
# Jobs for Clang builds on FreeBSD 13 (amd64)
clang:freebsd13:amd64:
variables:
CC: clang
CFLAGS: "${CFLAGS_COMMON} -Og"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config"
<<: *build_job
<<: *freebsd_autoscaler_13_amd64_tags
system:clang:freebsd13:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd13:amd64
artifacts: true
<<: *system_test_job
<<: *freebsd_autoscaler_13_amd64_tags
<<: *extra_system_tests_triggering_rules
unit:clang:freebsd13:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd13:amd64
artifacts: true
<<: *unit_test_job
<<: *freebsd_autoscaler_13_amd64_tags
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
# Jobs for Clang builds on FreeBSD 14 (amd64)
clang:freebsd14:amd64:
variables:
CC: clang
CFLAGS: "${CFLAGS_COMMON} -Og"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config"
<<: *build_job
<<: *freebsd_autoscaler_14_amd64_tags
system:clang:freebsd14:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd14:amd64
artifacts: true
<<: *system_test_job
<<: *freebsd_autoscaler_14_amd64_tags
unit:clang:freebsd14:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd14:amd64
artifacts: true
retry: 1 # GL #4924
<<: *unit_test_job
<<: *freebsd_autoscaler_14_amd64_tags
# Jobs for Clang builds on FreeBSD 15 (amd64)
clang:freebsd15:amd64:
variables:
CC: clang
CFLAGS: "${CFLAGS_COMMON} -Og"
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
#
# The "doh" unit test permanently fails on FreeBSD 15; see #5448.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config --disable-doh"
<<: *build_job
<<: *freebsd_autoscaler_15_amd64_tags
system:clang:freebsd15:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd15:amd64
artifacts: true
<<: *system_test_job
<<: *freebsd_autoscaler_15_amd64_tags
unit:clang:freebsd15:amd64:
variables:
GIT_CLONE_PATH: "${GIT_CLONE_PATH_INSTANCE_EXECUTOR}"
needs:
- job: clang:freebsd15:amd64
artifacts: true
<<: *unit_test_job
<<: *freebsd_autoscaler_15_amd64_tags
# Build and run tests against the latest git version of libuv
gcc:tumbleweed:libuv-git:amd64:
<<: *tumbleweed_latest_amd64_image
<<: *build_job
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -DDEBUG"
EXTRA_CONFIGURE: "--with-libidn2 ${WITH_LIBEDIT}"
before_script:
- *list_installed_package_versions
- zypper --non-interactive rm --clean-deps libuv-devel
- git clone --depth 1 https://github.com/libuv/libuv.git /tmp/libuv
- cd /tmp/libuv
- sh autogen.sh
- ./configure --prefix="$CI_PROJECT_DIR/libuv"
- make -j"$BUILD_PARALLEL_JOBS" CFLAGS=""
- make install
- cd "$CI_PROJECT_DIR"
- export PKG_CONFIG_PATH="$CI_PROJECT_DIR/libuv/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
rules:
- *rule_source_other_than_mr
system:gcc:tumbleweed:libuv-git:amd64:
<<: *tumbleweed_latest_amd64_image
<<: *system_test_job
needs:
- job: gcc:tumbleweed:libuv-git:amd64
artifacts: true
rules:
- *rule_source_other_than_mr
unit:gcc:tumbleweed:libuv-git:amd64:
<<: *tumbleweed_latest_amd64_image
<<: *unit_test_job
before_script:
- bin/named/named -V > named.version
- "grep -E '^compiled with libuv version: [0-9]+\\.[0-9]+\\.[0-9]+$' named.version"
- "grep -E '^linked to libuv version: [0-9]+\\.[0-9]+\\.[0-9]+-dev$' named.version"
needs:
- job: gcc:tumbleweed:libuv-git:amd64
artifacts: true
rules:
- *rule_source_other_than_mr
# Job producing a release directory
release:
<<: *base_image
stage: release
script:
- export RELEASE_DIRECTORY="bind-${CI_COMMIT_TAG}-release"
- export BIND_VERSION="bind-${CI_COMMIT_TAG#v}"
# Prepare release tarball contents (tarballs + documentation)
- mkdir -p "${RELEASE_DIRECTORY}/doc/arm"
- pushd "${RELEASE_DIRECTORY}"
- mv "../${BIND_VERSION}.tar.xz" .
- tar --extract --file="${BIND_VERSION}.tar.xz" --strip-components=1 "${BIND_VERSION}"/{COPYRIGHT,LICENSE,README.md,srcid}
- mv "../doc/arm/_build/html" doc/arm/
- mv "../doc/arm/_build/epub/Bv9ARM.epub" doc/arm/
- echo '<!DOCTYPE HTML><html lang="en"><meta http-equiv="refresh" content="0; url=doc/arm/html/notes.html"><title>Redirect</title></html>' > "RELEASE-NOTES-${BIND_VERSION}.html"
- echo '<!DOCTYPE HTML><html lang="en"><meta http-equiv="refresh" content="0; url=doc/arm/html/changelog.html"><title>Redirect</title></html>' > "CHANGELOG-${BIND_VERSION}.html"
- popd
needs:
- job: tarball-create
artifacts: true
- job: docs
artifacts: true
tags:
- smalljob
rules:
- *rule_tag
artifacts:
paths:
- bind-${CI_COMMIT_TAG}-release
expire_in: "1 month"
.manual_release_job: &manual_release_job
stage: release
when: manual
.signer-ssh-job: &signer_ssh_job
<<: *manual_release_job
allow_failure: false
tags:
- signer
script:
- ( rm -f "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" && umask 111 && touch "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" )
- |
cat > "/tmp/${CI_JOB_NAME}.sh" <<EOF
#!/bin/sh
set -e -x
{
${SSH_SCRIPT_CLIENT}
echo "${CI_COMMIT_TAG}" > "/tmp/${CI_JOB_NAME}-done"
} 2>&1 | tee "/tmp/${CI_JOB_NAME}.log"
EOF
- chmod +x "/tmp/${CI_JOB_NAME}.sh"
- /bin/sh -c "set -e -x; ${SSH_SCRIPT_RUNNER_PRE}"
- echo -e "\e[31m*** Sleeping until /tmp/${CI_JOB_NAME}.sh is executed over SSH... ⌛\e[0m"
- while [ "$(cat "/tmp/${CI_JOB_NAME}-done")" != "${CI_COMMIT_TAG}" ]; do sleep 10; done
- /bin/sh -c "set -e -x; ${SSH_SCRIPT_RUNNER_POST}"
- cp "/tmp/${CI_JOB_NAME}.log" "${CI_PROJECT_DIR}/${CI_JOB_NAME}-${CI_COMMIT_TAG}.log"
- rm -f "/tmp/${CI_JOB_NAME}.log" "/tmp/${CI_JOB_NAME}-done" "/tmp/${CI_JOB_NAME}.sh"
# Job signing the source tarballs in the release directory
sign:
<<: *signer_ssh_job
before_script:
- export SOURCE_TARBALL="bind-${CI_COMMIT_TAG#v}.tar.xz"
variables:
RELEASE_DIRECTORY: bind-${CI_COMMIT_TAG}-release
SSH_SCRIPT_RUNNER_PRE: |-
( umask 111 && cat "${RELEASE_DIRECTORY}/$${SOURCE_TARBALL}" > "/tmp/${CI_COMMIT_TAG}.bin" )
SSH_SCRIPT_CLIENT: |-
gpg2 --local-user "$${SIGNING_KEY_FINGERPRINT}" --armor --digest-algo SHA512 --detach-sign --output "/tmp/${CI_COMMIT_TAG}.asc" "/tmp/${CI_COMMIT_TAG}.bin"
SSH_SCRIPT_RUNNER_POST: |-
cat "/tmp/${CI_COMMIT_TAG}.asc" > "${RELEASE_DIRECTORY}/$${SOURCE_TARBALL}.asc"
tar --create --file="${RELEASE_DIRECTORY}".tar.gz --gzip "${RELEASE_DIRECTORY}"
rm -f "/tmp/${CI_COMMIT_TAG}.bin" "/tmp/${CI_COMMIT_TAG}.asc"
artifacts:
paths:
- bind-${CI_COMMIT_TAG}-release.tar.gz
- sign-${CI_COMMIT_TAG}.log
expire_in: never
needs:
- job: release
artifacts: true
rules:
- *rule_tag
# Job staging the signed tarballs
staging:
<<: *signer_ssh_job
variables:
RELEASE_TARBALL: bind-${CI_COMMIT_TAG}-release.tar.gz
SSH_SCRIPT_RUNNER_PRE: |-
mv "${RELEASE_TARBALL}" "/tmp/${RELEASE_TARBALL}"
SSH_SCRIPT_CLIENT: |-
scp "/tmp/${RELEASE_TARBALL}" "${STAGING_USER_UPLOAD}@${STAGING_HOST}:${STAGING_DIR}"
ssh "${STAGING_USER_ACTIONS}@${STAGING_HOST}" "unpack ${CI_COMMIT_TAG}"
SSH_SCRIPT_RUNNER_POST: |-
rm -f "/tmp/${RELEASE_TARBALL}"
artifacts:
paths:
- staging-${CI_COMMIT_TAG}.log
expire_in: "1 month"
needs:
- job: sign
artifacts: true
rules:
- *rule_tag
# Job copying a staged release to a secret location
publish-private:
<<: *signer_ssh_job
variables:
SSH_SCRIPT_CLIENT: |-
ssh "${STAGING_USER_ACTIONS}@${STAGING_HOST}" "publish-private ${CI_COMMIT_TAG}"
SSH_SCRIPT_RUNNER_POST: |-
awk '/^Public Use URL:/ {print $$NF}' "/tmp/${CI_JOB_NAME}.log" > "url-${CI_COMMIT_TAG}.txt"
artifacts:
paths:
- publish-private-${CI_COMMIT_TAG}.log
- url-${CI_COMMIT_TAG}.txt
expire_in: "1 month"
needs:
- job: staging
artifacts: false
rules:
- *rule_tag_security_or_subscription
# Job copying a staged release to a well-known location
publish:
<<: *signer_ssh_job
before_script:
- TODAY="$(date +%Y-%m-%d)"
- SCHEDULED_PUBLICATION="$(curl -m 5 -s "https://gitlab.isc.org/isc-projects/bind9-qa/-/raw/main/releng/metadata.json" | jq -r ".schedule.public")"
- if [ -z "${FORCE_PUBLICATION}" ] && [ "${TODAY}" != "${SCHEDULED_PUBLICATION}" ]; then echo "Unscheduled publication denied; publication is scheduled for ${SCHEDULED_PUBLICATION}"; exit 1; fi
variables:
SSH_SCRIPT_CLIENT: |-
ssh "${STAGING_USER_ACTIONS}@${STAGING_HOST}" "publish ${CI_COMMIT_TAG}"
artifacts:
paths:
- publish-${CI_COMMIT_TAG}.log
expire_in: "1 month"
needs:
- job: staging
artifacts: false
rules:
- *rule_tag_open_source
publish-cleanup:
<<: *base_image
stage: release
script:
- *git_clone_bind9-qa
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/manage_distros_token.py delete
needs:
- job: publish
artifacts: false
tags:
- smalljob
rules:
- *rule_tag_security
.manual_release_job_qa: &manual_release_job_qa
<<: *manual_release_job
<<: *base_image
before_script:
- *git_clone_bind9-qa
needs:
- job: staging
artifacts: false
tags:
- smalljob
# Job assigning issues and merge requests to version milestones
assign-milestones:
<<: *manual_release_job_qa
needs:
- job: sign
artifacts: false
script:
- |
"${CI_PROJECT_DIR}"/bind9-qa/releng/assign_mrs_to_versioned_milestones.py --version "${CI_COMMIT_TAG}" --metadata "${CI_PROJECT_DIR}"/bind9-qa/releng/metadata.json
rules:
- *rule_tag
# Jobs to update RPMs
.rpm-build-job: &rpm_build_job
<<: *manual_release_job_qa
needs:
- job: publish
artifacts: false
script:
- >
"${CI_PROJECT_DIR}"/bind9-qa/releng/update_rpms.py build --service "${SERVICE}" --version "${CI_COMMIT_TAG}"
.rpm-build-job-private: &rpm_build_job_private
<<: *manual_release_job_qa
needs:
- job: publish-private
artifacts: true
script:
- >
"${CI_PROJECT_DIR}"/bind9-qa/releng/update_rpms.py build --service "${SERVICE}" --version "${CI_COMMIT_TAG}" --base-url "$(cat "url-${CI_COMMIT_TAG}.txt")"
.rpm-publish-job: &rpm_publish_job
<<: *manual_release_job_qa
script:
- >
"${CI_PROJECT_DIR}"/bind9-qa/releng/update_rpms.py publish --service "${SERVICE}" --commit "$(cat "commit.txt")"
# Update Cloudsmith packages
rpms-cloudsmith-build:
<<: *rpm_build_job
variables:
SERVICE: cloudsmith
rules:
- *rule_tag_open_source_maintenance
artifacts:
paths:
- commit.txt
expire_in: "1 month"
rpms-cloudsmith-build-private:
<<: *rpm_build_job_private
variables:
SERVICE: cloudsmith
rules:
- *rule_tag_security_or_subscription
artifacts:
paths:
- commit.txt
expire_in: "1 month"
# Publish Cloudsmith packages
rpms-cloudsmith-publish:
<<: *rpm_publish_job
variables:
SERVICE: cloudsmith
needs:
- job: rpms-cloudsmith-build
artifacts: true
rules:
- *rule_tag_open_source_maintenance
rpms-cloudsmith-publish-private:
<<: *rpm_publish_job
variables:
SERVICE: cloudsmith
needs:
- job: rpms-cloudsmith-build-private
artifacts: true
rules:
- *rule_tag_security_or_subscription
# Update Copr packages
rpms-copr:
<<: *rpm_build_job
variables:
SERVICE: copr
rules:
- *rule_tag_open_source
# Setting the FORCE_CVE_IDS environment variable to a comma-separated
# list of CVE IDs enables overriding the autodetected ones.
#
# Setting the FORCE_SECURITY_RELEASES environment variable to a
# comma-separated list of BIND 9 versions enables overriding the
# autodetected ones.
.printing_press_job: &printing_press_job
<<: *manual_release_job_qa
variables:
GIT_DEPTH: 1
script:
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/printing_press_mr.py --document "${DOCUMENT}" --metadata "$CI_PROJECT_DIR"/bind9-qa/releng/metadata.json ${FORCE_CVE_IDS:+--force-cve-ids ${FORCE_CVE_IDS}} ${FORCE_SECURITY_RELEASES:+--force-security-releases ${FORCE_SECURITY_RELEASES}}
artifacts:
paths:
- printing-press/
when: on_failure
# Job updating the Docker image for a specific release
update-docker-image:
<<: *base_image
<<: *manual_release_job
variables:
RELEASE_DIRECTORY: "bind-${CI_COMMIT_TAG}-release"
script:
- VERSION="${CI_COMMIT_TAG#v}"
- CHECKSUM="$(sha256sum "${RELEASE_DIRECTORY}/bind-${VERSION}.tar.xz" | awk '{print $1}')"
- BRANCH="${CI_COMMIT_TAG%.*}"
- DOCKER_PROJECT="https://gitlab.isc.org/isc-projects/bind9-docker"
- CLONE_URL="https://oauth2:${BIND_TEAM_WRITE_TOKEN}@${DOCKER_PROJECT#https://}"
- git clone --depth 1 --branch "${BRANCH}" "${CLONE_URL}" docker-project
- cd docker-project
- sed -E -i Dockerfile -e "s/^(ARG BIND9_VERSION=).*/\1${VERSION}/"
- sed -E -i Dockerfile -e "s/^(ARG BIND9_CHECKSUM=).*/\1${CHECKSUM}/"
- git commit -m "Version bump to ${VERSION}" Dockerfile
- git push
- COMMIT_SHA="$(git log -n1 --format=%H)"
- MSG="Docker image for BIND ${BRANCH} updated to version ${CI_COMMIT_TAG}, commit [${COMMIT_SHA}](${DOCKER_PROJECT}/-/commit/${COMMIT_SHA})"
- |
curl -s -o /dev/null -X POST -H "Content-Type: application/json" -d '{"channel": "packaging", "text": "'"${MSG}"'"}' "${MATTERMOST_WEBHOOK_URL}"
needs:
- job: release
artifacts: true
- job: publish
artifacts: false
rules:
- *rule_tag_open_source
tags:
- smalljob
# Job creating the release announcement MR in Printing Press
prepare-release-announcement:
<<: *printing_press_job
variables:
DOCUMENT: release-announcement
rules:
- *rule_tag_open_source
after_script:
- if [ "${CI_JOB_STATUS}" = "success" ]; then "$CI_PROJECT_DIR"/bind9-qa/releng/send_release_links.py --metadata "$CI_PROJECT_DIR"/bind9-qa/releng/metadata.json --message-mattermost; fi
# Job preparing an EVN MR in Printing Press
prepare-evn:
<<: *printing_press_job
variables:
DOCUMENT: evn
rules:
- *rule_tag_security
# Job preparing a security pre-announcement MR in Printing Press
prepare-preannouncement:
<<: *printing_press_job
variables:
DOCUMENT: security-preannouncement
rules:
- *rule_tag_security
# Job preparing a packager notification MR in Printing Press
prepare-packager-notification:
<<: *printing_press_job
before_script:
- *git_clone_bind9-qa
# produce distros_git_url.txt to be immediately read by printing_press_mr.py
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/manage_distros_token.py create
variables:
DOCUMENT: packager-notification
rules:
- *rule_tag_security
# Job preparing a post-disclosure notification MR in Printing Press
prepare-post-disclosure-notification:
<<: *printing_press_job
variables:
DOCUMENT: post-disclosure-notification
rules:
- *rule_tag_security
# Job merging the tag back into its base branch
merge-tag:
<<: *manual_release_job_qa
variables:
GIT_DEPTH: 100
needs:
# TODO: if necessary, update job name after pushing tags from within CI is implemented
- job: publish
artifacts: false
script:
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/merge_tag.py --tag "$CI_COMMIT_TAG"
rules:
- *rule_tag_open_source
artifacts:
paths:
- bind9/
when: on_failure
update-stable-tag:
<<: *manual_release_job_qa
variables:
GIT_DEPTH: 1
needs:
# TODO: if necessary, update job name after pushing tags from within CI is implemented
- job: publish
artifacts: false
script:
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/update_stable_tag.py --tag "$CI_COMMIT_TAG"
# Work around https://github.com/readthedocs/readthedocs.org/issues/10838
- sleep 300
- rm -rf ./bind9 # remove already cloned project
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/update_stable_tag.py --tag "$CI_COMMIT_TAG"
rules:
- *rule_tag_open_source
artifacts:
paths:
- bind9/
when: on_failure
.customer-git: &customer_git
<<: *base_image
stage: release
when: manual
variables: # ensure clean git environment and sufficient history
GIT_STRATEGY: clone
GIT_DEPTH: 1000
# To trigger this job and push a branch to a customer, you must set the
# CUSTOMER job variable by clicking on the manual job (not the play button) and
# set it to the name of the target customer.
customer-git:branch:
<<: *customer_git
needs: []
rules:
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE == "merge_request_event"'
variables:
BRANCH: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE =~ /^(api|pipeline|trigger|web)$/ && $REBASE_ONLY != "1"'
variables:
BRANCH: '$CI_COMMIT_BRANCH'
before_script:
- test -n "$CUSTOMER"
- *git_clone_bind9-qa
script:
- git checkout -b "$BRANCH" # ensure refs/heads/$BRANCH exists; GitLab clones with detached HEAD
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/push_to_customer_repository.py --branch "$BRANCH" --customer "$CUSTOMER" --force
customer-git:tag:
<<: *customer_git
needs:
- job: release
artifacts: false
rules:
- *rule_tag
before_script:
- *git_clone_bind9-qa
- git clone --depth 1 "https://token:${ISC_CUSTOMERS_WRITE_TOKEN}@gitlab.isc.org/isc-customers/isc-customer-settings.git"
script:
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/push_to_customer_repository.py --tag "$CI_COMMIT_TAG" --entitlements isc-customer-settings/entitlements.yaml --force
# Respdiff tests
respdiff:
<<: *respdiff_job
<<: *base_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -DISC_TRACK_PTHREADS_OBJECTS"
MAX_DISAGREEMENTS_PERCENTAGE: "0.3"
script:
- bash respdiff.sh -m /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
- cd ../.. && make clean >/dev/null 2>&1
respdiff:asan:
<<: *respdiff_job
<<: *base_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -fsanitize=address,undefined"
LDFLAGS: "-fsanitize=address,undefined"
EXTRA_CONFIGURE: "--disable-dnsrps --without-jemalloc"
MAX_DISAGREEMENTS_PERCENTAGE: "0.3"
script:
- bash respdiff.sh -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
- cd ../.. && make clean >/dev/null 2>&1
respdiff:tsan:
<<: *respdiff_job
<<: *tsan_debian_trixie_amd64_image
variables:
CC: "${CLANG}"
CFLAGS: "${CFLAGS_COMMON} -ggdb -O2 -fsanitize=thread"
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--disable-dnsrps --enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
MAX_DISAGREEMENTS_PERCENTAGE: "0.3"
TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}"
script:
- bash respdiff.sh -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "/usr/local/respdiff-reference-bind/sbin/named"
- cd ../.. && make clean >/dev/null 2>&1
after_script:
- *parse_tsan
respdiff-third-party:
<<: *respdiff_job
<<: *base_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og"
MAX_DISAGREEMENTS_PERCENTAGE: "0.4"
script:
- bash respdiff.sh -s third_party -q "${PWD}/100k_mixed.txt" -c 1 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}"
- cd ../.. && make clean >/dev/null 2>&1
.respdiff-recent-named: &respdiff_recent_named
<<: *respdiff_job
<<: *base_image
needs:
- job: ci-variables
artifacts: true
script:
- cd ${CI_PROJECT_DIR}
- BASELINE=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-$BIND_BASELINE_VERSION}
- git fetch --unshallow origin ${BASELINE}
- git worktree add baseline-build FETCH_HEAD
- cd baseline-build
- autoreconf -fi
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} V=1
- cd "$CI_PROJECT_DIR"/bind9-qa/respdiff
- bash respdiff.sh -s named -q "${PWD}/100k_mixed.txt" -c 3 -w "${PWD}/rspworkdir" "${CI_PROJECT_DIR}" "${CI_PROJECT_DIR}/baseline-build/bin/named/named"
respdiff:recent-named:
<<: *respdiff_recent_named
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -DISC_TRACK_PTHREADS_OBJECTS"
MAX_DISAGREEMENTS_PERCENTAGE: "0.1"
# Performance tests
shotgun:udp:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: udp
SHOTGUN_TRAFFIC_MULTIPLIER: 15
shotgun:tcp:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: tcp
SHOTGUN_TRAFFIC_MULTIPLIER: 12
shotgun:dot:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: dot
SHOTGUN_TRAFFIC_MULTIPLIER: 5
shotgun:doh-get:
<<: *shotgun_job
variables:
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
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
- *rule_tag
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/ && $REBASE_ONLY != "1"'
- *rule_private_security_branch
trigger:
include:
- artifact: stress-test-configs.yml
job: generate-stress-test-configs
needs:
- job: generate-stress-test-configs
artifacts: true
gcov:
<<: *default_triggering_rules
<<: *base_image
stage: system
needs:
- job: system:gcc:trixie:amd64
artifacts: true
script:
# Ensure gcov files for unit tests are found via tests/ rather than
# lib/*/tests/ to prevent confusing gcovr.
- find lib/ -name tests -type l -delete
# The "a-conftest.gcno" file is result of the ./configure step and
# should be removed as it does not belong to the BIND 9 code base.
- rm a-conftest.gcno
# Generate XML file in the Cobertura XML format suitable for use by GitLab
# for the purpose of displaying code coverage information in the diff view
# of a given merge request.
- gcovr --exclude-directories bin/tests --exclude-directories doc --exclude-directories fuzz --exclude tests --cobertura-pretty -o coverage.xml
- gcovr --exclude-directories bin/tests --exclude-directories doc --exclude-directories fuzz --exclude tests --html-details -o coverage.html
- gcovr --exclude-directories bin/tests --exclude-directories doc --exclude-directories fuzz --exclude tests --txt -o coverage.txt
- tail -n 3 coverage.txt
coverage: /^TOTAL.*\s+(\d+\%)$/
artifacts:
paths:
- coverage*.html
- coverage.css
- coverage.txt
- coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
# Pairwise testing of ./configure options
pairwise:
<<: *base_image
stage: build
needs:
- job: autoreconf
artifacts: true
script:
- util/pairwise-testing.sh
artifacts:
paths:
- pairwise-commands.txt
- pairwise-model.txt
- pairwise-output.*.txt
when: on_failure
rules:
- if: '$PAIRWISE_TESTING != null'
.post_merge_template: &post_merge
<<: *base_image
stage: postmerge
needs: []
tags:
- smalljob
# post-merge processes should run even if another MR was merged while the job was running (or queued)
interruptible: false
variables:
# avoid leftover branches from previous jobs
GIT_STRATEGY: clone
# assumed max depth of a MR for backport or a rebased force-push
GIT_DEPTH: 1000
before_script:
# force-pushes should not trigger process automation (happens only in -sub branches)
- >
echo "previous branch tip: $CI_COMMIT_BEFORE_SHA"
- set +o pipefail; git log --format='%H' | grep --silent "$CI_COMMIT_BEFORE_SHA" && PREVIOUS_TIP_REACHABLE=1
- test "$PREVIOUS_TIP_REACHABLE" != "1" && echo "force-push detected, stop" && exit 0
# non-fast-forward merges are disabled so we have to have merge commit on top
- MERGE_REQUEST_ID="$(git log -1 --format='%b' | sed --silent -e "s|^See merge request ${CI_PROJECT_PATH}\!||p")"
- >
: stop if this is not a merge request in the current project\'s namespace
- test -n "$MERGE_REQUEST_ID" || exit 0
- *git_clone_bind9-qa
backports:
<<: *post_merge
rules:
# -sub branches are handled manually
- if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_REF_NAME =~ /^bind-9.[0-9]+$/ || $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH)'
script:
# CI job token is not sufficient for push operations
- git remote get-url origin | sed -e "s/gitlab-ci-token:$CI_JOB_TOKEN/oauth2:$BIND_TEAM_WRITE_TOKEN/" | xargs git remote set-url --push origin
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/backport_mr.py $CI_PROJECT_ID "$MERGE_REQUEST_ID"
merged-metadata:
<<: *post_merge
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_REF_NAME =~ /^bind-9.[0-9]+(-sub)?$/ || $CI_COMMIT_REF_NAME =~ /^v9.[0-9]+.[0-9]+-release$/ || $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH)'
script:
- >
"$CI_PROJECT_DIR"/bind9-qa/releng/after_merge.py "$CI_PROJECT_ID" "$MERGE_REQUEST_ID"
.autorebase-common: &autorebase_common
stage: postmerge
needs: []
interruptible: false
.autorebase: &autorebase
<<: *autorebase_common
<<: *base_image
# ensure autorebases for each distinct private branch are serialized when the
# upstream branch is pushed to multiple times in quick succession
resource_group: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
tags:
- smalljob
variables:
# avoid leftover branches from previous jobs
GIT_STRATEGY: clone
GIT_DEPTH: 1000
script:
# CI job token is not sufficient for push operations
- git remote get-url origin | sed -e "s/gitlab-ci-token:${CI_JOB_TOKEN}/oauth2:${BIND_TEAM_WRITE_TOKEN}/" | xargs git remote set-url --push origin
- git remote add base-project "https://oauth2:${BIND_TEAM_API_TOKEN}@gitlab.isc.org/${BASE_PROJECT}.git"
- git fetch --depth=1000 base-project "${BASE_COMMIT}"
- git rebase --rebase-merges "${BASE_COMMIT}"
- autoreconf -fi
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} V=1
- git range-diff --color=always "${BASE_COMMIT}" "${CI_COMMIT_SHA}" HEAD
- if ! git push --force-with-lease origin "HEAD:${CI_COMMIT_REF_NAME}"; then touch .git-push-failed; exit 1; fi
after_script:
- if [ "${CI_JOB_STATUS}" = "success" ]; then exit 0; fi
- OLDEST_MERGE_COMMIT="$(git log --reverse --merges --pretty=%H "${CI_COMMIT_SHA}..${BASE_COMMIT}" | head -1)"
- read -r OLDEST_MERGE_REQUEST_PROJECT OLDEST_MERGE_REQUEST_ID < <(git log --max-count=1 "${OLDEST_MERGE_COMMIT}" | sed -nE 's|^\s*See merge request ([a-z-]+/bind9)!([0-9]+).*|\1 \2|p' | head -1)
- |
if git rebase --abort; then
# Rebase failed; try applying recent commits from the base branch on top of the branch being rebased to determine which one introduces conflicts
git rebase --rebase-merges "${CI_COMMIT_SHA}" "${BASE_COMMIT}" || true
CONFLICT_COMMIT="$(git status | sed -nE 's/^\s*(pick|merge -C) ([0-9a-f]+).*/\2/p' | head -1 | git rev-list -n 1 --stdin)"
REASON="merge conflict introduced by a change in the base branch"
else
# Rebase did not fail; most likely, this is a build failure, or the job was canceled
CONFLICT_COMMIT="${OLDEST_MERGE_COMMIT}"
if [ "${CI_JOB_STATUS}" = "failed" ]; then
if [ -f ".git-push-failed" ]; then
REASON="branch was updated during rebase"
else
REASON="build failure after a successful rebase"
fi
else
REASON="job was canceled"
fi
fi
CONFLICT_COMMIT_AUTHOR="$(git log --max-count=1 --pretty="@%al" "${CONFLICT_COMMIT}")"
MSG="#### :rotating_light: Autorebase error for branch \`${CI_COMMIT_REF_NAME}\` :rotating_light:"
MSG="${MSG}\n**Job**: ${CI_JOB_URL}"
MSG="${MSG}\n**Reason**: ${REASON}"
MSG="${MSG}\n**First bad commit**: [${CONFLICT_COMMIT}](https://gitlab.isc.org/${OLDEST_MERGE_REQUEST_PROJECT}/-/commit/${CONFLICT_COMMIT}) (authored by ${CONFLICT_COMMIT_AUTHOR})"
MSG="${MSG}\n**First bad merge request**: https://gitlab.isc.org/${OLDEST_MERGE_REQUEST_PROJECT}/-/merge_requests/${OLDEST_MERGE_REQUEST_ID}"
- |
curl -s -o /dev/null -X POST -H content-type:application/json -d '{"channel":"bind-9-team", "text": "'"${MSG}"'" }' "${MATTERMOST_WEBHOOK_URL}"
autorebase-trigger-security:
<<: *autorebase_common
rules:
- if: '$CI_PROJECT_NAMESPACE == "isc-projects" && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME =~ /^(main|bind-9\.[0-9]+)$/'
inherit:
variables: false
variables:
REBASE_ONLY: 1
BASE_PROJECT: isc-projects/bind9
BASE_COMMIT: "${CI_COMMIT_SHA}"
trigger:
project: isc-private/bind9
branch: "security-${CI_COMMIT_BRANCH}"
autorebase-security:
<<: *autorebase
rules:
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE == "pipeline" && $CI_COMMIT_REF_NAME =~ /^security-(main|bind-9\.[0-9]+)$/ && $REBASE_ONLY == "1" && $CI_COMMIT_REF_NAME =~ $AUTOREBASED_BRANCHES'
autorebase-trigger-sub:
<<: *autorebase_common
<<: *base_image
rules:
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME =~ /^security-bind-9\.[0-9]+$/'
tags:
- smalljob
script:
- >
curl -X POST --fail --header "Content-Type: application/json" --data '{ "token": "'"${CI_JOB_TOKEN}"'", "ref": "'"${CI_COMMIT_BRANCH#security-}"'-sub", "variables": { "REBASE_ONLY": "1", "BASE_PROJECT": "isc-private/bind9", "BASE_COMMIT": "'"${CI_COMMIT_SHA}"'" } }' https://gitlab.isc.org/api/v4/projects/9/trigger/pipeline
autorebase-sub:
<<: *autorebase
rules:
- if: '$CI_PROJECT_NAMESPACE == "isc-private" && $CI_PIPELINE_SOURCE == "pipeline" && $CI_COMMIT_REF_NAME =~ /^bind-9\.[0-9]+-sub$/ && $REBASE_ONLY == "1" && $CI_COMMIT_REF_NAME =~ $AUTOREBASED_BRANCHES'