Skip to content

Commit 7f2c19b

Browse files
committed
ci: split the develop and release pipelines
releases/r10.0-staging was renamed to releases/r10.0-develop, which no job matched, so pushes to develop built nothing (run 142 skipped). Develop now publishes under its own names, so nothing it builds can reach clients: - develop: simplify9/bitween-develop image and the bitween-develop chart (ChartMuseum + GHCR), deployed to playground, no NuGet packages. charts/develop is charts/default symlinked under its own name, since the chart names the image after itself. The playground release stays bitween (nameOverride=bitween), so it upgrades in place: same resource names and selectors. - develop-tests runs the unit and integration tests, which the reusable only runs in its NuGet job. - r10.0: unchanged release (bitween chart to ChartMuseum, simplify9/bitween, NuGet, CLI, SDKs). - One concurrency queue per branch: the two pipelines no longer share a published name, and a shared queue let a develop push cancel a pending release. - Manual runs follow the branch they are started on. CLI pre-releases are -dev.<run>.
1 parent af969e6 commit 7f2c19b

10 files changed

Lines changed: 99 additions & 62 deletions

File tree

‎.github/workflows/bitween-api-cicd-gateway.yml‎

Lines changed: 73 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
name: Bitween API CI/CD (Gateway · both)
22
run-name: Run-${{ github.ref_name }}-${{ github.run_number }}
33

