From 66bf357a73612dc185bda95e63b9a5eaee9e9ca1 Mon Sep 17 00:00:00 2001 From: Patryk Osmaczko <33099791+osmaczko@users.noreply.github.com> Date: Thu, 12 Feb 2026 21:31:17 +0100 Subject: [PATCH] chore: add smoke test and redesign CI workflow Add a smoke test that validates the binary links all dependencies at runtime by instantiating a client without networking. Redesign CI into separate build and test jobs, with test gated on build. --- .github/workflows/ci.yml | 106 +++++++++++++++++++++++++++++ .github/workflows/test-windows.yml | 76 --------------------- .github/workflows/test.yml | 23 ------- Makefile | 2 +- library/declare_lib.nim | 2 +- nim_chat_poc.nimble | 11 +-- tests/smoke_test.nim | 21 ++++++ 7 files changed, 135 insertions(+), 106 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/test-windows.yml delete mode 100644 .github/workflows/test.yml create mode 100644 tests/smoke_test.nim diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c17caac --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,106 @@ +name: ci + +on: + pull_request: + branches: + - main + paths-ignore: + - "**README.md" + - ".gitignore" + - "LICENSE" + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + # Cache the Nim compiler built by nimbus-build-system (NBS). + # Building Nim from source is the slowest part of `make update`. + # Keyed on the NBS submodule commit — auto-invalidates when NBS is bumped. + - id: nbs + run: echo "hash=$(git rev-parse HEAD:vendor/nimbus-build-system)" >> $GITHUB_OUTPUT + - uses: actions/cache@v4 + with: + path: vendor/nimbus-build-system/vendor/Nim + key: ${{ runner.os }}-nbs-${{ steps.nbs.outputs.hash }} + - run: make update + - run: make all + + test: + needs: build + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - id: nbs + run: echo "hash=$(git rev-parse HEAD:vendor/nimbus-build-system)" >> $GITHUB_OUTPUT + - uses: actions/cache@v4 + with: + path: vendor/nimbus-build-system/vendor/Nim + key: ${{ runner.os }}-nbs-${{ steps.nbs.outputs.hash }} + - run: make update + - run: make tests + + test-windows: + needs: build + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + env: + MSYSTEM: MINGW64 + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + git + base-devel + mingw-w64-x86_64-toolchain + make + cmake + upx + mingw-w64-x86_64-rust + mingw-w64-x86_64-postgresql + mingw-w64-x86_64-gcc + mingw-w64-x86_64-gcc-libs + mingw-w64-x86_64-libwinpthread-git + mingw-w64-x86_64-zlib + mingw-w64-x86_64-openssl + mingw-w64-x86_64-python + mingw-w64-x86_64-cmake + mingw-w64-x86_64-llvm + mingw-w64-x86_64-clang + - run: | + echo "/usr/bin:$PATH" >> $GITHUB_PATH + echo "/mingw64/bin:$PATH" >> $GITHUB_PATH + echo "/usr/lib:$PATH" >> $GITHUB_PATH + echo "/mingw64/lib:$PATH" >> $GITHUB_PATH + - run: which upx gcc g++ make cmake cargo rustc python make mingw32-make + - id: nbs + run: echo "hash=$(git rev-parse HEAD:vendor/nimbus-build-system)" >> $GITHUB_OUTPUT + shell: bash + - uses: actions/cache@v4 + with: + path: vendor/nimbus-build-system/vendor/Nim + key: ${{ runner.os }}-nbs-${{ steps.nbs.outputs.hash }} + - run: make update + - run: | + cd vendor/nwaku/vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc + make -f Makefile.mingw CC=gcc CXX=g++ libminiupnpc.a V=1 + - run: | + cd vendor/nwaku/vendor/nim-nat-traversal/vendor/libnatpmp-upstream + make CC="gcc -fPIC -D_WIN32_WINNT=0x0600 -DNATPMP_STATICLIB" libnatpmp.a V=1 + - run: make tests diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml deleted file mode 100644 index bfc142c..0000000 --- a/.github/workflows/test-windows.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: test-windows - -on: - pull_request: - branches: - - main - paths-ignore: - - '**README.md' - - '.gitignore' - - 'LICENSE' -jobs: - tests-tasks: - runs-on: windows-latest - - defaults: - run: - shell: msys2 {0} - - env: - MSYSTEM: MINGW64 - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 - with: - update: true - install: >- - git - base-devel - mingw-w64-x86_64-toolchain - make - cmake - upx - mingw-w64-x86_64-rust - mingw-w64-x86_64-postgresql - mingw-w64-x86_64-gcc - mingw-w64-x86_64-gcc-libs - mingw-w64-x86_64-libwinpthread-git - mingw-w64-x86_64-zlib - mingw-w64-x86_64-openssl - mingw-w64-x86_64-python - mingw-w64-x86_64-cmake - mingw-w64-x86_64-llvm - mingw-w64-x86_64-clang - - - name: Add UPX to PATH - run: | - echo "/usr/bin:$PATH" >> $GITHUB_PATH - echo "/mingw64/bin:$PATH" >> $GITHUB_PATH - echo "/usr/lib:$PATH" >> $GITHUB_PATH - echo "/mingw64/lib:$PATH" >> $GITHUB_PATH - - - name: Verify dependencies - run: | - which upx gcc g++ make cmake cargo rustc python make mingw32-make - - - name: Update - run: make update - - - name: Building miniupnpc - run: | - cd vendor/nwaku/vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc - make -f Makefile.mingw CC=gcc CXX=g++ libminiupnpc.a V=1 - cd ../../../../../../.. - - - name: Building libnatpmp - run: | - cd vendor/nwaku/vendor/nim-nat-traversal/vendor/libnatpmp-upstream - make CC="gcc -fPIC -D_WIN32_WINNT=0x0600 -DNATPMP_STATICLIB" libnatpmp.a V=1 - cd ../../../../../../ - - - name: Tests - run: make tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 46f55d1..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: test - -on: - pull_request: - branches: - - main - paths-ignore: - - '**README.md' - - '.gitignore' - - 'LICENSE' -jobs: - tests-tasks: - strategy: - matrix: - os: [ubuntu-latest, macOS-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Update - run: make update - - name: Tests - run: make tests diff --git a/Makefile b/Makefile index 3f191d9..d243276 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ endif .PHONY: all update clean # default target, because it's the first one that doesn't start with '.' -all: | bot_echo pingpong +all: | bot_echo pingpong liblogoschat test_file := $(word 2,$(MAKECMDGOALS)) define test_name diff --git a/library/declare_lib.nim b/library/declare_lib.nim index 2051f37..3d8573d 100644 --- a/library/declare_lib.nim +++ b/library/declare_lib.nim @@ -1,7 +1,7 @@ import ffi import src/chat/client -declareLibrary("chat") +declareLibrary("logoschat") proc set_event_callback( ctx: ptr FFIContext[ChatClient], diff --git a/nim_chat_poc.nimble b/nim_chat_poc.nimble index 33510e6..04eaf01 100644 --- a/nim_chat_poc.nimble +++ b/nim_chat_poc.nimble @@ -39,17 +39,17 @@ proc buildLibrary(name: string, srcDir = "library/", params = "", lang = "c") = ## Build a shared library (.so on Linux, .dylib on macOS, .dll on Windows) if not dirExists "build": mkDir "build" - + # Determine library extension based on OS let libExt = when defined(macosx): "dylib" elif defined(windows): "dll" else: "so" - + var extra_params = params for i in 2 ..< paramCount(): extra_params &= " " & paramStr(i) - - exec "nim " & lang & " --app:lib --out:build/lib" & name & "." & libExt & + + exec "nim " & lang & " --app:lib --out:build/lib" & name & "." & libExt & " --mm:refc --nimMainPrefix:lib" & name & " " & extra_params & " " & srcDir & "lib" & name & ".nim" @@ -59,6 +59,7 @@ proc test(name: string, params = "-d:chronicles_log_level=DEBUG", lang = "c") = task tests, "Build & run tests": test "all_tests", "-d:chronicles_log_level=ERROR -d:chronosStrictException" + test "smoke_test", "-d:chronicles_log_level=ERROR" task waku_example, "Build Waku based simple example": let name = "waku_example" @@ -77,5 +78,5 @@ task pingpong, "Build the Pingpong example": buildBinary name, "examples/", "-d:chronicles_log_level='INFO' -d:chronicles_disabled_topics='waku node' " task liblogoschat, "Build the Chat SDK shared library (C bindings)": - buildLibrary "logoschat", "library/", + buildLibrary "logoschat", "library/", "-d:chronicles_log_level='INFO' -d:chronicles_enabled=on --path:src --path:vendor/nim-ffi" diff --git a/tests/smoke_test.nim b/tests/smoke_test.nim new file mode 100644 index 0000000..288df6a --- /dev/null +++ b/tests/smoke_test.nim @@ -0,0 +1,21 @@ +# Smoke test: validates that the binary links all dependencies at runtime. +# No networking, no start(), no message exchange — just instantiation. + +import ../src/chat + +proc main() = + try: + let waku = initWakuClient(DefaultConfig()) + let ident = createIdentity("SmokeTest") + var client = newClient(waku, ident) + if client.isNil: + raise newException(CatchableError, "newClient returned nil") + let id = client.getId() + echo "smoke_test: OK (client id: " & id & ")" + quit(QuitSuccess) + except CatchableError as e: + echo "smoke_test: FAILED — " & e.msg + quit(QuitFailure) + +when isMainModule: + main()