Skip to content

Commit 116f763

Browse files
committed
Add Helm chart
1 parent 6fcc57c commit 116f763

14 files changed

Lines changed: 507 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,31 @@ jobs:
4646

4747
- name: golangci-lint
4848
run: go tool golangci-lint run ./...
49+
50+
helm:
51+
name: Helm chart
52+
runs-on: ubuntu-latest
53+
steps:
54+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
55+
with:
56+
persist-credentials: false
57+
58+
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
59+
with:
60+
version: v3.18.6
61+
62+
- name: Lint chart
63+
run: helm lint deploy/charts/proxy
64+
65+
- name: Render chart variants
66+
run: |
67+
set -euo pipefail
68+
helm template proxy deploy/charts/proxy >/dev/null
69+
helm template proxy deploy/charts/proxy \
70+
--set persistence.enabled=false \
71+
--set config.existingConfigMap=proxy-config \
72+
--set ingress.enabled=true \
73+
--set 'ingress.hosts[0].host=proxy.example.com' \
74+
--set 'ingress.hosts[0].paths[0].path=/' \
75+
--set 'ingress.hosts[0].paths[0].pathType=Prefix' \
76+
>/dev/null

.github/workflows/publish.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,66 @@ jobs:
9696
for predicate in sbom-linux-amd64.spdx.json sbom-linux-arm64.spdx.json; do
9797
cosign attest --yes --type spdxjson --predicate "$predicate" "$reference"
9898
done
99+
100+
publish_chart:
101+
name: Push Helm chart to GHCR
102+
if: github.ref_type == 'tag'
103+
needs: push_to_registry
104+
runs-on: ubuntu-latest
105+
permissions:
106+
contents: read
107+
packages: write
108+
steps:
109+
- name: Check out the repo
110+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
111+
with:
112+
persist-credentials: false
113+
ref: ${{ github.sha }}
114+
115+
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
116+
with:
117+
version: v3.18.6
118+
119+
- name: Validate and normalize release version
120+
id: version
121+
env:
122+
TAG: ${{ github.ref_name }}
123+
run: |
124+
set -euo pipefail
125+
semver='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?$'
126+
[[ "$TAG" =~ $semver ]] || {
127+
echo "Tag must be strict SemVer of the form vMAJOR.MINOR.PATCH[-PRERELEASE]: $TAG" >&2
128+
exit 1
129+
}
130+
version="${TAG#v}"
131+
[[ "$version" != "0.0.0" ]] || {
132+
echo "0.0.0 is a development placeholder and must not be published" >&2
133+
exit 1
134+
}
135+
echo "version=$version" >> "$GITHUB_OUTPUT"
136+
137+
- name: Log in to GHCR
138+
env:
139+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
140+
run: printf '%s' "$GH_TOKEN" | helm registry login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
141+
142+
- name: Lint and package chart
143+
env:
144+
VERSION: ${{ steps.version.outputs.version }}
145+
run: |
146+
set -euo pipefail
147+
helm lint deploy/charts/proxy
148+
mkdir -p build
149+
helm package \
150+
--destination build \
151+
--version "$VERSION" \
152+
--app-version "$VERSION" \
153+
deploy/charts/proxy
154+
metadata="$(helm show chart "build/proxy-${VERSION}.tgz")"
155+
[[ "$(awk '$1 == "version:" {print $2}' <<<"$metadata")" == "$VERSION" ]]
156+
[[ "$(awk '$1 == "appVersion:" {gsub(/\"/, "", $2); print $2}' <<<"$metadata")" == "$VERSION" ]]
157+
158+
- name: Push chart
159+
env:
160+
VERSION: ${{ steps.version.outputs.version }}
161+
run: helm push "build/proxy-${VERSION}.tgz" oci://ghcr.io/git-pkgs/charts

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*.dll
55
*.so
66
*.dylib
7-
proxy
7+
/proxy
88

