name: CI on: push: branches: [ main, 'release/**' ] pull_request: branches: [ main, 'release/**' ] workflow_dispatch: schedule: - cron: '17 3 * * *' permissions: contents: read env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: pr-gate: name: PR gate (${{ matrix.os }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-24.04, macos-latest] steps: - uses: actions/checkout@v6 - name: Install dependencies (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y expect libssh-dev - name: Install dependencies (macOS) if: runner.os == 'macOS' run: | brew install libssh coreutils - name: Build run: make - name: Build with AddressSanitizer run: make asan - name: Run comprehensive tests run: make ci-test - name: Run release preflight run: make release-check extended-linux-runtime: name: Extended Linux runtime if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y expect libssh-dev valgrind - name: Run extended release preflight run: | RUN_INTEGRATION=1 RUN_SOAK=1 RUN_SLOW_CLIENT=1 make release-check - name: Check for memory leaks run: | set -eu STATE_DIR=$(mktemp -d) SERVER_LOG="$STATE_DIR/server.log" VALGRIND_LOG="$STATE_DIR/valgrind.log" PORT=13990 SERVER_PID="" cleanup() { if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true fi rm -rf "$STATE_DIR" } trap cleanup EXIT ssh-keygen -q -t rsa -b 4096 -m PEM -N "" -f "$STATE_DIR/host_key" chmod 600 "$STATE_DIR/host_key" TNT_RATE_LIMIT=0 valgrind --leak-check=full --error-exitcode=99 --log-file="$VALGRIND_LOG" \ ./tnt -p "$PORT" -d "$STATE_DIR" >"$SERVER_LOG" 2>&1 & SERVER_PID=$! READY=0 for _ in $(seq 1 60); do if ! kill -0 "$SERVER_PID" 2>/dev/null; then break fi OUT=$(ssh -n -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o BatchMode=yes -p "$PORT" localhost health 2>/dev/null || true) if [ "$OUT" = "ok" ]; then READY=1 break fi sleep 1 done if [ "$READY" -ne 1 ]; then echo "::group::server log" cat "$SERVER_LOG" || true echo "::endgroup::" echo "::group::valgrind log" cat "$VALGRIND_LOG" || true echo "::endgroup::" exit 1 fi kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true SERVER_PID="" if ! grep -q "ERROR SUMMARY: 0 errors" "$VALGRIND_LOG"; then cat "$VALGRIND_LOG" exit 1 fi portable-container-builds: name: Portable build (${{ matrix.name }}) if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: include: - name: debian-stable-glibc image: debian:stable-slim setup: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential libssh-dev ca-certificates - name: ubuntu-24.04-glibc image: ubuntu:24.04 setup: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential libssh-dev ca-certificates - name: alpine-musl image: alpine:3.20 setup: apk add --no-cache build-base libssh-dev ca-certificates steps: - uses: actions/checkout@v6 - name: Build in container run: | docker run --rm -v "$PWD:/src:ro" "${{ matrix.image }}" sh -c ' set -eu ${{ matrix.setup }} mkdir /work cp -R /src/. /work/ cd /work make clean make ./tnt --version ./tntctl --version ' package-recipe-gate: name: Package recipe gate if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'push' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - name: Install packaging tools run: | sudo apt-get update sudo apt-get install -y ruby cpio - name: Validate packaging metadata run: | for script in scripts/*.sh; do sh -n "$script" done bash -n packaging/arch/PKGBUILD ruby -c packaging/homebrew/tnt-chat.rb scripts/package_debian_source.sh "$RUNNER_TEMP/debian-source"