mq-bridge-py-basic 0.2.20__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/ci.yml +54 -79
  2. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/ibm-mq.yml +37 -11
  3. mq_bridge_py_basic-0.3.0/.github/workflows/node.yml +69 -0
  4. mq_bridge_py_basic-0.3.0/.github/workflows/publish-node.yml +251 -0
  5. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/publish-python.yml +6 -0
  6. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/python.yml +13 -0
  7. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/CONFIGURATION.md +80 -0
  8. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/Cargo.lock +114 -2
  9. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/Cargo.toml +1 -1
  10. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/PKG-INFO +1 -1
  11. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/README.md +2 -2
  12. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq-bridge.schema.json +48 -0
  13. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq_bridge/config.pyi +158 -152
  14. mq_bridge_py_basic-0.3.0/package-lock.json +6 -0
  15. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/Cargo.toml +9 -6
  16. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/scripts/gen_config_types.py +2 -1
  17. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/src/lib.rs +56 -7
  18. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/tests/test_config_types.py +7 -2
  19. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/tests/test_public_api.py +9 -0
  20. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/httparena/README.md +1 -1
  21. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +2 -2
  22. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/canonical_message.rs +2 -2
  23. mq_bridge_py_basic-0.3.0/src/connection_registry.rs +280 -0
  24. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/amqp.rs +71 -8
  25. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/aws.rs +5 -0
  26. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/file.rs +3 -0
  27. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/grpc.rs +33 -2
  28. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/http.rs +219 -53
  29. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/ibm_mq.rs +3 -0
  30. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/kafka.rs +57 -13
  31. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/endpoint.rs +176 -48
  32. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/mongodb.rs +33 -1
  33. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/mqtt.rs +8 -0
  34. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/nats.rs +39 -5
  35. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/sled.rs +5 -0
  36. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/sqlx.rs +41 -1
  37. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/static_endpoint.rs +4 -0
  38. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/stream_buffer.rs +3 -0
  39. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/websocket.rs +65 -22
  40. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/zeromq.rs +5 -0
  41. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/event_store.rs +3 -0
  42. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/lib.rs +1 -0
  43. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/buffer.rs +3 -0
  44. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/cookie_jar.rs +3 -0
  45. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/deduplication.rs +3 -0
  46. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/delay.rs +3 -0
  47. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/limiter.rs +3 -0
  48. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/metrics.rs +3 -0
  49. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/random_panic.rs +3 -0
  50. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/weak_join.rs +5 -1
  51. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/models.rs +30 -0
  52. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/route.rs +217 -13
  53. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/test_utils.rs +25 -6
  54. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/traits.rs +176 -43
  55. mq_bridge_py_basic-0.3.0/tests/README.md +29 -0
  56. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/armature_integration.rs +2 -0
  57. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/amqp.rs +65 -0
  58. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/grpc_tls.rs +2 -0
  59. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/http_tls.rs +3 -1
  60. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/ibm_mq_tls.rs +2 -0
  61. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/kafka_tls.rs +1 -0
  62. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mongodb_tls.rs +1 -0
  63. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration_test.rs +8 -2
  64. mq_bridge_py_basic-0.3.0/tests/memory_leak_test.rs +134 -0
  65. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/sqlite_test.rs +3 -1
  66. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/websocket_test.rs +48 -0
  67. mq_bridge_py_basic-0.2.20/tests/README.md +0 -19
  68. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  69. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  70. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  71. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/benchmark.yml +0 -0
  72. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/release.yml +0 -0
  73. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.github/workflows/test-matrix.yml +0 -0
  74. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/.gitignore +0 -0
  75. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/ARCHITECTURE.md +0 -0
  76. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/CONTRIBUTING.md +0 -0
  77. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/LICENSE +0 -0
  78. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/LICENSE.python +0 -0
  79. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/benches/performance_bench.rs +0 -0
  80. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/benches/router_bench.rs +0 -0
  81. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/build.rs +0 -0
  82. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/claude.md +0 -0
  83. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/examples/ipc_worker_queue.yaml +0 -0
  84. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq_bridge/__init__.py +0 -0
  85. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq_bridge/__init__.pyi +0 -0
  86. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq_bridge/config.py +0 -0
  87. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/mq_bridge/py.typed +0 -0
  88. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/pyproject.toml +0 -0
  89. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/LICENSE.python +0 -0
  90. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/README.md +0 -0
  91. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  92. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/example.py +0 -0
  93. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  94. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  95. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/examples/json_route.py +0 -0
  96. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/examples/memory.yaml +0 -0
  97. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/examples/raw_route.py +0 -0
  98. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/pyproject-basic.toml +0 -0
  99. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/tests/test_packaging.py +0 -0
  100. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  101. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/tests/test_routes.py +0 -0
  102. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/python/mq-bridge-py/uv.lock +0 -0
  103. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/HTTP_STREAM_ENDPOINT_PLAN.md +0 -0
  104. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/benches/metadata_bench.rs +0 -0
  105. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  106. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  107. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/http/http_flamegraph.py +0 -0
  108. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  109. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/analysis/http/run_http_ladder.sh +0 -0
  110. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  111. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  112. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  113. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  114. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  115. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  116. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/README.md +0 -0
  117. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/postgres.yml +0 -0
  118. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/seed.sql +0 -0
  119. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/techempower/verify.sh +0 -0
  120. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/the-benchmarker/README.md +0 -0
  121. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  122. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  123. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  124. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/command_handler.rs +0 -0
  125. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/fanout.rs +0 -0
  126. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/grpc.proto +0 -0
  127. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/http_stream.rs +0 -0
  128. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/ipc_unix.rs +0 -0
  129. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/ipc_windows.rs +0 -0
  130. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/memory_transport.rs +0 -0
  131. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/mod.rs +0 -0
  132. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/memory/transport.rs +0 -0
  133. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/mod.rs +0 -0
  134. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/null.rs +0 -0
  135. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/reader.rs +0 -0
  136. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/response.rs +0 -0
  137. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/endpoints/switch.rs +0 -0
  138. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/errors.rs +0 -0
  139. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/event_handler.rs +0 -0
  140. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/extensions.rs +0 -0
  141. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/dlq.rs +0 -0
  142. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/mod.rs +0 -0
  143. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/middleware/retry.rs +0 -0
  144. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/outcomes.rs +0 -0
  145. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/publisher.rs +0 -0
  146. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/response.rs +0 -0
  147. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/src/type_handler.rs +0 -0
  148. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/aws.rs +0 -0
  149. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/config.toml +0 -0
  150. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/amqp.yml +0 -0
  151. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/aws.yml +0 -0
  152. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  153. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  154. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  155. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  156. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  157. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  158. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  159. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  160. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/kafka.yml +0 -0
  161. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mariadb.yml +0 -0
  162. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  163. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  164. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mongodb.yml +0 -0
  165. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mosquitto.conf +0 -0
  166. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  167. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  168. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  169. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  170. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mqtt.yml +0 -0
  171. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  172. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/mysql.yml +0 -0
  173. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/nats.yml +0 -0
  174. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/docker-compose/postgres.yml +0 -0
  175. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/file.rs +0 -0
  176. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/grpc.rs +0 -0
  177. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/http.rs +0 -0
  178. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/ibm_mq.rs +0 -0
  179. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/ipc.rs +0 -0
  180. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/kafka.rs +0 -0
  181. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/logic_test.rs +0 -0
  182. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mariadb.rs +0 -0
  183. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/memory.rs +0 -0
  184. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mod.rs +0 -0
  185. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mongodb.rs +0 -0
  186. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mongodb_raw.rs +0 -0
  187. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mqtt.rs +0 -0
  188. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/mysql.rs +0 -0
  189. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/nats.rs +0 -0
  190. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/performance_static.rs +0 -0
  191. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/postgres.rs +0 -0
  192. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/route.rs +0 -0
  193. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/scripts/gen_certs.sh +0 -0
  194. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/sqlite.rs +0 -0
  195. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/tls_helpers.rs +0 -0
  196. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/websocket.rs +0 -0
  197. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/integration/zeromq.rs +0 -0
  198. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/ref_test.rs +0 -0
  199. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/tls_example.rs +0 -0
  200. {mq_bridge_py_basic-0.2.20 → mq_bridge_py_basic-0.3.0}/tests/unit_tests.md +0 -0
