├── tests └── charts │ └── application │ ├── ci │ └── empty-values.yaml │ ├── charts │ └── .gitignore │ ├── templates │ ├── serviceaccount.yaml │ ├── service.yaml │ ├── configmap.yaml │ ├── hpa.yaml │ ├── tests │ │ └── test-connection.yaml │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── ingress.yaml │ └── deployment.yaml │ ├── .helmignore │ ├── Chart.yaml │ ├── values.yaml │ └── README.md ├── .editorconfig ├── .github ├── workflows │ ├── pull-request-ci.yml │ ├── main-ci.yml │ └── __shared-ci.yml ├── dependabot.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE.md ├── CODE_OF_CONDUCT.md ├── action.yaml └── README.md /tests/charts/application/ci/empty-values.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/charts/application/charts/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | [*.yaml] 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /.github/workflows/pull-request-ci.yml: -------------------------------------------------------------------------------- 1 | name: Pull request - Continuous Integration 2 | 3 | on: 4 | merge_group: 5 | pull_request: 6 | branches: [main] 7 | 8 | permissions: 9 | contents: read 10 | packages: write 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | ci: 18 | uses: ./.github/workflows/__shared-ci.yml 19 | secrets: inherit 20 | -------------------------------------------------------------------------------- /.github/workflows/main-ci.yml: -------------------------------------------------------------------------------- 1 | name: Main - Continuous Integration 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | tags: ["*"] 7 | 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | packages: write 13 | 14 | concurrency: 15 | group: ${{ github.workflow }}-${{ github.ref }} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | ci: 20 | uses: ./.github/workflows/__shared-ci.yml 21 | secrets: inherit 22 | -------------------------------------------------------------------------------- /tests/charts/application/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "test-application.serviceAccountName" . }} 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | {{- include "test-application.labels" . | nindent 4 }} 9 | {{- with .Values.serviceAccount.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /tests/charts/application/.helmignore: -------------------------------------------------------------------------------- 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/charts/application/templates/service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "test-application.fullname" . }} 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | {{- include "test-application.labels" . | nindent 4 }} 9 | spec: 10 | type: {{ .Values.service.type }} 11 | ports: 12 | - port: {{ .Values.service.port }} 13 | targetPort: http 14 | protocol: TCP 15 | name: http 16 | selector: 17 | {{- include "test-application.selectorLabels" . | nindent 4 }} 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | open-pull-requests-limit: 20 6 | schedule: 7 | interval: weekly 8 | groups: 9 | github-actions-dependencies: 10 | patterns: 11 | - "*" 12 | 13 | - package-ecosystem: helm 14 | directories: 15 | - "/tests/charts/*" 16 | open-pull-requests-limit: 20 17 | schedule: 18 | interval: weekly 19 | groups: 20 | helm-dependencies: 21 | patterns: 22 | - "*" -------------------------------------------------------------------------------- /tests/charts/application/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | --- 3 | kind: ConfigMap 4 | apiVersion: v1 5 | metadata: 6 | name: {{ template "test-application.fullname" . }}-config 7 | namespace: {{ .Values.namespace }} 8 | labels: 9 | {{- include "test-application.labels" . | nindent 4 }} 10 | data: 11 | {{- with .Values.application }} 12 | DB_CONNECTION: {{ .dbConnection | quote }} 13 | DB_HOST: {{ .dbHost | quote }} 14 | DB_PORT: {{ .dbPort | quote }} 15 | DB_DATABASE: {{ .dbDatabase | quote }} 16 | DB_USERNAME: {{ .dbUsername | quote }} 17 | DB_PASSWORD: {{ .dbPassword | quote }} 18 | {{- end }} 19 | 20 | # jscpd:ignore-end -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 bsord 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /tests/charts/application/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | --- 3 | {{- if .Values.autoscaling.enabled }} 4 | apiVersion: autoscaling/v2 5 | kind: HorizontalPodAutoscaler 6 | metadata: 7 | name: {{ include "test-application.fullname" . }} 8 | labels: 9 | {{- include "test-application.labels" . | nindent 4 }} 10 | spec: 11 | scaleTargetRef: 12 | apiVersion: apps/v1 13 | kind: Deployment 14 | name: {{ include "test-application.fullname" . }} 15 | minReplicas: {{ .Values.autoscaling.minReplicas }} 16 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 17 | metrics: 18 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 19 | - type: Resource 20 | resource: 21 | name: cpu 22 | targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 23 | {{- end }} 24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 25 | - type: Resource 26 | resource: 27 | name: memory 28 | targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 29 | {{- end }} 30 | {{- end }} 31 | 32 | # jscpd:ignore-end -------------------------------------------------------------------------------- /tests/charts/application/Chart.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v2 3 | name: "helm-oci-chart-releaser" 4 | description: A Helm chart for Kubernetes 5 | 6 | # A chart can be either an 'application' or a 'library' chart. 7 | # 8 | # Application charts are a collection of templates that can be packaged into versioned archives 9 | # to be deployed. 10 | # 11 | # Library charts provide useful utilities or functions for the chart developer. They're included as 12 | # a dependency of application charts to inject those utilities and functions into the rendering 13 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 14 | type: application 15 | 16 | # This is the chart version. This version number should be incremented each time you make changes 17 | # to the chart and its templates, including the app version. 18 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 19 | version: 0.0.0 20 | 21 | # This is the version number of the application being deployed. This version number should be 22 | # incremented each time you make changes to the application. Versions are not expected to 23 | # follow Semantic Versioning. They should reflect the version the application is using. 24 | # It is recommended to use it with quotes. 25 | appVersion: "0.0.0" 26 | -------------------------------------------------------------------------------- /tests/charts/application/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | --- 3 | apiVersion: v1 4 | kind: Pod 5 | metadata: 6 | name: "{{ include "test-application.fullname" . }}-test-connection" 7 | namespace: {{ .Values.namespace }} 8 | labels: 9 | {{- include "test-application.labels" . | nindent 4 }} 10 | annotations: 11 | "helm.sh/hook": test 12 | spec: 13 | automountServiceAccountToken: false 14 | securityContext: 15 | containers: 16 | - name: wget 17 | image: busybox@sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7 18 | command: 19 | - /bin/sh 20 | - -c 21 | - | 22 | echo "+ testing the application using wget" 23 | set -x 24 | wget -O /dev/null -q '{{ include "test-application.fullname" . }}:{{ .Values.service.port }}' 25 | resources: 26 | limits: 27 | cpu: "100m" 28 | memory: "128Mi" 29 | requests: 30 | cpu: "100m" 31 | memory: "128Mi" 32 | securityContext: 33 | seccompProfile: 34 | type: RuntimeDefault 35 | readOnlyRootFilesystem: true 36 | runAsUser: 10001 37 | allowPrivilegeEscalation: false 38 | capabilities: 39 | drop: 40 | - NET_RAW 41 | - ALL 42 | restartPolicy: Never 43 | # jscpd:ignore-end 44 | -------------------------------------------------------------------------------- /tests/charts/application/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "test-application.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "test-application.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "test-application.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "test-application.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /tests/charts/application/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | jscpd:ignore-start 3 | */}} 4 | {{/* 5 | Expand the name of the chart. 6 | */}} 7 | {{- define "test-application.name" -}} 8 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 9 | {{- end }} 10 | 11 | {{/* 12 | Create a default fully qualified app name. 13 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 14 | If release name contains chart name it will be used as a full name. 15 | */}} 16 | {{- define "test-application.fullname" -}} 17 | {{- if .Values.fullnameOverride }} 18 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 19 | {{- else }} 20 | {{- $name := default .Chart.Name .Values.nameOverride }} 21 | {{- if contains $name .Release.Name }} 22 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 23 | {{- else }} 24 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 25 | {{- end }} 26 | {{- end }} 27 | {{- end }} 28 | 29 | {{/* 30 | Create chart name and version as used by the chart label. 31 | */}} 32 | {{- define "test-application.chart" -}} 33 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 34 | {{- end }} 35 | 36 | {{/* 37 | Common labels 38 | */}} 39 | {{- define "test-application.labels" -}} 40 | helm.sh/chart: {{ include "test-application.chart" . }} 41 | {{ include "test-application.selectorLabels" . }} 42 | {{- if .Chart.AppVersion }} 43 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 44 | {{- end }} 45 | app.kubernetes.io/managed-by: {{ .Release.Service }} 46 | {{- end }} 47 | 48 | {{/* 49 | Selector labels 50 | */}} 51 | {{- define "test-application.selectorLabels" -}} 52 | app.kubernetes.io/name: {{ include "test-application.name" . }} 53 | app.kubernetes.io/instance: {{ .Release.Name }} 54 | {{- end }} 55 | 56 | {{/* 57 | Create the name of the service account to use 58 | */}} 59 | {{- define "test-application.serviceAccountName" -}} 60 | {{- if .Values.serviceAccount.create }} 61 | {{- default (include "test-application.fullname" .) .Values.serviceAccount.name }} 62 | {{- else }} 63 | {{- default "default" .Values.serviceAccount.name }} 64 | {{- end }} 65 | {{- end }} 66 | {{/* 67 | jscpd:ignore-end 68 | */}} -------------------------------------------------------------------------------- /tests/charts/application/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | --- 3 | {{- if .Values.ingress.enabled -}} 4 | {{- $fullName := include "test-application.fullname" . -}} 5 | {{- $svcPort := .Values.service.port -}} 6 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 7 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 8 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 9 | {{- end }} 10 | {{- end }} 11 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 12 | apiVersion: networking.k8s.io/v1 13 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 14 | apiVersion: networking.k8s.io/v1beta1 15 | {{- else -}} 16 | apiVersion: extensions/v1beta1 17 | {{- end }} 18 | kind: Ingress 19 | metadata: 20 | name: {{ $fullName }} 21 | labels: 22 | {{- include "test-application.labels" . | nindent 4 }} 23 | {{- with .Values.ingress.annotations }} 24 | annotations: 25 | {{- toYaml . | nindent 4 }} 26 | {{- end }} 27 | spec: 28 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 29 | ingressClassName: {{ .Values.ingress.className }} 30 | {{- end }} 31 | {{- if .Values.ingress.tls }} 32 | tls: 33 | {{- range .Values.ingress.tls }} 34 | - hosts: 35 | {{- range .hosts }} 36 | - {{ . | quote }} 37 | {{- end }} 38 | secretName: {{ .secretName }} 39 | {{- end }} 40 | {{- end }} 41 | rules: 42 | {{- range .Values.ingress.hosts }} 43 | - host: {{ .host | quote }} 44 | http: 45 | paths: 46 | {{- range .paths }} 47 | - path: {{ .path }} 48 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 49 | pathType: {{ .pathType }} 50 | {{- end }} 51 | backend: 52 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 53 | service: 54 | name: {{ $fullName }} 55 | port: 56 | number: {{ $svcPort }} 57 | {{- else }} 58 | serviceName: {{ $fullName }} 59 | servicePort: {{ $svcPort }} 60 | {{- end }} 61 | {{- end }} 62 | {{- end }} 63 | {{- end }} 64 | 65 | # jscpd:ignore-end -------------------------------------------------------------------------------- /tests/charts/application/values.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | # Default values for test-application. 3 | # This is a YAML-formatted file. 4 | # Declare variables to be passed into your templates. 5 | --- 6 | application: 7 | dbConnection: mysql 8 | dbHost: "mysql" 9 | dbPort: 3306 10 | dbDatabase: test 11 | dbUsername: test 12 | dbPassword: test 13 | 14 | replicaCount: 1 15 | 16 | image: 17 | pullPolicy: Always 18 | # Overrides the image tag whose default is the chart appVersion. 19 | registry: "ghcr.io" 20 | repository: "hoverkraft-tech/ci-github-container/application-test" 21 | tag: "" 22 | digest: "sha256:da3b65f32ea75f8041079d220b72da4f605738996256a7dc32715424cc117271" 23 | 24 | imagePullSecrets: [] 25 | 26 | nameOverride: "" 27 | fullnameOverride: "" 28 | 29 | serviceAccount: 30 | # Specifies whether a service account should be created 31 | create: true 32 | # Annotations to add to the service account 33 | annotations: {} 34 | # The name of the service account to use. 35 | # If not set and create is true, a name is generated using the fullname template 36 | name: "" 37 | 38 | podAnnotations: {} 39 | 40 | podSecurityContext: 41 | {} 42 | # fsGroup: 2000 43 | 44 | securityContext: 45 | capabilities: 46 | drop: 47 | - ALL 48 | allowPrivilegeEscalation: false 49 | readOnlyRootFilesystem: true 50 | runAsNonRoot: true 51 | runAsUser: 10001 52 | seccompProfile: 53 | type: RuntimeDefault 54 | 55 | service: 56 | type: ClusterIP 57 | port: 8080 58 | 59 | ingress: 60 | enabled: false 61 | className: "" 62 | annotations: 63 | {} 64 | # kubernetes.io/ingress.class: nginx 65 | # kubernetes.io/tls-acme: "true" 66 | hosts: 67 | - host: chart-example.local 68 | paths: 69 | - path: / 70 | pathType: ImplementationSpecific 71 | tls: [] 72 | # - secretName: chart-example-tls 73 | # hosts: 74 | # - chart-example.local 75 | 76 | resources: 77 | # We usually recommend not to specify default resources and to leave this as a conscious 78 | # choice for the user. This also increases chances charts run on environments with little 79 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 80 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 81 | limits: 82 | cpu: 100m 83 | memory: 128Mi 84 | requests: 85 | cpu: 100m 86 | memory: 128Mi 87 | 88 | autoscaling: 89 | enabled: false 90 | minReplicas: 1 91 | maxReplicas: 100 92 | targetCPUUtilizationPercentage: 80 93 | # targetMemoryUtilizationPercentage: 80 94 | 95 | nodeSelector: {} 96 | 97 | tolerations: [] 98 | 99 | affinity: {} 100 | 101 | # chart dependencies 102 | mysql: 103 | fullnameOverride: mysql 104 | enabled: false 105 | auth: 106 | database: test 107 | username: test 108 | password: test 109 | rootPassword: root 110 | # jscpd:ignore-end 111 | -------------------------------------------------------------------------------- /tests/charts/application/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | # jscpd:ignore-start 2 | --- 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: {{ include "test-application.fullname" . }} 7 | namespace: {{ .Values.namespace }} 8 | labels: 9 | {{- include "test-application.labels" . | nindent 4 }} 10 | spec: 11 | {{- if not .Values.autoscaling.enabled }} 12 | replicas: {{ .Values.replicaCount }} 13 | {{- end }} 14 | selector: 15 | matchLabels: 16 | {{- include "test-application.selectorLabels" . | nindent 6 }} 17 | template: 18 | metadata: 19 | {{- with .Values.podAnnotations }} 20 | annotations: 21 | {{- toYaml . | nindent 8 }} 22 | {{- end }} 23 | labels: 24 | {{- include "test-application.selectorLabels" . | nindent 8 }} 25 | spec: 26 | automountServiceAccountToken: false 27 | {{- with .Values.imagePullSecrets }} 28 | imagePullSecrets: 29 | {{- toYaml . | nindent 8 }} 30 | {{- end }} 31 | serviceAccountName: {{ include "test-application.serviceAccountName" . }} 32 | securityContext: 33 | runAsNonRoot: true 34 | runAsUser: 101 35 | runAsGroup: 101 36 | fsGroup: 101 37 | volumes: 38 | - name: cache-nginx 39 | emptyDir: {} 40 | - name: var-run 41 | emptyDir: {} 42 | - name: tmp 43 | emptyDir: {} 44 | containers: 45 | - name: {{ .Chart.Name }} 46 | image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 47 | imagePullPolicy: {{ .Values.image.pullPolicy }} 48 | securityContext: 49 | privileged: false 50 | allowPrivilegeEscalation: false 51 | readOnlyRootFilesystem: true 52 | seccompProfile: 53 | type: RuntimeDefault 54 | capabilities: 55 | drop: 56 | - ALL 57 | add: 58 | - NET_BIND_SERVICE 59 | envFrom: 60 | - configMapRef: 61 | name: {{ template "test-application.fullname" . }}-config 62 | ports: 63 | - name: http 64 | containerPort: 8080 65 | protocol: TCP 66 | volumeMounts: 67 | - name: cache-nginx 68 | mountPath: /var/cache/nginx 69 | - name: var-run 70 | mountPath: /var/run 71 | - name: tmp 72 | mountPath: /tmp 73 | livenessProbe: 74 | httpGet: 75 | path: /health/check 76 | port: http 77 | readinessProbe: 78 | httpGet: 79 | path: /health/check 80 | port: http 81 | resources: 82 | {{- toYaml .Values.resources | nindent 12 }} 83 | {{- with .Values.nodeSelector }} 84 | nodeSelector: 85 | {{- toYaml . | nindent 8 }} 86 | {{- end }} 87 | {{- with .Values.affinity }} 88 | affinity: 89 | {{- toYaml . | nindent 8 }} 90 | {{- end }} 91 | {{- with .Values.tolerations }} 92 | tolerations: 93 | {{- toYaml . | nindent 8 }} 94 | {{- end }} 95 | 96 | # jscpd:ignore-end -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at it@appany.ru. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /action.yaml: -------------------------------------------------------------------------------- 1 | name: Helm OCI Chart Releaser 2 | description: Push Helm charts to OCI-based (Docker) registries 3 | author: sergeyshaykhullin 4 | branding: 5 | color: yellow 6 | icon: upload-cloud 7 | inputs: 8 | name: 9 | required: true 10 | description: Chart name 11 | repository: 12 | required: true 13 | description: Chart repository name 14 | tag: 15 | required: true 16 | description: Chart version 17 | app_version: 18 | required: false 19 | description: Set appVersion in the Chart 20 | path: 21 | required: false 22 | description: Chart path (Default 'charts/{name}') 23 | registry: 24 | required: true 25 | description: OCI registry 26 | registry_username: 27 | required: true 28 | description: OCI registry username 29 | registry_password: 30 | required: true 31 | description: OCI registry password 32 | sign: 33 | required: false 34 | default: 'false' 35 | description: Use a PGP private key to sign this package 36 | signing_key: 37 | required: false 38 | default: '' 39 | description: Name of the key to use when signing. Required if "sign" is true 40 | signing_passphrase: 41 | required: false 42 | default: '' 43 | description: Passphrase for the signing key 44 | signing_keyring: 45 | required: false 46 | default: ~/.gnupg/secring.gpg 47 | description: Location of the public keyring 48 | update_dependencies: 49 | required: false 50 | default: 'false' 51 | description: Update chart dependencies before packaging (Default 'false') 52 | outputs: 53 | image: 54 | value: ${{ steps.output.outputs.image }} 55 | description: Chart image (Default '{registry}/{repository}/{image}:{tag}') 56 | runs: 57 | using: composite 58 | steps: 59 | - name: Helm | Login 60 | shell: bash 61 | run: echo '${{ inputs.registry_password }}' | helm registry login -u '${{ inputs.registry_username }}' --password-stdin '${{ inputs.registry }}' 62 | env: 63 | HELM_EXPERIMENTAL_OCI: '1' 64 | 65 | - id: prepare-variables 66 | shell: bash 67 | run: | 68 | echo "path=${{ inputs.path == null && format('{0}/{1}', 'charts', inputs.name) || inputs.path }}" >> $GITHUB_OUTPUT 69 | echo "chart-file=${{ runner.temp }}/${{ inputs.name }}-${{ inputs.tag }}.tgz" >> $GITHUB_OUTPUT 70 | 71 | - name: Helm | Dependency 72 | if: ${{ inputs.update_dependencies == 'true' }} 73 | shell: bash 74 | run: helm dependency update ${{ steps.prepare-variables.outputs.path }} 75 | env: 76 | HELM_EXPERIMENTAL_OCI: '1' 77 | 78 | - name: Helm | Package 79 | shell: bash 80 | run: | 81 | ${{ inputs.sign == 'true' && inputs.signing_passphrase && format('echo ''{0}'' | ', inputs.signing_passphrase) || '' }} \ 82 | helm package \ 83 | '${{ steps.prepare-variables.outputs.path }}' \ 84 | --version '${{ inputs.tag }}' \ 85 | ${{ inputs.app_version != null && format('--app-version {0}', inputs.app_version) || '' }} \ 86 | --destination $(dirname '${{ steps.prepare-variables.outputs.chart-file }}') \ 87 | ${{ inputs.sign == 'true' && format('--sign --key ''{0}'' --keyring {1} --passphrase-file -', inputs.signing_key, inputs.signing_keyring) || '' }} 88 | env: 89 | HELM_EXPERIMENTAL_OCI: '1' 90 | 91 | - name: Helm | Push 92 | shell: bash 93 | run: | 94 | if [ ! -f '${{ steps.prepare-variables.outputs.chart-file }}' ]; then 95 | echo "Chart file '${{ steps.prepare-variables.outputs.chart-file }}' does not exist. Please check the 'name' input matches the chart name." 96 | exit 1 97 | fi 98 | 99 | helm push '${{ steps.prepare-variables.outputs.chart-file }}' 'oci://${{ inputs.registry }}/${{ inputs.repository }}' 100 | env: 101 | HELM_EXPERIMENTAL_OCI: '1' 102 | 103 | - name: Helm | Logout 104 | shell: bash 105 | run: helm registry logout '${{ inputs.registry }}' 106 | env: 107 | HELM_EXPERIMENTAL_OCI: '1' 108 | 109 | - name: Helm | Output 110 | id: output 111 | shell: bash 112 | run: echo 'image=${{ inputs.registry }}/${{ inputs.repository }}/${{ inputs.name }}:${{ inputs.tag }}' >> $GITHUB_OUTPUT 113 | -------------------------------------------------------------------------------- /.github/workflows/__shared-ci.yml: -------------------------------------------------------------------------------- 1 | name: Common Continuous Integration tasks 2 | 3 | on: 4 | workflow_call: 5 | 6 | permissions: 7 | contents: read 8 | packages: write 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | name: Lint 14 | steps: 15 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 16 | 17 | - name: actionlint 18 | uses: raven-actions/actionlint@3a24062651993d40fed1019b58ac6fbdfbf276cc # v2.0.1 19 | 20 | test-release-chart: 21 | runs-on: ubuntu-latest 22 | name: Test release chart 23 | steps: 24 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 25 | 26 | - name: Act 27 | id: act 28 | uses: ./ 29 | with: 30 | name: ${{ github.event.repository.name }} 31 | repository: ${{ github.repository }}/charts/application-test 32 | tag: "0.1.0-${{ github.run_id }}" 33 | path: tests/charts/application 34 | registry: ghcr.io 35 | registry_username: ${{ github.repository_owner }} 36 | registry_password: ${{ github.token }} 37 | 38 | - name: "Assert: outputs" 39 | run: | 40 | if [ "${{ steps.act.outputs.image }}" != "ghcr.io/${{ github.repository }}/charts/application-test/${{ github.event.repository.name }}:0.1.0-${{ github.run_id }}" ]; then 41 | echo "Unexpected chart image name" 42 | exit 1 43 | fi 44 | 45 | # Clean up package versions 46 | 47 | - id: get-package-version-ids 48 | if: always() 49 | uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 50 | with: 51 | script: | 52 | // Retrieve package version IDs for the created chart tag 53 | const packageName = `${{ github.event.repository.name }}/charts/application-test/${{ github.event.repository.name }}`; 54 | const tag = `0.1.0-${{ github.run_id }}`; 55 | const packageVersionIds = []; 56 | 57 | async function rateLimitRetryCall (fn, ...args) { 58 | try { 59 | return await fn(...args) 60 | } catch (error) { 61 | if (error.status === 403 && error.headers['retry-after']) { 62 | const retryAfter = parseInt(error.headers['retry-after'], 10) 63 | await new Promise((resolve) => 64 | setTimeout(resolve, (retryAfter + 1) * 1000) 65 | ) 66 | return rateLimitRetryCall(fn, ...args) 67 | } 68 | throw error 69 | } 70 | } 71 | 72 | async function getAllPackageVersions(page = 1) { 73 | // Get all package versions for the package owned by the user 74 | const { data } = await rateLimitRetryCall( 75 | github.rest.packages.getAllPackageVersionsForPackageOwnedByUser, 76 | { 77 | package_type: 'container', 78 | package_name: packageName, 79 | username: context.repo.owner, 80 | per_page: 100, 81 | page 82 | } 83 | ) 84 | return data 85 | } 86 | 87 | let currentPage = 1 88 | for (;;) { 89 | const data = await getAllPackageVersions(currentPage) 90 | 91 | currentPage++ 92 | 93 | if (!data.length) { 94 | break 95 | } 96 | 97 | // Filter package versions by tag 98 | const matchingPackageVersionIds = data 99 | .filter((version) => version.metadata.container.tags.includes(tag)) 100 | .map((version) => version.id) 101 | 102 | packageVersionIds.push(...matchingPackageVersionIds); 103 | } 104 | 105 | const uniquePackageVersionIds = [...new Set(packageVersionIds)]; 106 | 107 | // Return the package version IDs as a comma-separated string 108 | if (uniquePackageVersionIds.length > 0) { 109 | core.setOutput('package-version-ids', uniquePackageVersionIds.join(',')); 110 | } 111 | 112 | - name: Delete package versions 113 | uses: actions/delete-package-versions@v5 114 | if: always() && steps.get-package-version-ids.outputs.package-version-ids 115 | with: 116 | package-type: container 117 | package-name: ${{ github.event.repository.name }}/charts/application-test/${{ github.event.repository.name }} 118 | package-version-ids: ${{ steps.get-package-version-ids.outputs.package-version-ids }} 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💥 Helm OCI Chart Releaser 💥 2 | 3 | 🚀 Push Helm Charts to OCI-based (Docker) registries! 🚀 4 | 5 | 💡 Store **Helm Charts** with your **Docker images**. No more need to host Helm repositories ♿ 6 | 7 | 📝 More info about secure **OCI-based** hosting https://helm.sh/docs/topics/registries/ 8 | 9 | ## Usage 10 | 11 | - Push Helm Chart to **Github Container Registry** 12 | 13 | ```yaml 14 | - name: Chart | Push 15 | uses: appany/helm-oci-chart-releaser@v0.5.0 16 | with: 17 | name: my-chart 18 | repository: appany 19 | tag: 0.1.0 20 | path: charts/my-chart # Default charts/{name} 21 | registry: ghcr.io 22 | registry_username: ${{ secrets.REGISTRY_USERNAME }} 23 | registry_password: ${{ secrets.REGISTRY_PASSWORD }} 24 | update_dependencies: 'true' # Defaults to false 25 | 26 | # helm pull ghcr.io/appany/my-chart:0.1.0 27 | ``` 28 | 29 | - Push Helm Chart to **Github Container Registry** and sign the package 30 | 31 | ```yaml 32 | - name: Import GPG key 33 | uses: crazy-max/ghaction-import-gpg@v6 34 | id: gpg 35 | with: 36 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} # Private key of the GPG key 37 | passphrase: ${{ secrets.GPG_PASSPHRASE }} # Passphrase for the key, if required 38 | 39 | # Helm requires the legacy GPG format 40 | # @link https://helm.sh/docs/topics/provenance/#the-workflow 41 | - name: Convert GPG v2 key 42 | run: | 43 | gpg --export > ~/.gnupg/pubring.gpg 44 | gpg --batch --pinentry-mode loopback --yes --passphrase '${{ secrets.GPG_PASSPHRASE }}' --export-secret-key > ~/.gnupg/secring.gpg 45 | - name: Chart | Push and sign 46 | uses: appany/helm-oci-chart-releaser@v0.5.0 47 | with: 48 | name: my-chart 49 | repository: appany 50 | tag: 0.1.0 51 | path: charts/my-chart # Default charts/{name} 52 | registry: ghcr.io 53 | registry_username: ${{ secrets.REGISTRY_USERNAME }} 54 | registry_password: ${{ secrets.REGISTRY_PASSWORD }} 55 | sign: true 56 | signing_key: ${{ steps.gpg.outputs.name }} 57 | signing_passphrase: ${{ secrets.GPG_PASSPHRASE }} 58 | update_dependencies: 'true' # Defaults to false 59 | 60 | # helm pull ghcr.io/appany/my-chart:0.1.0 61 | ``` 62 | 63 | - Push Helm Chart to **Azure Container Registry** 64 | ```yaml 65 | - name: Chart | Push 66 | uses: appany/helm-oci-chart-releaser@v0.5.0 67 | with: 68 | name: my-chart 69 | repository: helm 70 | tag: 0.1.0 71 | path: charts/my-chart # Default charts/{name} 72 | registry: appany.azurecr.io 73 | registry_username: ${{ secrets.REGISTRY_USERNAME }} 74 | registry_password: ${{ secrets.REGISTRY_PASSWORD }} 75 | update_dependencies: 'true' # Defaults to false 76 | 77 | # helm pull appany.azurecr.io/helm/my-chart:0.1.0 78 | ``` 79 | 80 | ## Inputs 81 | 82 | ```yaml 83 | inputs: 84 | name: 85 | required: true 86 | description: Chart name 87 | repository: 88 | required: true 89 | description: Chart repository name 90 | tag: 91 | required: true 92 | description: Chart version 93 | path: 94 | required: false 95 | description: Chart path (Default 'charts/{name}') 96 | registry: 97 | required: true 98 | description: OCI registry 99 | registry_username: 100 | required: true 101 | description: OCI registry username 102 | registry_password: 103 | required: true 104 | description: OCI registry password 105 | sign: 106 | required: false 107 | default: 'false' 108 | description: Use a PGP private key to sign this package 109 | signing_key: 110 | required: false 111 | default: '' 112 | description: Name of the key to use when signing. Required if "sign" is true 113 | signing_passphrase: 114 | required: false 115 | default: '' 116 | description: Passphrase for the signing key 117 | signing_keyring: 118 | required: false 119 | default: ~/.gnupg/secring.gpg 120 | description: Location of the public keyring 121 | update_dependencies: 122 | required: false 123 | default: 'false' 124 | description: Update chart dependencies before packaging (Default 'false') 125 | ``` 126 | 127 | ## Outputs 128 | 129 | ```yaml 130 | outputs: 131 | image: 132 | value: ${{ steps.output.outputs.image }} 133 | description: Chart image (Default '{registry}/{repository}/{image}:{tag}') 134 | ``` 135 | 136 | ## ArgoCD 137 | 138 | 1. Add container registry and enable OCI support 139 | ```yaml 140 | repositories: 141 | ghcr: 142 | url: ghcr.io 143 | type: helm 144 | name: ... 145 | enableOCI: "true" 146 | 147 | credentialTemplates: 148 | ghcr: 149 | url: ghcr.io 150 | username: ... 151 | password: ... 152 | ``` 153 | 154 | 2. Create an Application 155 | ```yaml 156 | apiVersion: argoproj.io/v1alpha1 157 | kind: Application 158 | ... 159 | spec: 160 | source: 161 | repoURL: ghcr.io 162 | targetRevision: 0.1.0 163 | chart: appany/my-chart 164 | helm: 165 | ... 166 | ``` 167 | 168 | ## License 169 | 170 | This project is distributed under the [MIT license](LICENSE.md). 171 | -------------------------------------------------------------------------------- /tests/charts/application/README.md: -------------------------------------------------------------------------------- 1 | # test-application 2 | 3 | ![Version: 0.0.0](https://img.shields.io/badge/Version-0.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.0.0](https://img.shields.io/badge/AppVersion-0.0.0-informational?style=flat-square) 4 | 5 | A Helm chart for Kubernetes 6 | 7 | ## Requirements 8 | 9 | | Repository | Name | Version | 10 | | ---------- | ---- | ------- | 11 | 12 | ## Values 13 | 14 | | Key | Type | Default | Description | 15 | | ------------------------------------------ | ------ | --------------------------------------------------------------------------- | ----------- | 16 | | affinity | object | `{}` | | 17 | | application.dbConnection | string | `"mysql"` | | 18 | | application.dbDatabase | string | `"test"` | | 19 | | application.dbHost | string | `"mysql"` | | 20 | | application.dbPassword | string | `"test"` | | 21 | | application.dbPort | int | `3306` | | 22 | | application.dbUsername | string | `"test"` | | 23 | | autoscaling.enabled | bool | `false` | | 24 | | autoscaling.maxReplicas | int | `100` | | 25 | | autoscaling.minReplicas | int | `1` | | 26 | | autoscaling.targetCPUUtilizationPercentage | int | `80` | | 27 | | fullnameOverride | string | `""` | | 28 | | image.digest | string | `"sha256:da3b65f32ea75f8041079d220b72da4f605738996256a7dc32715424cc117271"` | | 29 | | image.pullPolicy | string | `"Always"` | | 30 | | image.registry | string | `"ghcr.io"` | | 31 | | image.repository | string | `"hoverkraft-tech/ci-github-container/application-test"` | | 32 | | image.tag | string | `""` | | 33 | | imagePullSecrets | list | `[]` | | 34 | | ingress.annotations | object | `{}` | | 35 | | ingress.className | string | `""` | | 36 | | ingress.enabled | bool | `false` | | 37 | | ingress.hosts[0].host | string | `"chart-example.local"` | | 38 | | ingress.hosts[0].paths[0].path | string | `"/"` | | 39 | | ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | | 40 | | ingress.tls | list | `[]` | | 41 | | mysql.auth.database | string | `"test"` | | 42 | | mysql.auth.password | string | `"test"` | | 43 | | mysql.auth.rootPassword | string | `"root"` | | 44 | | mysql.auth.username | string | `"test"` | | 45 | | mysql.enabled | bool | `false` | | 46 | | mysql.fullnameOverride | string | `"mysql"` | | 47 | | nameOverride | string | `""` | | 48 | | nodeSelector | object | `{}` | | 49 | | podAnnotations | object | `{}` | | 50 | | podSecurityContext | object | `{}` | | 51 | | replicaCount | int | `1` | | 52 | | resources.limits.cpu | string | `"100m"` | | 53 | | resources.limits.memory | string | `"128Mi"` | | 54 | | resources.requests.cpu | string | `"100m"` | | 55 | | resources.requests.memory | string | `"128Mi"` | | 56 | | securityContext.allowPrivilegeEscalation | bool | `false` | | 57 | | securityContext.capabilities.drop[0] | string | `"ALL"` | | 58 | | securityContext.readOnlyRootFilesystem | bool | `true` | | 59 | | securityContext.runAsNonRoot | bool | `true` | | 60 | | securityContext.runAsUser | int | `10001` | | 61 | | securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | 62 | | service.port | int | `8080` | | 63 | | service.type | string | `"ClusterIP"` | | 64 | | serviceAccount.annotations | object | `{}` | | 65 | | serviceAccount.create | bool | `true` | | 66 | | serviceAccount.name | string | `""` | | 67 | | tolerations | list | `[]` | | 68 | 69 | --- 70 | 71 | Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) 72 | --------------------------------------------------------------------------------