diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fc3d492..663d44f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,8 +16,6 @@ env: DOCKER_CACHE_BUCKET: "ci-cache" DOCKER_CACHE_REGION: "APAC" - # Helm - jobs: precommit: name: Pre-commit Check @@ -76,6 +74,28 @@ jobs: S3_REGION: ${{ env.DOCKER_CACHE_REGION }} LATEST_BRANCH: ${{ env.DOCKER_LATEST_BRANCH}} + publish: + name: Publish Helm + needs: build + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - uses: rlespinasse/github-slug-action@v3.x + + - name: Publish + env: + GITHUB_REPO_REF: ${{ github.repository }} + GITHUB_SHA: ${{ github.sha }} + GITHUB_BRANCH: ${{ env.GITHUB_REF_SLUG_URL }} + + DOMAIN: ${{ env.DOCKER_DOMAIN }} + + DOCKER_PASSWORD: ${{ env.DOCKER_PASSWORD }} + DOCKER_USER: ${{ env.DOCKER_USER }} + + run: nix develop .#ci -c scripts/ci/publish-helm.sh release: name: Semantic Release diff --git a/.gitignore b/.gitignore index ab3f512..1104a42 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ .task .pre-commit-config.yaml +debug.yaml + .DS_Store node_modules /build diff --git a/Taskfile.helm.yml b/Taskfile.helm.yml new file mode 100644 index 0000000..f90ef6c --- /dev/null +++ b/Taskfile.helm.yml @@ -0,0 +1,48 @@ +version: "3" + +includes: + lapras: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".lapras" + tauros: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".tauros" + pinsir: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".pinsir" + absol: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".absol" + raichu: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".raichu" + pichu: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".pichu" + pikachu: + taskfile: tasks/Taskfile.helm.yml + vars: + LANDSCAPE: ".pikachu" + +tasks: + latest: + desc: Get latest helm chart dependency versions + cmds: + - >- + echo "sulfoxide-bromine: $(skopeo list-tags docker://ghcr.io/atomicloud/sulfoxide.bromine/sulfoxide-bromine + | jq -r '.Tags[]' | sort -V | tail -n 1)" + - >- + echo "postgresql: $(skopeo list-tags docker://registry-1.docker.io/bitnamicharts/postgresql + | jq -r '.Tags[]' | sort -V | tail -n 1)" + - >- + echo "minio: $(skopeo list-tags docker://registry-1.docker.io/bitnamicharts/minio + | jq -r '.Tags[]' | sort -V | tail -n 1)" + - >- + echo "dragonfly: $(skopeo list-tags docker://ghcr.io/dragonflydb/dragonfly/helm/dragonfly + | jq -r '.Tags[]' | sort -V | tail -n 1)" diff --git a/Taskfile.yaml b/Taskfile.yaml index d8eeb0b..1cfa5fd 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -4,8 +4,12 @@ vars: SERVICE: helium USER: kirinnee/ + CHART_PATH: infra/root_chart + RELEASE_NAME: nitroso-helium + includes: docker: tasks/Taskfile.docker.yaml + helm: Taskfile.helm.yml tasks: setup: diff --git a/atomi_release.yaml b/atomi_release.yaml index 1055e5a..1e7635f 100644 --- a/atomi_release.yaml +++ b/atomi_release.yaml @@ -34,6 +34,9 @@ plugins: - module: "@semantic-release/exec" config: prepareCmd: scripts/ci/publish.sh ${nextRelease.version} + - module: "@semantic-release/exec" + config: + prepareCmd: scripts/ci/publish-helm.sh ${nextRelease.version} - module: "@semantic-release/github" # Angular Conventional Commit Example: https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines diff --git a/config/app/pichu.config.yaml b/config/app/pichu.config.yaml new file mode 100644 index 0000000..44542a7 --- /dev/null +++ b/config/app/pichu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: pichu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/config/app/pikachu.config.yaml b/config/app/pikachu.config.yaml new file mode 100644 index 0000000..d5e5dad --- /dev/null +++ b/config/app/pikachu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: pikachu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/config/app/raichu.config.yaml b/config/app/raichu.config.yaml new file mode 100644 index 0000000..bbb99e1 --- /dev/null +++ b/config/app/raichu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: raichu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/infra/root_chart/.helmignore b/infra/root_chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/infra/root_chart/.helmignore @@ -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/ diff --git a/infra/root_chart/Chart.lock b/infra/root_chart/Chart.lock new file mode 100644 index 0000000..9e84aca --- /dev/null +++ b/infra/root_chart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: sulfoxide-bromine + repository: oci://ghcr.io/atomicloud/sulfoxide.bromine + version: 1.3.0 +digest: sha256:87f9a17135d9751b34e6a250be4165aa0cc36d15390f9efef5d657fc777f9bc6 +generated: "2023-12-13T23:06:50.21722+08:00" diff --git a/infra/root_chart/Chart.yaml b/infra/root_chart/Chart.yaml new file mode 100644 index 0000000..abc2e39 --- /dev/null +++ b/infra/root_chart/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v2 +name: root-chart +description: Root Chart to a single Service + +type: application +version: 0.1.0 +appVersion: "1.16.0" + +dependencies: + - name: sulfoxide-bromine + version: 1.3.0 + condition: bromine.enable + alias: bromine + repository: oci://ghcr.io/atomicloud/sulfoxide.bromine diff --git a/infra/root_chart/README.md b/infra/root_chart/README.md new file mode 100644 index 0000000..d9cde42 --- /dev/null +++ b/infra/root_chart/README.md @@ -0,0 +1,31 @@ +# root-chart + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square) + +Root Chart to a single Service + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| oci://ghcr.io/atomicloud/sulfoxide.bromine | bromine(sulfoxide-bromine) | 1.3.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| appSettings | object | `{}` | | +| bromine.annotations."argocd.argoproj.io/sync-wave" | string | `"1"` | | +| bromine.enable | bool | `true` | | +| bromine.rootSecret | object | `{"ref":"NITROSO_HELIUM"}` | Secret of Secrets reference | +| bromine.rootSecret.ref | string | `"NITROSO_HELIUM"` | DOPPLER Token Reference | +| bromine.storeName | string | `"nitroso-helium"` | Store name to create | +| bromine.target | string | `"nitroso-helium"` | | +| serviceTree.landscape | string | `"lapras"` | | +| serviceTree.layer | string | `"2"` | | +| serviceTree.module | string | `"pollee"` | | +| serviceTree.platform | string | `"nitroso"` | | +| serviceTree.service | string | `"helium"` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.11.2](https://github.com/norwoodj/helm-docs/releases/v1.11.2) diff --git a/infra/root_chart/app/config.yaml b/infra/root_chart/app/config.yaml new file mode 100644 index 0000000..0e3cc20 --- /dev/null +++ b/infra/root_chart/app/config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: lapras + platform: nitroso + service: helium + module: pollee +caches: + live: + autoResubscribe: true + commandTimeout: 3000 + connectTimeout: 3000 + enableAutoPipelining: true + endpoints: + 0: tin-livecache:6379 + keyPrefix: "" + password: supersecret + readOnly: false + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: none + trace: + exporter: + use: none diff --git a/infra/root_chart/app/lapras.config.yaml b/infra/root_chart/app/lapras.config.yaml new file mode 100644 index 0000000..c20d167 --- /dev/null +++ b/infra/root_chart/app/lapras.config.yaml @@ -0,0 +1,17 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: lapras +caches: + live: + endpoints: + 0: localhost:6379 + password: supersecret + tls: false +otel: + logging: + enabled: true + level: info + prettify: true + safe: true diff --git a/infra/root_chart/app/pichu.config.yaml b/infra/root_chart/app/pichu.config.yaml new file mode 100644 index 0000000..44542a7 --- /dev/null +++ b/infra/root_chart/app/pichu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: pichu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/infra/root_chart/app/pikachu.config.yaml b/infra/root_chart/app/pikachu.config.yaml new file mode 100644 index 0000000..d5e5dad --- /dev/null +++ b/infra/root_chart/app/pikachu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: pikachu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/infra/root_chart/app/raichu.config.yaml b/infra/root_chart/app/raichu.config.yaml new file mode 100644 index 0000000..bbb99e1 --- /dev/null +++ b/infra/root_chart/app/raichu.config.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=./schema.json +$schema: ./schema.json + +app: + landscape: raichu +caches: + live: + endpoints: + 0: tin-livecache:6379 + tls: false +otel: + logging: + enabled: true + level: info + prettify: false + safe: true + metrics: + exporter: + interval: 1000 + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" + trace: + exporter: + use: otlp + otlp: + compression: gzip + headers: {} + timeout: 3000 + url: "http://silicon-otlp-collector.sulfoxide.svc:4318" diff --git a/infra/root_chart/app/schema.json b/infra/root_chart/app/schema.json new file mode 100644 index 0000000..34cea83 --- /dev/null +++ b/infra/root_chart/app/schema.json @@ -0,0 +1,191 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AppConfig": { + "properties": { + "landscape": { + "type": "string" + }, + "module": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "service": { + "type": "string" + } + }, + "type": "object" + }, + "CacheConfig": { + "properties": { + "autoResubscribe": { + "type": "boolean" + }, + "commandTimeout": { + "type": "number" + }, + "connectTimeout": { + "type": "number" + }, + "enableAutoPipelining": { + "type": "boolean" + }, + "endpoints": { + "additionalProperties": false, + "patternProperties": { + "^[0-9]+$": { + "type": "string" + } + }, + "type": "object" + }, + "keyPrefix": { + "type": "string" + }, + "password": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "tls": { + "type": "boolean" + } + }, + "type": "object" + }, + "ExporterConfig": { + "properties": { + "interval": { + "type": "number" + }, + "otlp": { + "$ref": "#/definitions/OtlpConfig" + }, + "use": { + "enum": ["console", "none", "otlp"], + "type": "string" + } + }, + "type": "object" + }, + "ExporterConfig_1": { + "properties": { + "otlp": { + "$ref": "#/definitions/OtlpConfig_1" + }, + "use": { + "enum": ["console", "none", "otlp"], + "type": "string" + } + }, + "type": "object" + }, + "LoggingConfig": { + "properties": { + "enabled": { + "type": "boolean" + }, + "level": { + "type": "string" + }, + "prettify": { + "type": "boolean" + }, + "safe": { + "type": "boolean" + } + }, + "type": "object" + }, + "MetricsConfig": { + "properties": { + "exporter": { + "$ref": "#/definitions/ExporterConfig" + } + }, + "type": "object" + }, + "OtelConfig": { + "properties": { + "logging": { + "$ref": "#/definitions/LoggingConfig" + }, + "metrics": { + "$ref": "#/definitions/MetricsConfig" + }, + "trace": { + "$ref": "#/definitions/TraceConfig" + } + }, + "type": "object" + }, + "OtlpConfig": { + "properties": { + "compression": { + "enum": ["gzip", "none"], + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "OtlpConfig_1": { + "properties": { + "compression": { + "enum": ["gzip", "none"], + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "TraceConfig": { + "properties": { + "exporter": { + "$ref": "#/definitions/ExporterConfig_1" + } + }, + "type": "object" + } + }, + "properties": { + "app": { + "$ref": "#/definitions/AppConfig" + }, + "caches": { + "additionalProperties": { + "$ref": "#/definitions/CacheConfig" + }, + "type": "object" + }, + "otel": { + "$ref": "#/definitions/OtelConfig" + } + }, + "type": "object" +} diff --git a/infra/root_chart/templates/_helpers.tpl b/infra/root_chart/templates/_helpers.tpl new file mode 100644 index 0000000..68d0a8d --- /dev/null +++ b/infra/root_chart/templates/_helpers.tpl @@ -0,0 +1,86 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "root-chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +allows triming of names +*/}} +{{- define "root-chart.fullname-with-suffix" -}} +{{ $fname := (include "root-chart.fullname" .root) }} +{{- printf "%s-%s" $fname .arg | 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 "root-chart.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 "root-chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "root-chart.labels" -}} +{{ include "root-chart.selectorLabels" . }} +{{- range $k, $v := .Values.serviceTree }} +"atomi.cloud/{{ $k }}": "{{ $v }}" +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Common annotations +*/}} +{{- define "root-chart.annotations" -}} +helm.sh/chart: {{ include "root-chart.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +atomi.cloud/chart: {{ include "root-chart.chart" . }} +{{- range $k, $v := .Values.serviceTree }} +"atomi.cloud/{{ $k }}": "{{ $v }}" +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "root-chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "root-chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- range $k, $v := .Values.atomiLabels }} +"atomi.cloud/{{ $k }}": "{{ $v }}" +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "root-chart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "root-chart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/infra/root_chart/templates/configmap.yaml b/infra/root_chart/templates/configmap.yaml new file mode 100644 index 0000000..0e4ccf0 --- /dev/null +++ b/infra/root_chart/templates/configmap.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "root-chart.fullname-with-suffix" (dict "arg" "config" "root" .) }} + labels: {{- include "root-chart.labels" . | nindent 4 }} + annotations: {{- include "root-chart.annotations" . | nindent 4 }} +data: + {{ .Values.serviceTree.landscape }}.config.yaml: | + {{- $path := printf "%s%s.config.yaml" "app/" .Values.serviceTree.landscape -}} + {{- $fileContent := .Files.Get $path -}} + {{- $config := fromYaml $fileContent -}} + {{- $final := deepCopy $config | merge (deepCopy .Values.appSettings) -}} + {{- toYaml $final | nindent 4 }} diff --git a/infra/root_chart/templates/externalsecret.yaml b/infra/root_chart/templates/externalsecret.yaml new file mode 100644 index 0000000..27c5df6 --- /dev/null +++ b/infra/root_chart/templates/externalsecret.yaml @@ -0,0 +1,21 @@ +{{- if .Values.bromine.enable }} +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: {{ template "root-chart.fullname-with-suffix" (dict "arg" .Values.bromine.target "root" .) }} + labels: {{- include "root-chart.labels" . | nindent 4 }} + annotations: {{- include "root-chart.annotations" . | nindent 4 }} + argocd.argoproj.io/sync-wave: "2" +spec: + secretStoreRef: + kind: SecretStore + name: {{ .Values.bromine.storeName }} + + target: + name: {{ .Values.bromine.target }} + + dataFrom: + - find: + name: + regexp: .* +{{- end }} diff --git a/infra/root_chart/values.lapras.yaml b/infra/root_chart/values.lapras.yaml new file mode 100644 index 0000000..24f4a97 --- /dev/null +++ b/infra/root_chart/values.lapras.yaml @@ -0,0 +1,5 @@ +serviceTree: + landscape: &landscape lapras + +bromine: + enable: true diff --git a/infra/root_chart/values.pichu.yaml b/infra/root_chart/values.pichu.yaml new file mode 100644 index 0000000..e976a17 --- /dev/null +++ b/infra/root_chart/values.pichu.yaml @@ -0,0 +1,5 @@ +serviceTree: + landscape: &landscape pichu + +bromine: + enable: true diff --git a/infra/root_chart/values.pikachu.yaml b/infra/root_chart/values.pikachu.yaml new file mode 100644 index 0000000..12d11e7 --- /dev/null +++ b/infra/root_chart/values.pikachu.yaml @@ -0,0 +1,5 @@ +serviceTree: + landscape: &landscape pikachu + +bromine: + enable: true diff --git a/infra/root_chart/values.raichu.yaml b/infra/root_chart/values.raichu.yaml new file mode 100644 index 0000000..c594c89 --- /dev/null +++ b/infra/root_chart/values.raichu.yaml @@ -0,0 +1,5 @@ +serviceTree: + landscape: &landscape raichu + +bromine: + enable: true diff --git a/infra/root_chart/values.tauros.yaml b/infra/root_chart/values.tauros.yaml new file mode 100644 index 0000000..d751285 --- /dev/null +++ b/infra/root_chart/values.tauros.yaml @@ -0,0 +1,4 @@ +serviceTree: + landscape: &landscape tauros +bromine: + enable: true diff --git a/infra/root_chart/values.yaml b/infra/root_chart/values.yaml new file mode 100644 index 0000000..8782ec8 --- /dev/null +++ b/infra/root_chart/values.yaml @@ -0,0 +1,21 @@ +serviceTree: &serviceTree + landscape: lapras + platform: nitroso + service: helium + module: pollee + layer: "2" + +bromine: + annotations: + argocd.argoproj.io/sync-wave: "1" + enable: true + # -- Store name to create + storeName: nitroso-helium + # -- Secret of Secrets reference + rootSecret: + # -- DOPPLER Token Reference + ref: "NITROSO_HELIUM" + + target: &target "nitroso-helium" + +appSettings: {} diff --git a/nix/env.nix b/nix/env.nix index 10d14ac..c4c1ff0 100644 --- a/nix/env.nix +++ b/nix/env.nix @@ -16,6 +16,9 @@ with packages; ]; infra = [ + helm + kubectl + docker ]; main = [ diff --git a/nix/packages.nix b/nix/packages.nix index bd5e9cb..ec5ba08 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -26,6 +26,7 @@ let { nodejs = nodejs_18; npm = nodePackages.npm; + helm = kubernetes-helm; inherit coreutils yq-go @@ -35,6 +36,9 @@ let jq findutils hadolint + helm-docs + kubectl + docker git diff --git a/nix/pre-commit.nix b/nix/pre-commit.nix index f43c46b..0bd62c8 100644 --- a/nix/pre-commit.nix +++ b/nix/pre-commit.nix @@ -75,6 +75,25 @@ pre-commit-lib.run { language = "system"; pass_filenames = true; }; + + a-config-sync = { + enable = true; + name = "Sync configurations to helm charts"; + entry = "${packages.bash}/bin/bash scripts/local/config-sync.sh"; + files = "config/app/.*\\.yaml"; + language = "system"; + pass_filenames = false; + }; + + a-helm-docs = { + enable = true; + name = "Helm Docs"; + entry = "${packages.helm-docs}/bin/helm-docs"; + files = ".*"; + language = "system"; + pass_filenames = false; + }; + }; settings = { diff --git a/scripts/ci/publish-helm.sh b/scripts/ci/publish-helm.sh new file mode 100755 index 0000000..ac08da7 --- /dev/null +++ b/scripts/ci/publish-helm.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +[ "${DOMAIN}" = '' ] && echo "❌ 'DOMAIN' env var not set" && exit 1 + +[ "${DOCKER_PASSWORD}" = '' ] && echo "❌ 'DOCKER_PASSWORD' env var not set" && exit 1 +[ "${DOCKER_USER}" = '' ] && echo "❌ 'DOCKER_USER' env var not set" && exit 1 + +[ "${GITHUB_SHA}" = '' ] && echo "❌ 'GITHUB_SHA' env var not set" && exit 1 +[ "${GITHUB_BRANCH}" = '' ] && echo "❌ 'GITHUB_BRANCH' env var not set" && exit 1 +[ "${GITHUB_REPO_REF}" = '' ] && echo "❌ 'GITHUB_REPO_REF' env var not set" && exit 1 + +HELM_VERSION="$1" + +set -euo pipefail + +SHA="$(echo "${GITHUB_SHA}" | head -c 6)" +# shellcheck disable=SC2001 +BRANCH="$(echo "${GITHUB_BRANCH}" | sed 's/[._-]*$//')" +IMAGE_VERSION="${SHA}-${BRANCH}" + +[ "${HELM_VERSION}" = '' ] && HELM_VERSION="v0.0.0-${IMAGE_VERSION}" + +echo "📝 Generating Image tags..." +echo "📝 Helm version: ${HELM_VERSION}" +echo "📝 Image version: ${IMAGE_VERSION}" + +echo "📝 Updating Chart.yaml..." + +find . -name "Chart.yaml" | while read -r file; do + echo "📝 Updating AppVersion: $file" + yq eval ".appVersion = \"${IMAGE_VERSION}\"" "$file" >"${file}.tmp" + mv "${file}.tmp" "$file" + echo "✅ Updated AppVersion: $file" +done + +echo "✅ Updated Chart.yaml" + +onExit() { + rc="$?" + rm -rf ./uploads + if [ "$rc" = '0' ]; then + echo "✅ Successfully published helm chart" + else + echo "❌ Failed to publish helm chart" + fi +} +trap onExit EXIT + +cd ./infra/root_chart || exit + +# login to registry +echo "🔐 Logging into docker registry..." +echo "${DOCKER_PASSWORD}" | helm registry login "${DOMAIN}" -u "${DOCKER_USER}" --password-stdin + +# packaging helm chart +echo "📦 Packaging helm chart..." +helm dependency build +helm package . -u --version "${HELM_VERSION}" --app-version "${IMAGE_VERSION}" -d ./uploads + +# push helm chart +echo "📤 Pushing helm chart..." +for filename in ./uploads/*.tgz; do + OCI_REF="$(echo "oci://${DOMAIN}/${GITHUB_REPO_REF}" | tr '[:upper:]' '[:lower:]')" + echo "📤 Pushing ${filename} to ${OCI_REF}" + helm push "$filename" "${OCI_REF}" +done diff --git a/scripts/local/config-sync.sh b/scripts/local/config-sync.sh new file mode 100755 index 0000000..184a2e1 --- /dev/null +++ b/scripts/local/config-sync.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +rm -rf ./infra/root_chart/app/ +cp -r ./config/app/ ./infra/root_chart/app/ diff --git a/tasks/Taskfile.helm.yml b/tasks/Taskfile.helm.yml new file mode 100644 index 0000000..443cb7a --- /dev/null +++ b/tasks/Taskfile.helm.yml @@ -0,0 +1,49 @@ +version: 3 + +tasks: + sync: + desc: Sync configuration + cmds: + - ./scripts/local/config-sync.sh + update: + desc: Install dependencies + cmds: + - helm dependency update ./infra/root_chart + build: + desc: Build dependencies + cmds: + - helm dependency build ./infra/root_chart + remove: + desc: Removes the chart + cmds: + - helm uninstall {{.RELEASE}} + install: + desc: Installs the chart + deps: + - sync + - dep + cmds: + - >- + helm upgrade --install {{.RELEASE}} ./infra/root_chart + --values ./infra/root_chart/values.yaml + --values ./infra/root_chart/values{{.LANDSCAPE}}.yaml + template: + desc: Templates the chart + deps: + - sync + - update + cmds: + - >- + helm template {{.RELEASE}} ./infra/root_chart + --values ./infra/root_chart/values.yaml + --values ./infra/root_chart/values{{.LANDSCAPE}}.yaml + debug: + desc: Debugs the chart + deps: + - sync + - update + cmds: + - >- + helm template --debug {{.RELEASE}} ./infra/root_chart + --values ./infra/root_chart/values.yaml + --values ./infra/root_chart/values{{.LANDSCAPE}}.yaml