99
# Test binary, built with `go test -c`
1010
*.test
@@ -43,4 +43,4 @@ cache/*
4343

4444
# Debug files
4545
__debug_bin
46-
debug
46+
debug

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ brew install git-pkgs/git-pkgs/proxy
6262

6363
Or download a binary from the [releases page](https://github.com/git-pkgs/proxy/releases).
6464

65+
### Helm
66+
67+
Install the chart from GHCR, setting the public URL that package-manager clients
68+
will use to reach the proxy:
69+
70+
```bash
71+
helm install proxy oci://ghcr.io/git-pkgs/charts/proxy \
72+
--set config.data.base_url=https://proxy.example.com
73+
```
74+
75+
The default chart deploys one replica backed by a 10 GiB persistent volume,
76+
using SQLite and filesystem artifact storage under `/data`. See
77+
[`deploy/charts/proxy/values.yaml`](deploy/charts/proxy/values.yaml) for ingress,
78+
external database and object-storage configuration options.
79+
6580
## Quick Start
6681

6782
```bash

deploy/charts/proxy/.helmignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
.git/
3+
.github/
4+
*.swp
5+
*.tmp
6+
*.tgz

deploy/charts/proxy/Chart.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v2
2+
name: proxy
3+
description: A caching proxy for package registries
4+
type: application
5+
version: 0.0.0
6+
appVersion: "0.0.0"
7+
home: https://github.com/git-pkgs/proxy
8+
sources:
9+
- https://github.com/git-pkgs/proxy
10+
annotations:
11+
artifacthub.io/license: MIT
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
git-pkgs proxy has been installed.
2+
3+
The default base URL is intended for local port forwarding. Before exposing the
4+
proxy, set config.data.base_url to the URL used by package-manager clients.
5+
6+
To access the proxy locally:
7+
8+
kubectl -n {{ .Release.Namespace }} port-forward service/{{ include "proxy.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }}
9+
10+
Then visit http://localhost:{{ .Values.service.port }}/.
11+
12+
{{- if not .Values.persistence.enabled }}
13+
WARNING: persistence is disabled. Cached artifacts and the default SQLite
14+
database will be lost when the pod is replaced.
15+
{{- end }}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{{/* Expand the chart name. */}}
2+
{{- define "proxy.name" -}}
3+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
4+
{{- end }}
5+
6+
{{/* Create a release-specific, DNS-safe resource name. */}}
7+
{{- define "proxy.fullname" -}}
8+
{{- if .Values.fullnameOverride }}
9+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
10+
{{- else }}
11+
{{- $name := include "proxy.name" . }}
12+
{{- if contains $name .Release.Name }}
13+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
14+
{{- else }}
15+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
16+
{{- end }}
17+
{{- end }}
18+
{{- end }}
19+
20+
{{- define "proxy.labels" -}}
21+
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
22+
{{ include "proxy.selectorLabels" . }}
23+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
24+
app.kubernetes.io/managed-by: {{ .Release.Service }}
25+
{{- end }}
26+
27+
{{- define "proxy.selectorLabels" -}}
28+
app.kubernetes.io/name: {{ include "proxy.name" . }}
29+
app.kubernetes.io/instance: {{ .Release.Name }}
30+
{{- end }}
31+
32+
{{- define "proxy.configMapName" -}}
33+
{{- default (include "proxy.fullname" .) .Values.config.existingConfigMap }}
34+
{{- end }}
35+
36+
{{- define "proxy.claimName" -}}
37+
{{- default (include "proxy.fullname" .) .Values.persistence.existingClaim }}
38+
{{- end }}
39+
40+
{{- define "proxy.image" -}}
41+
{{- if .Values.image.digest -}}
42+
{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}}
43+
{{- else -}}
44+
{{- printf "%s:%s" .Values.image.repository (default .Chart.AppVersion .Values.image.tag) -}}
45+
{{- end -}}
46+
{{- end }}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{{- if not .Values.config.existingConfigMap }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ include "proxy.fullname" . }}
6+
namespace: {{ .Release.Namespace }}
7+
labels:
8+
{{- include "proxy.labels" . | nindent 4 }}
9+
data:
10+
{{ required "config.existingConfigMapKey is required" .Values.config.existingConfigMapKey }}: |
11+
{{- toYaml .Values.config.data | nindent 4 }}
12+
{{- end }}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "proxy.fullname" . }}
5+
namespace: {{ .Release.Namespace }}
6+
labels:
7+
{{- include "proxy.labels" . | nindent 4 }}
8+
spec:
9+
replicas: {{ .Values.replicaCount }}
10+
strategy:
11+
{{- toYaml .Values.deploymentStrategy | nindent 4 }}
12+
selector:
13+
matchLabels:
14+
{{- include "proxy.selectorLabels" . | nindent 6 }}
15+
template:
16+
metadata:
17+
labels:
18+
{{- include "proxy.selectorLabels" . | nindent 8 }}
19+
{{- with .Values.podLabels }}
20+
{{- toYaml . | nindent 8 }}
21+
{{- end }}
22+
annotations:
23+
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
24+
{{- with .Values.podAnnotations }}
25+
{{- toYaml . | nindent 8 }}
26+
{{- end }}
27+
spec:
28+
automountServiceAccountToken: false
29+
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
30+
securityContext:
31+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
32+
{{- with .Values.imagePullSecrets }}
33+
imagePullSecrets:
34+
{{- toYaml . | nindent 8 }}
35+
{{- end }}
36+
containers:
37+
- name: {{ .Chart.Name }}
38+
image: {{ include "proxy.image" . | quote }}
39+
imagePullPolicy: {{ .Values.image.pullPolicy }}
40+
securityContext:
41+
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
42+
args:
43+
- serve
44+
- -config
45+
- /etc/proxy/{{ .Values.config.existingConfigMapKey }}
46+
{{- with .Values.extraEnv }}
47+
env:
48+
{{- toYaml . | nindent 12 }}
49+
{{- end }}
50+
{{- with .Values.extraEnvFrom }}
51+
envFrom:
52+
{{- toYaml . | nindent 12 }}
53+
{{- end }}
54+
ports:
55+
- name: http
56+
containerPort: {{ .Values.service.containerPort }}
57+
protocol: TCP
58+
startupProbe:
59+
{{- toYaml .Values.startupProbe | nindent 12 }}
60+
readinessProbe:
61+
{{- toYaml .Values.readinessProbe | nindent 12 }}
62+
livenessProbe:
63+
{{- toYaml .Values.livenessProbe | nindent 12 }}
64+
resources:
65+
{{- toYaml .Values.resources | nindent 12 }}
66+
volumeMounts:
67+
- name: config
68+
mountPath: /etc/proxy/{{ .Values.config.existingConfigMapKey }}
69+
subPath: {{ .Values.config.existingConfigMapKey }}
70+
readOnly: true
71+
- name: data
72+
mountPath: {{ .Values.persistence.mountPath }}
73+
volumes:
74+
- name: config
75+
configMap:
76+
name: {{ include "proxy.configMapName" . }}
77+
items:
78+
- key: {{ required "config.existingConfigMapKey is required" .Values.config.existingConfigMapKey }}
79+
path: {{ .Values.config.existingConfigMapKey }}
80+
- name: data
81+
{{- if .Values.persistence.enabled }}
82+
persistentVolumeClaim:
83+
claimName: {{ include "proxy.claimName" . }}
84+
{{- else }}
85+
emptyDir: {}
86+
{{- end }}
87+
{{- with .Values.nodeSelector }}
88+
nodeSelector:
89+
{{- toYaml . | nindent 8 }}
90+
{{- end }}
91+
{{- with .Values.affinity }}
92+
affinity:
93+
{{- toYaml . | nindent 8 }}
94+
{{- end }}
95+
{{- with .Values.tolerations }}
96+
tolerations:
97+
{{- toYaml . | nindent 8 }}
98+
{{- end }}
99+
{{- with .Values.topologySpreadConstraints }}
100+
topologySpreadConstraints:
101+
{{- toYaml . | nindent 8 }}
102+
{{- end }}

0 commit comments

Comments
 (0)