4+
# Two pipelines that publish nothing under the same name:
5+
# releases/r10.0-develop the simplify9/bitween-develop image and the bitween-develop chart,
6+
# deployed to playground. No NuGet packages, the CLI as a pre-release.
7+
# releases/r10.0 the simplify9/bitween image and the bitween chart clients install from
8+
# ChartMuseum, the NuGet packages, the CLI and the SDKs. Never deployed.
9+
# Run workflow by hand on either branch to rerun that branch's pipeline.
410
on:
511
push:
612
branches:
7-
- releases/**
13+
- releases/r10.0
14+
- releases/r10.0-develop
815
workflow_dispatch:
916

10-
# One queue for staging AND release, not one per branch. Both jobs below take their patch from
11-
# the same 10.0.x git tags and push the same docker.io/simplify9/bitween:10.0.<patch> image tag,
12-
# and a run only claims its patch when it tags at the very end. Two runs overlapping (a staging
13-
# push, then the staging -> r10.0 merge seconds later) would compute the same patch: the image
14-
# tag is overwritten by whichever finishes last, while ChartMuseum (409 = success) and NuGet
15-
# (--skip-duplicate) silently keep whichever came first.
17+
# One queue per branch. Both pipelines still take their patch from the same 10.0.x git tags, so a
18+
# develop run and a release run that overlap can compute the same patch, but they publish it under
19+
# different names (bitween-develop / bitween, cli-v10.0.N-dev.<run> / cli-v10.0.N, git tag
20+
# 10.0.N-releases-r10-0-develop.<run> / 10.0.N), so nothing is overwritten or silently kept. One
21+
# queue for both would be worse: GitHub keeps a single pending run per group, so a develop push
22+
# would cancel a release waiting behind another develop run.
1623
concurrency:
17-
group: cicd-gateway-bitween-10.0
24+
group: cicd-gateway-bitween-${{ github.ref_name }}
1825
cancel-in-progress: false
1926

2027
# contents: write -> tag job. packages: write -> publish AND pull the Helm chart
@@ -27,8 +34,8 @@ permissions:
2734

2835
jobs:
2936
build-publish-deploy:
30-
# Staging: build, publish to GHCR only, deploy to playground (or any branch, manually).
31-
if: ${{ (github.event_name == 'push' && github.ref_name == 'releases/r10.0-develop') || github.event_name == 'workflow_dispatch' }}
37+
# Develop: build, publish bitween-develop, deploy to playground.
38+
if: ${{ github.ref_name == 'releases/r10.0-develop' }}
3239
uses: simplify9/.github/.github/workflows/reusable-service-cicd.yml@main
3340
with:
3441
major-version: '10'
@@ -39,37 +46,31 @@ jobs:
3946
docker-context: '.'
4047
docker-platforms: 'linux/amd64'
4148

42-
chart-name: 'bitween' # must match charts/default Chart.yaml name:
43-
chart-path: './charts/default'
44-
45-
# 1) Publish the Helm chart to GHCR OCI only. ChartMuseum is what clients install from,
46-
# so only the release job below publishes there; staging versions are plain x.y.z and
47-
# would otherwise be the newest chart a client gets.
48-
chart-publish-method: 'github-oci'
49+
# charts/develop is charts/default under its own name (see its Chart.yaml): the reusable
50+
# requires chart-name to match Chart.yaml, and the production chart must stay bitween.
51+
chart-name: 'bitween-develop'
52+
chart-path: './charts/develop'
53+
# ChartMuseum to install it by hand, GHCR for the deploy below.
54+
chart-publish-method: 'both'
55+
chart-repo-url: 'https://charts.sf9.io'
4956

50-
# Docker image stays on Docker Hub
57+
# The chart's image is <image.repo>/<chart name>:<version>, so the image is named after
58+
# the chart. Its own repository also keeps develop off simplify9/bitween:latest.
5159
container-registry: 'docker.io'
52-
image-name: 'simplify9/bitween'
60+
image-name: 'simplify9/bitween-develop'
5361

54-
# Build + unit-test + push the SDK NuGet package (versioned with the
55-
# pipeline semver, e.g. 8.1.x - was 8.0.<run_number> in the old job),
56-
# and the adapter contract package (SimplyWorks.Bitween.Adapters) adapters reference.
57-
nuget-projects: >-
58-
SW.Bitween.Sdk/SW.Bitween.Sdk.csproj
59-
SW.Bitween.Adapters/SW.Bitween.Adapters.csproj
60-
run-tests: 'true'
61-
# Integration tests run against real Postgres/RabbitMQ/MailHog via
62-
# Testcontainers - self-contained, no extra CI services needed, since
63-
# ubuntu-latest already has a Docker daemon available.
64-
test-projects: |
65-
SW.Bitween.UnitTests/SW.Bitween.UnitTests.csproj
66-
SW.Bitween.IntegrationTests/SW.Bitween.IntegrationTests.csproj
62+
# No nuget-projects: develop publishes no packages. The reusable runs the tests only in
63+
# its NuGet job, so develop-tests below runs them.
6764

68-
# 2) Deploy to playground via Gateway API
65+
# Deploy to playground via Gateway API
6966
deploy: true
70-
# 3) Pull the chart from GHCR OCI
67+
# Pull the chart from GHCR OCI
7168
deploy-chart-source: 'github-oci'
7269
deploy-namespace: 'playground'
70+
# Upgrade the existing release in place: with nameOverride=bitween (helm-set-values) every
71+
# resource name and selector is what the bitween chart rendered. A new bitween-develop
72+
# release would run beside the old one, and the older HTTPRoute keeps app-dev.bitween.io.
73+
deploy-release-name: 'bitween'
7374
routing-mode: 'gateway-api'
7475
gateway-hostnames: 'app-dev.bitween.io'
7576
# '/' serves the admin SPA out of this image's wwwroot, so the root has to route
@@ -80,11 +81,13 @@ jobs:
8081
# dedicated listener + cert-manager Certificate on the parent gateway
8182
# (public-gateway · s9-dev-edge · cilium · letsencrypt-production-gateway).
8283

83-
# Non-routing chart values (routing itself is generated by gateway-api mode).
84+
# Non-routing chart values (routing itself is generated by gateway-api mode). Comments stay
85+
# out of this block: every line in it reaches helm as --set, and a # line fails the deploy.
86+
# replicaCount two: the lab's phase 6 kills one mid-traffic, and anything that runs on
87+
# every replica at once (scheduled jobs, data source leases) shows up here first.
8488
helm-set-values: |
89+
nameOverride=bitween
8590
global.environment=Development
86-
# Two: the lab's phase 6 kills one mid-traffic, and anything that runs on
87-
# every replica at once (scheduled jobs, data source leases) shows up here first.
8891
replicaCount=2
8992
resources.requests.cpu=25m
9093
resources.requests.memory=704Mi
@@ -94,14 +97,12 @@ jobs:
9497
# Docker image push credentials (Docker Hub)
9598
registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
9699
registry-password: ${{ secrets.DOCKERHUB_TOKEN }}
100+
chartmuseum-username: ${{ secrets.CM_USER }}
101+
chartmuseum-password: ${{ secrets.CM_PASSWORD }}
97102

98103
# GHCR chart push + pull and git tagging use the built-in token
99104
github-token: ${{ secrets.GITHUB_TOKEN }}
100105

101-
# NuGet API key for the SDK package push (publishes to nuget.org, the
102-
# reusable's default feed - no nuget-source override needed).
103-
nuget-api-key: ${{ secrets.SWNUGETKEY }}
104-
105106
# Gateway-API cluster kubeconfig (V2)
106107
kubeconfig-gateway: ${{ secrets.S9DEV_KUBECONFIG_V2 }}
107108

@@ -116,11 +117,33 @@ jobs:
116117
# (openssl rand -base64 48). Changing it signs out everyone holding an older token.
117118
helm-set-secret-values: 'global.token.key=${{ secrets.TokenKey }},db=${{ secrets.dbConnection }},global.bus.rabbitUrl=${{ secrets.rabbitUrl }},global.cloudFiles.secretAccessKey=${{ secrets.SecretAccessKey }},global.cloudFiles.accessKeyId=${{ secrets.AccessKeyId }},global.cloudFiles.serviceUrl=${{ secrets.ServiceUrl }},global.cloudFiles.bucketName=${{ secrets.BucketName }},environmentVariables.Bitween__RabbitMqManagementUrl=${{ secrets.RabbitMqManagementUrl }},environmentVariables.Bitween__RabbitMqManagementPassword=${{ secrets.RabbitMqManagementPassword }},environmentVariables.Bitween__RabbitMqManagementUsername=${{ secrets.RabbitMqManagementUsername }}'
118119

120+
develop-tests:
121+
# The same build and tests the reusable runs in its NuGet job, which develop skips. As before,
122+
# a failure does not hold back the deploy.
123+
if: ${{ github.ref_name == 'releases/r10.0-develop' }}
124+
runs-on: ${{ vars.S9_RUNNER || vars.S9_HOSTED_RUNNER || 'ubuntu-24.04' }}
125+
timeout-minutes: 30
126+
permissions:
127+
contents: read
128+
steps:
129+
- uses: actions/checkout@v7
130+
with:
131+
persist-credentials: false
132+
- uses: simplify9/.github/.github/actions/dotnet-build@main
133+
with:
134+
projects: '**/*.csproj'
135+
test-projects: |
136+
SW.Bitween.UnitTests/SW.Bitween.UnitTests.csproj
137+
SW.Bitween.IntegrationTests/SW.Bitween.IntegrationTests.csproj
138+
configuration: 'Release'
139+
dotnet-version: '10.0.x'
140+
run-tests: 'true'
141+
119142
publish-release:
120143
# Release: build and publish to ChartMuseum for clients, never deploy. releases/r10.0 is the
121144
# repository's default branch, so the reusable workflow treats it as a release: a clean
122145
# 10.0.<patch> git tag, and the critical Dependabot gate runs first.
123-
if: ${{ github.event_name == 'push' && github.ref_name == 'releases/r10.0' }}
146+
if: ${{ github.ref_name == 'releases/r10.0' }}
124147
uses: simplify9/.github/.github/workflows/reusable-service-cicd.yml@main
125148
with:
126149
major-version: '10'
@@ -144,6 +167,9 @@ jobs:
144167
SW.Bitween.Sdk/SW.Bitween.Sdk.csproj
145168
SW.Bitween.Adapters/SW.Bitween.Adapters.csproj
146169
run-tests: 'true'
170+
# Integration tests run against real Postgres/RabbitMQ/MailHog via
171+
# Testcontainers - self-contained, no extra CI services needed, since
172+
# ubuntu-latest already has a Docker daemon available.
147173
test-projects: |
148174
SW.Bitween.UnitTests/SW.Bitween.UnitTests.csproj
149175
SW.Bitween.IntegrationTests/SW.Bitween.IntegrationTests.csproj
@@ -158,12 +184,12 @@ jobs:
158184
nuget-api-key: ${{ secrets.SWNUGETKEY }}
159185
dependabot-alerts-token: ${{ secrets.DEPENDABOT_ALERTS_TOKEN }}
160186

