Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
202 commits
Select commit Hold shift + click to select a range
0f81595
Remove v2 source tree from v3 branch (v2 lives on master)
twatson83 May 21, 2026
e81d491
Add monorepo root scaffolding (pnpm, turbo, biome, tsconfig)
twatson83 May 21, 2026
a2736b6
Pin packageManager to pnpm@9.15.9 and gitignore .env files
twatson83 May 21, 2026
0e7a135
Initialize changesets with v3 base branch and public access
twatson83 May 21, 2026
aa7322d
Configure biome to use single quotes (matches plan and modern TS conv…
twatson83 May 21, 2026
85ccb64
Add @serviceconnect/core stub package
twatson83 May 21, 2026
f8d2475
Add @serviceconnect/rabbitmq stub package with core dependency probe
twatson83 May 21, 2026
189c2f9
Add @serviceconnect/persistence-memory stub package
twatson83 May 21, 2026
18a7640
Add @serviceconnect/persistence-mongodb stub package
twatson83 May 21, 2026
f0227ec
Add @serviceconnect/telemetry stub package
twatson83 May 21, 2026
75b2ed4
Add @serviceconnect/healthchecks stub package
twatson83 May 21, 2026
53e53d2
Add CI workflow (build, test, lint, changeset gate on PRs to v3)
twatson83 May 21, 2026
c17e9b7
Add release workflow (changesets publish on push to v3)
twatson83 May 21, 2026
eedde7e
Add skeleton e2e and soak workflows (content lands in Phase C and H)
twatson83 May 21, 2026
6babe2f
Lock down workflow permissions and add CI concurrency cancellation
twatson83 May 21, 2026
ecf43b5
Add core error hierarchy (Phase B Task 1)
twatson83 May 21, 2026
cc20828
Add Logger interface and consoleLogger (Phase B Task 2)
twatson83 May 21, 2026
bd20727
Add Message, Envelope, and Options primitive types (Phase B Task 3)
twatson83 May 21, 2026
e8492d8
Add Standard Schema, message-type registry, and JSON serializer (Phas…
twatson83 May 21, 2026
7ecdb58
Harden JSON serializer: duck-type async check and skip empty issues a…
twatson83 May 21, 2026
3951745
Add pipeline primitives and middleware-chain composition (Phase B Tas…
twatson83 May 21, 2026
0051bb5
Add FilterPipeline four-stage runner (Phase B Task 6)
twatson83 May 21, 2026
1ef3950
Add Handler types and HandlerRegistry (Phase B Task 7)
twatson83 May 21, 2026
3feeb2a
Bind class handler once in makeResolver to ensure stable identity
twatson83 May 21, 2026
779179d
Add transport interfaces and ConsumeContext (Phase B Task 8)
twatson83 May 21, 2026
f87bc0f
Add fakeTransport in-memory producer/consumer pair for tests (Phase B…
twatson83 May 21, 2026
1a8d002
Add inbound dispatcher with full pipeline orchestration (Phase B Task…
twatson83 May 21, 2026
fe3a929
Run afterConsuming pipeline when beforeConsuming returns Stop (Phase …
twatson83 May 21, 2026
cc9c7cf
Add Bus skeleton (lifecycle, chainable registration) (Phase B Task 11)
twatson83 May 21, 2026
d384175
Implement Bus outbound (publish, send, sendToMany) (Phase B Task 12)
twatson83 May 21, 2026
3364b02
Use typed InvalidOperationError for sendToMany empty-endpoints guard
twatson83 May 21, 2026
77ed704
Add Bus inbound integration tests via fakeTransport (Phase B Task 13)
twatson83 May 21, 2026
bdc4606
Add tests verifying Phase D stubs throw with expected message (Phase …
twatson83 May 21, 2026
de4b316
Make Phase D stubs async so they reject promises instead of throwing …
twatson83 May 21, 2026
c32fa5d
Wire up @serviceconnect/core public surface and upgrade rabbitmq prob…
twatson83 May 21, 2026
c648466
Add rabbitmq-client and testcontainers deps; configure unit + e2e vit…
twatson83 May 22, 2026
082ccb9
Empty vitest.config.ts to avoid vitest 3 forward-incompat dead code (…
twatson83 May 22, 2026
2dd044b
Add RabbitMQ-specific error subclasses (Phase C Task 2)
twatson83 May 22, 2026
5fea61c
Add RabbitMQTransportOptions config + resolve helpers (Phase C Task 3)
twatson83 May 22, 2026
01165be
Add AsyncMessage to Envelope mapping with header normalization (Phase…
twatson83 May 22, 2026
29ffdfc
Add consumer topology builder (queues, exchanges, bindings) (Phase C …
twatson83 May 22, 2026
5540519
Add retry disposition decision logic (Phase C Task 6)
twatson83 May 22, 2026
3ea3881
Add audit republish helper (Phase C Task 7)
twatson83 May 22, 2026
edbd888
Add RabbitMQ producer with lazy exchange declaration and snapshot (Ph…
twatson83 May 22, 2026
d15faab
Harden producer: register lazy exchanges with publisher for reconnect…
twatson83 May 22, 2026
1a1396d
Add RabbitMQ consumer with eager topology declaration, retry routing,…
twatson83 May 22, 2026
ec560ee
Harden consumer: explicit routingKey on queueBind; document coercion …
twatson83 May 22, 2026
f89dcd9
Add createRabbitMQTransport orchestrator wiring split connections (Ph…
twatson83 May 22, 2026
3c974df
Add testcontainers globalSetup for RabbitMQ E2E tests (Phase C Task 11)
twatson83 May 22, 2026
6860360
Add E2E round-trip and retry-path tests via testcontainers (Phase C T…
twatson83 May 22, 2026
b2cd425
Add E2E terminal-failure and cancellation tests (Phase C Task 13)
twatson83 May 22, 2026
a70817e
Add E2E topology shape and reconnect tests (Phase C Task 14)
twatson83 May 22, 2026
f4f2e97
Wire up @serviceconnect/rabbitmq public surface and upgrade smoke tes…
twatson83 May 22, 2026
b555d9b
Wire e2e.yml workflow to run @serviceconnect/rabbitmq test:e2e on PR …
twatson83 May 22, 2026
7f5f51d
Add Phase D error classes: RequestTimeoutError, RequestSendCancelledE…
twatson83 May 22, 2026
20e4f20
Add RequestReplyManager with single/multi/callback semantics and time…
twatson83 May 22, 2026
f07ed3c
Settle finaliser before map cleanup to avoid hung promise on throw
twatson83 May 22, 2026
839be95
Add parents field to message type registry for polymorphic dispatch (…
twatson83 May 22, 2026
23d90fa
HandlerRegistry walks parent chain via type registry for polymorphic …
twatson83 May 22, 2026
849fddb
Add reply-branch to dispatcher routing matched replies to RequestRepl…
twatson83 May 22, 2026
96fb8f8
Implement Bus sendRequest/sendRequestMulti/publishRequest backed by R…
twatson83 May 22, 2026
66277cd
Add signal to RequestOptions and thread it through Bus request-reply …
twatson83 May 22, 2026
c7e5c6b
Harden Bus request-reply: typed InvalidOperationError, swallow abando…
twatson83 May 22, 2026
62324fe
Add Bus request-reply integration tests via fakeTransport (Phase D Ta…
twatson83 May 22, 2026
5bc8df4
Producer declares parent exchanges + e2e bindings for polymorphic dis…
twatson83 May 22, 2026
afb41e2
Add E2E request-reply tests against real RabbitMQ (Phase D Task 9)
twatson83 May 22, 2026
20874fd
Add E2E polymorphic-message test for derived → parent exchange routin…
twatson83 May 22, 2026
c36bd96
Wire Phase D public exports, rabbitMQWithRegistry helper, and changes…
twatson83 May 22, 2026
2ff8b6e
Define ISagaStore interface and saga concurrency errors (Phase E Task 1)
twatson83 May 22, 2026
5ba3159
Define IAggregatorStore interface and AggregatorConfigurationError (P…
twatson83 May 22, 2026
f685fda
Define ITimeoutStore interface and TimeoutRecord (Phase E Task 3)
twatson83 May 22, 2026
e329fe0
Add routing-slip and streaming error classes (Phase E Task 4)
twatson83 May 22, 2026
4f88321
Add saga-store contract suite via @serviceconnect/core/testing and me…
twatson83 May 22, 2026
bfe5191
Pin @types/node 22.x in root devDeps to fix tsup DTS resolution
twatson83 May 22, 2026
463536f
Add aggregator-store contract suite and memoryAggregatorStore InMemor…
twatson83 May 22, 2026
43b6c21
Add timeout-store contract suite and memoryTimeoutStore InMemory impl…
twatson83 May 22, 2026
3c09c86
Define ProcessHandler interface and ProcessRegistry (Phase E Task 8)
twatson83 May 22, 2026
ebb7337
Add ProcessBuilder and Bus.registerProcessData/registerProcess (Phase…
twatson83 May 22, 2026
11a128a
Add saga branch to dispatcher: lookup, insert/update, markComplete, c…
twatson83 May 22, 2026
bdf0287
Add TimeoutPoller background service with publish-then-delete semanti…
twatson83 May 22, 2026
fb97382
Wire TimeoutPoller into Bus.start/stop with configurable interval (Ph…
twatson83 May 22, 2026
72abe6a
Add Aggregator abstract class, AggregatorRegistry, Bus.registerAggreg…
twatson83 May 22, 2026
d5a16c0
Add aggregator branch to dispatcher: appendAndClaim, execute, release…
twatson83 May 22, 2026
8bcebd9
Add AggregatorFlushTimer wired into Bus.start/stop (Phase E Task 15)
twatson83 May 22, 2026
1cb7eb7
Add routing-slip destination validator and header codec (Phase E Task…
twatson83 May 22, 2026
d961b58
Add Bus.route with up-front slip validation (Phase E Task 17)
twatson83 May 22, 2026
c86d59e
Forward routing slip to next destination on handler success (Phase E …
twatson83 May 22, 2026
0b579f5
Add StreamSender and Bus.openStream with monotonic sequence numbering…
twatson83 May 22, 2026
fc10255
Add StreamReceiver with reorder buffer and faulted-latch (Phase E Tas…
twatson83 May 22, 2026
16f5b7d
Add stream dispatch branch and Bus.handleStream (Phase E Task 21)
twatson83 May 22, 2026
981d4c8
Add WritableStream adapter via Bus.openWritableStream (Phase E Task 22)
twatson83 May 22, 2026
4c2eff7
Add E2E saga tests: round-trip + TimeoutPoller-driven timeout (Phase …
twatson83 May 22, 2026
e3b8f90
Add E2E aggregator tests: size-flush and timeout-flush (Phase E Task 24)
twatson83 May 22, 2026
0f4b417
Add E2E routing-slip tests: three-hop forward and validator rejection…
twatson83 May 22, 2026
9249096
Add E2E streaming tests: 1000-chunk round-trip and faulted-stream pro…
twatson83 May 22, 2026
9a2a831
Wire Phase E public exports and changeset (Phase E Task 27)
twatson83 May 22, 2026
ae56ce2
Add mongodb + @testcontainers/mongodb deps and vitest config (Phase F…
twatson83 May 22, 2026
69f2885
Wire testcontainers MongoDB setup and withFreshDb helper (Phase F Tas…
twatson83 May 22, 2026
3f688df
Add mongoSagaStore with optimistic-concurrency version field (Phase F…
twatson83 May 22, 2026
77e29e0
Add mongoAggregatorStore with one-doc-per-message lease semantics (Ph…
twatson83 May 22, 2026
309a222
Add mongoTimeoutStore with indexed runAt polling (Phase F Task 5)
twatson83 May 22, 2026
61f3613
Verify ensureIndexes creates the expected Mongo indexes (Phase F Task 6)
twatson83 May 22, 2026
206b3d7
Verify mongoSagaStore wins one of every concurrent insert/update race…
twatson83 May 22, 2026
8b13e54
Verify aggregator lease safety, producer-race uniqueness, and timeout…
twatson83 May 22, 2026
1c074da
Wire Phase F public exports, smoke test, and changeset (Phase F Task 9)
twatson83 May 22, 2026
4b23006
Add Bus.consumeWrapper, lastConsumedAt heartbeat, and expose consumer…
twatson83 May 22, 2026
39044a0
Add OpenTelemetry deps and attribute/metric helpers in telemetry pack…
twatson83 May 22, 2026
2f85a01
Add telemetryProducer with span + traceparent injection + publish met…
twatson83 May 22, 2026
9f37e4f
Add telemetryConsumeWrapper bracketing the dispatcher with a process …
twatson83 May 22, 2026
0997e92
Verify traceparent round-trip from telemetryProducer to telemetryCons…
twatson83 May 22, 2026
d0027e0
Verify publish.count, consume.count, error.count, processing.duration…
twatson83 May 22, 2026
f0863af
Wire healthchecks package with core workspace dep and result types (P…
twatson83 May 22, 2026
ca95955
Add producerConnectivity and consumerConnectivity healthchecks (Phase…
twatson83 May 22, 2026
e43d1c1
Add consumerBusy healthcheck reading Bus.lastConsumedAt with degraded…
twatson83 May 22, 2026
65e0332
Add E2E telemetry test verifying traceparent propagation through real…
twatson83 May 22, 2026
7745369
Wire Phase G public exports and changesets (Phase G Task 11)
twatson83 May 22, 2026
990ac94
Add harness/stress workspace member scaffold with tsx-driven CLI scri…
twatson83 May 23, 2026
418e35f
Add stress harness CLI scaffold with argv parser and mode dispatch (P…
twatson83 May 23, 2026
6959c80
Add stress harness bus-pair factory and persistence wiring (Phase H T…
twatson83 May 23, 2026
213006c
Add stress harness flow library and pubsub/send/request-reply drivers…
twatson83 May 23, 2026
0f63a0a
Add stress harness polymorphic, saga, and aggregator flow drivers (Ph…
twatson83 May 23, 2026
95c560c
Add stress harness routing-slip and streaming flow drivers (Phase H T…
twatson83 May 23, 2026
14a8dad
Add stress harness smoke mode, report writers, and vitest smoke runne…
twatson83 May 23, 2026
adf05d3
Add stress harness soak mode with memory budget enforcement (Phase H …
twatson83 May 23, 2026
b91cc4d
Add stress harness throughput mode with per-pattern latency percentil…
twatson83 May 23, 2026
2eeb44d
Add stress harness chaos integration scaffolding wired into soak mode…
twatson83 May 23, 2026
f4e26f5
Wire stress harness smoke job into ci.yml and replace soak.yml placeh…
twatson83 May 23, 2026
c4424ea
Add examples workspace scaffold: docker-compose, README, shared examp…
twatson83 May 23, 2026
a9c8c16
Add publish-subscribe example (Phase I Task 2)
twatson83 May 23, 2026
11b0505
Simplify publish-subscribe run.sh to use bare 'tsx' import via cd (Ph…
twatson83 May 23, 2026
14d9759
Add send example (Phase I Task 3)
twatson83 May 23, 2026
66ccf80
Add request-reply example with scatter-gather scenario (Phase I Task 4)
twatson83 May 23, 2026
46e0302
Add polymorphic example (Phase I Task 5)
twatson83 May 23, 2026
693e784
Add saga example with InMemory + Mongo persistence variants (Phase I …
twatson83 May 23, 2026
d830fc6
Add aggregator example (Phase I Task 7)
twatson83 May 23, 2026
603e7fd
Add routing-slip example with 3-hop itinerary (Phase I Task 8)
twatson83 May 23, 2026
f5b5039
Add streaming example with 50-chunk ordered round-trip (Phase I Task 9)
twatson83 May 23, 2026
2c6e06a
Add filters example: pipeline middleware + filter Stop semantics (Pha…
twatson83 May 23, 2026
7fe2b6a
Add telemetry example: in-memory exporter verifies traceparent propag…
twatson83 May 23, 2026
4a7fd94
Add examples/run-all.sh orchestrator and examples-smoke CI job (Phase…
twatson83 May 23, 2026
b7e135c
Scaffold @serviceconnect/website + GitHub Pages workflow (Phase J Tas…
twatson83 May 23, 2026
43aee38
Rewrite README; add landing + Getting Started (Phase J Task 2)
twatson83 May 23, 2026
6f32a7c
Add Core Concepts pages (Phase J Task 3)
twatson83 May 23, 2026
dc2830a
Add Messaging Patterns batch 1 (Phase J Task 4)
twatson83 May 23, 2026
82b4443
Add Messaging Patterns batch 2 (Phase J Task 5)
twatson83 May 23, 2026
c1254d9
Add Messaging Patterns batch 3 (Phase J Task 6)
twatson83 May 23, 2026
846137e
Add Reference: bus + messages (Phase J Task 7)
twatson83 May 23, 2026
60ddb69
Add Reference: handlers + filters (Phase J Task 8)
twatson83 May 23, 2026
13fe4b5
Add Reference: process-managers + healthchecks + telemetry (Phase J T…
twatson83 May 23, 2026
ac188f4
Add Reference: configuration (Phase J Task 10)
twatson83 May 23, 2026
8d79803
Add Reference: extension-points (Phase J Task 11)
twatson83 May 23, 2026
163108f
Add Operations batch 1 (Phase J Task 12)
twatson83 May 23, 2026
b4aae6d
Add Operations batch 2 (Phase J Task 13)
twatson83 May 23, 2026
0fe7635
Add migration guide + Releases + Samples (Phase J Task 14)
twatson83 May 23, 2026
3f9eb74
Final sweep — API drift corrections + reference coverage (Phase J Tas…
twatson83 May 23, 2026
b5fa303
Fix docs workflow: let pnpm/action-setup read version from packageMan…
twatson83 May 23, 2026
0a58a2d
Fix repo URLs: twatson83 -> R-Suite (Pages URL + GitHub links)
twatson83 May 23, 2026
d083b70
Fix all workflows: remove pnpm version pin conflicting with packageMa…
twatson83 May 23, 2026
7f06742
Fix critical/high review findings; add consumer concurrency option
twatson83 Jun 13, 2026
2bdd93b
Reformat to 4-space indentation
twatson83 Jun 13, 2026
b81148e
Fix CI and dependency vulnerabilities
twatson83 Jun 13, 2026
9d39857
Update Astro to v6 (clears remaining dependency advisories)
twatson83 Jun 13, 2026
e7f22b9
Retry flaky e2e tests against the shared CI broker
twatson83 Jun 13, 2026
f09f7bc
Scope release workflow to master
twatson83 Jun 13, 2026
8217e22
Align docs site with the C# docs (full parity)
twatson83 Jun 13, 2026
dbee47e
Fix homepage layout to match the C# docs
twatson83 Jun 13, 2026
2ed29bd
Use npm (not pnpm) in user-facing docs
twatson83 Jun 13, 2026
b51e5c0
Remove dead CLAUDE.md link from README
twatson83 Jun 13, 2026
8e3424d
Align CI with the C# pipeline; tag-driven npm releases
twatson83 Jun 13, 2026
baaf262
Fix Windows CI lint: force LF line endings, lint on Linux only
twatson83 Jun 13, 2026
bc60113
Add CONTRIBUTING guide (ported from the C# project)
twatson83 Jun 13, 2026
e043b03
Add MIT LICENSE file
twatson83 Jun 13, 2026
8b9e309
docs: fix 48 accuracy issues across the documentation site
twatson83 Jun 13, 2026
6a36310
docs: correct 92 accuracy issues from a fresh source-grounded audit
twatson83 Jun 14, 2026
791b501
chore: remove phase/ticket references from code comments
twatson83 Jun 14, 2026
6a7660e
feat(telemetry): align metrics and spans with the C# ServiceConnect.T…
twatson83 Jun 14, 2026
32c62f5
docs: fix broken anchor links in process-handler reference
twatson83 Jun 14, 2026
c151172
feat(metrics): emit messaging metrics always-on from core meter + tra…
twatson83 Jun 14, 2026
a00e569
fix(examples): read messaging.operation.name in the telemetry example
twatson83 Jun 14, 2026
b6dedf2
Revert always-on metrics: keep @serviceconnect/core dependency-free
twatson83 Jun 14, 2026
8321655
feat(core): add recursive PascalCase/camelCase key transform for the …
twatson83 Jun 14, 2026
84192e9
feat(core): serialize the message body as PascalCase JSON (master wir…
twatson83 Jun 14, 2026
0b1e66a
feat(core): add master wire-header codec (camelCase<->PascalCase + ty…
twatson83 Jun 14, 2026
8ff2fdd
feat(core): encode/decode headers in the master wire format (outbound…
twatson83 Jun 14, 2026
3e21484
fix(core): guard first-char access in casing transform (noUncheckedIn…
twatson83 Jun 14, 2026
6e7544b
refactor(rabbitmq): let core own wire headers; stop transport double-…
twatson83 Jun 14, 2026
908c00e
feat(core): export wire casing + header codec helpers
twatson83 Jun 14, 2026
163306f
test(rabbitmq): add (skipped) Node<->C# master interop e2e scaffold
twatson83 Jun 14, 2026
a1fcdc3
fix(core): source saga ctx.correlationId from the message body (wire-…
twatson83 Jun 14, 2026
91ae425
test(rabbitmq),examples(filters): align e2e + filters with master wir…
twatson83 Jun 14, 2026
7d80bfb
feat(rabbitmq): derive pub/sub exchange names as FullName-stripped (m…
twatson83 Jun 14, 2026
456f681
test(rabbitmq): e2e pub/sub round-trip on the FullName-stripped exchange
twatson83 Jun 14, 2026
63fe813
test(interop): prove Node<->C# master interop with a C# fixture + orc…
twatson83 Jun 14, 2026
5c99747
feat(rabbitmq): multi-publish to ancestor exchanges (master polymorph…
twatson83 Jun 14, 2026
b26f69e
fix(core): bind consumer to consumed types, not all registered (multi…
twatson83 Jun 14, 2026
3fc88f3
feat(rabbitmq): align retry/error/audit topology with C# master
twatson83 Jun 14, 2026
d9ec61d
test(rabbitmq): e2e topology asserts master retry/error/audit shape
twatson83 Jun 14, 2026
76bb1f9
fix(stress): wire parentsOf into harness bus transports
twatson83 Jun 14, 2026
8107905
docs: align docs with the master wire format (phases 0-3)
twatson83 Jun 14, 2026
4144bd5
docs/comments: strip phase/work-stream labels from source comments
twatson83 Jun 14, 2026
c1e8253
docs: migration guide is from v2, not v1 (legacy service-connect is 2…
twatson83 Jun 14, 2026
cb00919
Merge master into v3 (v3 supersedes the legacy single-package client)
twatson83 Jul 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
157 changes: 157 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: ci

on:
push:
branches: ['**']
pull_request:
branches: ['**']
workflow_dispatch:

permissions:
contents: read

# A new push to a PR / branch cancels the previous in-flight run for the same ref.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
name: Build + unit tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (packages)
run: pnpm exec turbo run build --filter='!@serviceconnect/website'
# Lint is OS-independent; run it once (Linux) to avoid redundant work and CRLF noise.
- name: Lint
if: matrix.os == 'ubuntu-latest'
run: pnpm lint
# Cross-platform unit suites only. The MongoDB and stress packages rely on
# Testcontainers (Docker / Linux containers) and run in the Linux-only jobs below.
- name: Unit tests
run: >-
pnpm exec turbo run test
--filter=@serviceconnect/core
--filter=@serviceconnect/telemetry
--filter=@serviceconnect/healthchecks
--filter=@serviceconnect/persistence-memory
--filter=@serviceconnect/rabbitmq

e2e:
name: E2E + MongoDB integration (Linux)
runs-on: ubuntu-latest
# Testcontainers spins up RabbitMQ + MongoDB; ubuntu-latest runners have Docker preinstalled.
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (packages)
run: pnpm exec turbo run build --filter='!@serviceconnect/website'
- name: MongoDB store tests
run: pnpm --filter @serviceconnect/persistence-mongodb test
- name: RabbitMQ end-to-end tests
run: pnpm --filter @serviceconnect/rabbitmq test:e2e

pack-validate:
name: Pack validation (dry-run)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (packages)
run: pnpm exec turbo run build --filter='!@serviceconnect/website'
- name: Pack publishable packages
run: |
mkdir -p "$GITHUB_WORKSPACE/artifacts"
pnpm --filter='./packages/*' exec -- npm pack --pack-destination "$GITHUB_WORKSPACE/artifacts"
- name: List produced tarballs
run: ls -la artifacts/
- name: Upload tarballs
uses: actions/upload-artifact@v4
with:
name: npm-tarballs
path: artifacts/*.tgz
if-no-files-found: error
retention-days: 14

stress-smoke:
name: Stress smoke (Linux)
needs: build-and-test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (packages)
run: pnpm exec turbo run build --filter='!@serviceconnect/website'
- name: Stress smoke
run: pnpm --filter @serviceconnect/stress-harness smoke
- name: Upload report on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: stress-smoke-report
path: harness/stress/out/

examples-smoke:
name: Examples smoke (Linux)
needs: build-and-test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (packages)
run: pnpm exec turbo run build --filter='!@serviceconnect/website'
- name: Run all examples
run: bash examples/run-all.sh
54 changes: 54 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: docs

on:
push:
branches: [master]
paths:
- 'website/**'
- '.github/workflows/docs.yml'
workflow_dispatch: {}

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build website (Astro + Starlight)
run: pnpm --filter @serviceconnect/website build
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: website/dist

deploy:
needs: build
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
103 changes: 103 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: release

# Triggered on a `v*` tag push (e.g. `v1.0.0`, or a pre-release `v1.0.0-beta.1`). The tag value
# drives the published version for every package — release the same source tree against a new tag
# by retagging, not by editing package.json versions. Pre-release tags (those with a SemVer
# `-suffix`) publish under the `next` dist-tag instead of `latest`, so `npm install <pkg>` never
# picks them up — the npm equivalent of a NuGet pre-release.

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version override (without leading v). Used only for manual dispatch; tag pushes use the tag value.'
required: false

permissions:
contents: read

jobs:
release:
name: Build + publish to npm
runs-on: ubuntu-latest
environment:
name: npm
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Full history so the release guard can test whether the tagged commit is contained in
# origin/master; the ancestry walk needs the commit graph, not just the tag tip.
fetch-depth: 0

# Releases are cut from master only. A v* tag (or a manual dispatch ref) can point at any
# commit, so gate the publish on the tagged commit being reachable from origin/master: a tag
# pushed on a feature branch fails here, before anything is built or published.
- name: Verify tag is on master
run: |
git fetch origin master --quiet
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/master; then
echo "::error::Tag ${GITHUB_REF#refs/tags/} ($GITHUB_SHA) is not contained in origin/master; refusing to release."
exit 1
fi
echo "Tag commit $GITHUB_SHA is contained in origin/master — proceeding."

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
registry-url: https://registry.npmjs.org

- name: Resolve and validate version
id: version
run: |
if [ -n "${{ inputs.version }}" ]; then
VERSION="${{ inputs.version }}"
else
# github.ref is "refs/tags/v1.0.0"; strip the prefix.
VERSION="${GITHUB_REF#refs/tags/v}"
fi
# Validate SemVer (with optional pre-release / build metadata).
if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$'; then
echo "::error::'$VERSION' is not a valid SemVer version."
exit 1
fi
# Pre-release tags (anything with a "-suffix") publish under the `next` dist-tag.
if echo "$VERSION" | grep -q '-'; then DIST_TAG=next; else DIST_TAG=latest; fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "dist_tag=$DIST_TAG" >> "$GITHUB_OUTPUT"
echo "Resolved version: $VERSION (dist-tag: $DIST_TAG)"

- name: Install
run: pnpm install --frozen-lockfile

# The tag is the single source of truth for the version, so stamp it onto every workspace
# package. pnpm rewrites the internal `workspace:*` dependencies to this version on publish.
- name: Set package versions from tag
run: pnpm -r exec -- npm pkg set version="${{ steps.version.outputs.version }}"

- name: Build
run: pnpm build

# Re-run the full suite against the exact tagged commit before publishing. CI already gates
# merges to master, but a tag can point at any commit and npm versions cannot be unpublished
# after 72h — a green run here is the last line of defence.
- name: Lint
run: pnpm lint
- name: Tests
run: pnpm test
- name: RabbitMQ end-to-end tests
run: pnpm --filter @serviceconnect/rabbitmq test:e2e

- name: Publish to npm
# --no-git-checks because the version stamp above leaves the tree dirty.
run: pnpm -r publish --access public --no-git-checks --tag "${{ steps.version.outputs.dist_tag }}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36 changes: 36 additions & 0 deletions .github/workflows/soak.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: soak

on:
schedule:
- cron: "0 2 * * *"
workflow_dispatch: {}

permissions:
contents: read

jobs:
soak:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Soak
run: pnpm --filter @serviceconnect/stress-harness exec tsx src/index.ts --mode soak --duration 300 --memory-budget-mb 256
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: soak-report
path: harness/stress/out/
Loading
Loading