Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add app helm chart #630

Merged
merged 11 commits into from
Feb 2, 2025
45 changes: 45 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,51 @@ jobs:
docker.io/tarampampam/webhook-tester:${{ steps.slug.outputs.version-major }}.${{ steps.slug.outputs.version-minor }}
docker.io/tarampampam/webhook-tester:${{ steps.slug.outputs.version-major }}

helm-pack:
name: Pack the Helm chart
runs-on: ubuntu-latest
defaults: {run: {working-directory: ./deployments/helm}}
steps:
- uses: actions/checkout@v4
- uses: azure/setup-helm@v4
- {uses: gacts/github-slug@v1, id: slug}
- run: |
helm package \
--app-version "${{ steps.slug.outputs.version }}" \
--version "${{ steps.slug.outputs.version }}" .
- uses: actions/upload-artifact@v4
with:
name: helm-chart
path: ./deployments/helm/*.tgz
if-no-files-found: error
retention-days: 1

helm-publish:
name: Put the Helm chart to the GitHub pages branch
runs-on: ubuntu-latest
needs: [helm-pack]
steps:
- {uses: actions/checkout@v4, with: {ref: gh-pages}}
- uses: azure/setup-helm@v4
- uses: actions/download-artifact@v4
with: {name: helm-chart, path: ./helm-charts}
- name: Update the index.yaml
run: |
helm repo index \
--url https://${{ github.actor }}.github.io/${{ github.event.repository.name }}/helm-charts/ \
--merge \
./helm-charts/index.yaml \
./helm-charts
- uses: yKicchan/generate-directory-listing-action@v1
with: {target: ., ignore: "**/index.html", override: true}
- name: Commit and push the changes
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git add .
git commit -m "Helm chart release"
git push origin gh-pages

deploy-on-render:
name: Deploy on Render
runs-on: ubuntu-latest
Expand Down
38 changes: 11 additions & 27 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ jobs:
- {uses: actions/checkout@v4, with: {fetch-depth: 0}}
- uses: gacts/gitleaks@v1

lint-charts:
name: Lint the chart
runs-on: ubuntu-latest
defaults: {run: {working-directory: ./deployments/helm}}
steps:
- uses: actions/checkout@v4
- uses: azure/setup-helm@v4
- run: helm dependency update .
- run: helm template . > /dev/null
- run: helm lint --strict .

lint-and-test-backend:
name: Test and lint the backend
runs-on: ubuntu-latest
Expand Down Expand Up @@ -95,33 +106,6 @@ jobs:
if-no-files-found: error
retention-days: 7

build-deb-package:
name: Build the Debian package
runs-on: ubuntu-latest
strategy: {matrix: {arch: [amd64, arm64]}}
needs: [build-app]
steps:
- {uses: gacts/github-slug@v1, id: slug}
- {uses: actions/download-artifact@v4, with: {name: "webhook-tester-linux-${{ matrix.arch }}"}}
- id: values
run: |
majorMinorPatch="${{ steps.slug.outputs.version-major }}.${{ steps.slug.outputs.version-minor }}.${{ steps.slug.outputs.version-patch }}"
echo "version=${majorMinorPatch}" >> $GITHUB_OUTPUT
echo "pkg-name=webhook-tester_${majorMinorPatch}-1_${{ matrix.arch }}" >> $GITHUB_OUTPUT
- run: |
mkdir -p ./${{ steps.values.outputs.pkg-name }}/usr/local/bin ./${{ steps.values.outputs.pkg-name }}/DEBIAN
mv ./webhook-tester-linux-${{ matrix.arch }} ./${{ steps.values.outputs.pkg-name }}/usr/local/bin/webhook-tester
echo -e "Package: webhook-tester\nVersion: ${{ steps.values.outputs.version }}" > ./${{ steps.values.outputs.pkg-name }}/DEBIAN/control
echo -e "Architecture: ${{ matrix.arch }}\nMaintainer: ${{ github.actor }}" >> ./${{ steps.values.outputs.pkg-name }}/DEBIAN/control
echo -e "Description: Powerful tool for testing WebHooks and more" >> ./${{ steps.values.outputs.pkg-name }}/DEBIAN/control
dpkg-deb --build --root-owner-group ${{ steps.values.outputs.pkg-name }}
- uses: actions/upload-artifact@v4
with:
name: ${{ steps.values.outputs.pkg-name }}.deb
path: ./${{ steps.values.outputs.pkg-name }}.deb
if-no-files-found: error
retention-days: 7

