34 Commits

Author SHA1 Message Date
0416653d69 Merge pull request #7 from jimeh/release-please--branches--main 2022-11-14 19:05:34 +00:00
github-actions[bot]
c802f2848d chore(main): release 2.0.0 2022-11-14 19:03:10 +00:00
a3c4a5e63c Merge pull request #8 from jimeh/remove-external-deps 2022-11-14 19:02:20 +00:00
623d2c21b0 feat(env): support BIND environment variable 2022-11-14 19:01:32 +00:00
9a904fee99 feat!: remove external dependencies
Remove the kingpin external dependency, and instead just use Go's stdlib
flag package.

BREAKING CHANGE: Long versions of command line flags are no longer supported.
2022-11-14 19:01:31 +00:00
2e7557a9aa ci(release): fix job dependencies 2022-11-14 18:37:48 +00:00
adcbb38c6c Merge pull request #6 from jimeh/add-helm-chart 2022-11-14 18:35:43 +00:00
4e36d51dc1 feat(chart): add kubernetes helm chart 2022-11-14 18:33:50 +00:00
99567edfc4 ci(release): remove bootstramp release-please config values 2022-11-14 17:38:58 +00:00
e0eef21fd2 Merge pull request #5 from jimeh/release-please--branches--main 2022-11-14 17:20:54 +00:00
github-actions[bot]
bbca419be6 chore(main): release 1.5.0 2022-11-14 17:18:47 +00:00
f944c6e7e8 chore(changelog): remove note about standard-version
We're using release-please instead now.
2022-11-14 17:13:22 +00:00
6603db3e69 ci: rename "release" job to "release-please" 2022-11-14 17:11:47 +00:00
1edbd2a7af chore: remove VERSION file 2022-11-14 17:11:36 +00:00
75ddccedf3 feat(deps): upgrade to Go 1.19 2022-11-14 17:05:23 +00:00
8791b80ff6 ci(release): really fix release job, hopefully for real this time :P 2022-11-14 17:01:27 +00:00
e53f79024b ci(release): actually fix release job (hopefully) 2022-11-14 16:58:29 +00:00
3813304041 ci(release): fix issues with release-please config 2022-11-14 16:54:40 +00:00
7863eddb09 Merge pull request #4 from jimeh/release-please/bootstrap/default 2022-11-14 16:50:28 +00:00
8ccc38c186 ci: update release job to use please-release 2022-11-14 16:49:24 +00:00
84da611833 chore: bootstrap releases for path: . 2022-11-14 15:14:21 +00:00
7a152b06b2 chore: fix hard-coded version in VERSION file 2022-11-14 15:10:53 +00:00
b7f4d11fc9 chore(release): 1.4.0 2022-05-24 17:40:24 +01:00
cdaaec6b0b feat: compare on GET requests with non-empty query string
Also add a /about page so there's a non-root page that does not return
404.
2022-05-24 17:39:12 +01:00
51717ebcd1 chore(ci): fix release job 2022-05-24 17:38:49 +01:00
7df597a842 chore(go): upgrade to Go 1.18 2022-05-24 17:38:24 +01:00
732c588dbc chore(release): 1.3.0 2022-02-13 04:13:41 +00:00
1816e93170 feat(release): setup for publishing docker images to ghcr 2022-02-13 04:11:29 +00:00
29902b2e8e chore(release): 1.2.3 2021-04-14 20:43:46 +01:00
36e0863cc3 fix(release): add missing GITHUB_TOKEN env var 2021-04-14 20:43:18 +01:00
5471ff95a7 chore(release): 1.2.2 2021-04-14 20:39:57 +01:00
4c89c92f75 build(release): tweak goreleaser config 2021-04-14 20:38:46 +01:00
d19eed020c Merge pull request #3 from jimeh/github-actions
ci(github): switch from CircleCI to GitHub Actions
2021-04-14 20:34:57 +01:00
aef3e832f5 ci(github): switch from CircleCI to GitHub Actions 2021-04-14 20:32:50 +01:00
23 changed files with 691 additions and 156 deletions

View File

@@ -1,57 +0,0 @@
version: 2
jobs:
build:
docker:
- image: circleci/golang:1.16
working_directory: /go/src/github.com/jimeh/casecmp
steps:
- checkout
- run:
name: Install dependencies
command: go mod download
- run:
name: Build binary
command: make
- run:
name: Start service
command: ./bin/casecmp --port=8080
background: true
- run:
name: Validate service is working
command: |
curl --retry 10 --retry-delay 1 --retry-connrefused \
http://localhost:8080/
release:
docker:
- image: circleci/golang:1.16
working_directory: /go/src/github.com/jimeh/casecmp
steps:
- checkout
- run: curl -sL https://git.io/goreleaser | bash
workflows:
version: 2
build:
jobs:
- build:
filters:
branches:
only: /.*/
tags:
ignore: /^v[0-9]+(\.[0-9]+)*/
build-and-release:
jobs:
- build:
filters:
branches:
ignore: /.*/
tags:
only: /^v[0-9]+(\.[0-9]+)*/
- release:
requires:
- build
filters:
branches:
ignore: /.*/
tags:
only: /^v[0-9]+(\.[0-9]+)*/

