ci: run the freesailarr install-test for real instead of skipping it

freesailarr was excluded from the install-test because gluetun never becomes
healthy without a real Wireguard key and no app container behind its kill
switch can become Ready. The green "Install-test freesailarr pass" was a
25-second SKIP on the most complex chart in the repo - a signal that proved
nothing.

With a CI-only Mullvad key in 1Password the reason is gone:

- ci/run-install-test.sh learns a general rule: ci/<chart>/fixtures.env.yaml is
  rendered with envsubst before it is applied, restricted to the variable names
  a chart declares in REQUIRED_ENV. A missing or empty declared variable fails
  the run loudly and names the variable - it never skips the chart.
- The install-test job loads the key from 1Password Connect for freesailarr
  only, following the pattern publish-helm-chart.yml documents: values via
  steps.<id>.outputs.*, mapped into the step's own env, quoted, with ":?"
  guards that name the missing op:// field before a cluster is created.
- Fixtures for freesailarr: three media claims, the gluetun secret template
  with variable names only, firewallOutboundSubnets so the kill switch does not
  block cluster DNS, and INSTALL_TIMEOUT=900 for nine containers.

freesailarr/Chart.yaml goes 3.0.0+up1.0.0 -> 3.0.1+up1.0.0. That bump is
deliberately empty of content: the install-test matrix follows changed chart
directories, and without it this PR could not run the test it adds.
This commit is contained in:
jklein committed 2026-08-26 14:30:42 +02:00
1 parent 5280554329
commit 69a280399c
9 files changed
+215 -7

No files matched your search

+22
View File
@@ -0,0 +1,22 @@
# The gluetun credentials Secret the 1Password operator materializes on the
# real cluster - here as a template with variable NAMES only. This file must
# never contain a value; ci/run-install-test.sh renders it with envsubst,
# restricted to the names declared in ci/freesailarr/settings.env
# (REQUIRED_ENV), and pipes the result straight into kubectl.
#
# The values come from a 1Password item holding a CI-only Mullvad key, loaded in
# the install-test job of .github/workflows/validate-charts.yml. A CI-only key
# on purpose: Mullvad ties an address to a key and sends the tunnel to the
# endpoint it saw last, so a shared key would let every pull request pull the
# tunnel out from under the running stack.
#
# Name and keys follow the chart: <release>-<chart>-gluetun-secret with the
# fields the StatefulSet reads via secretKeyRef. Release name is ci.
apiVersion: v1
kind: Secret
metadata:
name: ci-freesailarr-gluetun-secret
type: Opaque
stringData:
wireguard-private-key: "${FREESAILARR_WG_KEY}"
wireguard-addresses: "${FREESAILARR_WG_ADDRESSES}"
+43
View File
@@ -0,0 +1,43 @@
# Fixtures for the freesailarr install-test: the three media claims the chart
# mounts but never creates (media.*.existingClaim). The config volumes come from
# the StatefulSet's own volumeClaimTemplates and need nothing here.
#
# Default StorageClass (k3d's local-path), so the claims stay Pending until the
# pod is scheduled - WaitForFirstConsumer, which is exactly what the chart sees
# on a real cluster. local-path creates its directories mode 0777, so the claim
# roots are writable for PUID/PGID 1000 without a chown job.
#
# The gluetun credentials Secret is NOT here: it carries values that must not be
# committed and lives in fixtures.env.yaml.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ci-freesailarr-downloads
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ci-freesailarr-movies
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ci-freesailarr-tv
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
+10
View File
@@ -0,0 +1,10 @@
# Nine containers in one pod, several GB of images to pull, and the app
# containers only start once gluetun has completed its Wireguard handshake -
# each of them then runs its own startup probe (150s budget, 300s for seerr's
# first-boot migrations). The default of 300s is not enough for that.
INSTALL_TIMEOUT=900
# The gluetun credentials for ci/freesailarr/fixtures.env.yaml. Missing or empty
# values fail the install-test loudly instead of skipping it - see
# ci/run-install-test.sh.
REQUIRED_ENV="FREESAILARR_WG_KEY FREESAILARR_WG_ADDRESSES"
+39
View File
@@ -0,0 +1,39 @@
# freesailarr: the whole stack in one pod - gluetun plus eight app containers
# that share its network namespace and sit behind its kill switch. Nothing here
# is a shortcut around that: the install-test brings up a real Wireguard tunnel
# with a CI-only Mullvad key (see ci/freesailarr/fixtures.env.yaml), because a
# gluetun without a handshake keeps every app container from becoming Ready.
#
# Release name is ci, so the chart looks for the gluetun credentials in the
# Secret ci-freesailarr-gluetun-secret, which the fixtures create. The chart's
# own OnePasswordItem CR applies against the stub CRD and stays unreconciled -
# there is no 1Password operator in the CI cluster.
secrets:
# Required by the chart. Only the CR's itemPath, never resolved in CI.
gluetunSecretRef: op://ci/freesailarr-gluetun
media:
# The three media claims are pre-created in fixtures.yaml (one claim per
# category, no subPath - the shared-claim layout is a values question, not a
# startup question). local-path hands out its directories mode 0777, so the
# claim roots are writable for PUID/PGID as the chart requires.
downloads:
existingClaim: ci-freesailarr-downloads
movies:
existingClaim: ci-freesailarr-movies
tv:
existingClaim: ci-freesailarr-tv
gluetun:
vpn:
# Without this the kill switch drops cluster-internal egress as well, and
# the very first DNS lookup against cluster DNS fails. k3s defaults:
# 10.42.0.0/16 pods, 10.43.0.0/16 services.
firewallOutboundSubnets: "10.42.0.0/16,10.43.0.0/16"
ingress:
# Shared-domain mode with a placeholder host: the Ingress objects only have to
# be accepted by the API server. There is no ingress-nginx and no cert-manager
# in the CI cluster, and the install-test checks readiness, not routing.
host: freesailarr.example.com
clusterIssuer: ci