@@ -23,17 +23,13 @@ jobs:
23
23
  with:
24
24
  components: rustfmt, clippy
25
25
 
26
- - name: Cache cargo registry
27
- uses: actions/cache@v4
26
+ - name: Cache cargo build
27
+ uses: Swatinem/rust-cache@v2
28
28
  with:
29
- path: |
30
- ~/.cargo/bin/
31
- ~/.cargo/registry/cache/
32
- ~/.cargo/git/db/
33
- target/
34
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
35
- restore-keys: |
36
- ${{ runner.os }}-cargo-
29
+ # Differentiates the matrix `check` job per feature set; evaluates to an
30
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
31
+ # job id, OS, rustc version, and lockfiles automatically.
32
+ key: ${{ matrix.features }}
37
33
 
38
34
  - name: Check formatting
39
35
  run: cargo fmt --all -- --check
@@ -65,24 +61,20 @@ jobs:
65
61
  - name: Install Rust toolchain
66
62
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
67
63
 
68
- - name: Cache cargo registry
69
- uses: actions/cache@v4
64
+ - name: Cache cargo build
65
+ uses: Swatinem/rust-cache@v2
70
66
  with:
71
- path: |
72
- ~/.cargo/bin/
73
- ~/.cargo/registry/cache/
74
- ~/.cargo/git/db/
75
- target/
76
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
77
- restore-keys: |
78
- ${{ runner.os }}-cargo-
67
+ # Differentiates the matrix `check` job per feature set; evaluates to an
68
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
69
+ # job id, OS, rustc version, and lockfiles automatically.
70
+ key: ${{ matrix.features }}
79
71
 
