rsyslog/.github/workflows/run_checks.yml
Rainer Gerhards 0fe2e9d8f5 ci: enable TSan deadlock detection
ThreadSanitizer can report lock-order inversions when its deadlock detector is enabled. Turn that option on for the existing Linux and macOS TSan CI lanes so observed pthread lock cycles fail the relevant sanitizer jobs.

This only changes existing TSan runtime options. Kafka remains disabled in the current TSan lanes; adding Kafka-specific TSan coverage is left for a separate change.
2026-05-31 16:16:06 +02:00

1787 lines
71 KiB
YAML

# Copyright 2024-2026 Rainer Gerhards and Others
#
# https://github.com/rsyslog/rsyslog-pkg-ubuntu
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# References:
#
# https://help.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#github-actions-notification-options
# https://github.com/settings/notifications
# https://software.opensuse.org//download.html?project=home%3Argerhards&package=rsyslog
---
name: check
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
pull_request:
env:
RSYSLOG_TESTBENCH_BASE_SHA: ${{ github.event.pull_request.base.sha }}
RSYSLOG_TESTBENCH_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
RSYSLOG_UPLOAD_FAILURE_ARTIFACTS: '1'
jobs:
changes:
name: check change scope
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
outputs:
c_headers: ${{ steps.c_headers.outputs.any_changed }}
code: ${{ steps.code.outputs.any_changed }}
package_ubuntu: ${{ steps.package_ubuntu.outputs.any_changed }}
package_rpm: ${{ steps.package_rpm.outputs.any_changed }}
journal: ${{ steps.journal.outputs.any_changed }}
analyzer: ${{ steps.analyzer.outputs.any_changed }}
elasticsearch: ${{ steps.elasticsearch.outputs.any_changed }}
victorialogs: ${{ steps.victorialogs.outputs.any_changed }}
kafka: ${{ steps.kafka.outputs.any_changed }}
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check C/header changes
id: c_headers
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
- name: Check broad code changes
id: code
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Check Ubuntu package changes
id: package_ubuntu
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
packaging/ubuntu/**
devtools/run-deb-ubuntu-build.sh
files_ignore: |
doc/Makefile.am
- name: Check RPM package changes
id: package_rpm
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
packaging/rpm/**
devtools/run-rpm-build.sh
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Check journal changes
id: journal
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
runtime/*.[ch]
plugins/imjournal/*
plugins/omjournal/*
tests/imjournal*.sh
tests/omjournal*.sh
tests/journal_print.c
tests/diag.sh
tests/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Check static analyzer changes
id: analyzer
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
devtools/run-static-analyzer.sh
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Check Elasticsearch changes
id: elasticsearch
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
Makefile.am
runtime/Makefile.am
runtime/action.[ch]
runtime/batch.[ch]
runtime/conf.[ch]
runtime/datetime.[ch]
runtime/debug.[ch]
runtime/errmsg.[ch]
runtime/glbl.[ch]
runtime/modules.[ch]
runtime/msg.[ch]
runtime/obj.[ch]
runtime/obj-types.h
runtime/objomsr.[ch]
runtime/parser.[ch]
runtime/prop.[ch]
runtime/queue.[ch]
runtime/ratelimit.[ch]
runtime/rsconf.[ch]
runtime/rsyslog.[ch]
runtime/ruleset.[ch]
runtime/statsobj.[ch]
runtime/stringbuf.[ch]
runtime/template.[ch]
runtime/var.[ch]
runtime/wti.[ch]
runtime/wtp.[ch]
runtime/yamlconf.[ch]
plugins/omelasticsearch/*
tests/es*.sh
tests/elasticsearch*.sh
tests/omelasticsearch*.sh
tests/diag.sh
tests/Makefile.am
configure.ac
.github/workflows/run_checks.yml
- name: Check VictoriaLogs changes
id: victorialogs
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
tests/omhttp-victorialogs-jsonline.sh
tests/Makefile.am
contrib/omhttp/**
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Check Kafka changes
id: kafka
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
Makefile.am
runtime/Makefile.am
plugins/imkafka/Makefile.am
plugins/omkafka/Makefile.am
runtime/action.[ch]
runtime/batch.[ch]
runtime/conf.[ch]
runtime/datetime.[ch]
runtime/debug.[ch]
runtime/errmsg.[ch]
runtime/glbl.[ch]
runtime/modules.[ch]
runtime/msg.[ch]
runtime/obj.[ch]
runtime/obj-types.h
runtime/objomsr.[ch]
runtime/parser.[ch]
runtime/prop.[ch]
runtime/queue.[ch]
runtime/rsconf.[ch]
runtime/rsyslog.[ch]
runtime/ruleset.[ch]
runtime/statsobj.[ch]
runtime/stringbuf.[ch]
runtime/template.[ch]
runtime/var.[ch]
runtime/wti.[ch]
runtime/wtp.[ch]
runtime/yamlconf.[ch]
plugins/imkafka/*.[ch]
plugins/omkafka/*.[ch]
tests/*kafka*.sh
tests/diag.sh
tests/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Summarize change scope
env:
C_HEADERS_CHANGED: ${{ steps.c_headers.outputs.any_changed }}
CODE_CHANGED: ${{ steps.code.outputs.any_changed }}
PACKAGE_UBUNTU_CHANGED: ${{ steps.package_ubuntu.outputs.any_changed }}
PACKAGE_RPM_CHANGED: ${{ steps.package_rpm.outputs.any_changed }}
JOURNAL_CHANGED: ${{ steps.journal.outputs.any_changed }}
ANALYZER_CHANGED: ${{ steps.analyzer.outputs.any_changed }}
ELASTICSEARCH_CHANGED: ${{ steps.elasticsearch.outputs.any_changed }}
VICTORIALOGS_CHANGED: ${{ steps.victorialogs.outputs.any_changed }}
KAFKA_CHANGED: ${{ steps.kafka.outputs.any_changed }}
run: |
{
echo "### check workflow change scope"
echo
echo "| scope | changed |"
echo "| --- | --- |"
echo "| C/header | $C_HEADERS_CHANGED |"
echo "| broad code | $CODE_CHANGED |"
echo "| Ubuntu package | $PACKAGE_UBUNTU_CHANGED |"
echo "| RPM package | $PACKAGE_RPM_CHANGED |"
echo "| journal | $JOURNAL_CHANGED |"
echo "| static analyzer | $ANALYZER_CHANGED |"
echo "| Elasticsearch | $ELASTICSEARCH_CHANGED |"
echo "| VictoriaLogs | $VICTORIALOGS_CHANGED |"
echo "| Kafka | $KAFKA_CHANGED |"
} >> "$GITHUB_STEP_SUMMARY"
compile:
name: compile (${{ matrix.config }})
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
strategy:
fail-fast: true
matrix:
config: [clang21-ndebug, gcc15-gnu23-debug]
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
**/*.c
**/*.h
- name: cache configure results
if: steps.code_changes.outputs.any_changed == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-compile-${{ matrix.config }}
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-configure.sh') }}
- name: run compile check (container)
if: steps.code_changes.outputs.any_changed == 'true'
run: |
chmod -R go+rw .
export RSYSLOG_CONTAINER_UID="" # use default
export CI_CONFIGURE_CACHE=1
export CFLAGS='-g'
case "${{ matrix.config }}" in
'clang21-ndebug')
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA='--enable-debug=no'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CC='clang-21'
;;
'gcc15-gnu23-debug')
# omamqp1 seems to have an issue with the build system - exclude it for now
# rgerhards, 2024-12-06
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA='--enable-debug=yes --disable-omamqp1'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CFLAGS='-g -std=gnu23'
export CC='gcc-15'
;;
*)
echo "unknown configuration "
echo "error-terminating this check run"
exit 1
;;
esac
devtools/devcontainer.sh --rm devtools/run-configure.sh
devtools/devcontainer.sh --rm make -j20
- name: Skip compile check, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No C/header changes detected; required compile gate passes without building."
compile_extended:
name: extended compile (${{ matrix.config }})
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.c_headers == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
strategy:
fail-fast: true
matrix:
config: [alpine, clang9, clang21-noatomics, gcc8-debug]
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: cache configure results
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-compile-extended-${{ matrix.config }}
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-configure.sh') }}
- name: run compile check (container)
run: |
chmod -R go+rw .
export RSYSLOG_CONTAINER_UID="" # use default
export CI_CONFIGURE_CACHE=1
export CFLAGS='-g'
case "${{ matrix.config }}" in
'alpine')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_full:alpine_latest'
export CC='gcc'
;;
'clang9')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:20.04'
export CC='clang-9'
;;
'clang21-noatomics')
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA='--enable-atomic-operations=no'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CC='clang-21'
;;
'gcc8-debug')
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA='--enable-debug=yes'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:18.04'
export CC='gcc-8'
;;
*)
echo "unknown configuration "
echo "error-terminating this check run"
exit 1
;;
esac
devtools/devcontainer.sh --rm devtools/run-configure.sh
devtools/devcontainer.sh --rm make -j20
CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.code == 'true' }}
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 50
strategy:
# When set to true, cancel all in-progress jobs if any matrix job fails.
fail-fast: false
matrix:
config: [centos_7, debian_13,
ubuntu_26_imtcp_no_epoll,
fedora_44,
ubuntu_20, ubuntu_24,
ubuntu_26_san, ubuntu_26_tsan, ubuntu_22_distcheck,
openeuler, wolfssl, elasticsearch]
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: cache configure results
if: steps.code_changes.outputs.any_changed == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-ci-${{ matrix.config }}
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/apply-service-relevance.sh','devtools/run-configure.sh','devtools/run-ci.sh') }}
- name: run container CI pipeline
if: steps.code_changes.outputs.any_changed == 'true'
run: |
chmod -R go+rw .
CODECOV_repo_slug="$(git config --get remote.origin.url | sed -E 's#.*[:/]([^/]+/[^/.]+)(\\.git)?$#\1#')"
export CODECOV_repo_slug
CODECOV_commit_sha="$(git rev-parse HEAD)"
export CODECOV_commit_sha
export RSYSLOG_CONTAINER_UID="" # use default
export RSYSLOG_STATSURL='http://build.rsyslog.com/testbench-failedtest.php'
export CFLAGS='-g'
export CC='gcc'
export CI_CONFIGURE_CACHE=1
export USE_AUTO_DEBUG='off'
export CI_MAKE_OPT='-j20'
export CI_MAKE_CHECK_OPT='-j10'
export CI_CHECK_CMD='check'
export VERBOSE=1
case "${{ matrix.config }}" in
'centos_7')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_centos:7'
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests \
--disable-kafka-tests --disable-snmp-tests"
export CI_VALGRIND_SUPPRESSIONS='centos7.supp'
;;
'debian_13')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_debian:13'
export CI_VALGRIND_SUPPRESSIONS='centos7.supp'
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests --disable-kafka-tests \
--without-valgrind-testbench --enable-imdtls --enable-omdtls"
;;
'ubuntu_26_imtcp_no_epoll')
# This check tests if imtcp runs in poll (select) mode. We have only slow CI runners for
# platforms where this is the case, thus we do a quick run on ubuntu where we also have all
# thread and memory debuggers available.
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp"
# Note: we completely override the container configure options here!
export RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE="--enable-testbench --enable-omstdout \
--enable-imdiag --disable-imtcp-epoll --enable-imtcp-tests\
--disable-impstats --disable-impstats-push --disable-imfile --disable-imfile-tests \
--disable-fmhttp --enable-valgrind --enable-valgrind-testbench \
--disable-helgrind --disable-default-tests --disable-kafka-tests \
--disable-omkafka --disable-imkafka \
--enable-gnutls --enable-openssl --enable-gnutls-tests"
;;
'openeuler')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_openeuler:24.03-lts'
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests \
--disable-kafka-tests"
;;
'fedora_44')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_fedora:44'
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests \
--disable-kafka-tests --enable-debug --enable-imdtls --enable-omdtls"
;;
'ubuntu_20')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:20.04'
export CI_VALGRIND_SUPPRESSIONS="ubuntu20.04.supp"
;;
'ubuntu_24')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:24.04'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp"
# TODO: enable disabled components when the issues are fixed
# It is better to run at least the majority of checks than to postpone that
# any longer. 2025-01-31 RGerhards
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--enable-omazureeventhubs --enable-imdtls \
--enable-omdtls --enable-omotel --disable-omamqp1 --disable-snmp --disable-kafka-tests \
--disable-elasticsearch-tests --enable-mmsnareparse"
;;
'ubuntu_22_distcheck')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:22.04'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp"
export CI_CHECK_CMD='distcheck'
export ABORT_ALL_ON_TEST_FAIL='YES'
export VERBOSE=1
;;
'ubuntu_26_san')
# TODO: remove the -fno-sanitize=function once the root issue is solved. We use
# it in order to migrate to the newer sanitizer checker which otherwise
# would be much delayed. That was the prime reason we did not upgrade before.
export CI_SANITIZE_BLACKLIST='tests/asan.supp'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CC='clang-21'
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests \
--disable-libfaketime --without-valgrind-testbench --disable-valgrind \
--enable-omotel \
--disable-kafka-tests --enable-imdtls --enable-omdtls \
--enable-mmsnareparse"
export CFLAGS="-fstack-protector -D_FORTIFY_SOURCE=2 \
-fsanitize=address,undefined,nullability,unsigned-integer-overflow \
-fno-sanitize-recover=undefined,nullability,unsigned-integer-overflow \
-fno-sanitize=function \
-g -O3 -fno-omit-frame-pointer -fno-color-diagnostics"
export LSAN_OPTIONS='detect_leaks=0'
export UBSAN_OPTIONS='print_stacktrace=1'
;;
'ubuntu_26_tsan')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
# TSAN is CPU-heavy; try matching the default check parallelism after test hardening.
export CI_MAKE_CHECK_OPT='-j10'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp"
export CI_SANITIZE_BLACKLIST='tests/tsan.supp'
export CC='clang-21'
# Clang 21 TSAN disables ASLR; Docker's default seccomp profile blocks that.
export DOCKER_RUN_EXTRA_OPTS='--security-opt seccomp=unconfined'
# impstats has known and OK races
# mmpstrucdata TEMPORARILY disabled because of a threading hang on shutdown
# imhttp disabled because of race in civetweb (need to consider different lib)
export RSYSLOG_CONFIGURE_OPTIONS_EXTRA="--disable-elasticsearch-tests \
--enable-imfile-tests \
--disable-impstats --disable-impstats-push \
--disable-kafka-tests --disable-mmpstrucdata \
--enable-omotel \
--disable-clickhouse --disable-clickhouse-tests \
--disable-kafka-tests \
--disable-libfaketime --disable-imhttp \
--without-valgrind-testbench --disable-valgrind \
--enable-mmsnareparse"
export CFLAGS="-g -fstack-protector -D_FORTIFY_SOURCE=2 -fsanitize=thread \
-O0 -fno-omit-frame-pointer -fno-color-diagnostics"
# note: we need pathes in container, thus /rsyslog vs. $(pwd) in TSAN_OPTIONS
export TSAN_OPTIONS="halt_on_error=1:detect_deadlocks=1:suppressions=/rsyslog/tests/tsan-rt.supp"
export ABORT_ALL_ON_TEST_FAIL='YES'
;;
'wolfssl')
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:26.04'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp"
export ABORT_ALL_ON_TEST_FAIL='YES'
export RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE="--enable-testbench --enable-omstdout \
--enable-imdiag --enable-impstats --enable-imfile --disable-imfile-tests \
--disable-fmhttp --enable-valgrind --disable-default-tests --disable-imtcp-tests \
--enable-wolfssl"
export CI_MAKE_OPT='-j20'
export CI_MAKE_CHECK_OPT='-j10'
export CI_CHECK_CMD='check'
;;
'elasticsearch')
if ! tests/diag.sh module-needs-testing elasticsearch; then
echo "No relevant Elasticsearch changes detected; skipping Elasticsearch matrix CI."
exit 0
fi
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:22.04'
export ABORT_ALL_ON_TEST_FAIL='NO'
export RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE="--enable-testbench --enable-omstdout \
--enable-imdiag --enable-impstats --enable-imfile --disable-imfile-tests \
--disable-fmhttp --enable-valgrind --disable-default-tests --disable-imtcp-tests \
--enable-elasticsearch-tests --enable-elasticsearch"
export CI_MAKE_OPT='-j20'
export CI_MAKE_CHECK_OPT='-j10'
export CI_CHECK_CMD='check'
export CI_VALGRIND_SUPPRESSIONS="ubuntu22.04.supp" # they are still valid
;;
esac
case "${{ matrix.config }}" in
'elasticsearch'|'wolfssl'|'ubuntu_26_imtcp_no_epoll')
;;
*)
. devtools/apply-service-relevance.sh
rsyslog_apply_default_pr_service_suppressions
;;
esac
devtools/devcontainer.sh --rm devtools/run-ci.sh
# Failure artifacts are an opt-in transport for flake evidence. They are
# uploaded only for failed CI matrix attempts and include the run attempt
# plus matrix lane in the name so reruns cannot overwrite a previous
# failed attempt. Cancelled attempts are not uploaded because
# push-cancelled runs usually do not contain useful flake evidence. The
# long-term record belongs in the external flake-campaign evidence store;
# these artifacts are intentionally short lived and may be deleted by the
# collector after successful processing. Some logs are created by the
# container user, so normalize read permissions before upload.
- name: Prepare CI failure evidence
if: >-
${{ failure()
&& env.RSYSLOG_UPLOAD_FAILURE_ARTIFACTS == '1' }}
run: |
for path in failed-tests.log tests config.log; do
if [ -e "$path" ]; then
sudo chmod -R a+rX "$path" || true
fi
done
- name: Upload CI failure evidence
if: >-
${{ failure()
&& env.RSYSLOG_UPLOAD_FAILURE_ARTIFACTS == '1' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ci-failure-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.config }}
path: |
failed-tests.log
tests/failed-tests.log
tests/test-suite.log
tests/*.log
tests/*.trs
config.log
retention-days: 7
if-no-files-found: ignore
- name: Skip CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping container CI."
package_build_ubuntu:
name: package build (Ubuntu, ${{ matrix.suite }})
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.package_ubuntu == 'true' }}
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 35
strategy:
fail-fast: true
matrix:
include:
# Temporarily disabled: Ubuntu 20.04 (focal) is EOL and the package
# build no longer works reliably there.
- suite: jammy
- suite: noble
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check for package changes
id: package_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
packaging/ubuntu/**
devtools/run-deb-ubuntu-build.sh
files_ignore: |
doc/Makefile.am
- name: Get version
id: get_version
if: steps.package_changes.outputs.any_changed == 'true'
run: |
set -e
BASE_VER=$(sed -n 's/AC_INIT(\[rsyslog\],\[\([^]]*\)\].*/\1/p' configure.ac | sed 's/\.daily$//')
PR_NUM="${{ github.event.pull_request.number || '0' }}"
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
VERSION="${BASE_VER}-${PR_NUM}-${TIMESTAMP}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "UBUNTU_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "Using version: $VERSION"
- name: Install build dependencies
if: steps.package_changes.outputs.any_changed == 'true'
run: sudo apt-get update && sudo apt-get install -y dpkg-dev lintian wget
- name: Build Ubuntu package
if: steps.package_changes.outputs.any_changed == 'true'
env:
RSYSLOG_APT_PROXY: ${{ vars.RSYSLOG_APT_PROXY }}
RSYSLOG_UBUNTU_ARCHIVE_MIRROR: ${{ vars.RSYSLOG_UBUNTU_ARCHIVE_MIRROR }}
RSYSLOG_UBUNTU_SECURITY_MIRROR: ${{ vars.RSYSLOG_UBUNTU_SECURITY_MIRROR }}
RSYSLOG_APT_RETRIES: ${{ vars.RSYSLOG_APT_RETRIES }}
run: bash devtools/run-deb-ubuntu-build.sh ${{ matrix.suite }}
- name: List built packages
if: steps.package_changes.outputs.any_changed == 'true'
run: find . -maxdepth 2 -name "*.deb" -type f -exec ls -la {} \;
- name: Skip Ubuntu package build, no relevant changes
if: steps.package_changes.outputs.any_changed != 'true'
run: echo "No relevant package changes detected; skipping Ubuntu package build."
package_build_rpm:
name: package build (RPM)
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.package_rpm == 'true' }}
permissions:
contents: read
runs-on: ubuntu-22.04
timeout-minutes: 45
container:
image: quay.io/rockylinux/rockylinux:9
options: --privileged
steps:
- name: Install git (before checkout so it can clone)
run: dnf install -y git
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
packaging/rpm/**
devtools/run-rpm-build.sh
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: run RPM build
if: steps.code_changes.outputs.any_changed == 'true'
run: |
chmod -R go+rw .
echo "== Install EPEL and mock =="
dnf install -y epel-release
dnf install -y mock dnf-utils
echo "== Install build tools for autoreconf/configure/make dist =="
dnf install -y autoconf autoconf-archive automake libtool gcc make flex bison
echo "== Add Adiscon repo and install configure deps (libestr, libfastjson for make dist) =="
curl -fsSL -o /etc/pki/rpm-gpg/RPM-GPG-KEY-Adiscon https://download.adiscon.com/rpms/RPM-GPG-KEY-Adiscon
{
echo '[adiscon]'
echo 'name=adiscon'
echo "baseurl=https://rpms.adiscon.com/v8-stable/epel-9/\$basearch"
echo 'enabled=1'
echo 'gpgcheck=1'
echo 'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Adiscon'
} > /etc/yum.repos.d/adiscon.repo
dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y libestr-devel libfastjson4-devel zlib-devel libuuid-devel libgcrypt-devel libcurl-devel libyaml-devel file protobuf-c-compiler protobuf-c-devel snappy-devel python3-docutils dos2unix
echo "== Copy mock configs =="
cp -v packaging/rpm/etc-mock/*.cfg /etc/mock/ || true
mkdir -p build-result /var/lib/mock
echo "== Run RPM build =="
bash devtools/run-rpm-build.sh
- name: Skip RPM build, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping RPM build."
- name: Upload RPM artifacts
if: steps.code_changes.outputs.any_changed == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: rpms-epel-9-x86_64
path: build-result/
if-no-files-found: error
macos_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.code == 'true' }}
permissions:
contents: read
strategy:
# When set to true, cancel all in-progress jobs if any matrix job fails.
fail-fast: true
matrix:
include:
# 1 x from macos-14 (x64 NONE)
- os: macos-14
arch: x64
sanitizer: none
# 2 x from macos-15 (x64 ASAN and arm64 TSAN)
- os: macos-15
arch: x64
sanitizer: asan
- os: macos-15
arch: arm64
sanitizer: tsan
runs-on: ${{ matrix.os }}
timeout-minutes: 15
name: macOS CI (${{ matrix.os }}, ${{ matrix.arch }}, ${{ matrix.sanitizer }})
env:
USE_AUTO_DEBUG: true
ABORT_ALL_ON_TEST_FAIL: true
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: add extra dependencies
if: ${{ runner.os == 'macOS' && steps.code_changes.outputs.any_changed == 'true' }}
run: |
brew install pkgconf \
gnutls \
libestr \
libfastjson \
docutils \
autoconf \
autoconf-archive \
automake \
libtool
- name: add extra dependencies (Linux for act)
if: ${{ runner.os == 'Linux' && steps.code_changes.outputs.any_changed == 'true' }}
run: |
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
build-essential \
flex \
bison \
autoconf \
autoconf-archive \
automake \
libtool \
pkg-config \
libgnutls28-dev \
libestr-dev \
libfastjson-dev \
libyaml-dev \
python3-docutils
- name: check disk space
if: steps.code_changes.outputs.any_changed == 'true'
run: |
df -h
echo "Available disk space before build:"
df -h . | tail -1 | awk '{print "Free space: " $4 " (" $5 " used)"}'
- name: prepare for build
if: steps.code_changes.outputs.any_changed == 'true'
run: |
# Set debugging flags for better stack traces on segfaults
BASE_CFLAGS="-g -O1 -fno-omit-frame-pointer"
BASE_LDFLAGS="-g"
if [ "${{ matrix.sanitizer }}" = "asan" ]; then
# AddressSanitizer for memory error detection
export CFLAGS="$BASE_CFLAGS -fsanitize=address \
-fsanitize-address-use-after-scope"
export LDFLAGS="$BASE_LDFLAGS -fsanitize=address"
echo "Building with AddressSanitizer"
elif [ "${{ matrix.sanitizer }}" = "tsan" ]; then
# ThreadSanitizer for threading error detection
export CFLAGS="$BASE_CFLAGS -fsanitize=thread"
export LDFLAGS="$BASE_LDFLAGS -fsanitize=thread"
echo "Building with ThreadSanitizer"
else
# No sanitizer (normal build)
export CFLAGS="$BASE_CFLAGS"
export LDFLAGS="$BASE_LDFLAGS"
echo "Building without sanitizers"
fi
autoreconf -fvi
./configure --enable-silent-rules --enable-testbench \
--enable-imdiag --disable-imdocker --disable-imfile \
--disable-default-tests --disable-impstats --disable-impstats-push --disable-imptcp \
--disable-mmanon --disable-mmaudit --disable-mmfields \
--disable-mmjsonparse --disable-mmpstrucdata \
--disable-mmsequence --disable-mmutf8fix --disable-mail \
--disable-omprog --disable-improg --disable-omruleset \
--enable-omstdout --disable-omuxsock \
--disable-pmaixforwardedfrom --disable-pmciscoios \
--disable-pmcisconames --disable-pmlastmsg --disable-pmsnare \
--disable-libgcrypt --disable-mmnormalize \
--disable-omudpspoof --disable-relp --disable-mmsnmptrapd \
--enable-gnutls --enable-usertools --disable-mysql \
--disable-valgrind --disable-mmkubernetes --disable-omkafka \
--disable-imkafka --disable-ommongodb --disable-omrabbitmq \
--disable-mmdarwin --enable-compile-warnings=error \
--disable-helgrind --disable-uuid --disable-fmhttp
- name: build
if: steps.code_changes.outputs.any_changed == 'true'
run: |
make -j
- name: check disk space before tests
if: steps.code_changes.outputs.any_changed == 'true'
run: |
df -h . | tail -1 | \
awk '{print "Free space before tests: " $4 " (" $5 " used)"}'
# Clean up to free some space
rm -rf /tmp/rsyslog-test-*
- name: configure macOS core dump path
if: ${{ runner.os == 'macOS' && steps.code_changes.outputs.any_changed == 'true' }}
run: |
sudo mkdir -p /cores
sudo sysctl -w kern.corefile=/cores/core-%P
- name: make check (continue on error to collect results)
id: run_tests
if: steps.code_changes.outputs.any_changed == 'true'
run: |
# Enable core dumps for debugging segfaults
ulimit -c unlimited
# Configure sanitizer options based on which one we're using
if [ "${{ matrix.sanitizer }}" = "asan" ]; then
echo "Configuring AddressSanitizer options"
export ASAN_OPTIONS=":halt_on_error=1:\
check_initialization_order=1:strict_init_order=1:\
detect_stack_use_after_return=1:print_stacktrace=1:\
disable_coredump=0"
elif [ "${{ matrix.sanitizer }}" = "tsan" ]; then
echo "Configuring ThreadSanitizer options"
export TSAN_OPTIONS=":halt_on_error=1:\
detect_deadlocks=1:history_size=7:suppressions=$PWD/tests/tsan-rt.supp"
else
echo "Running without sanitizers"
fi
set +e
make -j10 check
EXIT_CODE=$?
STATUS=success
if [ "$EXIT_CODE" -ne 0 ]; then STATUS=failure; fi
echo "status=$STATUS" >> "$GITHUB_OUTPUT"
exit 0
- name: List core files before cleanup
if: steps.code_changes.outputs.any_changed == 'true'
run: |
echo "=== Core files before cleanup ==="
# Search only in likely locations and limit output
find_core_files() {
find /cores /tmp /var/tmp . -type f -name 'core*' 2>/dev/null
}
find_core_files | head -20 || true
CORE_COUNT=$(find_core_files | wc -l || echo 0)
echo "Total core files found: $CORE_COUNT"
- name: Free up disk space (keep core files)
if: steps.code_changes.outputs.any_changed == 'true'
run: |
sudo rm -rf /usr/local/share/gtk-doc
sudo rm -rf /usr/local/share/man
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/hostedtoolcache
brew cleanup
df -h
- name: List core files after cleanup
if: steps.code_changes.outputs.any_changed == 'true'
run: |
echo "=== Core files after cleanup ==="
# Search only in likely locations and limit output
find_core_files() {
find /cores /tmp /var/tmp . -type f -name 'core*' 2>/dev/null
}
find_core_files | head -20 || true
CORE_COUNT=$(find_core_files | wc -l || echo 0)
echo "Total core files found: $CORE_COUNT"
- name: show error logs and fail if tests failed
if: steps.run_tests.outputs.status == 'failure'
run: |
echo "=== Post-failure diagnostics ==="
echo "Note: Comprehensive error analysis including core dumps,"
echo "system info, and logs is now handled automatically by"
echo "tests/diag.sh during test failures."
echo ""
echo "=== Basic disk space check ==="
df -h . | tail -1 | awk '{print "Free space: " $4 " (" $5 " used)"}'
echo ""
echo "=== Additional error log collection ==="
if [ -f "devtools/gather-check-logs.sh" ]; then
devtools/gather-check-logs.sh || true
fi
if [ -f "failed-tests.log" ]; then
echo "=== Failed Tests Summary ==="
cat failed-tests.log
else
echo "failed-tests.log was not generated"
fi
exit 1
- name: Skip macOS CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping macOS CI."
elasticsearch_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.elasticsearch == 'true' }}
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 45
name: elasticsearch-8-tests
env:
RSYSLOG_TESTBENCH_EXTERNAL_ES_URL: http://127.0.0.1:19200
ES_HOST: 127.0.0.1
ES_PORT: 19200
DOCKER_RUN_EXTRA_OPTS: --network host
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.14.3
env:
discovery.type: single-node
xpack.security.enabled: "false"
ES_JAVA_OPTS: -Xms1g -Xmx1g
ports:
- 19200:9200
options: >-
--health-cmd="curl --fail http://localhost:9200/_cluster/health || exit 1"
--health-interval=10s
--health-timeout=5s
--health-retries=30
steps:
- name: checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: cache configure results
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-elasticsearch
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-configure.sh','devtools/run-ci.sh') }}
- name: run elasticsearch test matrix
env:
RSYSLOG_DEV_CONTAINER: rsyslog/rsyslog_dev_base_ubuntu:22.04
RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE: >-
--enable-testbench --enable-omstdout --enable-imdiag --enable-impstats
--disable-imfile --disable-imfile-tests --disable-fmhttp --enable-valgrind
--disable-default-tests --disable-imtcp-tests --enable-elasticsearch-tests
--enable-elasticsearch
CI_MAKE_OPT: -j20
CI_MAKE_CHECK_OPT: -j10
CI_CHECK_CMD: check
ABORT_ALL_ON_TEST_FAIL: 'NO'
CI_VALGRIND_SUPPRESSIONS: ubuntu22.04.supp
RSYSLOG_STATSURL: http://build.rsyslog.com/testbench-failedtest.php
CI_CONFIGURE_CACHE: '1'
USE_AUTO_DEBUG: 'off'
VERBOSE: '1'
run: |
chmod -R go+rw .
devtools/devcontainer.sh --rm devtools/run-ci.sh
victorialogs_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.victorialogs == 'true' }}
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 25
name: victorialogs-tests
env:
DOCKER_RUN_EXTRA_OPTS: --network host
services:
victorialogs:
image: victoriametrics/victoria-logs:latest # zizmor: ignore[unpinned-images] intentional: CI tracks latest VictoriaLogs compatibility
ports:
- 29428:9428
steps:
- name: checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
tests/omhttp-victorialogs-jsonline.sh
tests/Makefile.am
contrib/omhttp/**
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: cache configure results
if: steps.code_changes.outputs.any_changed == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-victorialogs
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-configure.sh','devtools/run-ci.sh') }}
- name: run victoria logs omhttp jsonl test
if: steps.code_changes.outputs.any_changed == 'true'
env:
RSYSLOG_DEV_CONTAINER: rsyslog/rsyslog_dev_base_ubuntu:22.04
RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE: >-
--enable-testbench --enable-omstdout --enable-imdiag --enable-omhttp
--disable-default-tests --disable-imtcp-tests --disable-imfile
--disable-imfile-tests --disable-fmhttp
CI_MAKE_OPT: -j20
CI_MAKE_CHECK_OPT: -j10 TESTS=omhttp-victorialogs-jsonline.sh
CI_CHECK_CMD: check
ABORT_ALL_ON_TEST_FAIL: 'NO'
CI_CONFIGURE_CACHE: '1'
USE_AUTO_DEBUG: 'off'
VERBOSE: '1'
run: |
for i in $(seq 1 60); do
if curl -fsS http://127.0.0.1:29428/metrics >/dev/null; then
echo "VictoriaLogs is ready"
break
fi
sleep 1
if [ "$i" -eq 60 ]; then
echo "VictoriaLogs service did not become ready in time"
exit 1
fi
done
chmod -R go+rw .
devtools/devcontainer.sh --rm devtools/run-ci.sh
- name: Skip VictoriaLogs CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping VictoriaLogs CI."
clang_analyzer_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.analyzer == 'true' }}
permissions:
contents: read
runs-on: ubuntu-latest
name: clang static analyzer
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
devtools/run-static-analyzer.sh
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: cache configure results
if: steps.code_changes.outputs.any_changed == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-clang-analyzer
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-static-analyzer.sh') }}
- name: Run clang static analyzer
if: steps.code_changes.outputs.any_changed == 'true'
id: run-clang
env:
RSYSLOG_DEV_CONTAINER: rsyslog/rsyslog_dev_base_ubuntu:26.04
SCAN_BUILD: scan-build
SCAN_BUILD_CC: clang
SCAN_BUILD_REPORT_DIR: scan-build-report
CI_MAKE_OPT: -j20
CI_CONFIGURE_CACHE: '1'
DOCKER_RUN_EXTRA_OPTS: >-
-e SCAN_BUILD -e SCAN_BUILD_CC -e SCAN_BUILD_REPORT_DIR
-e CI_CONFIGURE_CACHE
run: |
chmod -R go+rw .
set +e
devtools/devcontainer.sh --rm devtools/run-static-analyzer.sh 2>&1 | tee clang-analyzer.log
echo "exitcode=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT"
- name: Upload clang static analyzer report
if: ${{ always() && steps.code_changes.outputs.any_changed == 'true' }}
id: upload-report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: clang-static-analyzer-report
path: scan-build-report
retention-days: 7
if-no-files-found: ignore
- name: Show clang static analyzer report link
if: ${{ always() && steps.code_changes.outputs.any_changed == 'true' }}
env:
ARTIFACT_URL: ${{ steps.upload-report.outputs.artifact-url }}
run: |
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
Clang static analyzer HTML report (download):
$ARTIFACT_URL
EOF
echo "Clang static analyzer HTML report (download):"
echo "$ARTIFACT_URL"
- name: Fail if analysis failed
if: ${{ steps.code_changes.outputs.any_changed == 'true' && steps.run-clang.outputs.exitcode != '0' }}
env:
ARTIFACT_URL: ${{ steps.upload-report.outputs.artifact-url }}
run: |
echo "clang static analyzer detected issues:" >&2
tail -n 200 clang-analyzer.log >&2 || true
echo >&2
echo "Clang static analyzer HTML report (download): $ARTIFACT_URL" >&2
exit 1
- name: Skip clang analyzer CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping clang analyzer CI."
kafka_distcheck_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.kafka == 'true' }}
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 50
name: kafka distcheck CI
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: cache configure results
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: config.cache
key: >
cfgcache-kafka-distcheck
-cfg-${{ hashFiles('configure.ac','m4/*.m4','Makefile.am','.github/workflows/run_checks.yml','devtools/run-configure.sh','devtools/run-ci.sh') }}
- name: run container CI pipeline
run: |
chmod -R go+rw .
export RSYSLOG_CONFIGURE_OPTIONS_OVERRIDE="--enable-testbench --enable-omstdout \
--enable-imdiag --disable-impstats --disable-impstats-push --enable-imfile --disable-imfile-tests \
--disable-fmhttp --enable-valgrind --enable-valgrind-testbench \
--disable-helgrind --disable-default-tests --enable-kafka-tests \
--disable-default-tests \
--enable-omkafka --enable-gnutls --disable-gnutls-tests --enable-imkafka"
export RSYSLOG_CONTAINER_UID="" # use default
export RSYSLOG_STATSURL='http://build.rsyslog.com/testbench-failedtest.php'
export CC='gcc'
export CFLAGS='-g'
export CI_CONFIGURE_CACHE=1
export USE_AUTO_DEBUG='off'
export CI_MAKE_OPT='-j20'
export CI_MAKE_CHECK_OPT='-j10'
export CI_CHECK_CMD='distcheck'
export RSYSLOG_DEV_CONTAINER='rsyslog/rsyslog_dev_base_ubuntu:20.04'
export ABORT_ALL_ON_TEST_FAIL='YES'
export VERBOSE=1
devtools/devcontainer.sh --rm devtools/run-ci.sh
dev_container_definition_CI:
needs: [changes]
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 180
name: dev container definition CI
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream "https://github.com/$GITHUB_REPOSITORY.git"
git fetch upstream "$BASE_REF"
- name: Check for dev container definition changes
id: dev_container_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
devtools/ci/Dockerfile*
packaging/docker/dev_env/**/Dockerfile*
packaging/docker/dev_env/**/setup-system.sh
packaging/docker/dev_env/**/build.sh
packaging/docker/dev_env/common/**
.github/workflows/run_checks.yml
- name: Build changed dev containers
if: steps.dev_container_changes.outputs.any_changed == 'true'
env:
CHANGED_FILES: ${{ steps.dev_container_changes.outputs.all_changed_files }}
run: |
set -euo pipefail
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"; rm -rf packaging/docker/dev_env/alpine/common packaging/docker/dev_env/ubuntu/devel/common' EXIT
add_build() {
printf '%s\t%s\n' "$1" "$2" >> "$tmpdir/builds.tsv"
}
add_dir_dockerfiles() {
dir="$1"
for dockerfile in "$dir"/Dockerfile "$dir"/Dockerfile.arm; do
if [ -f "$dockerfile" ]; then
add_build "$dir" "$dockerfile"
fi
done
}
ensure_common_context() {
dir="$1"
case "$dir" in
packaging/docker/dev_env/alpine|packaging/docker/dev_env/ubuntu/devel)
rm -rf "$dir/common"
cp -r packaging/docker/dev_env/common "$dir/common"
;;
esac
}
for changed in $CHANGED_FILES; do
case "$changed" in
devtools/ci/Dockerfile*)
add_build . "$changed"
;;
packaging/docker/dev_env/common/*)
add_dir_dockerfiles packaging/docker/dev_env/alpine
add_dir_dockerfiles packaging/docker/dev_env/ubuntu/devel
;;
packaging/docker/dev_env/*)
filename="$(basename "$changed")"
changed_dir="$(dirname "$changed")"
case "$filename" in
Dockerfile|Dockerfile.arm)
add_build "$changed_dir" "$changed"
;;
setup-system.sh|build.sh)
add_dir_dockerfiles "$changed_dir"
;;
*)
echo "Ignoring unmatched dev-container-related path: $changed"
;;
esac
;;
.github/workflows/run_checks.yml)
echo "run_checks.yml changed; this job definition is validated by actionlint/zizmor and normal CI."
;;
*)
echo "Ignoring unmatched dev-container-related path: $changed"
;;
esac
done
if [ ! -s "$tmpdir/builds.tsv" ]; then
echo "No concrete dev-container Dockerfile build is required."
exit 0
fi
sort -u "$tmpdir/builds.tsv" > "$tmpdir/builds.unique.tsv"
while IFS="$(printf '\t')" read -r context dockerfile; do
ensure_common_context "$context"
tag_suffix="$(printf '%s' "$dockerfile" | tr '/:._' '----' | tr -cd '[:alnum:]-')"
tag="rsyslog-devcontainer-pr:${tag_suffix}"
echo "::group::docker build $dockerfile"
docker build --pull -f "$dockerfile" -t "$tag" "$context"
echo "::endgroup::"
done < "$tmpdir/builds.unique.tsv"
- name: Skip dev container build, no relevant changes
if: steps.dev_container_changes.outputs.any_changed != 'true'
run: echo "No dev container definition changes detected; required dev container build gate passes without building."
arm_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.code == 'true' }}
permissions:
contents: read
runs-on: ubuntu-24.04-arm
timeout-minutes: 150
name: arm64 CI (native, asan), asan
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
.github/workflows/run_checks.yml
.github/workflows/run_cross_arch_weekly.yml
devtools/ci/Dockerfile.arm
files_ignore: |
doc/Makefile.am
- name: Set up Docker Buildx
if: steps.code_changes.outputs.any_changed == 'true'
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build arm64 dev image (cached)
if: steps.code_changes.outputs.any_changed == 'true'
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
file: devtools/ci/Dockerfile.arm
platforms: linux/arm64
tags: rsyslog-cross-dev:arm64
load: true
cache-from: type=gha,scope=cross-dev-arm64
cache-to: type=gha,mode=max,scope=cross-dev-arm64
- name: Run arm64 build and testbench
if: steps.code_changes.outputs.any_changed == 'true'
run: |
chmod -R go+rw .
docker run --rm --platform linux/arm64 \
-e ARCH=arm64 \
--cap-add SYS_ADMIN \
--cap-add SYS_PTRACE \
--security-opt seccomp=unconfined \
-v "${{ github.workspace }}:/rsyslog" \
-w /rsyslog \
rsyslog-cross-dev:arm64 bash -c '
set -e
export CFLAGS="-g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope"
export LDFLAGS="-fsanitize=address"
export ASAN_OPTIONS="abort_on_error=1:symbolize=1:detect_leaks=0:disable_coredump=0"
export CC=gcc
export TEST_MAX_RUNTIME=1200
time_phase() {
phase="$1"
shift
start=$(date +%s)
echo "::group::arm64 $phase"
"$@"
rc=$?
end=$(date +%s)
echo "::endgroup::"
echo "timing: arm64 $phase $((end - start))s"
return "$rc"
}
time_phase autoreconf autoreconf -fvi
time_phase configure ./configure --enable-silent-rules --enable-testbench \
--enable-imdiag --disable-imdocker \
--enable-imfile \
--enable-impstats --enable-imptcp \
--enable-mmanon --enable-mmaudit \
--enable-mmfields --enable-mmjsonparse \
--enable-mmpstrucdata --enable-mmsequence \
--enable-mmutf8fix --enable-mail \
--enable-omprog --enable-improg \
--enable-omruleset --enable-omstdout \
--enable-omuxsock \
--disable-pmnormalize \
--enable-pmaixforwardedfrom --enable-pmciscoios \
--enable-pmcisconames --enable-pmlastmsg \
--enable-pmsnare --enable-libgcrypt \
--disable-mmnormalize --disable-omudpspoof \
--enable-relp --enable-mmsnmptrapd \
--enable-gnutls --enable-usertools \
--disable-mysql \
--disable-valgrind --disable-mmkubernetes \
--disable-omkafka --disable-imkafka \
--disable-ommongodb --disable-omrabbitmq \
--disable-mmdarwin \
--disable-helgrind --enable-uuid \
--disable-fmhttp \
--disable-elasticsearch-tests \
--disable-kafka-tests --disable-snmp-tests
time_phase build make -j8
time_phase check make -j10 check
'
- name: Skip arm64 CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping arm64 CI."
i386_CI:
needs: [compile, changes]
if: ${{ needs.compile.result == 'success' && needs.changes.outputs.code == 'true' }}
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 75
name: i386 CI (Debian 13, linux/386)
steps:
- name: git checkout project
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: fetch upstream (for changed-files diff)
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
git remote add upstream https://github.com/${{ github.repository }}.git
git fetch upstream "$BASE_REF"
- name: Check for code changes
id: code_changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
**/*.c
**/*.h
grammar/lexer.l
grammar/grammar.y
tests/*.sh
diag.sh
**/Makefile.am
configure.ac
.github/workflows/run_checks.yml
files_ignore: |
doc/Makefile.am
- name: Run i386 build and regular testbench
if: steps.code_changes.outputs.any_changed == 'true'
run: |
chmod -R go+rw .
docker run --rm --platform linux/386 \
-e ARCH=i386 \
--cap-add SYS_ADMIN \
--cap-add SYS_PTRACE \
--security-opt seccomp=unconfined \
-v "${{ github.workspace }}:/rsyslog" \
-w /rsyslog \
debian:13 bash -c '
set -e
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
build-essential autoconf autoconf-archive automake libtool libtool-bin \
pkg-config flex bison python3-docutils curl openssl \
libestr-dev libfastjson-dev libgnutls28-dev \
zlib1g-dev libgcrypt20-dev librelp-dev uuid-dev \
libyaml-dev libcurl4-gnutls-dev liblognorm-dev \
libmaxminddb-dev libsnmp-dev libssl-dev libsystemd-dev \
libzstd-dev libprotobuf-c-dev protobuf-c-compiler \
libsnappy-dev iproute2 gdb
rm -rf /var/lib/apt/lists/*
useradd --create-home rsyslogci
chown -R rsyslogci:rsyslogci /rsyslog
export CFLAGS="-g -O1 -fno-omit-frame-pointer"
export CC=gcc
export TEST_MAX_RUNTIME=1200
time_phase() {
phase="$1"
shift
start=$(date +%s)
echo "::group::i386 $phase"
"$@"
rc=$?
end=$(date +%s)
echo "::endgroup::"
echo "timing: i386 $phase $((end - start))s"
return "$rc"
}
time_su_phase() {
phase="$1"
shift
start=$(date +%s)
echo "::group::i386 $phase"
su rsyslogci -c "$*"
rc=$?
end=$(date +%s)
echo "::endgroup::"
echo "timing: i386 $phase $((end - start))s"
return "$rc"
}
time_phase autoreconf autoreconf -fvi
time_su_phase configure "./configure --enable-silent-rules \
--enable-testbench --disable-extended-tests \
--enable-imdiag --disable-imdocker \
--enable-imfile --enable-imfile-tests \
--enable-impstats --enable-imptcp \
--enable-mmanon --enable-mmaudit \
--enable-mmcount --enable-mmdblookup \
--enable-mmfields --enable-mmjsonparse \
--enable-mmnormalize --enable-mmpstrucdata \
--enable-mmrm1stspace --enable-mmsequence \
--enable-mmsnmptrapd --enable-mmutf8fix \
--enable-mail \
--disable-omhttp --enable-omjournal \
--enable-omprog --enable-omruleset \
--enable-omstdout --enable-omuxsock \
--enable-pmaixforwardedfrom --enable-pmciscoios \
--enable-pmcisconames --enable-pmlastmsg \
--enable-pmnull --enable-pmsnare \
--enable-gnutls --enable-openssl \
--enable-relp --enable-snmp \
--enable-usertools --enable-imdtls --enable-omdtls \
--enable-imjournal \
--enable-fmhash --enable-libzstd \
--enable-klog --enable-kmsg \
--enable-libsystemd=yes \
--disable-libgcrypt --disable-liblogging-stdlog \
--disable-fmhttp --disable-mysql \
--disable-valgrind --without-valgrind-testbench \
--disable-helgrind --disable-mmkubernetes \
--disable-omkafka --disable-imkafka \
--disable-ommongodb --disable-omrabbitmq \
--disable-mmdarwin \
--disable-root-tests \
--disable-elasticsearch-tests \
--disable-kafka-tests --disable-snmp-tests \
--disable-journal-tests"
time_su_phase "config sanity" "grep -q \"^#define HAVE_LIBYAML 1\" config.h"
time_su_phase build "make -j8"
time_su_phase check "timeout 45m make -j10 check"
'
- name: Skip i386 CI, no relevant changes
if: steps.code_changes.outputs.any_changed != 'true'
run: echo "No relevant changes detected; skipping i386 CI."