name: ci on: push: pull_request: # One runner: cancel the previous push's jobs (avoids a stuck ASan job # blocking every later commit). concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: linux: runs-on: ubuntu-latest timeout-minutes: 30 strategy: fail-fast: false matrix: cc: [gcc, clang] steps: - uses: actions/checkout@v4 - name: Install dependencies run: | SUDO=$(command -v sudo || true) $SUDO bash scripts/ci_pkg_mirror.sh $SUDO apt-get update $SUDO apt-get install -y --no-install-recommends \ build-essential clang cmake pkg-config python3 \ libcurl4-openssl-dev libncurses-dev - name: Build (warnings are errors) run: make CC=${{ matrix.cc }} CFLAGS="-std=c11 -Wall -Wextra -O2 -g -Werror" -j"$(nproc)" - name: Unit tests run: make CC=${{ matrix.cc }} check - name: CMake build + ctest run: | cmake -B build -DCMAKE_C_COMPILER=${{ matrix.cc }} -DCST_BUILD_TUI=ON cmake --build build -j"$(nproc)" ctest --test-dir build --output-on-failure - name: Smoke test run: | ./cst-agent --help ./cst-agent --workspace "$PWD" --list-sessions ./cst-agent --demo-ctl --workspace . sanitizers: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - name: Install dependencies run: | SUDO=$(command -v sudo || true) $SUDO bash scripts/ci_pkg_mirror.sh $SUDO apt-get update $SUDO apt-get install -y --no-install-recommends \ build-essential pkg-config libcurl4-openssl-dev libncurses-dev - name: ASan + UBSan timeout-minutes: 10 env: # Docker runners without SYS_PTRACE can spin forever on # AddressSanitizer:DEADLYSIGNAL; keep the handler shallow and # hard-cap wall time so the single runner is not wedged. ASAN_OPTIONS: abort_on_error=1:halt_on_error=1:detect_leaks=0:use_sigaltstack=0 UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 run: | if ! timeout -s KILL 480 make asan; then echo "::error::make asan failed or timed out after 8m (if the log is only DEADLYSIGNAL, give the runner SYS_PTRACE / seccomp=unconfined)" exit 1 fi musl: runs-on: ubuntu-latest timeout-minutes: 30 container: alpine:3.20 steps: - name: Install dependencies run: | # Container has no checkout yet; rewrite apk repos in place. sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' \ /etc/apk/repositories apk add --no-cache build-base pkgconf curl-dev ncurses-dev git nodejs bash python3 - uses: actions/checkout@v4 - name: Build + unit tests run: | make CFLAGS="-std=c11 -Wall -Wextra -O2 -Werror" -j"$(nproc)" make check # Gitea instances rarely have macOS runners; set the repository variable # HAVE_MACOS_RUNNER=true once one is registered. macos: if: ${{ vars.HAVE_MACOS_RUNNER == 'true' }} runs-on: macos-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Install dependencies run: brew install ncurses curl pkg-config - name: Build + unit tests run: | make -j"$(sysctl -n hw.ncpu)" make check