72
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,72 @@
---
name: CI
on: [push]
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.19
- name: Install dependencies
run: go mod download
- name: Build binary
run: make
- name: Run and make request
run: |
./bin/casecmp -p 8080 &
curl --silent --retry 10 --retry-delay 1 --retry-connrefused \
http://localhost:8080/
helm-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/setup-helm@v3
with:
token: "${{ secrets.GITHUB_TOKEN }}"
- name: Lint chart
run: helm lint chart
- name: Template chart
run: helm template chart
release-please:
runs-on: ubuntu-latest
needs: [build, helm-lint]
if: github.ref == 'refs/heads/main'
steps:
- uses: google-github-actions/release-please-action@v3
id: release-please
with:
command: manifest
- if: ${{ steps.release-please.outputs.release_created }}
uses: actions/checkout@v3
with:
fetch-depth: 0
- if: ${{ steps.release-please.outputs.release_created }}
name: Set up QEMU
uses: docker/setup-qemu-action@v2
- if: ${{ steps.release-please.outputs.release_created }}
uses: docker/setup-buildx-action@v2
- if: ${{ steps.release-please.outputs.release_created }}
name: Docker Login
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- if: ${{ steps.release-please.outputs.release_created }}
uses: actions/setup-go@v3
with:
go-version: 1.19
- if: ${{ steps.release-please.outputs.release_created }}
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -10,17 +10,18 @@ builds:
ldflags:
- "-s -w -X main.version={{ .Version }} -X main.commit={{ .Commit }}"
goos:
- darwin
- freebsd
- linux
- windows
- "darwin"
- "freebsd"
- "linux"
- "windows"
goarch:
- amd64
- 386
- arm
- "amd64"
- "386"
- "arm"
- "arm64"
goarm:
- 6
- 7
- "6"
- "7"
archives:
- format: tar.gz
@@ -30,20 +31,76 @@ archives:
format_overrides:
- goos: windows
format: zip
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: "checksums.txt"
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
skip: true
dockers:
- image_templates:
- "ghcr.io/jimeh/casecmp:{{ .Version }}-amd64"
- "ghcr.io/jimeh/casecmp:latest-amd64"
dockerfile: Dockerfile
use: buildx
goos: linux
goarch: amd64
build_flag_templates:
- "--platform=linux/amd64"
- image_templates:
- "ghcr.io/jimeh/casecmp:{{ .Version }}-386"
- "ghcr.io/jimeh/casecmp:latest-386"
dockerfile: Dockerfile
use: buildx
goos: linux
goarch: "386"
build_flag_templates:
- "--platform=linux/386"
- image_templates:
- "ghcr.io/jimeh/casecmp:{{ .Version }}-arm64"
- "ghcr.io/jimeh/casecmp:latest-arm64"
use: buildx
goos: linux
goarch: arm64
dockerfile: Dockerfile
build_flag_templates:
- "--platform=linux/arm64"
- image_templates:
- "ghcr.io/jimeh/casecmp:{{ .Version }}-armv6"
- "ghcr.io/jimeh/casecmp:latest-armv6"
use: buildx
goos: linux
goarch: arm
goarm: "6"
dockerfile: Dockerfile
build_flag_templates:
- "--platform=linux/arm/v6"
- image_templates:
- "ghcr.io/jimeh/casecmp:{{ .Version }}-armv7"
- "ghcr.io/jimeh/casecmp:latest-armv7"
use: buildx
goos: linux
goarch: arm
goarm: "7"
dockerfile: Dockerfile
build_flag_templates:
- "--platform=linux/arm/v7"
docker_manifests:
- name_template: ghcr.io/jimeh/casecmp:{{ .Version }}
image_templates:
- ghcr.io/jimeh/casecmp:{{ .Version }}-amd64
- ghcr.io/jimeh/casecmp:{{ .Version }}-386
- ghcr.io/jimeh/casecmp:{{ .Version }}-arm64
- ghcr.io/jimeh/casecmp:{{ .Version }}-armv6
- ghcr.io/jimeh/casecmp:{{ .Version }}-armv7
- name_template: ghcr.io/jimeh/casecmp:latest
image_templates:
- ghcr.io/jimeh/casecmp:latest-amd64
- ghcr.io/jimeh/casecmp:latest-386
- ghcr.io/jimeh/casecmp:latest-arm64
- ghcr.io/jimeh/casecmp:latest-armv6
- ghcr.io/jimeh/casecmp:latest-armv7