80
- - name: Build
72
+ - name: Check
81
73
  run: |
82
74
  if [ -z "${{ matrix.features }}" ]; then
83
- cargo build --release
75
+ cargo check --all-targets
84
76
  else
85
- cargo build --release --features "${{ matrix.features }}"
77
+ cargo check --all-targets --features "${{ matrix.features }}"
86
78
  fi
87
79
 
88
80
  # Unit tests
@@ -95,24 +87,26 @@ jobs:
95
87
  - name: Install Rust toolchain
96
88
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
97
89
 
98
- - name: Cache cargo registry
99
- uses: actions/cache@v4
90
+ - name: Cache cargo build
91
+ uses: Swatinem/rust-cache@v2
100
92
  with:
101
- path: |
102
- ~/.cargo/bin/
103
- ~/.cargo/registry/cache/
104
- ~/.cargo/git/db/
105
- target/
106
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
107
- restore-keys: |
108
- ${{ runner.os }}-cargo-
93
+ # Differentiates the matrix `check` job per feature set; evaluates to an
94
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
95
+ # job id, OS, rustc version, and lockfiles automatically.
96
+ key: ${{ matrix.features }}
109
97
 
110
98
  - name: Run unit tests
111
- run: cargo test --lib --features=full
99
+ run: cargo test --lib --features=full
112
100
  # currently - just random panic test
113
101
  # - name: Run long-running unit tests
114
102
  # run: cargo test --lib --features=full -- --ignored --nocapture
115
103
 
104
+ - name: Run non-Docker integration tests
105
+ run: cargo test --test ref_test --test sqlite_test --test tls_example --test websocket_test --features=full
106
+
107
+ - name: Memory leak soak (route commit-task JoinSet)
108
+ run: cargo test --test memory_leak_test --features=full -- --ignored --nocapture
109
+
116
110
  # Integration tests (requires Docker) split into parallel jobs
117
111
  integration-others:
118
112
  name: Integration — Others
@@ -127,17 +121,13 @@ jobs:
127
121
  - name: Install Rust toolchain
128
122
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
129
123
 
130
- - name: Cache cargo registry
131
- uses: actions/cache@v4
124
+ - name: Cache cargo build
125
+ uses: Swatinem/rust-cache@v2
132
126
  with:
133
- path: |
134
- ~/.cargo/bin/
135
- ~/.cargo/registry/cache/
136
- ~/.cargo/git/db/
137
- target/
138
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
139
- restore-keys: |
140
- ${{ runner.os }}-cargo-
127
+ # Differentiates the matrix `check` job per feature set; evaluates to an
128
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
129
+ # job id, OS, rustc version, and lockfiles automatically.
130
+ key: ${{ matrix.features }}
141
131
 
142
132
  - name: Pre-pull docker images
143
133
  run: |
@@ -175,17 +165,13 @@ jobs:
175
165
  - name: Install Rust toolchain
176
166
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
177
167
 
178
- - name: Cache cargo registry
179
- uses: actions/cache@v4
168
+ - name: Cache cargo build
169
+ uses: Swatinem/rust-cache@v2
180
170
  with:
181
- path: |
182
- ~/.cargo/bin/
183
- ~/.cargo/registry/cache/
184
- ~/.cargo/git/db/
185
- target/
186
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
187
- restore-keys: |
188
- ${{ runner.os }}-cargo-
171
+ # Differentiates the matrix `check` job per feature set; evaluates to an
172
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
173
+ # job id, OS, rustc version, and lockfiles automatically.
174
+ key: ${{ matrix.features }}
189
175
 
