Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
aea8ecf
ci: publish releases/r10.0 to ChartMuseum without deploying
MusaMisto Oct 7, 2026
139fcd2
Merge pull request #347 from simplify9/musa/ci/publish-r10-release-chart
MusaMisto Oct 7, 2026
ee113a4
Set the seeded administrator's password from Bitween__InitialAdminPas…
hamzahalq Oct 7, 2026
cd8f115
Sign back in after a password change instead of keeping the dead session
hamzahalq Oct 8, 2026
9d8f947
Save the admin password and session cleanup together; add the variabl…
hamzahalq Oct 8, 2026
957bbc8
Relicense under AGPL-3.0 with Simplify9 attribution terms; keep the S…
samerzughul Oct 8, 2026
015056e
Point commercial license inquiries to info@simplify9.com
samerzughul Oct 8, 2026
77c6eb3
P1 security, reliability and operations fixes
samerzughul Oct 8, 2026
fd3f83f
Merge P1 security, reliability and operations fixes
samerzughul Oct 8, 2026
f272033
Fix sign-in session races found by the end-to-end suite
samerzughul Oct 8, 2026
1749374
Bound the synchronous gateway wait
samerzughul Oct 8, 2026
ec87a24
Validate Microsoft sign-in tokens for this app and bind accounts to t…
samerzughul Oct 8, 2026
c019430
HTTP adapters: retryable 408/429, per-request timeout, cached OAuth t…
samerzughul Oct 8, 2026
81e12a3
Drop a kept secret when the adapter or its destination changes
samerzughul Oct 8, 2026
678db14
Retries and notifiers: keep failed retries, jitter, a chain ceiling, …
samerzughul Oct 8, 2026
1600c99
Receivers: one bad file no longer stops a run; FTP waits for files to…
samerzughul Oct 8, 2026
23d9e85
Helm chart: correct container port, probes on, password in the Secret…
samerzughul Oct 8, 2026
990a62b
Gateway: honour Idempotency-Key
samerzughul Oct 8, 2026
40cd04d
Auto-pause, information type schemas, dead-letter browse and requeue
samerzughul Oct 8, 2026
df5fe0b
Resident adapters target net10.0 on SDK 10.0.0
samerzughul Oct 8, 2026
8e8fb0a
Resident adapters honour ServerlessCommandTimeout
samerzughul Oct 8, 2026
797b42e
SW.Serverless 10.0.1: host and SDK
samerzughul Oct 8, 2026
89f5ff7
Adapter manifests, catalog and version pinning (needs SW.Serverless 1…
samerzughul Oct 8, 2026
229f809
Adapters page: installed adapters, built-in and custom, with versions…
samerzughul Oct 8, 2026
a571f51
Pinning an unknown version is a 400, not a 500
samerzughul Oct 8, 2026
3069208
Adapters page tests: wait for the page's five requests
samerzughul Oct 8, 2026
5b68bb7
Add HTTP pipeline tests hosting the real app
samerzughul Oct 8, 2026
6a2e58f
test: make the e2e suite seed itself and run from scratch with tools/…
samerzughul Oct 8, 2026
e112059
test: wait for RabbitMQ consumers in the e2e seed instead of reading …
samerzughul Oct 8, 2026
e29e6e7
Stamp retry-group usage with the application clock
samerzughul Oct 8, 2026
39be6a2
test: retry exchanges the API says can be retried, not whatever tops …
samerzughul Oct 8, 2026
dd7ce9c
Test messages through the real broker and consumers
samerzughul Oct 8, 2026
fabfb66
Remove unit tests that tested nothing
samerzughul Oct 8, 2026
e06435f
Test the far-reaching deletes and queue clean-up over HTTP
samerzughul Oct 8, 2026
5c95b98
Test members, roles and work groups over HTTP
samerzughul Oct 8, 2026
d2c20c2
Merge test/e2e-self-seeding: the e2e suite seeds itself and runs from…
samerzughul Oct 8, 2026
3eec111
Wrap the scheduled jobs' Pulls in column
samerzughul Oct 8, 2026
1413783
Test a subscription's validator step on the gateway
samerzughul Oct 8, 2026
86e15dd
Test cross-node cache revocation, saving a mapper and run clean-up
samerzughul Oct 8, 2026
fb64a82
Test signing in with Microsoft through the whole login handler
samerzughul Oct 8, 2026
be8d959
Test every admin read and the audit trail over HTTP
samerzughul Oct 8, 2026
0ae3759
Fix the S3 upload handler, and test S3 against a real server
samerzughul Oct 8, 2026
bdb1435
Test the Azure Blob adapters against Azurite
samerzughul Oct 8, 2026
fe36b7d
Read HTTP adapter headers as people type them, and test HTTP for real
samerzughul Oct 8, 2026
4a7919a
Add SFTP adapter tests, run when a Rebex key is set
samerzughul Oct 8, 2026
4a90048
Test the scheduler firing for real, and 404 an unknown receive-now
samerzughul Oct 8, 2026
6851a8a
Answer 404, not 500, for commands on records that don't exist
samerzughul Oct 8, 2026
69b021f
Make a MySQL install work, and test fresh installs on MySQL and SQL S…
samerzughul Oct 8, 2026
28ea4fb
Let a create-only role use the New dialogs, and open what it made
samerzughul Oct 9, 2026
9f0e580
Test member access end to end: roles, disable, lockout, guards, own p…
samerzughul Oct 9, 2026
287327b
Test gateway access end to end: partner keys and the gateway's auth s…
samerzughul Oct 9, 2026
3167a9b
Test editing an existing subscription, and pinning a custom adapter v…
samerzughul Oct 9, 2026
1ae769a
Clear the data source form after a save that only replaced a secret
samerzughul Oct 9, 2026
d2ca9cd
Test data sources end to end against the e2e PostgreSQL
samerzughul Oct 9, 2026
5ea5a55
Test notifiers end to end: a real failure posts to an endpoint the te…
samerzughul Oct 9, 2026
314f6f4
Test a response subscription end to end through a real exchange
samerzughul Oct 9, 2026
238db1d
Test the legacy JSON mapper editor through to a real delivery
samerzughul Oct 9, 2026
19fa4cf
Test bulk retry of all matching, retry with re-resolved settings, and…
samerzughul Oct 9, 2026
a1a058e
Test sending dead letters back and deleting unattended queues
samerzughul Oct 9, 2026
15bc9d1
Test Receive now and Roll up now through to what they deliver
samerzughul Oct 9, 2026
86ab4bd
Test the read-only views: Adapters page, flow map, subscription list …
samerzughul Oct 9, 2026
3930db9
Document what the e2e suite now needs beyond the browser
samerzughul Oct 9, 2026
b974810
Merge Phase 4 e2e coverage: security, configuration, operations and r…
samerzughul Oct 9, 2026
51e0d61
Add FTP/SFTP adapters that need no Rebex license
samerzughul Oct 9, 2026
0f6b8d3
Split the open-source FTP adapters by protocol and add FTPS
samerzughul Oct 9, 2026
321c84b
Add the Bitween adapter contract, with its .NET form
samerzughul Oct 9, 2026
79bf201
Document the Bitween adapter contract
samerzughul Oct 9, 2026
f292155
Document how adapters declare their settings and how Bitween lists them
samerzughul Oct 9, 2026
e4c2d55
Give the adapter contract example inputs
samerzughul Oct 9, 2026
0950919
Mark the receiver's DeleteFile as destructive in the contract
samerzughul Oct 9, 2026
86ad08b
Name the adapter contract as manifests name it: bitween
samerzughul Oct 9, 2026
f0b58c7
Move to SimplyWorks.Serverless 10.1.0
samerzughul Oct 9, 2026
d0644bf
List adapters that are only in the catalog
samerzughul Oct 9, 2026
20e0695
Publish SimplyWorks.Bitween.Adapters with the SDK
samerzughul Oct 9, 2026
597e2a9
Read and compare adapter source on the Adapters page
samerzughul Oct 9, 2026
11b658b
Describe adapters in other runtimes from their manifests alone
samerzughul Oct 9, 2026
0b67064
Wait for the exchanges rows before measuring the table
samerzughul Oct 9, 2026
35fdbc2
Add the Bitween contract for Python, simplyworks-bitween
samerzughul Oct 9, 2026
f5c21d2
Run Python adapters: python3 in the image, and tests through subscrip…
samerzughul Oct 9, 2026
0bed03d
Add the Bitween contract for Node, @simplyworks/bitween
samerzughul Oct 9, 2026
fc0098b
Run Node adapters: node in the image, and a test through a subscription
samerzughul Oct 9, 2026
87cdb3b
Write, check, try and publish Python and Node adapters from Bitween
samerzughul Oct 9, 2026
88b9ecc
Add the adapter editor to the Adapters page
samerzughul Oct 9, 2026
f6c8219
Move to SimplyWorks.Serverless 10.2.0 and the sw-serverless SDKs
samerzughul Oct 9, 2026
f28e6bf
Take Bitween's adapter know-how into SW.Bitween.Adapters.Tooling
samerzughul Oct 9, 2026
80485f7
Publish packages, list versions and withdraw through the API
samerzughul Oct 9, 2026
4707f84
Add the bitween CLI
samerzughul Oct 9, 2026
7982a4b
Keep the resident adapters design with Bitween
samerzughul Oct 9, 2026
0367b50
Run Python and Node adapters on every node
samerzughul Oct 9, 2026
3fed449
Document the bitween CLI, adapters in Python and Node, and the adapte…
samerzughul Oct 9, 2026
349a1dc
Publish the Python and Node adapter contract packages on an sdk-v tag
samerzughul Oct 10, 2026
12b8c12
Sign the bitween CLI in through the browser, and end its session on l…
samerzughul Oct 10, 2026
a18d65b
Refresh every node's cached adapter when a version is published, prom…
samerzughul Oct 10, 2026
aecdff1
Show what each custom adapter runs on, on the Adapters page and when …
samerzughul Oct 10, 2026
257761e
Let the adapter editor build drafts with dependencies, when the setti…
samerzughul Oct 10, 2026
f21e2ce
Refuse an editor save over someone else's, and offer theirs or an ove…
samerzughul Oct 10, 2026
eb872ea
Hold the adapter editor's checks and tries to a memory and CPU limit
samerzughul Oct 10, 2026
b960e02
Document browser sign-in for the CLI, logout, and the editor's depend…
samerzughul Oct 10, 2026
c6c488d
Count the CLI's token exchange among the handlers open without a session
samerzughul Oct 10, 2026
a64a854
Expect the runtime beside a pinned adapter in the end-to-end tests
samerzughul Oct 10, 2026
9a487cc
Build on SimplyWorks.Serverless 10.2.2, and read the CLI tests' outpu…
samerzughul Oct 10, 2026
f43a674
Merge releases/r10.0 into releases/r10.0-staging
samerzughul Oct 10, 2026
935dbcf
Release the CLI from releases/r10.0, and staging builds as -stg pre-r…
samerzughul Oct 10, 2026
f2392c5
Release the CLI and the SDKs from the CI run, at its version, instead…
samerzughul Oct 10, 2026
2f97376
Keep a subscription's own retry policy through a UI save
samerzughul Oct 10, 2026
ac5e4c6
Keep a data source's placement through a save, and let it be set in t…
samerzughul Oct 10, 2026
0a0a79d
Say when a page couldn't load, instead of showing it empty or gone
samerzughul Oct 10, 2026
25b7ee2
Lead every failure with its message in plain words, and fold the stac…
samerzughul Oct 10, 2026
88076ba
Load each page when it is first opened
samerzughul Oct 10, 2026
505bd2f
Show what this instance is and how it is set up, on Settings › About …
samerzughul Oct 10, 2026
e4925cc
List the cluster's nodes: which are there, which run data sources, wh…
samerzughul Oct 10, 2026
e2a5128
Let a stuck scheduled job's running mark be cleared
samerzughul Oct 10, 2026
48d0c13
Upload a package and withdraw a version from the Adapters page
samerzughul Oct 10, 2026
2f7010c
Show the calls a gateway turned away, and when each API key was last …
samerzughul Oct 10, 2026
e42dc1d
Show Bitween's own background work: its system jobs and its outbox
samerzughul Oct 10, 2026
2e04c02
Record operations and sign-ins in the audit trail, and show members' …
samerzughul Oct 10, 2026
2fad9e8
Give subscription categories a place in the UI
samerzughul Oct 10, 2026
78ff777
Bring the caveats up to date with the code
samerzughul Oct 10, 2026
111e4f8
Give focus its own color, so a focused field no longer looks wrong
samerzughul Oct 10, 2026
d4ff510
Show a new instance where to start, and offer the create button where…
samerzughul Oct 10, 2026
999aec5
Register the gateway activity recorder in the integration tests' host
samerzughul Oct 10, 2026
837992f
Offer New subscription on All subscriptions, asking what starts it
samerzughul Oct 10, 2026
f4d7fb5
Set up a data source in the order it needs: what it can't connect wit…
samerzughul Oct 10, 2026
38af041
Show the audit trail and every History card in the screens' own words
samerzughul Oct 10, 2026
90891b7
Name promoted properties as what they are, and put Cancel before the …
samerzughul Oct 10, 2026
86d0221
Keep pages within a phone's width
samerzughul Oct 10, 2026
ff23bf5
Answer a read of a record that isn't there with 404, not a server error
samerzughul Oct 10, 2026
69ca14e
Check a hand-made exchange's payload against its information type bef…
samerzughul Oct 10, 2026
b6bd936
Find New exchange's subscription picker by its name in the end-to-end…
samerzughul Oct 10, 2026
e2724cb
Fix the review's small bugs: sign-in text, accented names, exchange i…
samerzughul Oct 10, 2026
a3684b9
Keep the getting-started list off a set-up instance, and the end-to-e…
samerzughul Oct 10, 2026
5f672d6
UI: remove dead scaffolding
samerzughul Oct 10, 2026
4dfb534
UI: dialogs and clickable rows work from the keyboard
samerzughul Oct 10, 2026
1f7b8b7
UI: ask before leaving unsaved changes; readable muted text; labelled…
samerzughul Oct 10, 2026
e048ec0
UI: show a refused save's messages on the fields they are about
samerzughul Oct 10, 2026
5158281
UI: list searches run when typing pauses, not on every key
samerzughul Oct 10, 2026
a1d277e
UI: split mixed modules, lint warnings to zero, steadier tests, list …
samerzughul Oct 10, 2026
6121648
UI: declare every page once, in a page registry
samerzughul Oct 10, 2026
f95f0a8
UI: open scheduled jobs, aggregations and response subscriptions in t…
samerzughul Oct 10, 2026
e707929
UI: top bar with breadcrumbs, per-page tab titles, and an environment…
samerzughul Oct 10, 2026
0c986dc
UI: command palette (⌘K) for pages, configuration by name, and recent…
samerzughul Oct 10, 2026
46cd056
UI: sidebar leads with the dashboard and fits a laptop; rail labels; …
samerzughul Oct 10, 2026
0a85884
UI: one way to build a list page; end-to-end tests follow subscriptio…
samerzughul Oct 10, 2026
160fbcb
UI: Adapters in three tabs — Built-in, Installed, Marketplace
samerzughul Oct 10, 2026
eaebaee
CI: release only the CLI's own artifacts
samerzughul Oct 11, 2026
9e2badb
UI: the adapter editor becomes a VS Code-style workspace on Monaco
samerzughul Oct 11, 2026
d07bde7
Remove the long dash from the whole system
samerzughul Oct 11, 2026
91ef345
Metrics: count exchanges, adapter calls and gateway refusals as they …
samerzughul Oct 11, 2026
b421297
Metrics: read endpoints, a dashboard built on them, and adapter usage
samerzughul Oct 11, 2026
da1b253
Metrics: subscription, partner and node health in the UI
samerzughul Oct 11, 2026
595ddab
Metrics: a gateway's refusals over the week, across nodes and restarts
samerzughul Oct 11, 2026
5dce89d
Metrics: dashboard finishing touches from a look at real data
samerzughul Oct 11, 2026
c6decc0
CI: keep the admin UI's charts folder in the Docker build context
samerzughul Oct 11, 2026
5703ec9
Chart: route / by default, alongside /api and /swagger
MusaMisto Oct 11, 2026
7c25934
Merge pull request #353 from simplify9/musa/chart-ingress-root-path-r…
MusaMisto Oct 11, 2026
de55744
Release the staging CLI as a pre-release
samerzughul Oct 11, 2026
68fbbdb
Service accounts and tokens
samerzughul Oct 11, 2026
bea73d5
CLI: bitween plan, apply and export; sign in as a service account
samerzughul Oct 11, 2026
bfa246d
POP3 and SMTP: trust a server's own certificate by its thumbprint
samerzughul Oct 11, 2026
263b471
CLI: say once that the certificate isn't checked
samerzughul Oct 11, 2026
8952dd6
FTP and SFTP uploads: name the file after the message
samerzughul Oct 11, 2026
57036cc
Data source providers as packages; staging runs data sources
samerzughul Oct 11, 2026
729c4af
Exchanges: a list built for triage
samerzughul Oct 11, 2026
89935e1
Merge feature/exchanges-redesign: exchanges list redesign
samerzughul Oct 11, 2026
36b8f2d
SFTP waits at most TimeoutSeconds at each step
samerzughul Oct 11, 2026
e6d58a6
apply: no false warning for an adapter already published
samerzughul Oct 11, 2026
ae6df7b
apply: an aggregation with an information type is refused up front
samerzughul Oct 11, 2026
a8a01dc
HTTP handler: a failed delivery names its status code
samerzughul Oct 11, 2026
f597f00
Exchanges: keep the narrowed list informative, and show work in progr…
samerzughul Oct 12, 2026
0460dde
apply: a retry budget without a shared total is refused
samerzughul Oct 12, 2026
85f33dd
Built-in adapters: a call that never returns fails as a timeout
samerzughul Oct 12, 2026
0240213
Aggregations: one replica builds a roll-up, the others step aside
samerzughul Oct 12, 2026
edc97ed
Staging runs two replicas
samerzughul Oct 12, 2026
af969e6
CI: staging deploys from releases/r10.0-develop
samerzughul Oct 12, 2026
f55ab9c
CI: no comments inside helm-set-values
samerzughul Oct 12, 2026
195a61c
ci: split the develop and release pipelines
MusaMisto Oct 12, 2026
6035d45
ci: publish the production chart to GHCR as well as ChartMuseum
MusaMisto Oct 12, 2026
4ae009c
Merge pull request #368 from simplify9/musa/ci/develop-pipeline
MusaMisto Oct 12, 2026
27275f4
Develop: S3 checksums only when required, as an experiment
samerzughul Oct 12, 2026
7594ebb
Sync gateways can say what really happened when a delivery fails
samerzughul Oct 12, 2026
ba616e7
Prove Quartz runs each scheduled fire on one replica
samerzughul Oct 12, 2026
4bd583d
Say what is true about scheduled jobs on several replicas
samerzughul Oct 12, 2026
d0f4c06
Stop calling a destination that keeps failing
samerzughul Oct 12, 2026
c305b1c
Send to a notifier through one helper
samerzughul Oct 12, 2026
9b2f5a8
Let a subscription say how often it expects traffic
samerzughul Oct 12, 2026
4e86aaf
Tell notifiers when a subscription goes quiet, and when it is back
samerzughul Oct 12, 2026
d995ac6
Set expected traffic on the subscription page and show when it is quiet
samerzughul Oct 12, 2026
d229162
Document expected traffic and quiet subscriptions
samerzughul Oct 12, 2026
a0569b7
ci: publish develop from the production chart directory
MusaMisto Oct 12, 2026
2516f36
Merge pull request #370 from simplify9/musa/ci/develop-single-chart
MusaMisto Oct 12, 2026
631f105
fix(build): build SW.Bitween.Web once per solution build
MusaMisto Oct 12, 2026
9e0db43
Work groups: a name already taken is refused
samerzughul Oct 12, 2026
bc58550
ci: deploy develop to bitween-dev and releases to production
MusaMisto Oct 12, 2026
c4b6861
Merge pull request #372 from simplify9/musa/ci/deploy-targets
MusaMisto Oct 12, 2026
34c9faf
Merge pull request #371 from simplify9/musa/fix/web-built-once
MusaMisto Oct 12, 2026
f93fa15
ci: carry the S3 checksum setting into production
MusaMisto Oct 12, 2026
67042db
ci: serve app.bitween.io from the prod gateway's wildcard listener
MusaMisto Oct 12, 2026
09bb100
ci: serve app-dev.bitween.io from the dev gateway's wildcard listener
MusaMisto Oct 12, 2026
f9e061a
Merge pull request #373 from simplify9/musa/ci/prod-aws-checksum
MusaMisto Oct 12, 2026
0231b39
Merge releases/r10.0 into releases/r10.0-develop
MusaMisto Oct 12, 2026
736f612
Merge pull request #374 from simplify9/musa/sync-r10.0-into-develop
MusaMisto Oct 12, 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
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
**/*.jfm
**/azds.yaml
**/bin
**/charts
charts
**/docker-compose*
**/Dockerfile*
**/node_modules
Expand Down
182 changes: 138 additions & 44 deletions .github/workflows/bitween-api-cicd-gateway.yml

Large diffs are not rendered by default.

143 changes: 143 additions & 0 deletions .github/workflows/cli-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: bitween CLI release

# Publishes the bitween command as self-contained binaries on a GitHub release: nothing needs .NET
# installed to run them. Never run by hand or by a tag: the CI run that publishes this repository
# calls it with the version it computed (determine-semver: the next patch from the git tags), so the
# CLI carries the version of the release it ships with. The computed version is the bare x.y.z on
# develop too, so a develop build says so with prerelease and passes its run number.
# a release, 10.0.61 cli-v10.0.61 the latest release
# a prerelease, 10.0.61 with prerelease and run 121 cli-v10.0.61-dev.121 a pre-release, to try out
# Called by bitween-api-cicd-gateway.yml: after the release from releases/r10.0, and after each develop build.
on:
workflow_call:
inputs:
version:
description: "The version the calling run computed"
type: string
required: true
prerelease:
description: "Release as a pre-release, named after the run"
type: boolean
default: false
run-number:
description: "The calling run's number, for a pre-release"
type: string
default: ""

permissions:
contents: write

jobs:
channel:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.channel.outputs.version }}
prerelease: ${{ steps.channel.outputs.prerelease }}
steps:
- name: Channel
id: channel
env:
VERSION: ${{ inputs.version }}
PRERELEASE: ${{ inputs.prerelease }}
RUN_NUMBER: ${{ inputs.run-number }}
run: |
v="$VERSION"
if [ "$PRERELEASE" = "true" ]; then
# A pre-release names its run: 10.0.61 from run 121 is 10.0.61-dev.121.
v="${v%%-*}-dev.${RUN_NUMBER:-${GITHUB_RUN_NUMBER}}"
echo "prerelease=true" >> "$GITHUB_OUTPUT"
elif [[ "$v" == *-* ]]; then
# A version that already carries its branch and run: 10.0.61-releases-r10-0-develop.121 is 10.0.61-dev.121.
v="${v%%-*}-dev.${v##*.}"
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
echo "version=$v" >> "$GITHUB_OUTPUT"