161-
# The bitween CLI and the adapter contract packages carry the version the run above computed, so
162-
# nothing is tagged by hand. A staging build releases the CLI as a pre-release, cli-v<x.y.z>-stg.<run>;
163-
# the release from releases/r10.0 releases it as the latest, cli-v<x.y.z>, and publishes the SDKs.
164-
cli-staging:
187+
# The bitween CLI and the SDKs carry the version the run above computed, so nothing is tagged by
188+
# hand. A develop build releases the CLI as a pre-release, cli-v<x.y.z>-dev.<run>; the release
189+
# from releases/r10.0 releases it as the latest, cli-v<x.y.z>, and publishes the SDKs. Each runs
190+
# only when the job it needs ran, so the branch is decided above.
191+
cli-develop:
165192
needs: build-publish-deploy
166-
if: ${{ github.event_name == 'push' && github.ref_name == 'releases/r10.0-develop' }}
167193
uses: ./.github/workflows/cli-release.yml
168194
with:
169195
version: ${{ needs.build-publish-deploy.outputs.version }}
@@ -172,14 +198,12 @@ jobs:
172198

173199
cli-release:
174200
needs: publish-release
175-
if: ${{ github.event_name == 'push' && github.ref_name == 'releases/r10.0' }}
176201
uses: ./.github/workflows/cli-release.yml
177202
with:
178203
version: ${{ needs.publish-release.outputs.version }}
179204

