Playbooks

Upgrade and Release Process

How new bsqai-platform versions are versioned, security-scanned, released, and rolled out to running clusters.

Agentic Friendly

This playbook describes how a new bsqai-platform version moves from develop to a tagged release, and how that release reaches a running cluster. It complements the Deployment Sequence playbook, which covers deploying a given version for the first time.

Versioning

The platform version lives in a single VERSION file at the repository root, following SemVer. scripts/version-bump.sh <new-version> updates both VERSION and the version badge/title in README.md in one step, and validates that the argument is a well-formed SemVer string before writing anything.

Cutting a Release

Two GitHub Actions workflows drive release preparation, both triggered manually (workflow_dispatch):

  • Create Release Branch & Dev Bump — cuts release/<target_version> from develop (or a chosen source branch), running version-bump.sh on the release branch itself. It also immediately bumps develop forward to the next development version via a separate bump/<next_dev_version> branch and opens a PR back into develop, so development can continue without waiting for the release to stabilize. Optionally posts a feature-freeze notice to Slack.
  • Create Release PR — a simpler flow that computes the next version (patch/minor/major, or a custom value), branches release/v<version> from develop, updates VERSION/README.md, and opens a PR against main.

Once a release branch is stable, Finalize Release must be run from that release/* branch (it explicitly refuses to run from anything else). It resolves the version from the VERSION file (or an override input), fails if that tag already exists, and then creates a GitHub Release with auto-generated release notes. A downstream job posts a Slack notification to #bullsequana-ai-product announcing the release, or a failure notice if tagging failed.

Security Scanning

Helm Chart Security Scan (scan_platform_charts.py, scripts/helm-chart-scanner/) runs Trivy against every image referenced by the platform's rendered Helm charts, pulled directly from the ACR Helm repository. It runs on three triggers, each scanning a different scope:

TriggerScopePurpose
Pull requestSingle component (cert-manager)Lightweight smoke test that the scanner itself still works
Schedule (1st and 15th of the month, 01:30 UTC)main + develop, all componentsRecurring CVE sweep of both active branches
Manual dispatchChosen branch, all componentsOn-demand full scan

The scanner accepts a --severity filter (default CRITICAL,HIGH,MEDIUM,LOW) and a --fail-on threshold (HIGH, CRITICAL, or none) that controls its exit code independently of which severities are reported — the scheduled/PR runs currently use --fail-on none, so the workflow does not hard-fail the build on findings; it reports them instead. Results are written as a Markdown report to the job summary, and aggregated CVE counts per branch are posted to Slack after non-PR runs. Image tags that resolve to latest are flagged rather than scanned, since a floating tag would not reflect a version actually pinned by the codebase.

Deploying a Release to a Cluster

The reusable Cluster Upgrade workflow (upgrade-cluster.yml) applies a given branch/version to one of three long-lived clusters — demo, development, or release-staging — each mapped to its own AKS resource group and base domain. On a push to main or develop it auto-selects demo/development respectively; other targets require manual dispatch.

The rollout sequence is the same CLI flow used for first-time deployment:

  1. Connect to the target AKS cluster and save its kubeconfig as a build artifact.
  2. Generate platform.env (registry/Azure/DNS settings) and local.env (Git manifests target, tokens) from repository secrets.
  3. uv run -m src.cli.main validate — validate every component's configuration before rendering anything.
  4. uv run -m src.cli.main apply all -r — render manifests for all components.
  5. uv run -m src.cli.main apply-sealing-key — ensure the cluster has the sealed-secrets key needed to decrypt the sealed secrets just rendered.
  6. uv run -m src.cli.main push-manifests "CI: upgrade <environment> cluster" — push rendered manifests to bsqai-platform-manifests.
  7. uv run -m src.cli.main helm-apply argocd — apply/upgrade the ArgoCD Helm release directly (ArgoCD manages every other component, but has to be present to do so).
  8. Wait for the ArgoCD server pod to become ready and confirm the applications.argoproj.io API is reachable.

After this workflow completes, no manual sync step is needed — ArgoCD's automated sync policy picks up the pushed manifest changes and reconciles the cluster on its own, typically within 10–15 minutes for a full release.

On this page