build:
needs: channel
runs-on: ubuntu-latest
strategy:
matrix:
rid: [linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64, osx-x64, osx-arm64, win-x64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Publish
run: >
dotnet publish SW.Bitween.Cli -c Release -r ${{ matrix.rid }} --self-contained
-p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=none
-p:Version=${{ needs.channel.outputs.version }} -o out
- name: Package
run: |
mkdir -p dist
cp docs/cli.md out/README.md 2>/dev/null || true
if [[ "${{ matrix.rid }}" == win-* ]]; then
(cd out && zip -q -r ../dist/bitween-${{ matrix.rid }}.zip .)
else
tar -czf dist/bitween-${{ matrix.rid }}.tar.gz -C out .
fi
- uses: actions/upload-artifact@v4
with:
name: bitween-${{ matrix.rid }}
path: dist/*

# The data source providers (RabbitMQ, SQS and the database engines) as adapter packages, with the
# release's version: installed like any adapter, with bitween adapter publish or apply's adapters
# section. Nothing else publishes them, and a Bitween runs no data source without them.
providers:
needs: channel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Build
env:
VERSION: ${{ needs.channel.outputs.version }}
run: |
dotnet build SW.Bitween.Cli -c Release -o cli
mkdir -p dist
for project in SW.Bitween.Adapters.Bus.RabbitMq SW.Bitween.Adapters.Bus.Sqs SW.Bitween.Adapters.Db.PostgreSql \
SW.Bitween.Adapters.Db.MySql SW.Bitween.Adapters.Db.SqlServer SW.Bitween.Adapters.Db.Oracle; do
jq --arg v "$VERSION" '.version = $v' "$project/adapter.json" > adapter.json.tmp && mv adapter.json.tmp "$project/adapter.json"
dotnet cli/bitween.dll adapter build "$project" -o dist
done
ls -la dist
- uses: actions/upload-artifact@v4
with:
name: bitween-providers
path: dist/*.zip

release:
needs: [channel, build, providers]
runs-on: ubuntu-latest
steps:
# Only the CLI builds' own artifacts. Without a pattern this fetched every artifact in the run,
# including the build record docker/build-push-action uploads in the deploy job, which can't be
# extracted and failed the release (and would have landed in SHA256SUMS if it could).
- uses: actions/download-artifact@v4
with:
pattern: bitween-*
path: dist
merge-multiple: true
- name: Checksums
run: cd dist && sha256sum * > SHA256SUMS && cat SHA256SUMS
- name: Release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
v="${{ needs.channel.outputs.version }}"
install="curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/releases/r10.0/scripts/install-cli.sh"
if [ "${{ needs.channel.outputs.prerelease }}" = "true" ]; then
gh release create "cli-v$v" dist/* --title "bitween CLI $v (pre-release)" --target "${{ github.sha }}" --prerelease \
--notes "A pre-release of the bitween command, built from ${{ github.ref_name }}, to try out. Install: $install | BITWEEN_CLI_VERSION=$v sh - or download the archive for your platform and check it against SHA256SUMS."
else
gh release create "cli-v$v" dist/* --title "bitween CLI $v" --target "${{ github.sha }}" --latest \
--notes "The bitween command, self-contained for each platform. Install: $install | sh - or download the archive for your platform and check it against SHA256SUMS."
fi
8 changes: 4 additions & 4 deletions .github/workflows/critical-vuln-check.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# =============================================================================
# Critical Dependabot Vulnerability Check — Caller template
# Critical Dependabot Vulnerability Check - Caller template
# =============================================================================
# USAGE:
# Copy this file to your repo at .github/workflows/critical-vuln-check.yml.
# No REPLACE values needed — this template requires no customization.
# No REPLACE values needed - this template requires no customization.
#
# WHAT IT DOES:
# Runs on every PR targeting main or develop. Fails if the repository has
# any open CRITICAL-severity Dependabot alert.
#
# Enforcement differs by target branch via each repo's OWN branch
# protection settings (not by anything in this file):
# - On `main`: mark this check REQUIRED in branch protection — merge
# - On `main`: mark this check REQUIRED in branch protection - merge
# is physically blocked while a critical alert is open.
# - On `develop`: leave this check NOT required — it still shows as a
# - On `develop`: leave this check NOT required - it still shows as a
# failing/red check (a visible warning) without blocking
# the merge.
# =============================================================================
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# =============================================================================
# Dependabot Auto-Merge — Caller template
# Dependabot Auto-Merge - Caller template
# =============================================================================
# USAGE:
# Copy this file to your repo at .github/workflows/dependabot-auto-merge.yml.
Expand All @@ -10,13 +10,13 @@
# - The PR author is dependabot[bot]
# - The update is a semver PATCH bump (never minor/major)
# - The ecosystem is npm, nuget, pub, bundler, or github-actions
# (NEVER docker — base image bumps always need manual review)
# (NEVER docker - base image bumps always need manual review)
# - This repo currently has no open critical Dependabot alert (re-checked
# here explicitly — see workflow-templates/critical-vuln-check.yml's
# here explicitly - see workflow-templates/critical-vuln-check.yml's
# header for why this can't just `needs:` that file's job)
# "Auto-merge" here means GitHub's native auto-merge feature: it still
# waits for the repo's actual required status checks (build/test) to pass
# before merging — this workflow does not bypass those.
# before merging - this workflow does not bypass those.
# =============================================================================
name: Dependabot Auto-Merge

Expand Down Expand Up @@ -64,5 +64,5 @@ jobs:
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
set -euo pipefail
echo "::notice title=🤖 [AUTO-MERGE] Enabling auto-merge::${PR_URL} — patch-level ${{ steps.metadata.outputs.package-ecosystem }} bump, vuln gate passed"
echo "::notice title=🤖 [AUTO-MERGE] Enabling auto-merge::${PR_URL} - patch-level ${{ steps.metadata.outputs.package-ecosystem }} bump, vuln gate passed"
gh pr merge --auto --squash "$PR_URL"
50 changes: 50 additions & 0 deletions .github/workflows/dotnet-pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Builds the solution and runs the .NET unit tests on every pull request into a release branch.
#
# The deploy pipeline runs the .NET tests only after a merge, so a change that broke them was
# found once it had already landed on a release branch. Bitween runs at customer sites that
# upgrade in place, so this check runs before the merge instead. The unit tests need no
# database or broker and take seconds. The integration tests (Testcontainers) still run in the
# deploy pipeline.
name: .NET checks

on:
pull_request:
branches: [releases/**]
paths-ignore:
# Covered by frontend-tests.yml; the .NET build does not compile the SPA.
- 'SW.Bitween.Web/ClientApp/**'
- 'docs/**'
- '**/*.md'

permissions:
contents: read

concurrency:
group: dotnet-pr-checks-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
build-and-unit-test:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
# Pinned to commits, since a tag can be moved.
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: '10.0.x'
- run: dotnet restore SW.Bitween.sln
# SkipClientBuild keeps MSBuild from building the SPA should any target pull in publish.
- run: dotnet build SW.Bitween.sln --no-restore --configuration Release -p:SkipClientBuild=true
- run: >
dotnet test SW.Bitween.UnitTests/SW.Bitween.UnitTests.csproj
--no-build --configuration Release
--logger "trx;LogFileName=unit-tests.trx"
--results-directory TestResults
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: failure()
with:
name: unit-test-results
path: TestResults
4 changes: 2 additions & 2 deletions .github/workflows/frontend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# The deploy pipeline only runs the .NET test projects, and only after a merge, so until
# this existed nothing ever ran the frontend tests outside someone's machine. These need
# no backend or database — the component tests render pages against a mock network — so
# no backend or database - the component tests render pages against a mock network - so
# they take seconds. The Playwright e2e suite is not run here: it needs a running backend
# with seeded data.
name: Frontend tests
Expand Down Expand Up @@ -40,7 +40,7 @@ jobs:
cache: yarn
cache-dependency-path: SW.Bitween.Web/ClientApp/yarn.lock
- run: yarn install --frozen-lockfile
# The same type-check the Docker build runs, which covers the tests too — so a test file
# The same type-check the Docker build runs, which covers the tests too - so a test file
# that breaks it fails here rather than in the deploy after the merge.
- run: npx tsc -b
- run: yarn test
95 changes: 95 additions & 0 deletions .github/workflows/sdk-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: SDK release

# Publishes the adapter contract for Python to PyPI as simplyworks-bitween and for JavaScript and
# TypeScript to npm as @simplyworks/bitween. Never run by hand or by a tag: the release run on
# releases/r10.0 (bitween-api-cicd-gateway.yml) calls it with the version it computed, so they carry
# Bitween's version. Only a release version is published. Each is tested first against
# SW-Serverless's SDK from its default branch, and a version already on its registry is left alone,
# so a failed run can simply be run again.
on:
workflow_call:
inputs:
version:
description: "The version the calling run computed"
type: string
required: true

permissions:
contents: read

jobs:
python:
if: ${{ !contains(inputs.version, '-') }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk/python
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: simplify9/SW-Serverless
path: sw-serverless
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Version
id: version
env:
VERSION: ${{ inputs.version }}
run: |
v="$VERSION"
sed -i -E "s/^version = \".*\"/version = \"$v\"/" pyproject.toml
sed -i -E "s/^__version__ = \".*\"/__version__ = \"$v\"/" src/simplyworks_bitween/__init__.py
echo "value=$v" >> "$GITHUB_OUTPUT"
- name: Test
run: PYTHONPATH="src:$GITHUB_WORKSPACE/sw-serverless/sdk/python/src" python -m unittest discover -s tests
- name: Build
run: |
python -m pip install --upgrade build
python -m build
- uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: sdk/python/dist
password: ${{ secrets.PYPI_API_TOKEN }}
skip-existing: true

node:
if: ${{ !contains(inputs.version, '-') }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk/node
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: simplify9/SW-Serverless
path: sw-serverless
- uses: actions/setup-node@v4
with:
node-version: "22"
registry-url: "https://registry.npmjs.org"
- name: Version
id: version
env:
VERSION: ${{ inputs.version }}
run: |
v="$VERSION"
npm version "$v" --no-git-tag-version --allow-same-version
sed -i -E "s/^const VERSION = \".*\";/const VERSION = \"$v\";/" src/index.js
echo "value=$v" >> "$GITHUB_OUTPUT"
- name: Test
env:
SW_SERVERLESS_NODE: ${{ github.workspace }}/sw-serverless/sdk/node/src
run: node --test
- name: Publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
name=$(node -p "require('./package.json').name")
if npm view "$name@${{ steps.version.outputs.value }}" version >/dev/null 2>&1; then
echo "$name@${{ steps.version.outputs.value }} is already on npm."
else
npm publish --access public
fi
Loading
Loading