180205
sdk-release:
181206
needs: publish-release
182-
if: ${{ github.event_name == 'push' && github.ref_name == 'releases/r10.0' }}
183207
permissions:
184208
contents: read
185209
uses: ./.github/workflows/sdk-release.yml

‎.github/workflows/cli-release.yml‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ name: bitween CLI release
44
# installed to run them. Never run by hand or by a tag: the CI run that publishes this repository
55
# calls it with the version it computed (determine-semver: the next patch from the git tags), so the
66
# CLI carries the version of the release it ships with. The computed version is the bare x.y.z on
7-
# staging too, so a staging build says so with prerelease and passes its run number.
7+
# develop too, so a develop build says so with prerelease and passes its run number.
88
# a release, 10.0.61 cli-v10.0.61 the latest release
9-
# a prerelease, 10.0.61 with prerelease and run 121 cli-v10.0.61-stg.121 a pre-release, to try out
10-
# Called by bitween-api-cicd-gateway.yml: after the release from releases/r10.0, and after each staging build.
9+
# a prerelease, 10.0.61 with prerelease and run 121 cli-v10.0.61-dev.121 a pre-release, to try out
10+
# Called by bitween-api-cicd-gateway.yml: after the release from releases/r10.0, and after each develop build.
1111
on:
1212
workflow_call:
1313
inputs:
@@ -43,12 +43,12 @@ jobs:
4343
run: |
4444
v="$VERSION"
4545
if [ "$PRERELEASE" = "true" ]; then
46-
# A pre-release names its run: 10.0.61 from run 121 is 10.0.61-stg.121.
47-
v="${v%%-*}-stg.${RUN_NUMBER:-${GITHUB_RUN_NUMBER}}"
46+
# A pre-release names its run: 10.0.61 from run 121 is 10.0.61-dev.121.
47+
v="${v%%-*}-dev.${RUN_NUMBER:-${GITHUB_RUN_NUMBER}}"
4848
echo "prerelease=true" >> "$GITHUB_OUTPUT"
4949
elif [[ "$v" == *-* ]]; then
50-
# A version that already carries its branch and run: 10.0.61-releases-r10-0-staging.121 is 10.0.61-stg.121.
51-
v="${v%%-*}-stg.${v##*.}"
50+
# A version that already carries its branch and run: 10.0.61-releases-r10-0-develop.121 is 10.0.61-dev.121.
51+
v="${v%%-*}-dev.${v##*.}"
5252
echo "prerelease=true" >> "$GITHUB_OUTPUT"
5353
else
5454
echo "prerelease=false" >> "$GITHUB_OUTPUT"

