Skip to content

Commit 87fad2e

Browse files
authored
Merge pull request #2036 from diggerhq/feat/helm-charts-here
Feat/helm charts here
2 parents f52d053 + 7c60fda commit 87fad2e

16 files changed

+703
-0
lines changed

.github/workflows/helm-release.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Release Helm Charts
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'helm-charts/**'
9+
10+
permissions:
11+
contents: read
12+
packages: write
13+
14+
jobs:
15+
release:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Install Helm
22+
uses: azure/setup-helm@v4
23+
24+
- name: Login to GitHub Container Registry
25+
run: |
26+
echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin
27+
28+
- name: Package and push chart
29+
run: |
30+
cd helm-charts/digger-backend
31+
helm package .
32+
helm push digger-backend-*.tgz oci://ghcr.io/diggerhq/helm-charts

.github/workflows/helm-test.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Test Helm Charts
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'helm-charts/**'
7+
- '.github/workflows/helm-test.yml'
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
16+
- name: Install Helm
17+
uses: azure/setup-helm@v4
18+
19+
- name: Install helm-unittest
20+
run: |
21+
helm plugin install https://github.com/helm-unittest/helm-unittest.git
22+
23+
- name: Lint chart
24+
run: |
25+
helm lint helm-charts/digger-backend
26+
27+
- name: Run unit tests
28+
run: |
29+
helm unittest helm-charts/digger-backend

helm-charts/CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Repository Overview
6+
7+
This subdirectory contains the official Helm charts for Digger, an open-source CI/CD tool for Terraform. Currently maintains one chart: `digger-backend`.
8+
9+
## Common Development Commands
10+
11+
```bash
12+
# Install Helm unittest plugin (required for testing)
13+
helm plugin install https://github.com/quintush/helm-unittest
14+
15+
# Run unit tests for the chart
16+
helm unittest digger-backend/
17+
18+
# Lint the chart
19+
helm lint digger-backend/
20+
21+
# Test template rendering with specific values
22+
helm template digger-backend ./digger-backend/ -f custom-values.yaml
23+
24+
# Install the chart locally
25+
helm install digger-backend ./digger-backend/
26+
27+
# Upgrade a release
28+
helm upgrade digger-backend ./digger-backend/
29+
```
30+
31+
## Architecture and Structure
32+
33+
### Chart Organization
34+
- `digger-backend/` - Main Helm chart directory
35+
- `templates/` - Kubernetes resource templates
36+
- `tests/` - Helm unit tests using helm-unittest framework
37+
- `values.yaml` - Default configuration values
38+
- `Chart.yaml` - Chart metadata and dependencies
39+
40+
### Key Templates
41+
- `backend-deployment.yaml` - Main Digger backend deployment
42+
- `digger-secret.yaml` - Manages GitHub App credentials and database configuration
43+
- `postgres-statefulset.yaml` - Optional PostgreSQL for testing (enabled via `postgres.enabled`)
44+
- `backend-ingress.yaml` - Ingress configuration (enabled by default)
45+
46+
### CI/CD Workflows
47+
- **Pull Request Testing**: Automatically runs `helm unittest` on PR changes
48+
- **Release Process**: On merge to main, runs linting, testing, and publishes to GitHub Pages
49+
50+
### Important Configuration Patterns
51+
52+
1. **Secret Management**: The chart supports both direct values and references to existing secrets:
53+
```yaml
54+
# Direct values
55+
secrets:
56+
githubAppID: "12345"
57+
58+
# Or reference existing secret
59+
existingSecret: "my-existing-secret"
60+
```
61+
62+
2. **Database Configuration**: Can use external PostgreSQL or deploy test instance:
63+
```yaml
64+
# External database
65+
postgres:
66+
enabled: false
67+
secrets:
68+
databaseURL: "postgresql://..."
69+
70+
# Test database
71+
postgres:
72+
enabled: true
73+
```
74+
75+
3. **Resource Configuration**: Supports standard Kubernetes resource patterns (limits, requests, nodeSelector, tolerations, affinity)
76+
77+
### Testing Strategy
78+
- Unit tests in `digger-backend/tests/` verify template rendering
79+
- Tests use helm-unittest framework with snapshot testing
80+
- CI automatically runs tests on PRs and before releases