e2e-test:
name: End-to-end tests
runs-on: ubuntu-latest
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ You'll never miss a request!

## ⁉ FAQ

**Can I have pre-defined (static) webhook URLs (sessions) to ensure that the sent request will be captured even
**Can I have pre-defined (static) webhook URLs (sessions) to ensure that the sent request will be captured even
without data persistence?**

Yes, simply use the `--auto-create-sessions` flag or set the `AUTO_CREATE_SESSIONS=true` environment variable. In
`v1`, you needed to define sessions during app startup to enable this functionality. However, since `v2`, all you
need to do is enable this feature. It works quite simply - if the incoming request contains a UUID-formatted prefix
(e.g., `http://app/11111111-2222-3333-4444-555555555555/...`), a session for this request will be created
automatically. All that's left for you to do is open the session in the UI
Yes, simply use the `--auto-create-sessions` flag or set the `AUTO_CREATE_SESSIONS=true` environment variable. In
`v1`, you needed to define sessions during app startup to enable this functionality. However, since `v2`, all you
need to do is enable this feature. It works quite simply - if the incoming request contains a UUID-formatted prefix
(e.g., `http://app/11111111-2222-3333-4444-555555555555/...`), a session for this request will be created
automatically. All that's left for you to do is open the session in the UI
(`http://app/s/11111111-2222-3333-4444-555555555555`).

## 🧩 Installation
Expand Down Expand Up @@ -112,6 +112,10 @@ Alternatively, you can use the Docker image:
> It’s recommended to avoid using the `latest` tag, as **major** upgrades may include breaking changes.
> Instead, use specific tags in `X.Y.Z` format for version consistency.

To install it on Kubernetes (K8s), please use the Helm chart from [ArtifactHUB][artifact-hub].

[artifact-hub]:https://artifacthub.io/packages/helm/webhook-tester/webhook-tester

## ⚙ Usage

The easiest way to run the app is by using the Docker image:
Expand Down
13 changes: 13 additions & 0 deletions deployments/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# yaml-language-server: $schema=https://json.schemastore.org/chart.json

apiVersion: v2
name: webhook-tester
description: Powerful tool for testing WebHooks and more

