Validate Helm Charts / Detect changed charts (pull_request) Successful in 11s
Validate Helm Charts / Resource quantities (pull_request) Successful in 16s
Validate Helm Charts / Selector match (pull_request) Successful in 9s
Validate Helm Charts / HTTPRoute match (pull_request) Successful in 9s
Validate Helm Charts / Bump level (pull_request) Successful in 4s
Install-test / Install-test paperless-ngx (pull_request) Successful in 5m12s
Validate Helm Charts / YAML scalars (pull_request) Successful in 8s
Validate Helm Charts / NetworkPolicy (pull_request) Successful in 8s
Validate Helm Charts / Build paperless-ngx (pull_request) Successful in 5s
Validate Helm Charts / Trivy config paperless-ngx (pull_request) Successful in 13s
Validate Helm Charts / Build stalwart (pull_request) Successful in 5s
Validate Helm Charts / Trivy config stalwart (pull_request) Successful in 17s
Install-test / Install-test stalwart (pull_request) Successful in 1m32s
Validate Helm Charts / Install-test (pull_request) Successful in 6m44s
149 lines
8.5 KiB
YAML
149 lines
8.5 KiB
YAML
apiVersion: v2
|
|
name: stalwart
|
|
description: A Helm chart to deploy a cluster-capable Stalwart mail server (SMTP, IMAP, JMAP, ManageSieve) on Kubernetes
|
|
icon: https://avatars.githubusercontent.com/u/76623657
|
|
|
|
type: application
|
|
|
|
# appVersion is the exact image tag, and the "v" is part of it - so it is part
|
|
# of appVersion and of the "+up" suffix. Precedent: calibre-web-automated
|
|
# (+upv4.0.6), matrix-synapse (+upv1.159.0), ytdlp-web-player (+upv1.2.0).
|
|
#
|
|
# The glibc image, not "-alpine". Both flavours are published for every release
|
|
# from the same source and carry the same uid/gid 2000 and the same two volumes;
|
|
# the choice is a deployment decision, and keeping it out of the tag is what
|
|
# lets renovate.json5 anchor the version with a plain three-part regex instead
|
|
# of maintaining a compatibility suffix. The moving tags "latest", "v0.16" and
|
|
# their -alpine twins are excluded by that same anchor: measured on 2026-10-02
|
|
# all three of latest / v0.16 / v0.16.24 resolved to one digest pushed seconds
|
|
# apart, so either floating name would change the running image with no commit
|
|
# in this repository and nothing to report it.
|
|
# MAJOR for Gitea #5, and the reason is that the test the two MINOR rounds
|
|
# below passed is the one this round FAILS. Those rounds argued from a diff:
|
|
# the spread constraint and PodDisruptionBudget of #96 (both gated on the
|
|
# COMPUTED replica count being >= 2, with the chart shipping full: 1 / mx: 0)
|
|
# and the MTA-STS routes of #123 (the list is the switch and it ships EMPTY)
|
|
# added no object and made no value required, so `helm template` against the
|
|
# previous version rendered byte-for-byte identically for the defaults AND for
|
|
# ci/stalwart/test-values.yaml - measured, both empty diffs. New optional
|
|
# values with unchanged defaults is exactly the minor case.
|
|
#
|
|
# #5 is the opposite on every count. networkPolicy.ingressController is new,
|
|
# the policy's rendered form changes, and - the part that decides it - the
|
|
# object reaches a RUNNING release on the next upgrade and changes what can
|
|
# reach the pod. A wrong source there makes a service mute, which is precisely
|
|
# the breaking-change case (README, "Versioning"). The app-version patch
|
|
# Renovate landed as 1.3.1 is absorbed by this major rather than added to it.
|
|
#
|
|
# Note for whoever bumps this next: the suffix tracks appVersion, so a major
|
|
# here keeps the +up<appVersion> it was merged with.
|
|
version: 3.0.0+upv0.16.26
|
|
appVersion: "v0.16.26"
|
|
|
|
maintainers:
|
|
- name: jklein
|
|
|
|
# The second chart in this repo with a dependency (after ytdlp-web-player).
|
|
# README, "Chart dependencies", holds the bar it has to clear and the price;
|
|
# both are restated here because the price is paid by whoever reads this file
|
|
# next, not by whoever added the line.
|
|
#
|
|
# WHY ONE HERE. Stalwart's in-memory store is not a cache that can be dropped:
|
|
# from v0.16 it also carries the cluster coordinator ("the Default variant
|
|
# reuses the Redis connection already configured on the in-memory store"), so a
|
|
# multi-node install does not work without it. Redis/Valkey is admissible as
|
|
# the in-memory store ONLY - never as the data or blob store. Offering it inside
|
|
# the chart means the wiring (host, port, egress rule) is in one place instead
|
|
# of split across two releases that have to agree.
|
|
#
|
|
# WHY IT IS OFF BY DEFAULT: an installation that already runs a Valkey points
|
|
# externalServices.valkey.host at it and this dependency renders nothing. The
|
|
# subchart is the path for an installation that has none.
|
|
#
|
|
# THE SUBCHART IS OUR OWN valkey CHART, resolved from the published index -
|
|
# NOT upstream's. So guideline 14.2 ("we consume their chart as it comes") does
|
|
# not apply here and there is nothing of someone else's to leave unpatched: the
|
|
# subchart follows this repo's conventions because it IS this repo's chart. What
|
|
# does apply is everything about the subchart being invisible downstream, plus
|
|
# one hazard that a self-referencing dependency adds and an external one does
|
|
# not - see the PR-ordering warning below.
|
|
dependencies:
|
|
- name: valkey
|
|
# KEEP THIS VERSION MOVING - it is the only path a Valkey update has.
|
|
#
|
|
# A subchart is invisible to everything downstream that watches Helm release
|
|
# versions: what this file declares is baked into our packaged .tgz, and
|
|
# Fleet only ever sees the version of "stalwart". So a new valkey chart - a
|
|
# security fix included - reaches a cluster ONLY when this line is raised
|
|
# and a new stalwart version is published. Nothing reports the gap.
|
|
#
|
|
# Renovate's BUILT-IN helmv3 manager reads this block and opens the PR (no
|
|
# customManagers entry exists or would help - repository and version sit
|
|
# together in one file, which is the case that manager is for), and
|
|
# ci/renovate-bump-chart.sh bumps this chart's patch version, which is what
|
|
# actually ships it. That chain is the whole safety net; switched off, this
|
|
# line needs a human on a calendar instead.
|
|
#
|
|
# MEASURED, not assumed, because the registry is self-hosted and the version
|
|
# carries build metadata - two things that could each have broken the chain
|
|
# silently. Renovate 44.132.2, dry run on 2026-10-02 with this dependency
|
|
# pinned at a lower version: manager helmv3 matched the file, took
|
|
# registryUrls from the line below, and offered
|
|
# newVersion: "1.0.0+up9.1.2.alpine", versioning: "helm"
|
|
# with the release timestamp read from our index. So both the self-hosted
|
|
# index and the "+up..." suffix are handled.
|
|
#
|
|
# Independent of appVersion: raising it is a patch or minor bump of this
|
|
# chart and is never tied to the Stalwart image.
|
|
version: "2.0.0+up9.1.2.alpine"
|
|
# Our own published index, and the READ path only. It is anonymously
|
|
# readable - measured 2026-10-02: GET .../index.yaml returns 200 without
|
|
# credentials - so ci/helm-dependencies.sh needs no secret and was not
|
|
# touched. Verified with an empty HELM_REPOSITORY_CONFIG, i.e. the state a
|
|
# fresh runner is in: helm reports "Getting updates for unmanaged Helm
|
|
# repositories" and resolves the exact build-metadata version from the URL
|
|
# alone, with no "helm repo add" anywhere. Both "helm dependency update" and
|
|
# "helm dependency build" were tried.
|
|
#
|
|
# The PUBLISH target and its credentials still live in 1Password and appear
|
|
# nowhere in this repository - see README, "CI/CD".
|
|
repository: "https://git.jk-dev.de/api/packages/jlab-cluster/helm"
|
|
# Off by default, so a plain install renders none of its objects.
|
|
#
|
|
# NOT "valkey.enabled", AND THAT IS NOT A STYLE CHOICE. Everything under the
|
|
# "valkey:" key is passed to the subchart as its values, and our valkey
|
|
# chart ships a values.schema.json with additionalProperties: false and no
|
|
# "enabled" property - so "valkey.enabled" is rejected by the SUBCHART:
|
|
# Error: values don't meet the specifications of the schema(s) in the
|
|
# following chart(s): valkey: - at '': additional properties 'enabled'
|
|
# not allowed
|
|
# Measured. Worse, Helm skips a disabled subchart's schema validation, so
|
|
# the error appears only for whoever first sets it to true - the default
|
|
# path renders clean.
|
|
#
|
|
# The condition is therefore a key of OUR OWN, outside the subchart's value
|
|
# subtree, which is also the honest shape: "enabled" is not a valkey value.
|
|
# It only ever looked like one because upstream's schema was permissive.
|
|
# The alternative - adding "enabled" to valkey/values.schema.json - would
|
|
# have to be its own PR and be published first (see the warning below), for
|
|
# a key that chart does not read.
|
|
condition: valkeySubchart.enabled
|
|
#
|
|
# !!! NEVER CHANGE valkey/ AND THIS CHART IN THE SAME PULL REQUEST !!!
|
|
#
|
|
# The hazard a self-referencing dependency adds. This dependency resolves out of
|
|
# the PUBLISHED index, not out of the working tree, and valkey/ is only
|
|
# published by a push to main that touches it. So in one PR carrying both:
|
|
#
|
|
# - every helm command here - lint, package, render, AND the install-test -
|
|
# pulls the OLD valkey .tgz, because the new one does not exist yet;
|
|
# - the PR therefore goes green against a version of the subchart that is not
|
|
# the one in the diff, and the diff to valkey/ is reviewed while nothing
|
|
# actually exercised it;
|
|
# - after the merge both charts publish, and the first install of the new
|
|
# stalwart is the first time the new valkey is used anywhere.
|
|
#
|
|
# Two consecutive pull requests instead: change valkey/, merge, let it publish,
|
|
# then raise the version here. The ordering is not a nicety - the green check on
|
|
# the combined PR is a statement about the wrong artifact.
|