diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..b819d1c --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +nix_direnv_watch_file "./nix/env.nix" "./nix/fmt.nix" "./nix/packages.nix" "./nix/shells.nix" "./nix/pre-commit.nix" "./flake.nix" "./parse.nix" +use flake diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..253bcb7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily diff --git a/.github/workflows/deployment.yaml b/.github/workflows/deployment.yaml new file mode 100644 index 0000000..9385c25 --- /dev/null +++ b/.github/workflows/deployment.yaml @@ -0,0 +1,31 @@ +name: CI-CD + +on: + push: + +jobs: + precommit: + name: Pre-commit Check + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Run pre-commit + run: nix develop .#ci -c ./scripts/ci/pre-commit.sh + + release: + name: Semantic Release + needs: + - precommit + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - uses: rlespinasse/github-slug-action@v3.x + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: nix develop .#releaser -c scripts/ci/release.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf95946 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.direnv +.task +.pre-commit-config.yaml +.idea +.env +dist +debug.yaml +.DS_Store \ No newline at end of file diff --git a/.gitlint b/.gitlint new file mode 100644 index 0000000..96b180f --- /dev/null +++ b/.gitlint @@ -0,0 +1,6 @@ +[general] +contrib=CT1 +ignore=B6 + +[contrib-title-conventional-commits] +types = action,chore,config,docs,feat,fix,release,upstream diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..7374737 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,25 @@ +## [1.1.0](https://github.com/AtomiCloud/sulfoxide.chlorine/compare/v1.0.1...v1.1.0) (2023-09-30) + + +### ๐Ÿš€ New Features + +* values.yaml example ([323720f](https://github.com/AtomiCloud/sulfoxide.chlorine/commit/323720fc32f4f05d58cafe3ecaa12a7a7ec4dfdd)) + + +### ๐Ÿ› Bug Fixes + +* migrate to sulfoxide-chlorine for Chart.yaml and Taskfile.yaml ([9b3eda1](https://github.com/AtomiCloud/sulfoxide.chlorine/commit/9b3eda1524b02ae9ff2a82fcc227bb8d2f6e4b9c)) + +## [1.0.1](https://github.com/AtomiCloud/sulfoxide.chlorine/compare/v1.0.0...v1.0.1) (2023-09-27) + + +### ๐Ÿ› Bug Fixes + +* incorrect k3d configuration ([f5ecdab](https://github.com/AtomiCloud/sulfoxide.chlorine/commit/f5ecdab1de6097ee04e32afe9337feb2bd2d6821)) + +## 1.0.0 (2023-09-27) + + +### ๐Ÿš€ New Features + +* initial commit ([4bd320e](https://github.com/AtomiCloud/sulfoxide.chlorine/commit/4bd320e576c1afee2e23ab0ff6409d906ec1defd)) diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..a1ee52f --- /dev/null +++ b/README.MD @@ -0,0 +1,17 @@ +# Sulfoxide Coblat + +Helm Chart to install External Secrets, our secret operator, and SecretStore to AtomiCloud's Kubernetes Cluster + +## Prerequisites +- nix +- direnv +- docker + +## Helm Docs + +You can view the helm documentation generated at [helm-docs](./chart/README.md) +## Contributing + +Please contact contributors and read the [developer docs](./docs/developer/CommitConventions.md) for information on contributing to this project. + +- [ernest@atomi.cloud](mailto:ernest@atomi.cloud) diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..7a6722f --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,40 @@ +version: "3" + +env: + RELEASE_NAME: sulfoxide-cobalt + +includes: + util: tasks/Taskfile.util.yaml + pichu:opal: + taskfile: tasks/Taskfile.cluster.yaml + vars: + LANDSCAPE: pichu + CLUSTER: opal + +tasks: + # Utility + start:cluster: + desc: Starts the playground cluster to test helm charts + cmds: + - ./scripts/local/create-k3d-cluster.sh + + stop:cluster: + desc: Destroys the playground cluster to test helm charts + cmds: + - ./scripts/local/delete-k3d-cluster.sh + + # Helm Operations + update: + desc: Update Helm dependencies + dir: chart + cmds: + - helm dependency update + + latest: + desc: Get the latest version of External Secrets Operator + cmds: + - task: util:latest + vars: + REPO_NAME: external-secrets + REPO_URL: https://charts.external-secrets.io + CHART_NAME: external-secrets diff --git a/atomi_release.yaml b/atomi_release.yaml new file mode 100644 index 0000000..122b4f0 --- /dev/null +++ b/atomi_release.yaml @@ -0,0 +1,142 @@ +gitlint: .gitlint + +conventionMarkdown: + path: docs/developer/CommitConventions.md + template: | + --- + id: commit-conventions + title: Commit Conventions + --- + var___convention_docs___ +keywords: + - BREAKING CHANGE + - BREAKING CHANGES + - BREAKING + +branches: + - main + +specialScopes: + no-release: + desc: Prevent release from happening + release: false + +plugins: + - module: "@semantic-release/changelog" + config: + changelogFile: Changelog.md + - module: "@semantic-release/exec" + config: + prepareCmd: ./scripts/ci/publish.sh ${nextRelease.version} + - module: "@semantic-release/git" + config: + message: "release: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + assets: + - chart/**/*.* + - Changelog.md + - docs/developer/CommitConventions.md + - module: "semantic-release-major-tag" + config: + customTags: + - "v${major}" + - "v${major}.${minor}" + - module: "@semantic-release/github" + +# Helm +types: + - type: upstream + desc: "Changes from dependencies upstream" + section: ๐Ÿ“ฆ Upstreams Changes + scopes: + default: + desc: Generic update from upstream dependencies + release: "minor" + vae: + verb: update upstream + application: , + example: "upstream(mysql): from v5.7 to v8.0" + + - type: config + desc: "Changes to configuration files and scripts" + scopes: + default: + desc: Updates the configuration of the repository, not related to the other scopes + release: false + lint: + desc: Add, update or remove linters + release: false + fmt: + desc: Add, updatge or remove formatters + release: false + build: + desc: Add, update or change build pipelines and generators + release: false + nix: + desc: Add, update or change nix shell + release: false + env: + desc: Add, update or change environment + release: false + ignore: + desc: Add, update or change ignore configurations + release: false + ci: + desc: Add, update or change CI configuration files + release: false + vae: + verb: configure + application: <scope> to <title> + example: "config(ci): setup nix before executing" + + - type: release + desc: Initiate a release (machine initiated) + scopes: + default: + desc: Machine initiated release + release: false + + - type: docs + section: ๐Ÿ“ Documentation Updates + desc: Documentation only changes + scopes: + default: + desc: Update generic documentation file + release: false + vae: + verb: add + application: <scope> documention <title> + example: "docs(developer): on how to install dependency packages" + - type: feat + section: ๐Ÿš€ New Features + desc: A new feature + vae: + verb: add + application: <scope> <title> + example: "feat(rapid): new withdraw api" + scopes: + default: + desc: Release a new features + release: minor + - type: action + desc: Imperative action, mainly changing the values files + scopes: + default: + desc: Imperative action, mainly changing the values files + release: false + - type: fix + section: ๐Ÿ› Bug Fixes + desc: A bug fix + vae: + verb: fix + application: <title> + example: "fix(rapid): deposit api for rapid" + scopes: + default: + desc: Generic fixes + release: patch + - type: chore + desc: Menial Tasks + scopes: + default: + desc: Menial Tasks + release: false diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/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/chart/Chart.lock b/chart/Chart.lock new file mode 100644 index 0000000..ef34c13 --- /dev/null +++ b/chart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: external-secrets + repository: https://charts.external-secrets.io + version: 0.9.5 +digest: sha256:024c10e7d3d1b0dd9adc23bebf6b3cf12aca8b1d4d2a9b881a292c6f80bf4e54 +generated: "2023-09-30T19:26:31.766839+08:00" diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..7c300ca --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: sulfoxide-cobalt +description: Helm Chart to install External Secrets, our secret operator, and SecretStore to AtomiCloud's Kubernetes Cluster +type: application +version: 1.1.0 +appVersion: "v0.9.5" +dependencies: + - name: external-secrets + version: v0.9.5 + repository: https://charts.external-secrets.io diff --git a/chart/README.md b/chart/README.md new file mode 100644 index 0000000..a130a77 --- /dev/null +++ b/chart/README.md @@ -0,0 +1,28 @@ +# sulfoxide-cobalt + +![Version: 1.1.0](https://img.shields.io/badge/Version-1.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.9.5](https://img.shields.io/badge/AppVersion-v0.9.5-informational?style=flat-square) + +Helm Chart to install External Secrets, our secret operator, and SecretStore to AtomiCloud's Kubernetes Cluster + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://charts.external-secrets.io | external-secrets | v0.9.5 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| external-secrets | object | `{"certController":{"podAnnotations":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"cert-controller"},"podLabels":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"cert-controller"},"podSecurityContext":{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000},"resources":{"limits":{"cpu":"200m","memory":"256Mi"},"requests":{"cpu":"50m","memory":"128Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}},"installCRDs":true,"podAnnotations":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"operator"},"podLabels":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"operator"},"podSecurityContext":{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000},"resources":{"limits":{"cpu":"200m","memory":"256Mi"},"requests":{"cpu":"50m","memory":"128Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000},"serviceMonitor":{"enabled":true},"webhook":{"podAnnotations":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"webhook"},"podLabels":{"<<":{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"},"atomi.cloud/module":"webhook"},"podSecurityContext":{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000},"resources":{"limits":{"cpu":"200m","memory":"256Mi"},"requests":{"cpu":"50m","memory":"128Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}}}` | External Secrets Configuration. See [External Secrets Operator Documentation](https://github.com/external-secrets/external-secrets/tree/main/deploy/charts/external-secrets) | +| podSecurityContext | object | `{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}` | YAML Anchor for PodSecurityContext | +| rootToken | object | `{"key":"DOPPLER_TOKEN","value":""}` | The Root Doppler Token for deploying SecretStore | +| rootToken.key | string | `"DOPPLER_TOKEN"` | The Kubernetes Secret Key holding the Root Doppler Token | +| rootToken.value | string | `""` | The Root Doppler Token Value for deploying SecretStore. This value is sensitive | +| securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}` | YAML Anchor for SecurityContext | +| serviceTree | object | `{"layer":"1","platform":"sulfoxide","service":"chlorine"}` | AtomiCloud Service Tree. See [ServiceTree](https://atomicloud.larksuite.com/wiki/OkfJwTXGFiMJkrk6W3RuwRrZs64?theme=DARK&contentTheme=DARK#MHw5d76uDo2tBLx86cduFQMRsBb) | +| storeName | string | `"doppler"` | The name of the doppler ClusterSecretStore that is going to be deployed | +| tags | object | `{"atomi.cloud/layer":"1","atomi.cloud/platform":"sulfoxide","atomi.cloud/service":"chlorine"}` | Kubernetes labels and annotations, following Service Tree | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.11.1](https://github.com/norwoodj/helm-docs/releases/v1.11.1) \ No newline at end of file diff --git a/chart/charts/external-secrets-0.9.5.tgz b/chart/charts/external-secrets-0.9.5.tgz new file mode 100644 index 0000000..717bbbe Binary files /dev/null and b/chart/charts/external-secrets-0.9.5.tgz differ diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt new file mode 100644 index 0000000..bbf72a8 --- /dev/null +++ b/chart/templates/NOTES.txt @@ -0,0 +1 @@ +Install AtomiCloud's Secret Operator diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..f652f03 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,75 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "sulfoxide-cobalt.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 "sulfoxide-cobalt.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 "sulfoxide-cobalt.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "sulfoxide-cobalt.labels" -}} +helm.sh/chart: {{ include "sulfoxide-cobalt.chart" . }} +{{- range $k, $v := .Values.serviceTree }} +"atomi.cloud/{{ $k }}": "{{ $v }}" +{{- end }} +{{ include "sulfoxide-cobalt.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Common annotations +*/}} +{{- define "sulfoxide-cobalt.annotations" -}} +helm.sh/chart: {{ include "sulfoxide-cobalt.chart" . }} +{{- range $k, $v := .Values.serviceTree }} +"atomi.cloud/{{ $k }}": "{{ $v }}" +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "sulfoxide-cobalt.selectorLabels" -}} +app.kubernetes.io/name: {{ include "sulfoxide-cobalt.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "sulfoxide-cobalt.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "sulfoxide-cobalt.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/chart/templates/secret.yaml b/chart/templates/secret.yaml new file mode 100644 index 0000000..505825c --- /dev/null +++ b/chart/templates/secret.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "sulfoxide-cobalt.fullname" . }} + labels: {{- include "sulfoxide-cobalt.labels" . | nindent 4 }} + atomi.cloud/module: "credentials" + annotations: {{- include "sulfoxide-cobalt.annotations" . | nindent 4 }} + atomi.cloud/module: "credentials" +type: Opaque +data: + "{{ .Values.rootToken.key }}": "{{ .Values.rootToken.value | b64enc }}" \ No newline at end of file diff --git a/chart/templates/secret_store.yaml b/chart/templates/secret_store.yaml new file mode 100644 index 0000000..0b038bb --- /dev/null +++ b/chart/templates/secret_store.yaml @@ -0,0 +1,18 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ClusterSecretStore +metadata: + name: "{{ .Values.storeName }}" + labels: {{- include "sulfoxide-cobalt.labels" . | nindent 4 }} + atomi.cloud/module: "cluster-store" + annotations: {{- include "sulfoxide-cobalt.annotations" . | nindent 4 }} + atomi.cloud/module: "cluster-store" + helm.sh/hook: post-install,post-upgrade +spec: + provider: + doppler: + auth: + secretRef: + dopplerToken: + name: {{ include "sulfoxide-cobalt.fullname" . }} + key: {{ .Values.rootToken.key }} + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/chart/values.example.yaml b/chart/values.example.yaml new file mode 100644 index 0000000..9c3b35f --- /dev/null +++ b/chart/values.example.yaml @@ -0,0 +1,29 @@ +serviceTree: + landscape: &landscape lapras + cluster: &cluster opal + +tags: &tags + atomi.cloud/landscape: *landscape + atomi.cloud/cluster: *cluster + +rootToken: + value: "supersecret" + +external-secrets: + podAnnotations: + <<: *tags + podLabels: + <<: *tags + + webhook: + podLabels: + <<: *tags + podAnnotations: + <<: *tags + + certController: + podLabels: + <<: *tags + podAnnotations: + <<: *tags + diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..70ac982 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,99 @@ +# -- AtomiCloud Service Tree. See [ServiceTree](https://atomicloud.larksuite.com/wiki/OkfJwTXGFiMJkrk6W3RuwRrZs64?theme=DARK&contentTheme=DARK#MHw5d76uDo2tBLx86cduFQMRsBb) +serviceTree: + platform: &platform sulfoxide + service: &service chlorine + layer: &layer "1" + +# -- Kubernetes labels and annotations, following Service Tree +tags: &tags + atomi.cloud/platform: *platform + atomi.cloud/service: *service + atomi.cloud/layer: *layer + +# -- YAML Anchor for PodSecurityContext +podSecurityContext: &podSecurityContext + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + runAsNonRoot: true + +# -- YAML Anchor for SecurityContext +securityContext: &securityContext + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + capabilities: + drop: + - ALL + +# -- The Root Doppler Token for deploying SecretStore +rootToken: + # -- The Kubernetes Secret Key holding the Root Doppler Token + key: "DOPPLER_TOKEN" + # -- The Root Doppler Token Value for deploying SecretStore. This value is sensitive + value: "" + +# -- The name of the doppler ClusterSecretStore that is going to be deployed +storeName: doppler + +# -- External Secrets Configuration. See [External Secrets Operator Documentation](https://github.com/external-secrets/external-secrets/tree/main/deploy/charts/external-secrets) +external-secrets: + + installCRDs: true + + serviceMonitor: + enabled: true + + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + + podSecurityContext: *podSecurityContext + securityContext: *securityContext + podAnnotations: + <<: *tags + atomi.cloud/module: operator + podLabels: + <<: *tags + atomi.cloud/module: operator + + webhook: + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + podSecurityContext: *podSecurityContext + securityContext: *securityContext + podLabels: + <<: *tags + atomi.cloud/module: webhook + podAnnotations: + <<: *tags + atomi.cloud/module: webhook + + certController: + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + podSecurityContext: *podSecurityContext + securityContext: *securityContext + podLabels: + <<: *tags + atomi.cloud/module: cert-controller + podAnnotations: + <<: *tags + atomi.cloud/module: cert-controller + diff --git a/config/dev.yaml b/config/dev.yaml new file mode 100644 index 0000000..235b44d --- /dev/null +++ b/config/dev.yaml @@ -0,0 +1,3 @@ +landscape: lapras +platform: sulfoxide +service: app-of-apps diff --git a/docs/developer/.gitkeep b/docs/developer/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/developer/CommitConventions.md b/docs/developer/CommitConventions.md new file mode 100644 index 0000000..f6c038a --- /dev/null +++ b/docs/developer/CommitConventions.md @@ -0,0 +1,141 @@ +--- +id: commit-conventions +title: Commit Conventions +--- +This project uses [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) loosely as the specification +for our commits. + +Commit message will be in the format: + +``` +type(scope): title + +body +``` + +This page will document the types and scopes used. + +# Types + +| Type | Description | +| --------------------- | --------------------------------------------------- | +| [upstream](#upstream) | Changes from dependencies upstream | +| [config](#config) | Changes to configuration files and scripts | +| [release](#release) | Initiate a release (machine initiated) | +| [docs](#docs) | Documentation only changes | +| [feat](#feat) | A new feature | +| [action](#action) | Imperative action, mainly changing the values files | +| [fix](#fix) | A bug fix | +| [chore](#chore) | Menial Tasks | + +## upstream + +Changes from dependencies upstream + +| **V.A.E** | V.A.E values | +| --------------- | ------------------------------------------------------------------------------------- | +| verb | update upstream | +| application | when this commit is applied, it will _update upstream_ `<scope>, <title>` | +| example | upstream(mysql): from v5.7 to v8.0 | +| example applied | when this commit is applied, it will _update upstream_ `mysql`, **from v5.7 to v8.0** | + +| Scope | Description | Bump | +| ------- | ----------------------------------------- | ------- | +| default | Generic update from upstream dependencies | `minor` | + +## config + +Changes to configuration files and scripts + +| **V.A.E** | V.A.E values | +| --------------- | --------------------------------------------------------------------------------------- | +| verb | configure | +| application | when this commit is applied, it will _configure_ `<scope> to <title>` | +| example | config(ci): setup nix before executing | +| example applied | when this commit is applied, it will _configure_ `ci` to **setup nix before executing** | + +| Scope | Description | Bump | +| -------- | ---------------------------------------------------------------------------- | ----- | +| default | Updates the configuration of the repository, not related to the other scopes | `nil` | +| `lint` | Add, update or remove linters | `nil` | +| `fmt` | Add, updatge or remove formatters | `nil` | +| `build` | Add, update or change build pipelines and generators | `nil` | +| `nix` | Add, update or change nix shell | `nil` | +| `env` | Add, update or change environment | `nil` | +| `ignore` | Add, update or change ignore configurations | `nil` | +| `ci` | Add, update or change CI configuration files | `nil` | + +## release + +Initiate a release (machine initiated) + +| Scope | Description | Bump | +| ------- | ------------------------- | ----- | +| default | Machine initiated release | `nil` | + +## docs + +Documentation only changes + +| **V.A.E** | V.A.E values | +| --------------- | ------------------------------------------------------------------------------------------------------------ | +| verb | add | +| application | when this commit is applied, it will _add_ `<scope> documention <title>` | +| example | docs(developer): on how to install dependency packages | +| example applied | when this commit is applied, it will _add_ `developer` documention **on how to install dependency packages** | + +| Scope | Description | Bump | +| ------- | --------------------------------- | ----- | +| default | Update generic documentation file | `nil` | + +## feat + +A new feature + +| **V.A.E** | V.A.E values | +| --------------- | ----------------------------------------------------------------------- | +| verb | add | +| application | when this commit is applied, it will _add_ `<scope> <title>` | +| example | feat(rapid): new withdraw api | +| example applied | when this commit is applied, it will _add_ `rapid` **new withdraw api** | + +| Scope | Description | Bump | +| ------- | ---------------------- | ------- | +| default | Release a new features | `minor` | + +## action + +Imperative action, mainly changing the values files + +| Scope | Description | Bump | +| ------- | --------------------------------------------------- | ----- | +| default | Imperative action, mainly changing the values files | `nil` | + +## fix + +A bug fix + +| **V.A.E** | V.A.E values | +| --------------- | -------------------------------------------------------------------- | +| verb | fix | +| application | when this commit is applied, it will _fix_ `<title>` | +| example | fix(rapid): deposit api for rapid | +| example applied | when this commit is applied, it will _fix_ **deposit api for rapid** | + +| Scope | Description | Bump | +| ------- | ------------- | ------- | +| default | Generic fixes | `patch` | + +## chore + +Menial Tasks + +| Scope | Description | Bump | +| ------- | ------------ | ----- | +| default | Menial Tasks | `nil` | + +# Special Scopes + +| Scope | Description | Bump | +| ------------ | ------------------------------ | ----- | +| `no-release` | Prevent release from happening | `nil` | diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..ef1e5a3 --- /dev/null +++ b/flake.lock @@ -0,0 +1,611 @@ +{ + "nodes": { + "atomipkgs": { + "inputs": { + "dev-atomi_classic": "dev-atomi_classic", + "dev-npkgs": "dev-npkgs", + "dev-npkgs-unstable-05-Oct-2022": "dev-npkgs-unstable-05-Oct-2022", + "dev-npkgs-unstable-11-Dec-2022": "dev-npkgs-unstable-11-Dec-2022", + "dev-npkgs-unstable-20-Sep-2023": "dev-npkgs-unstable-20-Sep-2023", + "fenix": "fenix", + "flake-utils": "flake-utils_2", + "npkgs": "npkgs", + "npkgs-unstable": "npkgs-unstable" + }, + "locked": { + "lastModified": 1695526514, + "narHash": "sha256-kDwlfpgEqS/hrktjbZfpKldPFZKS68/d2zxfMPobK6c=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "82cce29ae2d3c150247d112c513e8be274218b91", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "v21.0.0", + "repo": "test-nix-repo", + "type": "github" + } + }, + "atomipkgs_classic": { + "inputs": { + "flake-utils": "flake-utils_3", + "pkgs": "pkgs_2", + "pkgs_25_Jul_2021": "pkgs_25_Jul_2021_2" + }, + "locked": { + "lastModified": 1689236000, + "narHash": "sha256-MEqyIPlD4ueJji6FtfDs8qqZifM9hyYH1svBs3oxrrc=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "2d9d80544d2e81ff736fa23345ad0a9cc5a6c8ab", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "classic", + "repo": "test-nix-repo", + "type": "github" + } + }, + "dev-atomi_classic": { + "inputs": { + "flake-utils": "flake-utils", + "pkgs": "pkgs", + "pkgs_25_Jul_2021": "pkgs_25_Jul_2021" + }, + "locked": { + "lastModified": 1689236000, + "narHash": "sha256-MEqyIPlD4ueJji6FtfDs8qqZifM9hyYH1svBs3oxrrc=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "2d9d80544d2e81ff736fa23345ad0a9cc5a6c8ab", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "classic", + "repo": "test-nix-repo", + "type": "github" + } + }, + "dev-npkgs": { + "locked": { + "lastModified": 1689048911, + "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8163a64662b43848802092d52015ef60777d6129", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "dev-npkgs-unstable-05-Oct-2022": { + "locked": { + "lastModified": 1664847737, + "narHash": "sha256-Wxl0CtRH3Vo8+qEZ/PbCcx+9D8wEEi56tJPmROum2ss=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "indirect" + } + }, + "dev-npkgs-unstable-11-Dec-2022": { + "locked": { + "lastModified": 1670681895, + "narHash": "sha256-kZH9DSU36W4fn1z81a/24JCGkU517TcY50VE0RFJ9k4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", + "type": "indirect" + } + }, + "dev-npkgs-unstable-20-Sep-2023": { + "locked": { + "lastModified": 1694959747, + "narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "970a59bd19eff3752ce552935687100c46e820a5", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "970a59bd19eff3752ce552935687100c46e820a5", + "type": "indirect" + } + }, + "fenix": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1695709315, + "narHash": "sha256-XKzbb4NqYmUVlORwjCT//RGeQiJa+6LuGYllpaLP5lQ=", + "owner": "nix-community", + "repo": "fenix", + "rev": "f5845b16d889d8bf9930fe1098820074da4cbce9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1695360818, + "narHash": "sha256-JlkN3R/SSoMTa+CasbxS1gq+GpGxXQlNZRUh9+LIy/0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e35dcc04a3853da485a396bdd332217d0ac9054f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-sep-24-23": { + "locked": { + "lastModified": 1695360818, + "narHash": "sha256-JlkN3R/SSoMTa+CasbxS1gq+GpGxXQlNZRUh9+LIy/0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e35dcc04a3853da485a396bdd332217d0ac9054f", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "e35dcc04a3853da485a396bdd332217d0ac9054f", + "type": "indirect" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1695360818, + "narHash": "sha256-JlkN3R/SSoMTa+CasbxS1gq+GpGxXQlNZRUh9+LIy/0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e35dcc04a3853da485a396bdd332217d0ac9054f", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "e35dcc04a3853da485a396bdd332217d0ac9054f", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1685866647, + "narHash": "sha256-4jKguNHY/edLYImB+uL8jKPL/vpfOvMmSlLAGfxSrnY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a53a3bec10deef6e1cc1caba5bc60f53b959b1e8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1680945546, + "narHash": "sha256-8FuaH5t/aVi/pR1XxnF0qi4WwMYC+YxlfdsA0V+TEuQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d9f759f2ea8d265d974a6e1259bd510ac5844c5d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "npkgs": { + "locked": { + "lastModified": 1689048911, + "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8163a64662b43848802092d52015ef60777d6129", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "npkgs-unstable": { + "locked": { + "lastModified": 1689008574, + "narHash": "sha256-VFMgyHDiqsGDkRg73alv6OdHJAqhybryWHv77bSCGIw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "4a729ce4b1fe5ec4fffc71c67c96aa5184ebb462", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pkgs": { + "locked": { + "lastModified": 1643805626, + "narHash": "sha256-AXLDVMG+UaAGsGSpOtQHPIKB+IZ0KSd9WS77aanGzgc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "indirect" + } + }, + "pkgs_2": { + "locked": { + "lastModified": 1643805626, + "narHash": "sha256-AXLDVMG+UaAGsGSpOtQHPIKB+IZ0KSd9WS77aanGzgc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "indirect" + } + }, + "pkgs_25_Jul_2021": { + "locked": { + "lastModified": 1627107260, + "narHash": "sha256-CwvSwz3kvpp7uEFyOj2Dq6bdtY6P2N0Bzd7ZVgsIICw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "indirect" + } + }, + "pkgs_25_Jul_2021_2": { + "locked": { + "lastModified": 1627107260, + "narHash": "sha256-CwvSwz3kvpp7uEFyOj2Dq6bdtY6P2N0Bzd7ZVgsIICw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "indirect" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils_5", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs_3", + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1689328505, + "narHash": "sha256-9B3+OeUn1a/CvzE3GW6nWNwS5J7PDHTyHGlpL3wV5oA=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5e28316db471d1ac234beb70031b635437421dd6", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "atomipkgs": "atomipkgs", + "atomipkgs_classic": "atomipkgs_classic", + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_2", + "nixpkgs-sep-24-23": "nixpkgs-sep-24-23", + "pre-commit-hooks": "pre-commit-hooks", + "treefmt-nix": "treefmt-nix" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1695642814, + "narHash": "sha256-xR1+YaPcutqXN7BYYCyHPU8VVh/gjW+bVFTfA+vHpv0=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "d3cc3bc00e310ff49268ce0c593eaa6bf4724bbd", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1689243103, + "narHash": "sha256-IfBt2AD8qCwZs+m6BlOGEitBIkVJ0iMscMueb6QYUk4=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "f1dca68b908f3dd656b923b9fb62f7d755133662", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5a5f7be --- /dev/null +++ b/flake.nix @@ -0,0 +1,70 @@ +{ + inputs = { + # util + flake-utils.url = "github:numtide/flake-utils"; + treefmt-nix.url = "github:numtide/treefmt-nix"; + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + + # registry + nixpkgs.url = "nixpkgs/e35dcc04a3853da485a396bdd332217d0ac9054f"; + nixpkgs-sep-24-23.url = "nixpkgs/e35dcc04a3853da485a396bdd332217d0ac9054f"; + atomipkgs.url = "github:kirinnee/test-nix-repo/v21.0.0"; + atomipkgs_classic.url = "github:kirinnee/test-nix-repo/classic"; + + }; + outputs = + { self + + # utils + , flake-utils + , treefmt-nix + , pre-commit-hooks + + # registries + , atomipkgs + , atomipkgs_classic + , nixpkgs + , nixpkgs-sep-24-23 + + } @inputs: + (flake-utils.lib.eachDefaultSystem + ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + pkgs-sep-24-23 = nixpkgs-sep-24-23.legacyPackages.${system}; + atomi = atomipkgs.packages.${system}; + atomi_classic = atomipkgs_classic.packages.${system}; + pre-commit-lib = pre-commit-hooks.lib.${system}; + in + with rec { + pre-commit = import ./nix/pre-commit.nix { + inherit packages pre-commit-lib formatter; + }; + formatter = import ./nix/fmt.nix { + inherit treefmt-nix pkgs; + }; + packages = import ./nix/packages.nix + { + inherit pkgs pkgs-sep-24-23 atomi atomi_classic; + }; + env = import ./nix/env.nix { + inherit pkgs packages; + }; + devShells = import ./nix/shells.nix { + inherit pkgs env packages; + shellHook = checks.pre-commit-check.shellHook; + }; + checks = { + pre-commit-check = pre-commit; + format = formatter; + }; + }; + { + inherit checks formatter packages devShells; + } + ) + ) + ; + +} diff --git a/infra/k3d.lapras.yaml b/infra/k3d.lapras.yaml new file mode 100644 index 0000000..84f1ca5 --- /dev/null +++ b/infra/k3d.lapras.yaml @@ -0,0 +1,20 @@ +apiVersion: k3d.io/v1alpha4 +kind: Simple +metadata: + name: lapras +servers: 1 +agents: 0 +network: lapras +image: rancher/k3s:v1.25.12-k3s1 +ports: + - port: 20010:80 + nodeFilters: + - loadbalancer + - port: 20011:443 + nodeFilters: + - loadbalancer +registries: + create: + name: lapras.registry.lvh.me + host: "0.0.0.0" + hostPort: "20012" diff --git a/nix/env.nix b/nix/env.nix new file mode 100644 index 0000000..72cfe9b --- /dev/null +++ b/nix/env.nix @@ -0,0 +1,40 @@ +{ pkgs, packages }: +with packages; +{ + system = [ + coreutils + sd + bash + jq + yq-go + ]; + + dev = [ + pls + git + ]; + + infra = [ + k3d + helm + kubectl + ]; + + main = [ + ]; + + lint = [ + # core + treefmt + + helm-docs + + gitlint + shellcheck + ]; + + releaser = [ + nodejs_20 + sg + ]; +} diff --git a/nix/fmt.nix b/nix/fmt.nix new file mode 100644 index 0000000..66809f9 --- /dev/null +++ b/nix/fmt.nix @@ -0,0 +1,24 @@ +{ treefmt-nix, pkgs, ... }: +let + fmt = { + projectRootFile = "flake.nix"; + + # enable or disable formatters, see https://github.com/numtide/treefmt-nix#supported-programs + programs = { + nixpkgs-fmt = { + enable = true; + }; + prettier = { + enable = true; + }; + shfmt = { + enable = true; + }; + }; + + + }; +in +(treefmt-nix.lib.evalModule pkgs fmt).config.build.wrapper + + diff --git a/nix/packages.nix b/nix/packages.nix new file mode 100644 index 0000000..c8543e8 --- /dev/null +++ b/nix/packages.nix @@ -0,0 +1,52 @@ +{ pkgs, atomi, atomi_classic, pkgs-sep-24-23 }: +let + + all = { + atomipkgs = ( + with atomi; + { + inherit + infisical + pls; + } + ); + atomipkgs_classic = ( + with atomi_classic; + { + inherit + sg; + } + ); + sep-24-23 = ( + with pkgs-sep-24-23; + { + inherit + coreutils + sd + bash + git + jq + yq-go + + nodejs_20 + + # lint + treefmt + + # infra + k3d + helm-docs + kubectl + gitlint + shellcheck + ; + helm = kubernetes-helm; + + } + ); + }; +in +with all; +atomipkgs // +atomipkgs_classic // +sep-24-23 diff --git a/nix/pre-commit.nix b/nix/pre-commit.nix new file mode 100644 index 0000000..f2373ad --- /dev/null +++ b/nix/pre-commit.nix @@ -0,0 +1,98 @@ +{ packages, formatter, pre-commit-lib }: +pre-commit-lib.run { + src = ./.; + + # hooks + hooks = { + # formatter + treefmt = { + enable = true; + excludes = [ "chart/.*(yaml|yml)" "chart/README.md" "Changelog.md" "docs/developer/CommitConventions.md" ]; + }; + + # linters From https://github.com/cachix/pre-commit-hooks.nix + shellcheck = { + enable = false; + }; + + a-infisical = { + enable = true; + name = "Secrets Scanning (Past Commits)"; + description = "Scan for possible secrets in past commits"; + entry = "${packages.infisical}/bin/infisical scan . -v"; + language = "system"; + pass_filenames = false; + }; + + a-infisical-staged = { + enable = true; + name = "Secrets Scanning (Staged)"; + description = "Scan for possible secrets in staged files"; + entry = "${packages.infisical}/bin/infisical scan git-changes --staged -v"; + language = "system"; + pass_filenames = false; + }; + + a-helm-lint = { + enable = true; + name = "Helm Lint"; + description = "Lints helm"; + entry = "${packages.helm}/bin/helm lint -f chart/values.yaml chart"; + files = "chart/.*"; + language = "system"; + pass_filenames = false; + }; + + a-gitlint = { + enable = true; + name = "Gitlint"; + description = "Lints git commit message"; + entry = "${packages.gitlint}/bin/gitlint --staged --msg-filename .git/COMMIT_EDITMSG"; + language = "system"; + pass_filenames = false; + stages = [ "commit-msg" ]; + }; + + a-enforce-gitlint = { + enable = true; + name = "Enforce gitlint"; + description = "Enforce atomi_releaser conforms to gitlint"; + entry = "${packages.sg}/bin/sg gitlint"; + files = "(atomi_release\\.yaml|\\.gitlint)"; + language = "system"; + pass_filenames = false; + }; + + a-shellcheck = { + enable = true; + name = "Shell Check"; + entry = "${packages.shellcheck}/bin/shellcheck"; + files = ".*sh$"; + language = "system"; + pass_filenames = true; + }; + + a-enforce-exec = { + enable = true; + name = "Enforce Shell Script executable"; + entry = "${packages.coreutils}/bin/chmod +x"; + files = ".*sh$"; + language = "system"; + pass_filenames = true; + }; + a-helm-docs = { + enable = true; + name = "Helm Docs"; + entry = "${packages.helm-docs}/bin/helm-docs"; + files = ".*"; + language = "system"; + pass_filenames = false; + }; + }; + + settings = { + treefmt = { + package = formatter; + }; + }; +} diff --git a/nix/shells.nix b/nix/shells.nix new file mode 100644 index 0000000..ae01149 --- /dev/null +++ b/nix/shells.nix @@ -0,0 +1,18 @@ +{ pkgs, packages, env, shellHook }: +with env; +{ + default = pkgs.mkShell { + buildInputs = system ++ main ++ dev ++ env.lint ++ infra; + inherit shellHook; + }; + + ci = pkgs.mkShell { + buildInputs = system ++ main ++ lint ++ infra; + inherit shellHook; + }; + + releaser = pkgs.mkShell { + buildInputs = system ++ main ++ lint ++ infra ++ releaser; + inherit shellHook; + }; +} diff --git a/scripts/ci/pre-commit.sh b/scripts/ci/pre-commit.sh new file mode 100755 index 0000000..af245ca --- /dev/null +++ b/scripts/ci/pre-commit.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eou pipefail + +pre-commit run --all-files -v diff --git a/scripts/ci/publish.sh b/scripts/ci/publish.sh new file mode 100755 index 0000000..1516d43 --- /dev/null +++ b/scripts/ci/publish.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +version="$1" + +set -eou pipefail + +echo "๐Ÿš€ Publishing version ${version}" + +yq eval ".version = \"${version}\"" ./chart/Chart.yaml >"Chart.tmp" +mv "Chart.tmp" ./chart/Chart.yaml + +echo "๐Ÿ“ Generating Documentation" +helm-docs +echo "โœ… Documentation Generated" diff --git a/scripts/ci/release.sh b/scripts/ci/release.sh new file mode 100755 index 0000000..a0950a9 --- /dev/null +++ b/scripts/ci/release.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -eou pipefail + +rm .git/hooks/* || true +sg release diff --git a/scripts/local/create-k3d-cluster.sh b/scripts/local/create-k3d-cluster.sh new file mode 100755 index 0000000..2e5601b --- /dev/null +++ b/scripts/local/create-k3d-cluster.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +dev_config="$1" + +set -eou pipefail + +[ "$dev_config" = '' ] && dev_config="./config/dev.yaml" + +# check if dev config exists +if [ ! -f "$dev_config" ]; then + echo "โŒ Dev config '$dev_config' does not exist!" + exit 1 +fi + +input="$(yq '.landscape' "$dev_config")" +config="./infra/k3d.$input.yaml" +echo "๐Ÿงฌ Attempting to start cluster '$input' using '$config'..." + +# obtain existing cluster +current="$(k3d cluster ls -o json | jq -r --arg input "${input}" '.[] | select(.name == $input) | .name')" +if [ "$current" = "$input" ]; then + echo "โœ… Cluster already exist!" +else + # ask if to create cluster + echo "๐ŸฅŸ Cluster does not exist, creating..." + k3d cluster create "$input" --config "$config" --wait + echo "๐Ÿš€ Cluster created!" +fi + +echo "๐Ÿ›  Generating kubeconfig" +mkdir -p "$HOME/.kube/configs" +mkdir -p "$HOME/.kube/k3dconfigs" + +echo "๐Ÿ“ Writing to '$HOME/.kube/k3dconfigs/k3d-$input'" +k3d kubeconfig get "$input" >"$HOME/.kube/k3dconfigs/k3d-$input" +KUBECONFIG=$(cd ~/.kube/configs && find "$(pwd)"/* | awk 'ORS=":"')$(cd ~/.kube/k3dconfigs && find "$(pwd)"/* | awk 'ORS=":"') kubectl config view --flatten >~/.kube/config +chmod 600 ~/.kube/config +echo "โœ… Generated kube config file" +# wait for cluster to be ready +echo "๐Ÿ•‘ Waiting for cluster to be ready..." +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.readyReplicas=1 --timeout=300s deployment metrics-server +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.readyReplicas=1 --timeout=300s deployment coredns +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.readyReplicas=1 --timeout=300s deployment local-path-provisioner +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.succeeded=1 --timeout=300s job helm-install-traefik-crd +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.succeeded=1 --timeout=300s job helm-install-traefik +kubectl --context "k3d-$input" -n kube-system wait --for=jsonpath=.status.readyReplicas=1 --timeout=300s deployment traefik +echo "โœ… Cluster is ready!" diff --git a/scripts/local/delete-k3d-cluster.sh b/scripts/local/delete-k3d-cluster.sh new file mode 100755 index 0000000..0ee6c1c --- /dev/null +++ b/scripts/local/delete-k3d-cluster.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +dev_config="$1" + +set -eou pipefail + +[ "$dev_config" = '' ] && dev_config="./config/dev.yaml" + +# check if dev config exists +if [ ! -f "$dev_config" ]; then + echo "โŒ Dev config '$dev_config' does not exist!" + exit 1 +fi + +input="$(yq '.landscape' "$dev_config")" + +echo "๐Ÿ› ๏ธ Attempting to delete cluster '$input'..." + +# obtain existing cluster +current="$(k3d cluster ls -o json | jq -r --arg input "${input}" '.[] | select(.name == $input) | .name')" +if [ "$current" = "$input" ]; then + echo "๐Ÿ—‘๏ธ Cluster found! Deleting cluster..." + k3d cluster delete "$input" + echo "โœ… Cluster deleted!" +else + echo "โš ๏ธ Cluster does not exist!" +fi +echo "๐Ÿงน Cleaning up kubeconfig files..." +mkdir -p "$HOME/.kube/configs" +mkdir -p "$HOME/.kube/k3dconfigs" +rm "$HOME/.kube/k3dconfigs/k3d-$input" || true +KUBECONFIG=$(cd ~/.kube/configs && find "$(pwd)"/* | awk 'ORS=":"')$(cd ~/.kube/k3dconfigs && find "$(pwd)"/* | awk 'ORS=":"') kubectl config view --flatten >~/.kube/config +chmod 600 ~/.kube/config +echo "โœ… Config is cleared!" diff --git a/tasks/Taskfile.cluster.yaml b/tasks/Taskfile.cluster.yaml new file mode 100644 index 0000000..71d8bb5 --- /dev/null +++ b/tasks/Taskfile.cluster.yaml @@ -0,0 +1,30 @@ +version: "3" + +tasks: + debug: + desc: Debug the helm chart + dir: chart + cmds: + - helm dependency update + - helm template $RELEASE_NAME . --debug --values values.yaml --values values.{{.LANDSCAPE}}.{{.CLUSTER}}.yaml {{.CLI_ARGS}} + + render: + desc: Render the helm chart + dir: chart + cmds: + - helm dependency update + - >- + helm template $RELEASE_NAME . --values values.yaml --values values.{{.LANDSCAPE}}.{{.CLUSTER}}.yaml + {{.CLI_ARGS}} > rendered/{{.LANDSCAPE}}/{{.CLUSTER}}/manifest.yaml + + install: + desc: Installs the chart + dir: chart + cmds: + - helm dependency update + - helm upgrade --kube-context {{.LANDSCAPE}}-{{.CLUSTER}} --install $RELEASE_NAME . --values values.yaml --values values.{{.LANDSCAPE}}.{{.CLUSTER}}.yaml {{.CLI_ARGS}} + + remove: + desc: Removes an installed release + cmds: + - helm uninstall --kube-context {{.LANDSCAPE}}-{{.CLUSTER}} $RELEASE_NAME diff --git a/tasks/Taskfile.util.yaml b/tasks/Taskfile.util.yaml new file mode 100644 index 0000000..0a69559 --- /dev/null +++ b/tasks/Taskfile.util.yaml @@ -0,0 +1,10 @@ +version: "3" + +tasks: + latest: + internal: true + desc: Get the latest version of a Helm Chart + cmds: + - helm repo add {{.REPO_NAME}} {{.REPO_URL}} + - helm repo update + - helm search repo {{.REPO_NAME}}/{{.CHART_NAME}} --versions --max-col-width=0 | grep {{.REPO_NAME}}/{{.CHART_NAME}} | head -n 1 | awk '{print $2}'