type: application
version: 0.0.0 # will be replaced by the release workflow
appVersion: 0.0.0 # will be replaced by the release workflow
icon: https://github.com/user-attachments/assets/e2e659dc-7fb1-4ac2-ad3c-883899f5fc38
home: https://github.com/tarampampam/webhook-tester
sources: [https://github.com/tarampampam/webhook-tester]
keywords: [webhook, tester, http, webhooks, testing, tool]
33 changes: 33 additions & 0 deletions deployments/helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# WebHook Tester

Important note: Since the chart is released together with the app under the same version (i.e., the chart version
matches the app version), its versioning is not compatible with semantic versioning (SemVer). I will do my best to
avoid non-backward-compatible changes in the chart, but due to Murphy's Law, I cannot guarantee that they will
never occur.

## Usage

```shell
helm repo add webhook-tester https://tarampampam.github.io/webhook-tester/helm-charts
helm repo update

helm install my-webhook-tester webhook-tester/webhook-tester --version <version_here>
```

Alternatively, add the following lines to your `Chart.yaml`:

```yaml
dependencies:
- name: webhook-tester
version: <version_here>
repository: https://tarampampam.github.io/webhook-tester/helm-charts
```

And override the default values in your `values.yaml`:

```yaml
webhook-tester:
# ...
service: {port: 8800}
# ...
```
52 changes: 52 additions & 0 deletions deployments/helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{{/* Define namespace of chart, useful for multi-namespace deployments */}}
{{- define "webhook-tester.namespace" -}}
{{- if .Values.namespaceOverride }}
{{- .Values.namespaceOverride }}
{{- else }}
{{- .Release.Namespace }}
{{- end }}
{{- end }}

{{/* Expand the name of the chart */}}
{{- define "webhook-tester.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "webhook-tester.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/* Create chart name and version as used by the chart label */}}
{{- define "webhook-tester.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/* Common labels */}}
{{- define "webhook-tester.commonLabels" -}}
helm.sh/chart: {{ include "webhook-tester.chart" . }}
{{ include "webhook-tester.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/* Selector labels */}}
{{- define "webhook-tester.selectorLabels" -}}
app.kubernetes.io/name: {{ include "webhook-tester.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
155 changes: 155 additions & 0 deletions deployments/helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{{- if .Values.deployment.enabled }}
apiVersion: apps/v1
kind: Deployment

metadata:
name: {{ include "webhook-tester.fullname" . }}
namespace: {{ template "webhook-tester.namespace" . }}
labels:
{{- include "webhook-tester.commonLabels" . | nindent 4 }}

spec:
{{- with .Values.deployment }}
replicas: {{ .replicas | default 1 }}
selector:
matchLabels:
{{- include "webhook-tester.selectorLabels" $ | nindent 6 }}
template:
metadata:
{{- with .podAnnotations }}
annotations:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
labels:
{{- include "webhook-tester.commonLabels" $ | nindent 8 }}
{{- with .labels }}
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
spec:
automountServiceAccountToken: false
{{- with .imagePullSecrets }}
imagePullSecrets:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
containers:
- name: {{ include "webhook-tester.fullname" $ }}

{{- with .securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}

{{- with $.Values.image }}
image: "{{ .repository }}:{{ .tag | default $.Chart.AppVersion }}"
imagePullPolicy: {{ .pullPolicy | default "IfNotPresent" }}
{{- end }}
ports:
- name: http
containerPort: {{ $.Values.config.listen.port }}
protocol: TCP
env:
{{- with $.Values.config }}
- {name: HTTP_PORT, value: "{{ .listen.port }}"}
{{- if .log.level }}
- {name: LOG_LEVEL, value: "{{ .log.level }}"}
{{- end }}
{{- if .log.format }}
- {name: LOG_FORMAT, value: "{{ .log.format }}"}
{{- end }}
{{- if .listen.address }}
- {name: SERVER_ADDR, value: "{{ .listen.address }}"}
{{- end }}
{{- if ne .timeouts.read nil }}
- {name: HTTP_READ_TIMEOUT, value: "{{ .timeouts.read }}"}
{{- end }}
{{- if ne .timeouts.write nil }}
- {name: HTTP_WRITE_TIMEOUT, value: "{{ .timeouts.write }}"}
{{- end }}
{{- if ne .timeouts.idle nil }}
- {name: HTTP_IDLE_TIMEOUT, value: "{{ .timeouts.idle }}"}
{{- end }}
{{- if ne .timeouts.shutdown nil }}
- {name: SHUTDOWN_TIMEOUT, value: "{{ .timeouts.shutdown }}"}
{{- end }}
{{- if .storage.driver }}
- {name: STORAGE_DRIVER, value: "{{ .storage.driver }}"}
{{- end }}
{{- if .storage.dirPath }}
- {name: FS_STORAGE_DIR, value: "{{ .storage.dirPath }}"}
{{- end }}
{{- if .pubsub.driver }}
- {name: PUBSUB_DRIVER, value: "{{ .pubsub.driver }}"}
{{- end }}
{{- if .tunnel.driver }}
- {name: TUNNEL_DRIVER, value: "{{ .tunnel.driver }}"}
{{- end }}
{{- if .tunnel.ngrokAuthToken }}
- {name: NGROK_AUTHTOKEN, value: "{{ .tunnel.ngrokAuthToken }}"}
{{- end }}
{{- if .redis.dsn }}
- {name: REDIS_DSN, value: "{{ .redis.dsn }}"}
{{- end }}
{{- if ne .limits.sessionTTL nil }}
- {name: SESSION_TTL, value: "{{ .limits.sessionTTL }}"}
{{- end }}
{{- if ne .limits.maxRequests nil }}
- {name: MAX_REQUESTS, value: "{{ .limits.maxRequests }}"}
{{- end }}
{{- if ne .limits.maxRequestBodySize nil }}
- {name: MAX_REQUEST_BODY_SIZE, value: "{{ .limits.maxRequestBodySize }}"}
{{- end }}
{{- if .autoCreateSessions }}
- {name: AUTO_CREATE_SESSIONS, value: "true"}
{{- end }}
{{- with $.Values.deployment.env }}
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- end }}

{{- with .args }}
args:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}

{{- with .probe }}
livenessProbe:
httpGet: {port: http, path: /healthz}
periodSeconds: {{ .interval }}
initialDelaySeconds: {{ .initialDelay }}
readinessProbe:
httpGet: {port: http, path: /ready}
periodSeconds: {{ .interval }}
initialDelaySeconds: {{ .initialDelay }}
{{- end }}

{{- with .resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}

{{- with .volumeMounts }}
volumeMounts:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}

{{- with .volumes }}
volumes:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}

{{- with .nodeSelector }}
nodeSelector:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}

{{- with .affinity }}
affinity:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}

{{- with .tolerations }}
tolerations:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
Loading