From c726276f56b632e8288abc233b04984be32a7ceb Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:17:57 +0000 Subject: [PATCH 1/5] chore: Add PVC, Secret, and ConfigMap templates; update Deployment to reference them --- helm/templates/configmap.yaml | 12 +++++++++++ helm/templates/deployment.yaml | 38 +++++++++++++++++++++++++++------- helm/templates/pvc.yaml | 17 +++++++++++++++ helm/templates/secret.yaml | 18 ++++++++++++++++ helm/values.yaml | 10 ++++----- 5 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 helm/templates/configmap.yaml create mode 100644 helm/templates/pvc.yaml create mode 100644 helm/templates/secret.yaml diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml new file mode 100644 index 00000000..86e6187b --- /dev/null +++ b/helm/templates/configmap.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "open-git.fullname" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +data: + DB_TYPE: {{ .Values.db.type | quote }} + REDIS_ADDR: {{ .Values.redis.addr | quote }} + PORT: {{ .Values.service.backend.port | default 8080 | quote }} + GIT_STORAGE_PATH: {{ .Values.persistence.reposPath | default "/data/repos" | quote }} + MINIO_ENDPOINT: {{ .Values.minio.endpoint | quote }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 090fa8bf..2c387407 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -27,9 +27,25 @@ spec: protocol: TCP env: - name: PORT - value: "8080" + valueFrom: + configMapKeyRef: + name: {{ include "open-git.fullname" . }} + key: PORT - name: DB_TYPE - value: {{ .Values.db.type | quote }} + valueFrom: + configMapKeyRef: + name: {{ include "open-git.fullname" . }} + key: DB_TYPE + - name: GIT_STORAGE_PATH + valueFrom: + configMapKeyRef: + name: {{ include "open-git.fullname" . }} + key: GIT_STORAGE_PATH + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.fullname" . }} + key: jwt-secret {{- if eq .Values.db.type "postgres" }} - name: POSTGRES_HOST value: {{ .Values.db.postgres.host | quote }} @@ -42,24 +58,30 @@ spec: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-db - key: postgres-password + name: {{ include "open-git.fullname" . }} + key: db-password {{- else }} - name: SQLITE_PATH value: {{ .Values.db.sqlite.path | quote }} {{- end }} - name: REDIS_ADDR - value: {{ .Values.redis.addr | quote }} + valueFrom: + configMapKeyRef: + name: {{ include "open-git.fullname" . }} + key: REDIS_ADDR {{- if .Values.minio.enabled }} - name: MINIO_ENDPOINT - value: {{ .Values.minio.endpoint | quote }} + valueFrom: + configMapKeyRef: + name: {{ include "open-git.fullname" . }} + key: MINIO_ENDPOINT - name: MINIO_ACCESS_KEY value: {{ .Values.minio.accessKey | quote }} - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-minio - key: secret-key + name: {{ include "open-git.fullname" . }} + key: minio-root-password - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} diff --git a/helm/templates/pvc.yaml b/helm/templates/pvc.yaml new file mode 100644 index 00000000..401226dd --- /dev/null +++ b/helm/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "open-git.fullname" . }}-repos + labels: + {{- include "open-git.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.reposSize | default "20Gi" }} + {{- with .Values.global.storageClass }} + storageClassName: {{ . | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml new file mode 100644 index 00000000..50f6af37 --- /dev/null +++ b/helm/templates/secret.yaml @@ -0,0 +1,18 @@ +{{/* +Secrets should be passed at install time, e.g.: + helm install open-git ./helm \ + --set secrets.jwtSecret=your-jwt-secret \ + --set secrets.dbPassword=your-db-password \ + --set secrets.minioRootPassword=your-minio-password +*/}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "open-git.fullname" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +type: Opaque +data: + jwt-secret: {{ .Values.secrets.jwtSecret | b64enc | quote }} + db-password: {{ .Values.secrets.dbPassword | b64enc | quote }} + minio-root-password: {{ .Values.secrets.minioRootPassword | b64enc | quote }} diff --git a/helm/values.yaml b/helm/values.yaml index 81a5cb02..e81ccfb5 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -23,10 +23,8 @@ autoscaling: targetCPUUtilizationPercentage: 70 persistence: - repositories: - size: 50Gi - accessMode: ReadWriteOnce - retainOnDelete: true + enabled: true + reposSize: "20Gi" db: type: sqlite # sqlite or postgres @@ -64,7 +62,9 @@ ssh: serviceType: LoadBalancer secrets: - existingSecret: "" + jwtSecret: "" + dbPassword: "" + minioRootPassword: "" serviceAccount: create: true From b983b280790dc68133d47460b4c7cbc63c1be87c Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:31:42 +0000 Subject: [PATCH 2/5] chore: Add PVC, Secret, and ConfigMap templates; update Deployment to reference them --- .github/workflows/helm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index 4c042f61..2d21d214 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -28,4 +28,4 @@ jobs: cat /tmp/rendered.yaml | docker run --rm -i ghcr.io/yannh/kubeconform:latest -strict -ignore-missing-schemas - - name: Dry-run install - run: helm install gitforge helm/ --dry-run --generate-name --set ingress.host=test.example.com + run: helm install gitforge helm/ --dry-run=client --set ingress.host=test.example.com From 0e50cec2ea288411ea563f936cf57cb72de84651 Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:37:45 +0000 Subject: [PATCH 3/5] chore: Add PVC, Secret, and ConfigMap templates; update Deployment to reference them --- .github/workflows/helm.yml | 20 ++++++++++++--- helm/templates/deployment.yaml | 11 ++++++--- helm/templates/pvc.yaml | 13 ++++++++-- helm/templates/secret.yaml | 45 ++++++++++++++++++++++++++++++---- helm/values.yaml | 21 +++++++++++++++- 5 files changed, 95 insertions(+), 15 deletions(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index 2d21d214..f2243b61 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -20,12 +20,26 @@ jobs: run: helm dependency update helm/ - name: Lint chart - run: helm lint helm/ --strict + run: | + helm lint helm/ --strict \ + --set secrets.jwtSecret=ci-test-jwt-secret \ + --set secrets.minioRootPassword=ci-test-minio-password \ + --set secrets.minioAccessKey=ci-test-minio-access-key - name: Validate templates run: | - helm template gitforge helm/ > /tmp/rendered.yaml + helm template gitforge helm/ \ + --set secrets.jwtSecret=ci-test-jwt-secret \ + --set secrets.minioRootPassword=ci-test-minio-password \ + --set secrets.minioAccessKey=ci-test-minio-access-key \ + > /tmp/rendered.yaml cat /tmp/rendered.yaml | docker run --rm -i ghcr.io/yannh/kubeconform:latest -strict -ignore-missing-schemas - - name: Dry-run install - run: helm install gitforge helm/ --dry-run=client --set ingress.host=test.example.com + run: | + helm install gitforge helm/ --dry-run=client --generate-name \ + --set ingress.host=test.example.com \ + --set secrets.jwtSecret=ci-test-jwt-secret \ + --set secrets.dbPassword=ci-test-db-password \ + --set secrets.minioRootPassword=ci-test-minio-password \ + --set secrets.minioAccessKey=ci-test-minio-access-key diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 2c387407..ac115fb5 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -44,7 +44,7 @@ spec: - name: JWT_SECRET valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }} + name: {{ include "open-git.fullname" . }}-secrets key: jwt-secret {{- if eq .Values.db.type "postgres" }} - name: POSTGRES_HOST @@ -58,7 +58,7 @@ spec: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }} + name: {{ include "open-git.fullname" . }}-secrets key: db-password {{- else }} - name: SQLITE_PATH @@ -76,11 +76,14 @@ spec: name: {{ include "open-git.fullname" . }} key: MINIO_ENDPOINT - name: MINIO_ACCESS_KEY - value: {{ .Values.minio.accessKey | quote }} + valueFrom: + secretKeyRef: + name: {{ include "open-git.fullname" . }}-secrets + key: minio-access-key - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }} + name: {{ include "open-git.fullname" . }}-secrets key: minio-root-password - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} diff --git a/helm/templates/pvc.yaml b/helm/templates/pvc.yaml index 401226dd..c44d524a 100644 --- a/helm/templates/pvc.yaml +++ b/helm/templates/pvc.yaml @@ -1,16 +1,25 @@ {{- if .Values.persistence.enabled }} +{{- $size := .Values.persistence.reposSize | default .Values.persistence.repositories.size | default "50Gi" | toString }} +{{- if not (regexMatch "^[0-9]+(\\.[0-9]+)?(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$" $size) }} +{{- fail (printf "Invalid persistence storage size %q — use a Kubernetes quantity (e.g. 50Gi, 100Mi)" $size) }} +{{- end }} +{{- $retain := or .Values.persistence.retainOnDelete .Values.persistence.repositories.retainOnDelete }} apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ include "open-git.fullname" . }}-repos labels: {{- include "open-git.labels" . | nindent 4 }} + {{- if $retain }} + annotations: + helm.sh/resource-policy: keep + {{- end }} spec: accessModes: - - ReadWriteOnce + - {{ .Values.persistence.repositories.accessMode | default "ReadWriteOnce" }} resources: requests: - storage: {{ .Values.persistence.reposSize | default "20Gi" }} + storage: {{ $size | quote }} {{- with .Values.global.storageClass }} storageClassName: {{ . | quote }} {{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml index 50f6af37..2d0512e2 100644 --- a/helm/templates/secret.yaml +++ b/helm/templates/secret.yaml @@ -3,16 +3,51 @@ Secrets should be passed at install time, e.g.: helm install open-git ./helm \ --set secrets.jwtSecret=your-jwt-secret \ --set secrets.dbPassword=your-db-password \ - --set secrets.minioRootPassword=your-minio-password + --set secrets.minioRootPassword=your-minio-password \ + --set secrets.minioAccessKey=your-minio-access-key + +The main Secret uses the "-secrets" suffix to avoid colliding with the ConfigMap +({{ include "open-git.fullname" . }}). Legacy "-db" / "-minio" Secrets are also +rendered for backward compatibility with existing worker deployments. */}} apiVersion: v1 kind: Secret metadata: - name: {{ include "open-git.fullname" . }} + name: {{ include "open-git.fullname" . }}-secrets labels: {{- include "open-git.labels" . | nindent 4 }} type: Opaque data: - jwt-secret: {{ .Values.secrets.jwtSecret | b64enc | quote }} - db-password: {{ .Values.secrets.dbPassword | b64enc | quote }} - minio-root-password: {{ .Values.secrets.minioRootPassword | b64enc | quote }} + jwt-secret: {{ required "secrets.jwtSecret is required — pass via --set secrets.jwtSecret=" .Values.secrets.jwtSecret | b64enc | quote }} + {{- if eq .Values.db.type "postgres" }} + db-password: {{ required "secrets.dbPassword is required when db.type is postgres — pass via --set secrets.dbPassword=" .Values.secrets.dbPassword | b64enc | quote }} + {{- end }} + {{- if .Values.minio.enabled }} + minio-root-password: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} + minio-access-key: {{ required "secrets.minioAccessKey is required when minio.enabled — pass via --set secrets.minioAccessKey=" .Values.secrets.minioAccessKey | b64enc | quote }} + {{- end }} +{{- if eq .Values.db.type "postgres" }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "open-git.fullname" . }}-db + labels: + {{- include "open-git.labels" . | nindent 4 }} +type: Opaque +data: + postgres-password: {{ required "secrets.dbPassword is required when db.type is postgres — pass via --set secrets.dbPassword=" .Values.secrets.dbPassword | b64enc | quote }} +{{- end }} +{{- if .Values.minio.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "open-git.fullname" . }}-minio + labels: + {{- include "open-git.labels" . | nindent 4 }} +type: Opaque +data: + secret-key: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} + access-key: {{ required "secrets.minioAccessKey is required when minio.enabled — pass via --set secrets.minioAccessKey=" .Values.secrets.minioAccessKey | b64enc | quote }} +{{- end }} diff --git a/helm/values.yaml b/helm/values.yaml index e81ccfb5..d48a0614 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -22,9 +22,25 @@ autoscaling: maxReplicas: 10 targetCPUUtilizationPercentage: 70 +# Persistence for Git repositories. +# +# Migration guide (breaking change from flat reposSize-only schema): +# - Old installs used persistence.repositories.{size,accessMode,retainOnDelete}. +# - New flat keys (reposSize, reposPath, retainOnDelete) are preferred for new installs. +# - Templates accept either form; reposSize takes precedence, then repositories.size. +# - Default size restored to 50Gi (was 20Gi in the intermediate schema). +# - Set retainOnDelete: true (default) to annotate PVCs with helm.sh/resource-policy: keep +# so data survives helm uninstall. Verify existing PVC reclaim policy in your cluster +# before upgrading — shrinking size on an existing PVC is not supported by Kubernetes. persistence: enabled: true - reposSize: "20Gi" + reposSize: "" + reposPath: "/data/repos" + retainOnDelete: true + repositories: + size: 50Gi + accessMode: ReadWriteOnce + retainOnDelete: true db: type: sqlite # sqlite or postgres @@ -61,10 +77,13 @@ ssh: enabled: true serviceType: LoadBalancer +# Secrets must be supplied at install time (empty defaults will fail template rendering). +# Example: --set secrets.jwtSecret=... --set secrets.minioAccessKey=... --set secrets.minioRootPassword=... secrets: jwtSecret: "" dbPassword: "" minioRootPassword: "" + minioAccessKey: "" serviceAccount: create: true From b9251b179f68951416ff464ae0f364b8cdb4ae30 Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:39:53 +0000 Subject: [PATCH 4/5] chore: Add PVC, Secret, and ConfigMap templates; update Deployment to reference them --- .github/workflows/helm.yml | 27 +++++++++++++++++---------- helm/templates/configmap.yaml | 4 +++- helm/templates/deployment.yaml | 11 ++++++----- helm/templates/pvc.yaml | 5 ++++- helm/templates/secret.yaml | 13 ++++++++----- helm/values.yaml | 20 ++++++++++++++++++-- 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index f2243b61..8fa4ac99 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -11,6 +11,11 @@ on: jobs: helm-validate: runs-on: ubuntu-latest + env: + HELM_CI_JWT_SECRET: ci-test-jwt-secret + HELM_CI_DB_PASSWORD: ci-test-db-password + HELM_CI_MINIO_ROOT_PASSWORD: ci-test-minio-password + HELM_CI_MINIO_ACCESS_KEY: ci-test-minio-access-key steps: - uses: actions/checkout@v4 @@ -22,16 +27,18 @@ jobs: - name: Lint chart run: | helm lint helm/ --strict \ - --set secrets.jwtSecret=ci-test-jwt-secret \ - --set secrets.minioRootPassword=ci-test-minio-password \ - --set secrets.minioAccessKey=ci-test-minio-access-key + --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ + --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ + --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ + --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" - name: Validate templates run: | helm template gitforge helm/ \ - --set secrets.jwtSecret=ci-test-jwt-secret \ - --set secrets.minioRootPassword=ci-test-minio-password \ - --set secrets.minioAccessKey=ci-test-minio-access-key \ + --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ + --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ + --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ + --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" \ > /tmp/rendered.yaml cat /tmp/rendered.yaml | docker run --rm -i ghcr.io/yannh/kubeconform:latest -strict -ignore-missing-schemas - @@ -39,7 +46,7 @@ jobs: run: | helm install gitforge helm/ --dry-run=client --generate-name \ --set ingress.host=test.example.com \ - --set secrets.jwtSecret=ci-test-jwt-secret \ - --set secrets.dbPassword=ci-test-db-password \ - --set secrets.minioRootPassword=ci-test-minio-password \ - --set secrets.minioAccessKey=ci-test-minio-access-key + --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ + --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ + --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ + --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml index 86e6187b..fab82be0 100644 --- a/helm/templates/configmap.yaml +++ b/helm/templates/configmap.yaml @@ -7,6 +7,8 @@ metadata: data: DB_TYPE: {{ .Values.db.type | quote }} REDIS_ADDR: {{ .Values.redis.addr | quote }} - PORT: {{ .Values.service.backend.port | default 8080 | quote }} + PORT: {{ .Values.service.backend.port | default 8080 | toString | quote }} GIT_STORAGE_PATH: {{ .Values.persistence.reposPath | default "/data/repos" | quote }} + {{- if .Values.minio.enabled }} MINIO_ENDPOINT: {{ .Values.minio.endpoint | quote }} + {{- end }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index ac115fb5..6ca0591f 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -17,6 +17,7 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: backend spec: + {{- $secretName := .Values.secrets.existingSecret | default (printf "%s-secrets" (include "open-git.fullname" .)) }} containers: - name: backend image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" @@ -44,7 +45,7 @@ spec: - name: JWT_SECRET valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-secrets + name: {{ $secretName }} key: jwt-secret {{- if eq .Values.db.type "postgres" }} - name: POSTGRES_HOST @@ -58,7 +59,7 @@ spec: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-secrets + name: {{ $secretName }} key: db-password {{- else }} - name: SQLITE_PATH @@ -78,13 +79,13 @@ spec: - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-secrets + name: {{ $secretName }} key: minio-access-key - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: - name: {{ include "open-git.fullname" . }}-secrets - key: minio-root-password + name: {{ $secretName }} + key: minio-secret-key - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} diff --git a/helm/templates/pvc.yaml b/helm/templates/pvc.yaml index c44d524a..87be5e78 100644 --- a/helm/templates/pvc.yaml +++ b/helm/templates/pvc.yaml @@ -1,5 +1,8 @@ {{- if .Values.persistence.enabled }} -{{- $size := .Values.persistence.reposSize | default .Values.persistence.repositories.size | default "50Gi" | toString }} +{{- $size := .Values.persistence.reposSize | default .Values.persistence.repositories.size | default "50Gi" | toString | trimAll " " }} +{{- if eq $size "" }} +{{- fail "persistence storage size must not be empty — set persistence.reposSize (e.g. 50Gi)" }} +{{- end }} {{- if not (regexMatch "^[0-9]+(\\.[0-9]+)?(Ei|Pi|Ti|Gi|Mi|Ki|E|P|T|G|M|K)?$" $size) }} {{- fail (printf "Invalid persistence storage size %q — use a Kubernetes quantity (e.g. 50Gi, 100Mi)" $size) }} {{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml index 2d0512e2..e58c6ac2 100644 --- a/helm/templates/secret.yaml +++ b/helm/templates/secret.yaml @@ -7,9 +7,11 @@ Secrets should be passed at install time, e.g.: --set secrets.minioAccessKey=your-minio-access-key The main Secret uses the "-secrets" suffix to avoid colliding with the ConfigMap -({{ include "open-git.fullname" . }}). Legacy "-db" / "-minio" Secrets are also -rendered for backward compatibility with existing worker deployments. +({{ include "open-git.fullname" . }}). Set secrets.existingSecret to reference a +pre-created Secret instead. Legacy "-db" / "-minio" Secrets are optional (see +secrets.legacySecrets) for backward compatibility with existing worker deployments. */}} +{{- if not .Values.secrets.existingSecret }} apiVersion: v1 kind: Secret metadata: @@ -23,10 +25,11 @@ data: db-password: {{ required "secrets.dbPassword is required when db.type is postgres — pass via --set secrets.dbPassword=" .Values.secrets.dbPassword | b64enc | quote }} {{- end }} {{- if .Values.minio.enabled }} - minio-root-password: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} + minio-secret-key: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} minio-access-key: {{ required "secrets.minioAccessKey is required when minio.enabled — pass via --set secrets.minioAccessKey=" .Values.secrets.minioAccessKey | b64enc | quote }} {{- end }} -{{- if eq .Values.db.type "postgres" }} +{{- end }} +{{- if and .Values.secrets.legacySecrets (eq .Values.db.type "postgres") }} --- apiVersion: v1 kind: Secret @@ -38,7 +41,7 @@ type: Opaque data: postgres-password: {{ required "secrets.dbPassword is required when db.type is postgres — pass via --set secrets.dbPassword=" .Values.secrets.dbPassword | b64enc | quote }} {{- end }} -{{- if .Values.minio.enabled }} +{{- if and .Values.secrets.legacySecrets .Values.minio.enabled }} --- apiVersion: v1 kind: Secret diff --git a/helm/values.yaml b/helm/values.yaml index d48a0614..8d23379f 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -28,13 +28,23 @@ autoscaling: # - Old installs used persistence.repositories.{size,accessMode,retainOnDelete}. # - New flat keys (reposSize, reposPath, retainOnDelete) are preferred for new installs. # - Templates accept either form; reposSize takes precedence, then repositories.size. -# - Default size restored to 50Gi (was 20Gi in the intermediate schema). +# - Default size is 50Gi. # - Set retainOnDelete: true (default) to annotate PVCs with helm.sh/resource-policy: keep # so data survives helm uninstall. Verify existing PVC reclaim policy in your cluster # before upgrading — shrinking size on an existing PVC is not supported by Kubernetes. +# +# Secret migration guide (upgrade from legacy -db / -minio Secrets): +# 1. Ensure install/upgrade passes all required --set secrets.* values (or use +# secrets.existingSecret pointing at a pre-created Secret with keys: +# jwt-secret, db-password, minio-access-key, minio-secret-key). +# 2. Run `helm upgrade` — Helm renders the unified -secrets Secret and updated +# backend Deployment in the same release; Kubernetes creates the Secret before +# rolling out pods that reference it. +# 3. Keep secrets.legacySecrets: true (default) until worker deployments are migrated +# to the unified -secrets Secret; then set legacySecrets: false to remove duplicates. persistence: enabled: true - reposSize: "" + reposSize: "50Gi" reposPath: "/data/repos" retainOnDelete: true repositories: @@ -79,11 +89,17 @@ ssh: # Secrets must be supplied at install time (empty defaults will fail template rendering). # Example: --set secrets.jwtSecret=... --set secrets.minioAccessKey=... --set secrets.minioRootPassword=... +# Set existingSecret to skip chart-managed Secret creation and reference an external Secret +# (must contain keys: jwt-secret, db-password, minio-access-key, minio-secret-key). secrets: + existingSecret: "" jwtSecret: "" dbPassword: "" minioRootPassword: "" minioAccessKey: "" + # Deprecated: legacy -db / -minio Secrets for backward compatibility with worker pods. + # Set to false once all deployments reference the unified -secrets Secret. + legacySecrets: true serviceAccount: create: true From b78763d9b8957a9908aa089197ae4dd203400e98 Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:43:58 +0000 Subject: [PATCH 5/5] chore: Add PVC, Secret, and ConfigMap templates; update Deployment to reference them --- .github/workflows/helm.yml | 34 +++++++++++++--------------------- helm/templates/deployment.yaml | 3 ++- helm/templates/pvc.yaml | 5 +++-- helm/templates/secret.yaml | 26 +++++++++++++++++++++++++- helm/values.yaml | 29 +++++++++++++---------------- 5 files changed, 56 insertions(+), 41 deletions(-) diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index 8fa4ac99..3cf4f750 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -11,42 +11,34 @@ on: jobs: helm-validate: runs-on: ubuntu-latest - env: - HELM_CI_JWT_SECRET: ci-test-jwt-secret - HELM_CI_DB_PASSWORD: ci-test-db-password - HELM_CI_MINIO_ROOT_PASSWORD: ci-test-minio-password - HELM_CI_MINIO_ACCESS_KEY: ci-test-minio-access-key steps: - uses: actions/checkout@v4 - uses: azure/setup-helm@v4 + - name: Generate ephemeral CI secrets and helm --set flags + run: | + JWT="$(openssl rand -hex 32)" + DB="$(openssl rand -hex 32)" + MINIO_ROOT="$(openssl rand -hex 32)" + MINIO_ACCESS="$(openssl rand -hex 16)" + { + echo "HELM_SECRET_SET_FLAGS=--set secrets.jwtSecret=${JWT} --set secrets.dbPassword=${DB} --set secrets.minioRootPassword=${MINIO_ROOT} --set secrets.minioAccessKey=${MINIO_ACCESS}" + } >> "$GITHUB_ENV" + - name: Update chart dependencies run: helm dependency update helm/ - name: Lint chart - run: | - helm lint helm/ --strict \ - --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ - --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ - --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ - --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" + run: helm lint helm/ --strict ${HELM_SECRET_SET_FLAGS} - name: Validate templates run: | - helm template gitforge helm/ \ - --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ - --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ - --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ - --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" \ - > /tmp/rendered.yaml + helm template gitforge helm/ ${HELM_SECRET_SET_FLAGS} > /tmp/rendered.yaml cat /tmp/rendered.yaml | docker run --rm -i ghcr.io/yannh/kubeconform:latest -strict -ignore-missing-schemas - - name: Dry-run install run: | helm install gitforge helm/ --dry-run=client --generate-name \ --set ingress.host=test.example.com \ - --set secrets.jwtSecret="${HELM_CI_JWT_SECRET}" \ - --set secrets.dbPassword="${HELM_CI_DB_PASSWORD}" \ - --set secrets.minioRootPassword="${HELM_CI_MINIO_ROOT_PASSWORD}" \ - --set secrets.minioAccessKey="${HELM_CI_MINIO_ACCESS_KEY}" + ${HELM_SECRET_SET_FLAGS} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 6ca0591f..2f52a37b 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -1,3 +1,4 @@ +{{- $secretName := .Values.secrets.existingSecret | default (printf "%s-secrets" (include "open-git.fullname" .)) }} apiVersion: apps/v1 kind: Deployment metadata: @@ -17,7 +18,6 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: backend spec: - {{- $secretName := .Values.secrets.existingSecret | default (printf "%s-secrets" (include "open-git.fullname" .)) }} containers: - name: backend image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" @@ -76,6 +76,7 @@ spec: configMapKeyRef: name: {{ include "open-git.fullname" . }} key: MINIO_ENDPOINT + optional: true - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: diff --git a/helm/templates/pvc.yaml b/helm/templates/pvc.yaml index 87be5e78..509f22ac 100644 --- a/helm/templates/pvc.yaml +++ b/helm/templates/pvc.yaml @@ -19,11 +19,12 @@ metadata: {{- end }} spec: accessModes: - - {{ .Values.persistence.repositories.accessMode | default "ReadWriteOnce" }} + - {{ .Values.persistence.accessMode | default .Values.persistence.repositories.accessMode | default "ReadWriteOnce" }} resources: requests: storage: {{ $size | quote }} - {{- with .Values.global.storageClass }} + {{- $storageClass := .Values.persistence.storageClass | default .Values.global.storageClass }} + {{- with $storageClass }} storageClassName: {{ . | quote }} {{- end }} {{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml index e58c6ac2..23c13216 100644 --- a/helm/templates/secret.yaml +++ b/helm/templates/secret.yaml @@ -10,8 +10,29 @@ The main Secret uses the "-secrets" suffix to avoid colliding with the ConfigMap ({{ include "open-git.fullname" . }}). Set secrets.existingSecret to reference a pre-created Secret instead. Legacy "-db" / "-minio" Secrets are optional (see secrets.legacySecrets) for backward compatibility with existing worker deployments. + +Warning: values passed via --set secrets.* are stored in Helm release metadata +(helm get values / helm history). Prefer secrets.existingSecret or --set-file for +production deployments. */}} -{{- if not .Values.secrets.existingSecret }} +{{- if .Values.secrets.existingSecret }} +{{- $existing := lookup "v1" "Secret" .Release.Namespace .Values.secrets.existingSecret }} +{{- if $existing }} +{{- $data := $existing.data | default dict }} +{{- if not (hasKey $data "jwt-secret") }} +{{- fail (printf "secrets.existingSecret %q is missing required key jwt-secret" .Values.secrets.existingSecret) }} +{{- end }} +{{- if and (eq .Values.db.type "postgres") (not (hasKey $data "db-password")) }} +{{- fail (printf "secrets.existingSecret %q is missing required key db-password (db.type is postgres)" .Values.secrets.existingSecret) }} +{{- end }} +{{- if and .Values.minio.enabled (not (hasKey $data "minio-access-key")) }} +{{- fail (printf "secrets.existingSecret %q is missing required key minio-access-key (minio.enabled)" .Values.secrets.existingSecret) }} +{{- end }} +{{- if and .Values.minio.enabled (not (hasKey $data "minio-secret-key")) }} +{{- fail (printf "secrets.existingSecret %q is missing required key minio-secret-key (minio.enabled)" .Values.secrets.existingSecret) }} +{{- end }} +{{- end }} +{{- else }} apiVersion: v1 kind: Secret metadata: @@ -51,6 +72,9 @@ metadata: {{- include "open-git.labels" . | nindent 4 }} type: Opaque data: + minio-secret-key: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} + minio-access-key: {{ required "secrets.minioAccessKey is required when minio.enabled — pass via --set secrets.minioAccessKey=" .Values.secrets.minioAccessKey | b64enc | quote }} + # Deprecated aliases kept for worker pods that still reference legacy key names. secret-key: {{ required "secrets.minioRootPassword is required when minio.enabled — pass via --set secrets.minioRootPassword=" .Values.secrets.minioRootPassword | b64enc | quote }} access-key: {{ required "secrets.minioAccessKey is required when minio.enabled — pass via --set secrets.minioAccessKey=" .Values.secrets.minioAccessKey | b64enc | quote }} {{- end }} diff --git a/helm/values.yaml b/helm/values.yaml index 8d23379f..397226ab 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -24,10 +24,9 @@ autoscaling: # Persistence for Git repositories. # -# Migration guide (breaking change from flat reposSize-only schema): +# Migration guide (upgrade from persistence.repositories.* nested schema): # - Old installs used persistence.repositories.{size,accessMode,retainOnDelete}. -# - New flat keys (reposSize, reposPath, retainOnDelete) are preferred for new installs. -# - Templates accept either form; reposSize takes precedence, then repositories.size. +# - Use the flat keys below; templates still accept repositories.* as a fallback. # - Default size is 50Gi. # - Set retainOnDelete: true (default) to annotate PVCs with helm.sh/resource-policy: keep # so data survives helm uninstall. Verify existing PVC reclaim policy in your cluster @@ -40,17 +39,16 @@ autoscaling: # 2. Run `helm upgrade` — Helm renders the unified -secrets Secret and updated # backend Deployment in the same release; Kubernetes creates the Secret before # rolling out pods that reference it. -# 3. Keep secrets.legacySecrets: true (default) until worker deployments are migrated -# to the unified -secrets Secret; then set legacySecrets: false to remove duplicates. +# 3. Legacy -db / -minio Secrets use the same key names as the unified Secret where +# applicable (minio-access-key, minio-secret-key). Set legacySecrets: true only +# while worker pods still reference the legacy Secret names; then set false. persistence: enabled: true reposSize: "50Gi" reposPath: "/data/repos" + accessMode: ReadWriteOnce + storageClass: "" retainOnDelete: true - repositories: - size: 50Gi - accessMode: ReadWriteOnce - retainOnDelete: true db: type: sqlite # sqlite or postgres @@ -87,19 +85,18 @@ ssh: enabled: true serviceType: LoadBalancer -# Secrets must be supplied at install time (empty defaults will fail template rendering). +# Secrets must be supplied at install time via --set / --set-file / -f (never commit real +# values in this file — they would remain in Git history). Prefer secrets.existingSecret +# or an external secret manager for production. Note: --set secrets.* values are stored +# in Helm release metadata (helm get values / helm history); use existingSecret to avoid that. # Example: --set secrets.jwtSecret=... --set secrets.minioAccessKey=... --set secrets.minioRootPassword=... # Set existingSecret to skip chart-managed Secret creation and reference an external Secret # (must contain keys: jwt-secret, db-password, minio-access-key, minio-secret-key). secrets: existingSecret: "" - jwtSecret: "" - dbPassword: "" - minioRootPassword: "" - minioAccessKey: "" # Deprecated: legacy -db / -minio Secrets for backward compatibility with worker pods. - # Set to false once all deployments reference the unified -secrets Secret. - legacySecrets: true + # Enable only while worker deployments still reference the legacy Secret names. + legacySecrets: false serviceAccount: create: true