‎charts/develop/.helmignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../default/.helmignore

‎charts/develop/Chart.yaml‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# The develop build of charts/default: the same templates and values (symlinked), published as
2+
# bitween-develop so it can never be mistaken for the production bitween chart clients install.
3+
# The image is <image.repo>/<chart name>, so this chart runs simplify9/bitween-develop.
4+
# CI overwrites version and appVersion.
5+
apiVersion: v2
6+
version: 0.0.1
7+
appVersion: 0.0.1
8+
description: A Helm chart for Bitween (develop builds from releases/r10.0-develop)
9+
name: bitween-develop

‎charts/develop/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../default/README.md

‎charts/develop/templates‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../default/templates

‎charts/develop/values.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../default/values.yaml

‎docs/cli.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ its contract, its Python and Node packages, and publishing through Bitween's API
1313

1414
Each release has a self-contained binary for Linux (x64, arm64, and musl x64 and arm64 for Alpine), macOS (x64, arm64) and
1515
Windows (x64), with a `SHA256SUMS` file. Each release of Bitween from `releases/r10.0` releases the CLI with it, at Bitween's version, as
16-
`cli-v<version>`; each staging build releases a pre-release, `cli-v<version>-stg.<run>`. It needs nothing else
16+
`cli-v<version>`; each build from `releases/r10.0-develop` releases a pre-release, `cli-v<version>-dev.<run>`. It needs nothing else
1717
installed, apart from what the adapters you build need: the .NET SDK for .NET adapters, Python 3.12 or
1818
later for Python ones (with pip when they have requirements), Node 22 or later for JavaScript and
1919
TypeScript ones (with npm when they have dependencies).
@@ -24,7 +24,7 @@ curl -fsSL https://raw.githubusercontent.com/simplify9/Bitween-api/releases/r10.
2424