190
176
  - name: Pre-pull docker images
191
177
  run: |
@@ -223,17 +209,13 @@ jobs:
223
209
  - name: Install Rust toolchain
224
210
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
225
211
 
226
- - name: Cache cargo registry
227
- uses: actions/cache@v4
212
+ - name: Cache cargo build
213
+ uses: Swatinem/rust-cache@v2
228
214
  with:
229
- path: |
230
- ~/.cargo/bin/
231
- ~/.cargo/registry/cache/
232
- ~/.cargo/git/db/
233
- target/
234
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
235
- restore-keys: |
236
- ${{ runner.os }}-cargo-
215
+ # Differentiates the matrix `check` job per feature set; evaluates to an
216
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
217
+ # job id, OS, rustc version, and lockfiles automatically.
218
+ key: ${{ matrix.features }}
237
219
 
238
220
  - name: Pre-pull docker images
239
221
  run: |
@@ -264,20 +246,13 @@ jobs:
264
246
  - name: Install Rust toolchain
265
247
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
266
248
 
267
- - name: Cache cargo registry
268
- uses: actions/cache@v4
249
+ - name: Cache cargo build
250
+ uses: Swatinem/rust-cache@v2
269
251
  with:
270
- path: |
271
- ~/.cargo/bin/
272
- ~/.cargo/registry/cache/
273
- ~/.cargo/git/db/
274
- target/
275
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
276
- restore-keys: |
277
- ${{ runner.os }}-cargo-
278
-
279
- - name: Build documentation
280
- run: cargo doc --all-features --no-deps
252
+ # Differentiates the matrix `check` job per feature set; evaluates to an
253
+ # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
254
+ # job id, OS, rustc version, and lockfiles automatically.
255
+ key: ${{ matrix.features }}
281
256
 
282
- - name: Check for broken links
283
- run: cargo doc --all-features --no-deps 2>&1 | grep -i "warning\|error" && exit 1 || exit 0
257
+ - name: Build documentation (deny warnings)
258
+ run: RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps
@@ -54,10 +54,18 @@ jobs:
54
54
  ${{ runner.os }}-cargo-
55
55
 
56
56
  - name: Install IBM MQ Client Libraries
57
+ id: mqclient
57
58
  run: |
58
59
  archive_url="$IBM_MQ_REDIST_URL"
59
60
  archive_name="$(basename "$archive_url")"
60
- curl -fsSLO "$archive_url"
61
+ # IBM's download host is occasionally unreachable from runners. Treat a
62
+ # download failure as infrastructure flakiness and skip the rest of the
63
+ # job (see `if:` guards below). Checksum/extract failures still fail.
64
+ if ! curl -fsSLO --retry 5 --retry-all-errors --retry-delay 5 --connect-timeout 30 "$archive_url"; then
65
+ echo "::warning::IBM MQ redist download failed (host unreachable); skipping IBM MQ build."
66
+ echo "available=false" >> "$GITHUB_OUTPUT"
67
+ exit 0
68
+ fi
61
69
  echo "${IBM_MQ_REDIST_SHA256} ${archive_name}" | sha256sum -c -
62
70
  # The redist archive extracts a self-contained MQ install tree
63
71
  # (bin/, lib64/, inc/, ...) with no top-level mqm/ dir, so unpack
@@ -66,16 +74,20 @@ jobs:
66
74
  sudo tar -xzf "$archive_name" -C /opt/mqm
67
75
  echo "LD_LIBRARY_PATH=/opt/mqm/lib64:$LD_LIBRARY_PATH" >> $GITHUB_ENV
68
76
  echo "MQ_INSTALLATION_PATH=/opt/mqm" >> $GITHUB_ENV
69
-
77
+ echo "available=true" >> "$GITHUB_OUTPUT"
78
+
70
79
  - name: Verify MQ client installation
80
+ if: steps.mqclient.outputs.available == 'true'
71
81
  run: |
72
82
  ls -la /opt/mqm/lib64/ || echo "MQ lib64 directory not found"
73
83
  echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
74
-
84
+
75
85
  - name: Build with IBM MQ feature
86
+ if: steps.mqclient.outputs.available == 'true'
76
87
  run: cargo build --features ibm-mq
77
-
88
+
78
89
  - name: Run clippy on IBM MQ code
90
+ if: steps.mqclient.outputs.available == 'true'
79
91
  run: cargo clippy --features ibm-mq -- -D warnings
80
92
 
