Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/actions/build-spine/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Build Spine
description: Install the build dependencies, then bootstrap and configure Spine.

inputs:
extra-packages:
description: Additional apt packages, beyond the set every Spine build needs.
required: false
default: ''
configure-args:
description: Arguments passed through to ./configure.
required: false
default: ''
cflags:
description: CFLAGS for ./configure.
required: false
default: ''
ldflags:
description: LDFLAGS for ./configure.
required: false
default: ''

runs:
using: composite
steps:
# mysql-server is deliberately absent: configure only looks for mysql.h and
# libmysqlclient, both of which come from libmysqlclient-dev, and no job
# starts or connects to a server.
- name: Install build dependencies
shell: bash
env:
EXTRA_PACKAGES: ${{ inputs.extra-packages }}
run: |
set -euo pipefail
sudo apt-get update
# shellcheck disable=SC2086
sudo apt-get install -y \
autoconf automake libtool build-essential help2man dos2unix \
libmysqlclient-dev libsnmp-dev libssl-dev libcmocka-dev \
$EXTRA_PACKAGES

- name: Bootstrap and configure
shell: bash
env:
CONFIGURE_ARGS: ${{ inputs.configure-args }}
IN_CFLAGS: ${{ inputs.cflags }}
IN_LDFLAGS: ${{ inputs.ldflags }}
run: |
set -euo pipefail
./bootstrap
args=()
if [ -n "$CONFIGURE_ARGS" ]; then
read -ra args <<< "$CONFIGURE_ARGS"
fi
if [ -n "$IN_CFLAGS" ]; then
args+=("CFLAGS=$IN_CFLAGS")
fi
if [ -n "$IN_LDFLAGS" ]; then
args+=("LDFLAGS=$IN_LDFLAGS")
fi
./configure ${args[@]+"${args[@]}"}
120 changes: 39 additions & 81 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,82 +24,45 @@ jobs:
env:
CC: ${{ matrix.compiler }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
mysql-server libmysqlclient-dev \
libsnmp-dev libssl-dev build-essential \
help2man autoconf automake libtool dos2unix libcmocka-dev

- name: Prepare for Spine Build
run: |
./bootstrap
./configure --enable-warnings
- uses: ./.github/actions/build-spine
with:
configure-args: --enable-warnings

- name: Build Spine
run: |
set -euo pipefail
make -j"$(nproc)"

- name: Run the unit tests
run: |
set -euo pipefail
make check

# cppcheck:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
#
# - name: Install cppcheck
# run: |
# sudo apt-get update
# sudo apt-get install -y cppcheck build-essential
#
# - name: Run cppcheck
# run: |
# cppcheck \
# --enable=all \
# --std=c11 \
# --error-exitcode=1 \
# --suppress=missingIncludeSystem \
# --suppress=unusedFunction \
# --suppress=checkersReport \
# --suppress=variableScope \
# --suppress=unreadVariable \
# --suppress=shadowVariable \
# --suppress=constVariablePointer \
# --suppress=redundantAssignment \
# --suppress=toomanyconfigs \
# *.c *.h

# Coverage is reported, not gated. The number is only meaningful once
# something measures it; the threshold conversation comes after that.
coverage:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install build dependencies
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y mysql-server libmysqlclient-dev libsnmp-dev \
libssl-dev build-essential help2man autoconf automake libtool \
dos2unix libcmocka-dev gcovr
- uses: ./.github/actions/build-spine
with:
extra-packages: gcovr
cflags: -g -O0 --coverage
ldflags: --coverage

- name: Build instrumented
run: |
set -euo pipefail
./bootstrap
./configure CFLAGS="-g -O0 --coverage" LDFLAGS="--coverage"
make -j"$(nproc)"

- name: Run the unit tests
run: make check
run: |
set -euo pipefail
make check

- name: Report coverage
run: |
Expand All @@ -113,9 +76,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.x"

Expand All @@ -127,71 +90,66 @@ jobs:
# informational so we have a baseline to chip away at.
- name: Run flawfinder
run: |
set -euo pipefail
flawfinder \
--minlevel=3 \
--error-level=5 \
--columns \
--context \
. | tee flawfinder-report.txt

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: flawfinder-report
path: flawfinder-report.txt

# Spine is a threaded network daemon; ASan and UBSan are the checks most
# likely to catch a real defect here.
# likely to catch a real defect here. The unit tests are what actually
# exercises the code, so they are what runs instrumented.
sanitizers:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
CC: clang
ASAN_OPTIONS: detect_leaks=1:exitcode=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install build dependencies
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y clang mysql-server libmysqlclient-dev libsnmp-dev \
libssl-dev build-essential help2man autoconf automake libtool dos2unix libcmocka-dev
- uses: ./.github/actions/build-spine
with:
extra-packages: clang
cflags: -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1
ldflags: -fsanitize=address,undefined

- name: Build with ASan and UBSan
env:
CC: clang
run: |
set -euo pipefail
./bootstrap
./configure \
CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -g -O1" \
LDFLAGS="-fsanitize=address,undefined"
make -j"$(nproc)"

- name: Run the binary under the sanitizers
env:
ASAN_OPTIONS: detect_leaks=1:exitcode=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
- name: Run the unit tests under the sanitizers
run: |
set -euo pipefail
make check

- name: Smoke-test the binary under the sanitizers
run: |
set -euo pipefail
./spine --version
./spine --help > /dev/null

# A release tarball that cannot be compiled is a release blocker, and the
# only way to catch it is to build from the tarball the way a packager does.
distcheck:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install build dependencies
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y mysql-server libmysqlclient-dev libsnmp-dev \
libssl-dev build-essential help2man autoconf automake libtool dos2unix libcmocka-dev
- uses: ./.github/actions/build-spine

- name: make distcheck
run: |
set -euo pipefail
./bootstrap
./configure
make distcheck
19 changes: 5 additions & 14 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install build dependencies
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y clang libmysqlclient-dev libsnmp-dev libssl-dev \
autoconf automake libtool help2man pkg-config

- name: Generate config.h
run: |
set -euo pipefail
./bootstrap
./configure
- uses: ./.github/actions/build-spine
with:
extra-packages: clang pkg-config

# A pull request gets a short regression run against the committed corpus.
# The weekly schedule runs long enough to explore.
Expand All @@ -47,7 +38,7 @@ jobs:
fi
make -C tests/fuzz FUZZ_SECONDS="$seconds" run

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure()
with:
name: fuzz-crashes
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Brings up MariaDB and an snmpd, then polls a real device through
# poll_host() and checks the value lands in poller_output.
- name: Poll an SNMPv3 device end to end
run: tests/snmpv3/scripts/run-integration.sh
run: |
set -euo pipefail
tests/snmpv3/scripts/run-integration.sh

- name: Show container logs on failure
if: failure()
run: |
set -euo pipefail
cd tests/snmpv3
docker compose logs --no-color || true