2525
That installs the latest release to `~/.local/bin`, after checking the download against `SHA256SUMS`;
2626
`INSTALL_DIR` changes where, and `BITWEEN_CLI_VERSION=10.0.60` picks a version. The script never
27-
picks a staging pre-release on its own, only when named: `BITWEEN_CLI_VERSION=10.0.61-stg.121`. It works on Linux and
27+
picks a develop pre-release on its own, only when named: `BITWEEN_CLI_VERSION=10.0.61-dev.121`. It works on Linux and
2828
macOS, on x64 and arm64, glibc or musl (Alpine). On Windows, download
2929
`bitween-win-x64.zip` from the [releases](https://github.com/simplify9/Bitween-api/releases) and put
3030
`bitween.exe` on your `PATH`.

‎docs/deployment.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ Run several replicas behind a load balancer for throughput and availability, and
122122

123123
| Pipeline | Trigger | What it does |
124124
|---|---|---|
125-
| `.github/workflows/bitween-api-cicd-gateway.yml` | Push to `releases/r10.0-staging`, or manual | Runs unit and integration tests, pushes the image to Docker Hub, publishes the chart to GHCR, pushes `SimplyWorks.Bitween.Sdk` and `SimplyWorks.Bitween.Adapters` to NuGet, tags the repository, and deploys the playground environment |
126-
| `.github/workflows/bitween-api-cicd-gateway.yml` | Push to `releases/r10.0` | The same build, tests, image and NuGet packages, with the chart published to `charts.sf9.io` instead. Nothing is deployed. |
127-
| `.github/workflows/cli-release.yml` | Called by the CI/CD workflow, never run by hand or by a tag: after the release from `releases/r10.0`, and after each staging build | Publishes the [bitween CLI](cli.md) at the version that run computed, as self-contained single-file binaries for `linux-x64`, `linux-arm64`, `linux-musl-x64`, `linux-musl-arm64`, `osx-x64`, `osx-arm64` and `win-x64`, with a `SHA256SUMS` file. From the release it is `cli-v<version>`, the latest release; from staging, the pre-release `cli-v<version>-stg.<run>`. `scripts/install-cli.sh` installs the latest release, a pre-release only when named. |
125+
| `.github/workflows/bitween-api-cicd-gateway.yml` | Push to `releases/r10.0-develop`, or manual on it | Runs unit and integration tests, pushes the `simplify9/bitween-develop` image to Docker Hub, publishes the `bitween-develop` chart (`charts/develop`, the default chart under its own name) to `charts.sf9.io` and GHCR, tags the repository, and deploys the playground environment. Publishes no NuGet packages. |
126+
| `.github/workflows/bitween-api-cicd-gateway.yml` | Push to `releases/r10.0`, or manual on it | Runs unit and integration tests, pushes the `simplify9/bitween` image to Docker Hub, publishes the `bitween` chart clients install to `charts.sf9.io`, pushes `SimplyWorks.Bitween.Sdk` and `SimplyWorks.Bitween.Adapters` to NuGet, and tags the repository. Nothing is deployed. |
127+
| `.github/workflows/cli-release.yml` | Called by the CI/CD workflow, never run by hand or by a tag: after the release from `releases/r10.0`, and after each develop build | Publishes the [bitween CLI](cli.md) at the version that run computed, as self-contained single-file binaries for `linux-x64`, `linux-arm64`, `linux-musl-x64`, `linux-musl-arm64`, `osx-x64`, `osx-arm64` and `win-x64`, with a `SHA256SUMS` file. From the release it is `cli-v<version>`, the latest release; from develop, the pre-release `cli-v<version>-dev.<run>`. `scripts/install-cli.sh` installs the latest release, a pre-release only when named. |
128128
| `.github/workflows/sdk-release.yml` | Called by the CI/CD workflow after the release from `releases/r10.0` | Publishes the adapter contract packages at Bitween's version: `simplyworks-bitween` to PyPI and `@simplyworks/bitween` to npm, each tested first against SW-Serverless's SDK. Uses the `PYPI_API_TOKEN` and `NPM_TOKEN` secrets; a version already published is left alone. |
129129
| `.github/workflows/dotnet-pr-checks.yml` | Pull requests to `releases/**` | Builds the solution and runs the .NET unit tests |
130130
| `.github/workflows/frontend-tests.yml` | Pull requests to `releases/**` that touch the UI | Runs the UI unit and component tests |

‎scripts/install-cli.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ case "$arch" in
2020
esac
2121
rid="$os-$arch"
2222

23-
# The newest release; a pre-release (-stg) only when named.
23+
# The newest release; a pre-release (-dev) only when named.
2424
if [ -n "${BITWEEN_CLI_VERSION:-}" ]; then tag="cli-v$BITWEEN_CLI_VERSION"
2525
else tag=$(curl -fsSL "https://api.github.com/repos/$repo/releases" | grep -o '"tag_name": *"cli-v[^"]*"' | sed 's/.*"\(cli-v[^"]*\)"/\1/' | grep -E '^cli-v[0-9.]+$' | head -1); fi
2626
[ -n "$tag" ] || { echo "No bitween CLI release found" >&2; exit 1; }

0 commit comments

Comments
 (0)