Update AGENT_SANDBOX_VERSION to v1.0.8 and the docs that quote the control-plane pin (example prerequisites, architecture, versioning table, minimal-single-tenant template comment, platform skill). The v1.0.8 release adds only one CRD field, spec.failedPodPolicy (Sandbox and SandboxTemplate, enum Retain|Recreate, default Retain), so the existing manifests keep their behavior: Retain is the default and neither the API version (v1beta1) nor any field we set changed. All five custom resources still validate against the v1.0.8 CRD schemas. Behavior changes in the controller itself (bounded MCP output, router kustomization, creation-latency metric timing) do not affect the platform because it uses neither the sandbox-router nor the MCP server. Co-authored-by: SREDevOpsAgents <agents@sredevops.org>
7.3 KiB
Versioning, releases and changelog
versions.env is the single source of truth for the DSH ref, the repository revision, the pnpm version, the control-plane component versions and the image names. Nothing else may hard-code a version: scripts/check-versions.sh fails when a pin drifts, and it also verifies that prose mentions only the current release identity or its base DSH tag.
Release identity
release identity = DSH_VERSION + optional "-" + RELEASE_REVISION
| Piece | Meaning |
|---|---|
DSH_VERSION |
The upstream DeepSeek Harness git ref being packaged, e.g. dsh-v0.2.1-rc.3. It mirrors upstream's own tag, which is what "mirrored-DSH scheme" means. |
RELEASE_REVISION |
An optional repository revision at that DSH ref: empty for the first release, rN (N >= 2) for a repository-only re-release. |
Examples:
DSH_VERSION=dsh-v0.2.1-rc.3,RELEASE_REVISION=→ identitydsh-v0.2.1-rc.3(first release at that upstream ref).DSH_VERSION=dsh-v0.2.1-rc.3,RELEASE_REVISION=r4→ identitydsh-v0.2.1-rc.3-r4(documentation, CI or gateway changes on top of the same upstream DSH; no DSH upgrade).
A DSH upgrade produces a new base identity (for example the next upstream ref
with an empty revision); a repository-only change at the same DSH ref increments
rN.
Why the current identity is dsh-v0.2.1-rc.3-r4
The image tag dsh-v0.2.1-rc.3 was already published to GHCR for an earlier
repository state. Container tags are immutable in this project: re-pushing a
tag would silently change what an existing deployment runs. The mirrored-DSH
scheme therefore starts its first identity at -r2: the plain tag is
conceptually revision 1 and is taken, so the first publishable repository
revision at the same upstream ref is r2.
The identity is stored in versions.env and consumed everywhere:
the Dockerfile label, the example manifests, the Makefile and the release
workflow. The legacy dsh-v0.2.1-rc.3 tag remains published but is not updated;
new deployments use dsh-v0.2.1-rc.3-r4.
The gateway image moved from the repository-level :gateway tag to a nested
package (<repository>/dsh-agents-as-a-service/gateway). The release workflow
also republishes the legacy <repository>:gateway tag as a deprecated
compatibility alias; it may be removed in a later release, so deployments
should pin the nested package.
Channels
| Channel | Image tag | Meaning |
|---|---|---|
| Release | dsh-v0.2.1-rc.3-r4 |
The current immutable release identity. What production should pin (preferably by digest). |
latest |
latest |
Alias for the most recent release; moves only when a new release is published. |
main |
main |
Development channel, rebuilt from every push to main. Never treat it as a release; it exists so main can be tested. |
The same channels exist for every published package, including the nested example component image.
Compatibility matrix
Values from versions.env at the current identity:
| Component | Pin | Source |
|---|---|---|
| Upstream DSH source | DSH_REPO |
versions.env |
| DSH ref | dsh-v0.2.1-rc.3 |
DSH_VERSION |
| Repository revision | r4 |
RELEASE_REVISION |
| pnpm | 11.28.5 |
PNPM_VERSION |
| agent-sandbox (CRDs) | v1.0.8 |
AGENT_SANDBOX_VERSION, used by the examples and CI dry-run |
| Kubernetes Gateway API | v1.2.1 |
GATEWAY_API_VERSION, used by the SSO exposure variant |
| oauth2-proxy | quay.io/oauth2-proxy/oauth2-proxy:v7.15.5 |
OAUTH2_PROXY_IMAGE |
| Main image | ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox |
GHCR_IMAGE |
| Gateway image | ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox/dsh-agents-as-a-service/gateway |
GATEWAY_IMAGE, nested below GHCR_IMAGE |
Example component images are always nested below the main package:
<GHCR_IMAGE>/<example>/<component>. check-versions.sh rejects an unrelated
top-level package.
Bumping versions
make set-version DSH_VERSION=dsh-vX.Y.Z RELEASE_REVISION=rN
make check
set-version updates versions.env through
scripts/set-version.sh and leaves every consuming
file to derive from it. Never edit the Dockerfile, manifests, Makefile or
workflows with a literal version.
- New upstream DSH ref: change
DSH_VERSIONand clearRELEASE_REVISION. - Repository-only change at the same DSH ref: keep
DSH_VERSION, setRELEASE_REVISION=r(N+1).
Release checklist
mainis green andmake check,make test,make lintpass locally.make imageandmake gatewaybuild; smoke-test the images.- Bump the pins with
make set-version(commit that change through a PR). make release-dry-run— verifies the identity, prints the image names, checks the tag does not already exist, and previews the generated notes.- Create and push the annotated
dsh-*release tag (or dispatchrelease.yamlwith an existing tag). The workflow validates that the tag matches versions.env. - The workflow builds and pushes multi-arch images for the main image and the
example components (the identity tag plus
latest), creates the GitHub Release from the git-cliff notes, records the published digests, and opens achore(changelog)PR that refreshesCHANGELOG.mdonmain. - Merge the changelog PR. Verify:
docker buildx imagetools inspect <image>:<identity>shows both platforms, and the GitHub Release references the tag and the digest. - Announce the identity and the digest; deployments pin the digest.
Rollback
Tags and release identities are immutable, so a bad release is never re-tagged or deleted. Fix forward:
- Fix the problem on a
hotfix/<slug>branch (see gitflow). - Publish a new identity with the next revision,
-r(N+1), at the sameDSH_VERSION. - Point deployments at the new digest; keep the broken tag for audit history.
Emergency rollback to the previous release is also a re-deploy of a previous
digest, not a move of latest.
Changelog
CHANGELOG.md is generated by git-cliff from
Conventional Commits, configured in cliff.toml:
make changelog # regenerate CHANGELOG.md locally
- Do not edit
CHANGELOG.mdby hand; the release workflow regenerates it and opens a PR to refresh it onmain. - Commit messages and PR titles must be Conventional Commits so they are grouped correctly (Added / Fixed / Changed / Documentation / Build / CI / Tests / Maintenance).
- The changelog groups commits since the previous
dsh-*tag; release notes use the same rendering. - The changelog is excluded from the version-token check because it records historical identities on purpose.
Digest pinning
Release identities are mutable only in theory; deployments should still pin the resolved digest for reproducibility and supply-chain safety:
docker buildx imagetools inspect ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox:dsh-v0.2.1-rc.3-r4
# then, in the deployment:
# image: ghcr.io/sredevopsorg/deepseek-kubernetes-sandbox@sha256:<digest>
The example manifests use the identity tag so they stay readable and upgrade with
versions.env; production overlays should pin the digest. Release images carry
SBOM and provenance attestations (see SECURITY.md).