81
93
  # Integration tests with Docker
@@ -102,10 +114,18 @@ jobs:
102
114
  ${{ runner.os }}-cargo-
103
115
 
104
116
  - name: Install IBM MQ Client Libraries
117
+ id: mqclient
105
118
  run: |
106
119
  archive_url="$IBM_MQ_REDIST_URL"
107
120
  archive_name="$(basename "$archive_url")"
108
- curl -fsSLO "$archive_url"
121
+ # IBM's download host is occasionally unreachable from runners. Treat a
122
+ # download failure as infrastructure flakiness and skip the rest of the
123
+ # job (see `if:` guards below). Checksum/extract failures still fail.
124
+ if ! curl -fsSLO --retry 5 --retry-all-errors --retry-delay 5 --connect-timeout 30 "$archive_url"; then
125
+ echo "::warning::IBM MQ redist download failed (host unreachable); skipping IBM MQ integration tests."
126
+ echo "available=false" >> "$GITHUB_OUTPUT"
127
+ exit 0
128
+ fi
109
129
  echo "${IBM_MQ_REDIST_SHA256} ${archive_name}" | sha256sum -c -
110
130
  # The redist archive extracts a self-contained MQ install tree
111
131
  # (bin/, lib64/, inc/, ...) with no top-level mqm/ dir, so unpack
@@ -114,23 +134,28 @@ jobs:
114
134
  sudo tar -xzf "$archive_name" -C /opt/mqm
115
135
  echo "LD_LIBRARY_PATH=/opt/mqm/lib64:$LD_LIBRARY_PATH" >> $GITHUB_ENV
116
136
  echo "MQ_INSTALLATION_PATH=/opt/mqm" >> $GITHUB_ENV
117
-
137
+ echo "available=true" >> "$GITHUB_OUTPUT"
138
+
118
139
  - name: Install JDK (for keytool - TLS tests)
140
+ if: steps.mqclient.outputs.available == 'true'
119
141
  run: |
120
142
  sudo apt-get update
121
143
  sudo apt-get install -y default-jdk
122
-
144
+
123
145
  - name: Generate TLS certificates
146
+ if: steps.mqclient.outputs.available == 'true'
124
147
  run: |
125
148
  chmod +x tests/integration/scripts/gen_certs.sh
126
149
  ./tests/integration/scripts/gen_certs.sh ibm-mq
127
-
150
+
128
151
  - name: Pull IBM MQ Docker images
152
+ if: steps.mqclient.outputs.available == 'true'
129
153
  run: |
130
154
  docker compose -f tests/integration/docker-compose/ibm_mq.yml pull
131
155
  docker compose -f tests/integration/docker-compose/ibm_mq_tls.yml pull
132
-
156
+
133
157
  - name: Run IBM MQ integration tests
158
+ if: steps.mqclient.outputs.available == 'true'
134
159
  run: |
135
160
  cargo test --test integration_test --features ibm-mq,test-utils,rustls-ring -- \
136
161
  --ignored --nocapture --test-threads=1 \
@@ -138,8 +163,9 @@ jobs:
138
163
  test_ibm_mq_performance_pipeline \
139
164
  test_ibm_mq_chaos \
140
165
  test_ibm_mq_status
141
-
166
+
142
167
  - name: Run IBM MQ TLS tests
168
+ if: steps.mqclient.outputs.available == 'true'
143
169
  run: |
144
170
  cargo test --test integration_test --features ibm-mq,test-utils,rustls-ring -- \
145
171
  --ignored --nocapture --test-threads=1 \
@@ -171,7 +197,7 @@ jobs:
171
197
  run: |
172
198
  archive_url="$IBM_MQ_REDIST_URL"
173
199
  archive_name="$(basename "$archive_url")"
174
- curl -fsSLO "$archive_url"
200
+ curl -fsSLO --retry 5 --retry-all-errors --retry-delay 5 --connect-timeout 30 "$archive_url"
175
201
  echo "${IBM_MQ_REDIST_SHA256} ${archive_name}" | sha256sum -c -
176
202
  # The redist archive extracts a self-contained MQ install tree
177
203
  # (bin/, lib64/, inc/, ...) with no top-level mqm/ dir, so unpack