View File

@@ -0,0 +1,3 @@
{
".": "2.0.0"
}

35
CHANGELOG.md Normal file
View File

@@ -0,0 +1,35 @@
# Changelog
## [2.0.0](https://github.com/jimeh/casecmp/compare/v1.5.0...v2.0.0) (2022-11-14)
### ⚠ BREAKING CHANGES
* Long versions of command line flags are no longer supported.
### Features
* **chart:** add kubernetes helm chart ([4e36d51](https://github.com/jimeh/casecmp/commit/4e36d51dc1c081fd50b1397eabb736ad3fe21541))
* **env:** support BIND environment variable ([623d2c2](https://github.com/jimeh/casecmp/commit/623d2c21b0a25d3b54b6cf3e18fc147a2faa8cd6))
* remove external dependencies ([9a904fe](https://github.com/jimeh/casecmp/commit/9a904fee99e203d7ddb2a84e2d056d3ed8ec197a))
## [1.5.0](https://github.com/jimeh/casecmp/compare/v1.4.0...v1.5.0) (2022-11-14)
### Features
* **deps:** upgrade to Go 1.19 ([75ddcce](https://github.com/jimeh/casecmp/commit/75ddccedf330497c0e04cd4b7f0679e647b8e190))
## [1.4.0](https://github.com/jimeh/casecmp/compare/v1.3.0...v1.4.0) (2022-05-24)
### Features
* compare on GET requests with non-empty query string ([cdaaec6](https://github.com/jimeh/casecmp/commit/cdaaec6b0b763141476562047578844e6105ec7a))
## [1.3.0](https://github.com/jimeh/casecmp/compare/v1.2.3...v1.3.0) (2022-02-13)
### Features
* **release:** setup for publishing docker images to ghcr ([1816e93](https://github.com/jimeh/casecmp/commit/1816e93170bb725f8da073b91070a981dd039fad))

View File

@@ -1,17 +1,5 @@
FROM golang:1.16-alpine as builder
RUN apk add --no-cache \
git
WORKDIR /app
COPY . /app
RUN env CGO_ENABLED=0 \
go build -a -o /casecmp -ldflags "-s -w \
-X main.version=$(cat VERSION) \
-X main.commit=$(git show --format='%h' --no-patch) \
-X main.date=$(date +%Y-%m-%dT%T%z)"
FROM scratch
COPY --from=builder /casecmp /
COPY ./casecmp /
ENV PORT 8080
EXPOSE 8080
WORKDIR /

View File

@@ -4,11 +4,10 @@ VERSION ?= $(shell cat VERSION)
SOURCES = $(shell find . -name '*.go' -o -name 'Makefile')
$(BINARY): $(SOURCES)
CGO_ENABLED=0 go build -a -o ${BINARY} -ldflags \ "\
CGO_ENABLED=0 go build -o ${BINARY} -ldflags \ "\
-s -w \
-X main.version=${VERSION} \
-X main.commit=$(shell git show --format="%h" --no-patch) \
-X main.date=$(shell date +%Y-%m-%dT%T%z)"
-X main.commit=$(shell git show --format="%h" --no-patch)"
.PHONY: build
build: $(BINARY)

View File

@@ -1 +0,0 @@
1.2.1

23
chart/.helmignore Normal file
View File

@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

24
chart/Chart.yaml Normal file
View File

@@ -0,0 +1,24 @@
apiVersion: v2
name: casecmp
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 2.0.0 # x-release-please-version
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: 2.0.0 # x-release-please-version

22
chart/templates/NOTES.txt Normal file
View File

@@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "casecmp.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "casecmp.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "casecmp.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "casecmp.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "casecmp.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 "casecmp.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 "casecmp.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "casecmp.labels" -}}
helm.sh/chart: {{ include "casecmp.chart" . }}
{{ include "casecmp.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "casecmp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "casecmp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "casecmp.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "casecmp.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,61 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "casecmp.fullname" . }}
labels:
{{- include "casecmp.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "casecmp.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "casecmp.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "casecmp.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

28
chart/templates/hpa.yaml Normal file
View File

@@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "casecmp.fullname" . }}
labels:
{{- include "casecmp.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "casecmp.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "casecmp.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "casecmp.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "casecmp.fullname" . }}
labels:
{{- include "casecmp.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "casecmp.selectorLabels" . | nindent 4 }}

View File

@@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "casecmp.serviceAccountName" . }}
labels:
{{- include "casecmp.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "casecmp.fullname" . }}-test-connection"
labels:
{{- include "casecmp.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "casecmp.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

86
chart/values.yaml Normal file
View File

@@ -0,0 +1,86 @@
# Default values for casecmp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: ghcr.io/jimeh/casecmp
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations:
{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

9
go.mod
View File

@@ -1,10 +1,3 @@
module github.com/jimeh/casecmp
go 1.16
require (
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/stretchr/testify v1.7.0 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
go 1.19

16
go.sum
View File

@@ -1,16 +0,0 @@
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

113
main.go
View File

@@ -2,34 +2,35 @@ package main
import (
"bytes"
"flag"
"fmt"
"log"
"net/http"
"os"
"strconv"
"strings"
"gopkg.in/alecthomas/kingpin.v2"
"time"
)
var (
version = "dev"
commit = "unknown"
)
const (
name = "casecmp"
version = "dev"
commit = "unknown"
date = "unknown"
defaultPort = "8080"
defaultPort = 8080
defaultBind = "0.0.0.0"
)
// Argument parsing setup.
var (
portFlag = kingpin.Flag("port", "Port to listen to.").Short('p').
Default("").String()
bindFlag = kingpin.Flag("bind", "Bind address.").Short('b').
Default("0.0.0.0").String()
forceHTTPSFlag = kingpin.Flag(
"force-https", "Use https:// in example curl commands",
).Bool()
versionFlag = kingpin.Flag("version", "Print version info.").
Short('v').Bool()
portFlag = flag.Int("p", defaultPort, "Port to listen on")
bindFlag = flag.String("b", defaultBind, "Bind address")
forceHTTPSFlag = flag.Bool(
"f", false, "Use https:// in example curl commands",
)
versionFlag = flag.Bool("v", false, "Print version info")
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
@@ -44,13 +45,26 @@ Case-insensitive string comparison, as an API. Because ¯\_(ツ)_/¯
Example usage:
curl -X POST -F "a=Foo Bar" -F "b=FOO BAR" %s://%s/
curl -X POST "%s://%s/?a=Foo+Bar&b=FOO+BAR"`,
curl -X GET "%s://%s/?a=Foo+Bar&b=FOO+BAR"
`,
name, version, scheme, r.Host, scheme, r.Host)
if err != nil {
log.Fatal(err)
}
}
func aboutHandler(w http.ResponseWriter, _ *http.Request) {
_, err := fmt.Fprintf(w,
`%s %s
https://github.com/jimeh/casecmp
`,
name, version)
if err != nil {
log.Fatal(err)
}
}
func casecmpHandler(w http.ResponseWriter, r *http.Request) {
a := r.FormValue("a")
b := r.FormValue("b")
@@ -59,22 +73,24 @@ func casecmpHandler(w http.ResponseWriter, r *http.Request) {
if strings.EqualFold(string(a), string(b)) {
resp = "1"
}
_, err := fmt.Fprintf(w, resp)
_, err := fmt.Fprint(w, resp)
if err != nil {
log.Fatal(err)
}
}
func rootHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
if r.Method == "GET" {
func handler(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/":
if r.Method != "GET" || r.URL.RawQuery != "" {
casecmpHandler(w, r)
return
}
indexHandler(w, r)
} else {
casecmpHandler(w, r)
case "/about":
aboutHandler(w, r)
default:
http.NotFound(w, r)
}
}
@@ -89,15 +105,23 @@ func printVersion() {
fmt.Println(buffer.String())
}
func startServer() {
http.HandleFunc("/", rootHandler)
if *portFlag == "" {
func startServer() error {
if *portFlag == defaultPort {
envPort := os.Getenv("PORT")
if envPort != "" {
*portFlag = envPort
} else {
*portFlag = defaultPort
v, err := strconv.Atoi(envPort)
if err != nil {
return err
}
*portFlag = v
}
}
if *bindFlag == defaultBind {
envBind := os.Getenv("BIND")
if envBind != "" {
*bindFlag = envBind
}
}
@@ -105,17 +129,30 @@ func startServer() {
*forceHTTPSFlag = true
}
address := *bindFlag + ":" + *portFlag
address := fmt.Sprintf("%s:%d", *bindFlag, *portFlag)
fmt.Printf("Listening on %s\n", address)
log.Fatal(http.ListenAndServe(address, nil))
srv := &http.Server{
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
IdleTimeout: 30 * time.Second,
Handler: http.HandlerFunc(handler),
Addr: address,
}
return srv.ListenAndServe()
}
func main() {
kingpin.Parse()
flag.Parse()
if *versionFlag {
printVersion()
} else {
startServer()
return
}
err := startServer()
if err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,16 @@
{
"release-type": "go",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"packages": {
".": {
"changelog-path": "CHANGELOG.md",
"draft": false,
"prerelease": false,
"extra-files": [
"chart/Chart.yaml"
]
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}