helm-charts/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<img width="1470" alt="digger-opensource-gitops-banner" src="https://github.com/diggerhq/digger/assets/1280498/7fb44db3-38ca-4021-8714-87a2f1a14982">
2+
3+
CI/CD for Terraform is [tricky](https://itnext.io/pains-in-terraform-collaboration-249a56b4534e). To make life easier, specialised CI systems aka [TACOS](https://itnext.io/spice-up-your-infrastructure-as-code-with-tacos-1a9c179e0783) exist - Terraform Cloud, Spacelift, Atlantis, etc.
4+
5+
But why have 2 CI systems? Why not reuse the async jobs infrastructure with compute, orchestration, logs, etc of your existing CI?
6+
7+
Digger runs terraform natively in your CI. This is:
8+
9+
- Secure, because cloud access secrets aren't shared with a third-party
10+
- Cost-effective, because you are not paying for additional compute just to run your terraform
11+
12+
## Differences Compared to Atlantis
13+
14+
- No need to host and maintain a server
15+
- Secure by design
16+
- Scalable compute with jobs isolation
17+
- Role-based access control via OPA
18+
- Read more about differences with Atlantis in our blog post
19+
20+
## Compared to Terraform Cloud and other TACOs
21+
22+
- Open source
23+
- No duplication of the CI/CD stack
24+
- Secrets not shared with a third party
25+
26+
## Support for other CI’s
27+
28+
We are currently designing Digger to be Multi-CI, so that in addition to GitHub Actions, you can run Terraform/OpenTofu within other CI’s such as Gitlab CI, Azure DevOps, Bitbucket, TeamCity, Circle CI and Jenkins, while still having the option to orchestrate jobs using Digger’s Orchestrator Backend.
29+
30+
Read more in this [blog](https://blog.digger.dev/how-we-are-designing-digger-to-support-multiple-ci-systems/), and please share your requirement on [Slack](https://bit.ly/diggercommunity) if you require support for other CI’s. Your feedback/insight would help us a lot as this feature is in active development.
31+
32+
33+
34+
# Digger Backend Helm Chart
35+
36+
## Installation steps
37+
38+
The installation must be executed in two steps, as explaned in the [Digger official documentation](https://docs.digger.dev/self-host/deploy-docker-compose#create-github-app):
39+
40+
1. Install the `digger-backend` helm chart from https://diggerhq.github.io/helm-charts/, leaving empty all the data related to the GitHub App
41+
2. Go to `your_digger_hostname/github/setup` to install and configure the GitHub App
42+
3. Configure in the helm values or in the external secret all the data related to the new GitHub app and upgrade the helm installation to reload the Digger application with the new configuration
43+
44+
## Configuration Details
45+
46+
To configure the Digger backend deployment with the Helm chart, you'll need to set several values in the `values.yaml` file. Below are the key configurations to consider:
47+
48+
- `digger.image.repository`: The Docker image repository for the Digger backend (e.g., `registry.digger.dev/diggerhq/digger_backend`).
49+
- `digger.image.tag`: The specific version tag of the Docker image to deploy (e.g., `"v0.4.2"`).
50+
51+
- `digger.service.type`: The type of Kubernetes service to create, such as `ClusterIP`, `NodePort`, or `LoadBalancer`.
52+
- `digger.service.port`: The port number that the service will expose (e.g., `3000`).
53+
54+
- `digger.ingress.enabled`: Set to `true` to create an Ingress for the service.
55+
- `digger.annotations`: Add the needed annotations based on your ingress controller configuration.
56+
- `digger.ingress.host`: The hostname to use for the Ingress resource (e.g., `digger-backend.test`).
57+
- `digger.ingress.path`: The path for the Ingress resource (e.g., `/`).
58+
- `digger.ingress.className`: the classname to use for ingress (only considered for kuberetes >= 1.18)
59+
- `digger.ingress.tls.secretName`: The name of the TLS secret to use for Ingress encryption (e.g., `digger-backend-tls`).
60+
61+
- `digger.secret.*`: Various secrets needed for the application, such as `HTTP_BASIC_AUTH_PASSWORD` and `BEARER_AUTH_TOKEN`. You can provide them directly or reference an existing Kubernetes secret by setting `useExistingSecret` to `true` and specifying `existingSecretName`.
62+
63+
- `digger.postgres.*`: If you're using an external Postgres database, configure the `user`, `database`, and `host` accordingly. Ensure you provide the `password` either directly or through an existing secret in the `secret.*` section.
64+
65+
Remember to replace placeholders and default values with your specific, sensitive information before deploying the chart. For example, it's essential to generate a strong `bearerAuthToken` and `postgresPassword` rather than using the defaults for security reasons.
66+
67+
You can also deploy a PostgreSQL database ONLY FOR TEST PURPOSES configuring the `postgres.*` section:
68+
69+
- `postgres.enabled`: Set to `true` if you want to deploy a postgres database
70+
- `postgres.secret.*`: As for the digger secret, you can pass the `postgres` user password directly or through an existing secret
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
24+
tests/

helm-charts/digger-backend/Chart.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: v2
2+
name: digger-backend
3+
description: A Helm chart for Kubernetes
4+
5+
# A chart can be either an 'application' or a 'library' chart.
6+
#
7+
# Application charts are a collection of templates that can be packaged into versioned archives
8+
# to be deployed.
9+
#
10+
# Library charts provide useful utilities or functions for the chart developer. They're included as
11+
# a dependency of application charts to inject those utilities and functions into the rendering
12+
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
13+
type: application
14+
15+
# This is the chart version. This version number should be incremented each time you make changes
16+
# to the chart and its templates, including the app version.
17+
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18+
version: 0.1.12
19+
20+
# This is the version number of the application being deployed. This version number should be
21+
# incremented each time you make changes to the application. Versions are not expected to
22+
# follow Semantic Versioning. They should reflect the version the application is using.
23+
# It is recommended to use it with quotes.
24+
appVersion: "v0.6.106"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "digger-backend.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "digger-backend.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "digger-backend.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "digger-backend.labels" -}}
37+
helm.sh/chart: {{ include "digger-backend.chart" . }}
38+
{{ include "digger-backend.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "digger-backend.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "digger-backend.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "digger-backend.fullname" . }}-web
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: {{ include "digger-backend.name" . }}-web
10+
template:
11+
metadata:
12+
labels:
13+
app: {{ include "digger-backend.name" . }}-web
14+
spec:
15+
{{- if $.Values.digger.nodeSelector }}
16+
nodeSelector:
17+
{{- toYaml $.Values.digger.nodeSelector | nindent 8 }}
18+
{{- end }}
19+
{{- if $.Values.digger.tolerations }}
20+
tolerations:
21+
{{- toYaml $.Values.digger.tolerations | nindent 8 }}
22+
{{- end }}
23+
containers:
24+
- name: web
25+
image: "{{ .Values.digger.image.repository }}:{{ .Values.digger.image.tag }}"
26+
ports:
27+
- containerPort: 3000
28+
livenessProbe:
29+
{{ .Values.digger.livenessProbe | toYaml | indent 10 | trim }}
30+
startupProbe:
31+
{{ .Values.digger.startupProbe | toYaml | indent 10 | trim }}
32+
envFrom:
33+
- secretRef:
34+
{{- if not .Values.digger.secret.useExistingSecret }}
35+
name: {{ include "digger-backend.fullname" . }}-secret
36+
{{- else }}
37+
name: {{ .Values.digger.secret.existingSecretName }}
38+
{{- end }}
39+
{{- with .Values.digger.resources }}
40+
resources:
41+
{{- toYaml . | nindent 10 }}
42+
{{- end }}
43+
env:
44+
- name: POSTGRES_PASSWORD
45+
{{- if and .Values.postgres.enabled .Values.postgres.secret.useExistingSecret }}
46+
valueFrom:
47+
secretKeyRef:
48+
name: {{ .Values.postgres.secret.existingSecretName }}
49+
key: postgres-password
50+
{{- else if .Values.digger.postgres.existingSecretName }}
51+
valueFrom:
52+
secretKeyRef:
53+
name: {{ .Values.digger.postgres.existingSecretName }}
54+
key: {{ .Values.digger.postgres.existingSecretKey }}
55+
{{- else }}
56+
valueFrom:
57+
secretKeyRef:
58+
name: {{ include "digger-backend.fullname" . }}-postgres-secret
59+
key: postgres-password
60+
{{- end }}
61+
- name: HTTP_BASIC_AUTH
62+
value: "1"
63+
- name: DATABASE_URL
64+
{{- if .Values.postgres.enabled }}
65+
value: "postgres://postgres:$(POSTGRES_PASSWORD)@{{ include "digger-backend.fullname" . }}-postgres:5432/postgres?sslmode={{ .Values.postgres.sslmode }}"
66+
{{- else }}
67+
{{- $pg := .Values.digger.postgres }}
68+
value: "postgres://{{ $pg.user }}:$(POSTGRES_PASSWORD)@{{ $pg.host }}:{{ $pg.port }}/{{ $pg.database }}?sslmode={{ $pg.sslmode }}"
69+
{{- end }}
70+
- name: ALLOW_DIRTY
71+
value: "{{ .Values.digger.postgres.allow_dirty }}"
72+
- name: DIGGER_LOG_LEVEL
73+
value: {{ .Values.digger.logLevel | quote }}
74+
{{- with .Values.digger.customEnv }}
75+
{{- toYaml . | nindent 8 }}
76+
{{- end }}

0 commit comments

Comments
 (0)