@@ -0,0 +1,69 @@
1
+ name: Node
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - ".github/workflows/node.yml"
8
+ - "node/mq-bridge-node/**"
9
+ - "Cargo.toml"
10
+ - "Cargo.lock"
11
+ - "src/**"
12
+ pull_request:
13
+ branches: [main, dev]
14
+ paths:
15
+ - ".github/workflows/node.yml"
16
+ - "node/mq-bridge-node/**"
17
+ - "Cargo.toml"
18
+ - "Cargo.lock"
19
+ - "src/**"
20
+ workflow_dispatch:
21
+
22
+ env:
23
+ CARGO_TERM_COLOR: always
24
+
25
+ jobs:
26
+ test:
27
+ name: Node binding smoke test
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
31
+ with:
32
+ persist-credentials: false
33
+
34
+ - name: Install Rust toolchain
35
+ uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
36
+
37
+ - name: Set up Node
38
+ uses: actions/setup-node@v4
39
+ with:
40
+ node-version: "20"
41
+ cache: npm
42
+ cache-dependency-path: node/mq-bridge-node/package-lock.json
43
+
44
+ - name: Cache cargo registry
45
+ uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
46
+ with:
47
+ path: |
48
+ ~/.cargo/bin/
49
+ ~/.cargo/registry/cache/
50
+ ~/.cargo/git/db/
51
+ target/
52
+ key: ${{ runner.os }}-node-cargo-${{ hashFiles('**/Cargo.lock') }}
53
+ restore-keys: |
54
+ ${{ runner.os }}-node-cargo-
55
+
56
+ - name: Install Node dependencies
57
+ working-directory: node/mq-bridge-node
58
+ run: npm ci
59
+
60
+ - name: Check Rust binding
61
+ run: cargo check -p mq-bridge-node --no-default-features --features "http middleware schema"
62
+
63
+ - name: Build native addon
64
+ working-directory: node/mq-bridge-node
65
+ run: npm run build:ci
66
+
67
+ - name: Run Node tests
68
+ working-directory: node/mq-bridge-node
69
+ run: npm test
@@ -0,0 +1,251 @@
1
+ name: Publish Node Package
2
+
3
+ # Publishes the napi-rs addon as the standard layout: a thin root package
4
+ # `mq-bridge` plus one binary package per platform
5
+ # (`mq-bridge-darwin-arm64`, `mq-bridge-linux-x64-gnu`, ...). The root lists the
6
+ # platform packages as optionalDependencies, so each consumer downloads only its
7
+ # own ~20MB binary; the napi loader (native.js) requires the matching one.
8
+ #
9
+ # Linux is built inside a Debian 11 (glibc 2.31) container so the binaries run on
10
+ # RHEL 9 (glibc 2.34), Debian 11/12 and Ubuntu 20.04+ — covering the priority
11
+ # server targets. macOS/Windows build natively.
12
+ #
13
+ # Auth: token-or-OIDC. If the `NPM_TOKEN` secret is set it is used (needed for the
14
+ # one-time bootstrap that creates the 5 platform packages, since npm has no
15
+ # pending-publisher concept). Once all six packages exist and trusted publishing
16
+ # is configured for them, remove the secret and publishing continues via OIDC
17
+ # (id-token) with provenance — no token.
18
+
19
+ on:
20
+ release:
21
+ types:
22
+ - published
23
+ workflow_dispatch:
24
+
25
+ env:
26
+ CARGO_TERM_COLOR: always
27
+
28
+ jobs:
29
+ build-linux:
30
+ name: Build ${{ matrix.target }}
31
+ runs-on: ${{ matrix.runner }}
32
+ permissions:
33
+ contents: read
34
+ container:
35
+ # Debian 11 bullseye => glibc 2.31 baseline (runs on RHEL 9 / Debian 11+ /
36
+ # Ubuntu 20.04+). Pulled natively per arch on the matching runner.
37
+ image: node:20-bullseye
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ include:
42
+ - runner: ubuntu-22.04
43
+ target: x86_64-unknown-linux-gnu
44
+ - runner: ubuntu-22.04-arm
45
+ target: aarch64-unknown-linux-gnu
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+
49
+ # rdkafka builds librdkafka from source (cc/make) and aws-lc-sys needs
50
+ # cmake; the slim node image lacks these.
51
+ - name: Install build toolchain
52
+ run: |
53
+ apt-get update -qq
54
+ apt-get install -y --no-install-recommends build-essential cmake perl pkg-config
55
+
56
+ - name: Install Rust toolchain
57
+ run: |
58
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
59
+ echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
60
+
61
+ - name: Install Node dependencies
62
+ working-directory: node/mq-bridge-node
63
+ run: npm ci
64
+
65
+ - name: Build native addon (full)
66
+ working-directory: node/mq-bridge-node
67
+ env:
68
+ CARGO_NET_RETRY: "5"
69
+ CARGO_NET_GIT_FETCH_WITH_CLI: "true"
70
+ run: >-
71
+ npx napi build --platform --release --strip
72
+ --target ${{ matrix.target }}
73
+ --js native.js --dts native.d.ts
74
+
75
+ - name: Upload addon
76
+ uses: actions/upload-artifact@v4
77
+ with:
78
+ name: bindings-${{ matrix.target }}
79
+ path: node/mq-bridge-node/*.node
80
+ if-no-files-found: error
81
+
82
+ # The root package ships the generated loader; upload it once.
83
+ - name: Upload loader
84
+ if: matrix.target == 'x86_64-unknown-linux-gnu'
85
+ uses: actions/upload-artifact@v4
86
+ with:
87
+ name: loader
88
+ path: |
89
+ node/mq-bridge-node/native.js
90
+ node/mq-bridge-node/native.d.ts
91
+ if-no-files-found: error
92
+
93
+ build-native:
94
+ name: Build ${{ matrix.target }}
95
+ runs-on: ${{ matrix.runner }}
96
+ permissions:
97
+ contents: read
98
+ strategy:
99
+ fail-fast: false
100
+ matrix:
101
+ include:
102
+ - runner: macos-15-intel
103
+ target: x86_64-apple-darwin
104
+ - runner: macos-latest
105
+ target: aarch64-apple-darwin
106
+ - runner: windows-latest
107
+ target: x86_64-pc-windows-msvc
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+
111
+ - name: Set up Node
112
+ uses: actions/setup-node@v4
113
+ with:
114
+ node-version: "20"
115
+ cache: npm
116
+ cache-dependency-path: node/mq-bridge-node/package-lock.json
117
+
118
+ - name: Install Rust toolchain
119
+ uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
120
+ with:
121
+ targets: ${{ matrix.target }}
122
+
123
+ - name: Install Node dependencies
124
+ working-directory: node/mq-bridge-node
125
+ run: npm ci
126
+
127
+ - name: Build native addon (full)
128
+ working-directory: node/mq-bridge-node
129
+ env:
130
+ CARGO_NET_RETRY: "5"
131
+ CARGO_NET_GIT_FETCH_WITH_CLI: "true"
132
+ run: >-
133
+ npx napi build --platform --release --strip
134
+ --target ${{ matrix.target }}
135
+ --js native.js --dts native.d.ts
136
+
137
+ - name: Upload addon
138
+ uses: actions/upload-artifact@v4
139
+ with:
140
+ name: bindings-${{ matrix.target }}
141
+ path: node/mq-bridge-node/*.node
142
+ if-no-files-found: error
143
+
144
+ publish:
145
+ name: Publish to npm
146
+ runs-on: ubuntu-latest
147
+ needs: [build-linux, build-native]
148
+ permissions:
149
+ contents: read
150
+ id-token: write # OIDC trusted publishing + provenance
151
+ steps:
152
+ - uses: actions/checkout@v4
153
+
154
+ - name: Set up Node
155
+ uses: actions/setup-node@v4
156
+ with:
157
+ node-version: "20"
158
+ registry-url: "https://registry.npmjs.org"
159
+ cache: npm
160
+ cache-dependency-path: node/mq-bridge-node/package-lock.json
161
+
162
+ # Trusted publishing (OIDC) requires npm >= 11.5.1.
163
+ - name: Update npm
164
+ run: npm install -g npm@11.5.1
165
+
166
+ - name: Install Node dependencies
167
+ working-directory: node/mq-bridge-node
168
+ run: npm ci
169
+
170
+ - name: Sync version from Cargo workspace
171
+ working-directory: node/mq-bridge-node
172
+ run: npm run sync-version
173
+
174
+ - name: Download loader into package root
175
+ uses: actions/download-artifact@v4
176
+ with:
177
+ name: loader
178
+ path: node/mq-bridge-node
179
+
180
+ - name: Download platform addons
181
+ uses: actions/download-artifact@v4
182
+ with:
183
+ pattern: bindings-*
184
+ path: node/mq-bridge-node/artifacts
185
+
186
+ - name: Create per-platform npm dirs
187
+ working-directory: node/mq-bridge-node
188
+ run: npx napi create-npm-dirs
189
+
190
+ - name: Distribute addons into npm dirs
191
+ working-directory: node/mq-bridge-node
192
+ run: npx napi artifacts -d artifacts
193
+
194
+ - name: List npm dirs
195
+ working-directory: node/mq-bridge-node
196
+ run: ls -R npm
197
+
198
+ # The default per-platform README is ~88 bytes; paired with a 50-67MB
199
+ # binary that low-content signature trips npm's new-package spam filter
200
+ # (E403 "Package name triggered spam detection"). Give each stub a real
201
+ # README plus description/homepage/keywords so it doesn't read as a
202
+ # placeholder. (Server-side heuristic; reduces but cannot guarantee a pass.)
203
+ - name: Enrich platform package metadata
204
+ working-directory: node/mq-bridge-node
205
+ run: |
206
+ set -e
207
+ for dir in npm/*/; do
208
+ name=$(node -p "require('./$dir/package.json').name")
209
+ cat > "$dir/README.md" <<EOF
210
+ # $name
211
+
212
+ Prebuilt native binary for the [\`mq-bridge\`](https://github.com/marcomq/mq-bridge)
213
+ Node.js addon (napi-rs). This is a platform-specific dependency of the
214
+ \`mq-bridge\` package and is selected automatically via optionalDependencies —
215
+ you install \`mq-bridge\`, not this package directly.
216
+ EOF
217
+ node -e "const p='./$dir/package.json',j=require(p);j.description='Prebuilt '+j.name+' binary for the mq-bridge Node.js addon';j.homepage='https://github.com/marcomq/mq-bridge#readme';j.keywords=['mq-bridge','napi','native','prebuilt','addon'];require('fs').writeFileSync(p,JSON.stringify(j,null,2)+'\n')"
218
+ done
219
+
220
+ - name: Publish platform packages and root
221
+ working-directory: node/mq-bridge-node
222
+ env:
223
+ # Empty when the secret is unset -> npm falls back to OIDC.
224
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
225
+ NPM_CONFIG_PROVENANCE: "true"
226
+ run: |
227
+ set -e
228
+ publish() {
229
+ local dir="$1" name ver
230
+ name=$(node -p "require('./$dir/package.json').name")
231
+ ver=$(node -p "require('./$dir/package.json').version")
232
+ # Skip if this exact version is already on the registry; a re-run
233
+ # after a partial publish must not fail on already-published dirs.
234
+ if npm view "$name@$ver" version >/dev/null 2>&1; then
235
+ echo "Skipping $name@$ver (already published)"
236
+ return 0
237
+ fi
238
+ echo "Publishing $dir ($name@$ver)"
239
+ npm publish "$dir" --access public
240
+ }
241
+ for dir in npm/*/; do
242
+ publish "$dir"
243
+ done
244
+ echo "Publishing root package"
245
+ root_name=$(node -p "require('./package.json').name")
246
+ root_ver=$(node -p "require('./package.json').version")
247
+ if npm view "$root_name@$root_ver" version >/dev/null 2>&1; then
248
+ echo "Skipping $root_name@$root_ver (already published)"
249
+ else
250
+ npm publish --access public
251
+ fi
@@ -114,6 +114,12 @@ jobs:
114
114
 
115
115
  - name: Build wheels
116
116
  uses: PyO3/maturin-action@v1
117
+ env:
118
+ # Work around intermittent "HTTP2 framing layer" curl errors when
119
+ # cargo downloads crates inside the manylinux container.
120
+ CARGO_HTTP_MULTIPLEXING: "false"
121
+ CARGO_NET_RETRY: "5"
122
+ CARGO_NET_GIT_FETCH_WITH_CLI: "true"
117
123
  with:
118
124
  working-directory: python/mq-bridge-py
119
125
  command: build
@@ -67,3 +67,16 @@ jobs:
67
67
  - name: Smoke test import
68
68
  working-directory: python/mq-bridge-py
69
69
  run: uv run python -c "from mq_bridge import Message, Publisher, Route; print(Message, Publisher, Route)"
70
+
71
+ - name: Run no-default feature regression tests
72
+ run: |
73
+ cargo test -p mq-bridge-py --no-default-features --features http,rustls-ring test_config_schema_is_always_available
74
+ cargo test -p mq-bridge-py --no-default-features --features http,rustls-ring test_module_init_installs_rustls_provider
75
+
76
+ - name: Rebuild extension with lean no-default feature set
77
+ working-directory: python/mq-bridge-py
78
+ run: uv run maturin develop --no-default-features -F http -F rustls-ring -F pyo3/extension-module
79
+
80
+ - name: Run lean no-default public API tests
81
+ working-directory: python/mq-bridge-py
82
+ run: uv run pytest -q tests/test_public_api.py tests/test_config_types.py