Skip to content

feat: full safety and cyber pack — TARA, FMEA, SAS, boundary, safety manual, IEC 62443, CI hardening #6

feat: full safety and cyber pack — TARA, FMEA, SAS, boundary, safety manual, IEC 62443, CI hardening

feat: full safety and cyber pack — TARA, FMEA, SAS, boundary, safety manual, IEC 62443, CI hardening #6

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
name: ${{ matrix.os }} / ${{ matrix.compiler }} / C++${{ matrix.std }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
compiler: clang-14
std: 17
cc: clang-14
cxx: clang++-14
- os: ubuntu-22.04
compiler: gcc-12
std: 17
cc: gcc-12
cxx: g++-12
- os: ubuntu-22.04
compiler: gcc-12
std: 20
cc: gcc-12
cxx: g++-12
- os: macos-14
compiler: clang
std: 17
cc: clang
cxx: clang++
- os: windows-2022
compiler: msvc
std: 17
cc: cl
cxx: cl
steps:
- uses: actions/checkout@v4
- name: Install tools (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update -qq
sudo apt-get install -y cmake ninja-build
- name: Set up MSVC environment (Windows)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
- name: Configure
shell: bash
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${{ matrix.std }} \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-G Ninja
- name: Build
run: cmake --build build --parallel
- name: Test (single-threaded to avoid TempDir races)
run: ctest --test-dir build --output-on-failure -j1
coverage:
name: Coverage (LCOV)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build lcov
- name: Configure (coverage build)
run: |
cmake -B build-cov \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="--coverage -O0" \
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
-G Ninja
- name: Build
run: cmake --build build-cov --parallel
- name: Test
run: ctest --test-dir build-cov --output-on-failure -j1
- name: Collect LCOV data
run: |
lcov --capture \
--directory build-cov \
--output-file coverage.info
lcov --remove coverage.info \
'*/tests/*' '*/catch2/*' '*/FetchContent/*' '*/_deps/*' \
'/usr/include/*' '/usr/lib/*' \
--output-file coverage.info
- name: Enforce 70% line coverage gate
run: |
COVERAGE=$(lcov --summary coverage.info 2>&1 | awk '/lines/ {gsub(/%/,""); print $2}')
echo "Line coverage: ${COVERAGE}%"
if ! awk "BEGIN {exit (${COVERAGE} + 0 >= 70) ? 0 : 1}"; then
echo "::error::Line coverage ${COVERAGE}% is below the required 70%"
exit 1
fi
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.info
relay-conform:
name: RELAY conformance (relay conform)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build
- name: Build CLI
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17 \
-G Ninja
cmake --build build --parallel --target cpp-lin-cli
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 'stable'
- name: Install relay tool
run: go install github.com/SoundMatt/RELAY/cmd/relay@latest
- name: RELAY conformance gate
run: relay conform ./build/cli/cpp-lin-cli --strict
- name: RELAY interop gate (§20 Continuous Conformance)
run: relay interop --protocol LIN ./build/cli/cpp-lin-cli
sanitizers:
name: ASan + UBSan (IEC 61508 SIL-2 dynamic analysis)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
sudo apt-get update -qq
sudo apt-get install -y cmake ninja-build gcc-12 g++-12
- name: Configure (ASan + UBSan)
env:
CC: gcc-12
CXX: g++-12
run: |
cmake -B build-san \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined" \
-G Ninja
- name: Build
run: cmake --build build-san --parallel
- name: Test with sanitizers
env:
ASAN_OPTIONS: "halt_on_error=1:detect_stack_use_after_return=1"
UBSAN_OPTIONS: "halt_on_error=1:print_stacktrace=1"
run: ctest --test-dir build-san --output-on-failure -j1
tsan:
name: ThreadSanitizer (REQ-VIRT-018 concurrent access)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
sudo apt-get update -qq
sudo apt-get install -y cmake ninja-build gcc-12 g++-12
- name: Configure (ThreadSanitizer)
env:
CC: gcc-12
CXX: g++-12
run: |
cmake -B build-tsan \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \
-G Ninja
- name: Build
run: cmake --build build-tsan --parallel
- name: Test with ThreadSanitizer
env:
TSAN_OPTIONS: "halt_on_error=1:second_deadlock_stack=1"
run: ctest --test-dir build-tsan --output-on-failure -j1
fusa-asil-b:
name: cpp-FuSa ASIL-B qualification
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- name: Check out cpp-LIN
uses: actions/checkout@v4
with:
path: cpp-LIN
- name: Check out cpp-FuSa
uses: actions/checkout@v4
with:
repository: SoundMatt/cpp-FuSa
path: cpp-FuSa
- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build zip
- name: Build cpfusa
run: |
cmake -B cpp-FuSa/build \
-S cpp-FuSa \
-DCMAKE_BUILD_TYPE=Release \
-G Ninja
cmake --build cpp-FuSa/build --parallel
- name: cpfusa init
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa init --name cpp-LIN --standard iso26262 --asil ASIL-B --project-version 0.1.0 --force || true
- name: cpfusa check
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa check --dir .
- name: cpfusa lint
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa lint --dir .
- name: cpfusa trace (requirements traceability)
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa trace --dir .
- name: cpfusa cyber
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa cyber --write --dir .
- name: cpfusa qualify (ASIL-B gate)
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa qualify --dir .
- name: cpfusa hara init
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa hara init --project cpp-LIN --dir . || true
- name: cpfusa iso26262 (ASIL-B)
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa iso26262 \
--asil ASIL-B \
--output iso26262-gap-report.json \
--dir . || true
- name: cpfusa iec61508 (SIL-2)
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa iec61508 \
--sil SIL-2 \
--output iec61508-gap-report.json \
--dir . || true
- name: cpfusa boundary
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa boundary --dir .
- name: cpfusa tara
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa tara --dir .
- name: cpfusa fmea
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa fmea --dir .
- name: cpfusa safety-case
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa safety-case --dir .
- name: cpfusa sas
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa sas --dir .
- name: cpfusa sci
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa sci --dir .
- name: cpfusa badge
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa badge --dir .
- name: cpfusa vuln
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa vuln --dir .
- name: cpfusa metrics record
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa metrics record --dir .
- name: cpfusa report (JSON)
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa report \
--format json \
--output check-report.json \
--dir .
- name: Upload ASIL-B evidence artifacts
uses: actions/upload-artifact@v4
with:
name: asil-b-evidence
path: |
cpp-LIN/check-report.json
cpp-LIN/qualify-report.json
cpp-LIN/cyber-report.json
cpp-LIN/tara.json
cpp-LIN/tara.md
cpp-LIN/fmea.json
cpp-LIN/fmea.csv
cpp-LIN/safety-case.json
cpp-LIN/safety-case.mermaid
cpp-LIN/safety-case.md
cpp-LIN/sbom.json
cpp-LIN/provenance.json
cpp-LIN/artifact-manifest.json
cpp-LIN/fusa-badge.svg
cpp-LIN/iso26262-gap-report.json
cpp-LIN/iec61508-gap-report.json
cpp-LIN/sas.json
cpp-LIN/sas.md
cpp-LIN/sci.json
cpp-LIN/vuln.json
cpp-LIN/boundary.mermaid
cpp-LIN/boundary.dot
cpp-LIN/.fusa-hara.json
cpp-LIN/.fusa-metrics.json
cpp-LIN/TARA.md
cpp-LIN/SAFETY_MANUAL.md
cpp-LIN/INCIDENT-RESPONSE.md
cpp-LIN/SECURITY.md
static-analysis:
name: Static analysis (clang-tidy)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
sudo apt-get update -qq
sudo apt-get install -y cmake ninja-build clang-14 clang-tidy-14
- name: Configure (generate compile_commands.json)
env:
CC: clang-14
CXX: clang++-14
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-G Ninja
- name: clang-tidy
run: |
find src include -name '*.cpp' -o -name '*.hpp' | \
xargs clang-tidy-14 \
-p build \
--checks='-*,clang-analyzer-*,bugprone-*,modernize-use-override,modernize-use-nullptr,cppcoreguidelines-no-malloc' \
2>&1 | tee clang-tidy.log || true
if grep -q "error:" clang-tidy.log; then
echo "::error::clang-tidy reported errors"
grep "error:" clang-tidy.log
exit 1
fi
docker-build:
name: Docker build (smoke test)
runs-on: ubuntu-22.04
needs: build-and-test
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -f docker/Dockerfile --target test -t cpp-lin-test .
- name: Smoke test - run all tests in container
run: docker run --rm cpp-lin-test
sarif:
name: SARIF upload
runs-on: ubuntu-22.04
needs: build-and-test
permissions:
security-events: write
steps:
- name: Check out cpp-LIN
uses: actions/checkout@v4
with:
path: cpp-LIN
- name: Check out cpp-FuSa
uses: actions/checkout@v4
with:
repository: SoundMatt/cpp-FuSa
path: cpp-FuSa
- name: Install tools
run: sudo apt-get update -qq && sudo apt-get install -y cmake ninja-build
- name: Build cpfusa
run: |
cmake -B cpp-FuSa/build \
-S cpp-FuSa \
-DCMAKE_BUILD_TYPE=Release \
-G Ninja
cmake --build cpp-FuSa/build --parallel
- name: cpfusa init
working-directory: cpp-LIN
run: ../cpp-FuSa/build/cpfusa init --name cpp-LIN --standard iso26262 --asil ASIL-B --project-version 0.1.0 --force || true
- name: Generate SARIF report
working-directory: cpp-LIN
run: |
../cpp-FuSa/build/cpfusa check \
--format sarif \
--output cpfusa.sarif \
--dir . || true
- name: Upload SARIF to GitHub Security tab
if: hashFiles('cpp-LIN/cpfusa.sarif') != ''
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: cpp-LIN/cpfusa.sarif