From 7742cc06a5f63bf20d73f5328067e5b4a22d954a Mon Sep 17 00:00:00 2001 From: Noel Date: Fri, 2 Feb 2024 10:31:40 -0800 Subject: [PATCH] Initial commit --- .charted.hcl | 44 +++ .devcontainer/devcontainer.json | 20 ++ .envrc | 35 ++ .github/CODEOWNERS | 1 + .github/CODE_OF_CONDUCT.md | 76 ++++ .github/CONTRIBUTING.md | 1 + .github/workflows/CI.yaml | 98 ++++++ .github/workflows/UpdateValues.yaml | 52 +++ .gitignore | 508 +++++++++++++++++++++++++++ .prettierrc.json | 9 + .vscode/settings.json | 9 + LICENSE | 21 ++ README.md | 22 ++ bun.lockb | Bin 0 -> 176009 bytes charts/charted/Chart.lock | 12 + charts/charted/Chart.yaml | 72 ++++ charts/charted/README.md | 57 +++ charts/charted/templates/NOTES.txt | 0 charts/charted/templates/helpers.tpl | 0 charts/charted/values.yaml | 87 +++++ charts/emails/Chart.lock | 6 + charts/emails/Chart.yaml | 57 +++ charts/emails/README.md | 57 +++ charts/emails/templates/NOTES.txt | 0 charts/emails/templates/helpers.tpl | 0 charts/emails/values.yaml | 87 +++++ default.nix | 28 ++ flake.lock | 78 ++++ flake.nix | 49 +++ package.json | 1 + scripts/emit-values | 77 ++++ shell.nix | 28 ++ 32 files changed, 1592 insertions(+) create mode 100644 .charted.hcl create mode 100644 .devcontainer/devcontainer.json create mode 100644 .envrc create mode 100644 .github/CODEOWNERS create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/workflows/CI.yaml create mode 100644 .github/workflows/UpdateValues.yaml create mode 100644 .gitignore create mode 100644 .prettierrc.json create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 README.md create mode 100755 bun.lockb create mode 100644 charts/charted/Chart.lock create mode 100644 charts/charted/Chart.yaml create mode 100644 charts/charted/README.md create mode 100644 charts/charted/templates/NOTES.txt create mode 100644 charts/charted/templates/helpers.tpl create mode 100644 charts/charted/values.yaml create mode 100644 charts/emails/Chart.lock create mode 100644 charts/emails/Chart.yaml create mode 100644 charts/emails/README.md create mode 100644 charts/emails/templates/NOTES.txt create mode 100644 charts/emails/templates/helpers.tpl create mode 100644 charts/emails/values.yaml create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 package.json create mode 100755 scripts/emit-values create mode 100644 shell.nix diff --git a/.charted.hcl b/.charted.hcl new file mode 100644 index 0000000..962db52 --- /dev/null +++ b/.charted.hcl @@ -0,0 +1,44 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +charted { + # view https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#tilde-requirements + # to see what `~` is meant since `charted-helm-plugin` uses Cargo's SemVer implementation. + version = "~ 0.1-beta" + helm = "~ 3.12" +} + +registry "default" { + version = 1 + url = "https://charts.noelware.org/api" +} + +repository "charted-server" { + registry = registry.default + source = "${cwd}/charts/charted" + path = "charted/server" +} + +repository "charted-emails" { + registry = registry.default + source = "${cwd}/charts/emails" + path = "charted/emails" +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c17ed1d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +{ + "name": "charted-server", + "remoteUser": "noel", + "image": "ghcr.io/auguwu/coder-images/base", + "containerUser": "noel", + "customizations": { + "vscode": { + "extensions": ["redhat.vscode-yaml", "hashicorp.hcl"], + "settings": { + "dotfiles.installCommand": "bootstrap.sh", + "dotfiles.repository": "https://github.com/auguwu/.dotfiles" + } + } + }, + "features": { + "ghcr.io/devcontainers/features/sshd:1": { + "version": "latest" + } + } +} diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..9c62d52 --- /dev/null +++ b/.envrc @@ -0,0 +1,35 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8=" +fi + +# make .direnv if it doesn't exist +mkdir -p "$(direnv_layout_dir)" + +watch_file shell.nix +watch_file flake.nix +watch_file flake.lock + +# try to use flakes, if it fails use normal nix (ie. shell.nix) +use flake || use nix +eval "$shellHook" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..dab0f1b --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @auguwu @IceeMC @spotlightishere diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..83592fc --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at **team@noelware.org**. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..b2f0c99 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1 @@ +coming soon near a gay dog diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml new file mode 100644 index 0000000..9d4645c --- /dev/null +++ b/.github/workflows/CI.yaml @@ -0,0 +1,98 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +name: CI +on: + workflow_dispatch: {} + push: + branches: + - 'issues/gh-**' + - 'feat/**' + - main + paths-ignore: + - '.github/**' + - '.coder/**' + - '.devcontainer/**' + - '.vscode/**' + - 'docs/**' + - 'scripts/**' + - '.*ignore' + - '**.md' + - renovate.json + - LICENSE + pull_request: + types: [opened, synchronize] + branches: + - main + paths-ignore: + - '.coder/**' + - '.devcontainer/**' + - '.vscode/**' + - 'docs/**' + - '.*ignore' + - '**.md' + - renovate.json + - LICENSE +jobs: + ci: + name: helm test [${{matrix.chart}}; Kubernetes ${{matrix.kubernetes}}] + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + chart: [charted, emails] + kubernetes: [v1.26.13, v1.28.6, v1.29.1] + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Helm + uses: Azure/setup-helm@v3 + + - name: Setup Minikube cluster + uses: medyagh/setup-minikube@v0.0.14 + with: + kubernetes-version: ${{matrix.kubernetes}} + container-runtime: containerd + minikube-version: 1.32.0 + start-args: '--delete-on-failure --profile=helm-test' + memory: 4000m + addons: ingress + cache: true + cpus: 4 + wait: true + cni: bridge + + - name: Lint + working-directory: ./charts/${{matrix.chart}} + run: helm lint + + # - name: Install chart + # working-directory: ./charts/${{matrix.chart}} + # run: helm install ${{matrix.chart}} --namespace ci --create-namespace --wait --atomic + + # - name: Test + # working-directory: ./charts/${{matrix.chart}} + # run: helm test + + - name: Delete cluster (since we're done) + if: ${{ always() }} + run: minikube delete --profile=helm-test diff --git a/.github/workflows/UpdateValues.yaml b/.github/workflows/UpdateValues.yaml new file mode 100644 index 0000000..eb4753c --- /dev/null +++ b/.github/workflows/UpdateValues.yaml @@ -0,0 +1,52 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +name: Update Values +on: + workflow_dispatch: {} + push: + paths: + - './charts/**/values.yaml' +jobs: + update-values: + name: Update README.md for `values.yaml` parameters + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + + - name: Write values.yaml into README + run: ./scripts/emit-values + + - name: Prettier! + run: bunx prettier --config=${GITHUB_WORKSPACE}/.prettierrc.json --write charts/**/README.md + + - name: Commit! + uses: EndBug/add-and-commit@v9 + with: + author_name: Noel[bot] + default_author: user_info + author_email: noelbot@users.noreply.github.com + message: '[skip ci] :sparkles: Update Protobufs in repository' + push: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18d6a3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,508 @@ +### Helm ### +# Chart dependencies +**/charts/*.tgz + +### JetBrains+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### JetBrains+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +*.code-workspace + +# Local History for Visual Studio Code + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml + +### VisualStudio Patch ### +# Additional files built by Visual Studio + +.direnv/ +.cache/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..1f4372b --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "semi": true, + "tabWidth": 4, + "singleQuote": true, + "endOfLine": "lf", + "printWidth": 120, + "trailingComma": "none", + "bracketSpacing": true +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..733ef09 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.tabSize": 4, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[yaml]": { + "editor.defaultFormatter": "redhat.vscode-yaml" + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d52cee8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-2024 Noelware, LLC. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..681b497 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# 🐻‍❄️🪻 Helm Charts for `charted` + +> _Helm Charts available for Noelware's charted project_ + +This is the way to deploy [charted-server](https://github.com/charted-dev/charted) and [charted-emails](https://github.com/charted-dev/emails) on Kubernetes with Helm. + +> [!IMPORTANT] +> All Helm charts require the Kubernetes API to be v1.26 or higher and Helm v3.12 or higher to be used. + +| Helm Chart | Version | +| :--------------------------------------------------------- | :----------------------------- | +| [`charted-server`](https://github.com/charted-dev/charted) | [v0.1.0-beta][charted-release] | +| [`charted-emails`](https://github.com/charted-dev/emails) | [v0.2.0][emails-release] | + +## License + +Helm charts are released under the **MIT License** while `charted-server` and `charted-emails` are both released by the **Apache 2.0** License with love and care by Noelware, LLC.! :purple_heart: + +Please read the `LICENSE` files in for the software and the [repository](/LICENSE) for more information on what you can do with the source code. + +[charted-release]: https://github.com/charted-dev/charted/releases/0.1.0-beta +[emails-release]: https://github.com/charted-dev/emails/releases/0.2.0 diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..10660245cfc3c1bce536bbf97b12b3b7fb7b3465 GIT binary patch literal 176009 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

*>e3Mbz&(~ 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

Gx3U#NxBQ! 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 +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +kubeVersion: ">=1.26" +description: "📦 Free, open source, and reliable Helm Chart registry made in Rust" +apiVersion: v2 + +# renovate: datasource=github-tags version=charted-dev/charted +appVersion: 0.1.0-beta +version: 0.1.0 +type: application +home: https://charts.noelware.org +name: charted-server +icon: https://cdn.noelware.org/branding/charted.svg +sources: + - https://github.com/charted-dev/charted + - https://github.com/charted-dev/helm-charts +keywords: + - helm-chart + - chart-registry + - registry +maintainers: + - name: Noelware, LLC. + email: team@noelware.org + url: https://noelware.org + - name: Noel Towa + email: cutie@floofy.dev + url: https://floofy.dev + - name: Spotlight + email: spotlight@joscomputing.space + url: https://joscomputing.space + - name: John Burke + email: winter@winterfox.tech + url: https://winterfox.tech +annotations: + charts.noelware.org/licenses: Apache-2.0 + charts.noelware.org/categories: Registry + charts.noelware.org/owners: |- + - user: noel + maintainer: Noel Towa + - organization: noelware + maintainer: Noelware, LLC. +dependencies: + - name: common + version: 2.14.1 + repository: oci://registry-1.docker.io/bitnamicharts + - name: postgresql + version: 13.4.4 + repository: oci://registry-1.docker.io/bitnamicharts + condition: external.postgresql.enabled + - name: redis + version: 18.12.0 + repository: oci://registry-1.docker.io/bitnamicharts + condition: external.redis.enabled diff --git a/charts/charted/README.md b/charts/charted/README.md new file mode 100644 index 0000000..8eb330b --- /dev/null +++ b/charts/charted/README.md @@ -0,0 +1,57 @@ +# 🐻‍❄️🪻 Helm Chart for `charted-server` + +This is the Helm Chart to install [charted-server](https://github.com/charted-dev/charted) on Kubernetes with Helm. + +## Requirements + +- Kubernetes v1.26 or higher +- Helm 3.12 or higher + +## Installation + +```shell +$ helm repo add charted https://charts.noelware.org/~/charted +$ helm install emails charted/server --namespace charted --create-namespace +``` + +## Parameters + +### Global Parameters + +Contains any global parameters that will affected all objects in the `youtrack` Helm chart. + +| Name | Description | Value | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `global.replicas` | Amount of replicas to spawn | `1` | +| `global.resources` | Resource list to apply to all containers. | `{}` | +| `global.fullNameOverride` | String to fully override the Helm installation name for all objects | `""` | +| `global.nameOverride` | String to override the Helm installation name for all objects, will be in conjunction with a prefix of `-` | `""` | +| `global.clusterDomain` | Domain host that maps to the cluster | `cluster.local` | +| `global.nodeSelector` | Selector labels to apply to contraint the pods to specific nodes. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). | `{}` | +| `global.tolerations` | List of all taints/tolerations to apply in conjunction with `global.affinity`. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) | `[]` | +| `global.affinity` | Map of all the affinity to apply to the spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). | `{}` | +| `global.annotations` | Map of annotations to append to on all objects that this Helm chart creates. | `{}` | +| `global.extraEnvVars` | List of extra environment variables to append to all init/sidecar containers and normal containers. | `[]` | +| `global.initContainers` | List of init containers to create. | `[]` | +| `global.podSecurityContext` | Security context for all spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | `{}` | +| `global.containerSecurityContext` | Security context for all init, sidecar, and normal containers. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | `{}` | + +### Docker Image Parameters + +Parameters to modify the Docker image that is ran. + +| Name | Description | Value | +| ------------------ | --------------------------------------------------------------------------------------------------------------- | ------------------- | +| `image.pullPolicy` | [Pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) when pulling the image. | `""` | +| `image.registry` | Registry URL to point to. For Docker Hub, use an empty string. | `cr.noelware.cloud` | +| `image.image` | Image name. | `charted/server` | +| `image.tag` | The tag of the image. Keep this as a empty string if you wish to use the default app's version. | `""` | +| `image.digest` | Digest in the form of `:`, this will replace the `image.tag` property if this is not empty. | `""` | + +### Service Account Parameters + +| Name | Description | Value | +| ---------------------------- | ------------------------------------------------------------------------------------------ | ------ | +| `serviceAccount.create` | Whether or not if the service account should be created for this Helm installation. | `true` | +| `serviceAccount.annotations` | Any additional annotations to append to this ServiceAccount | `{}` | +| `serviceAccount.name` | The name of the service account, this will be the Helm installation name if this is empty. | `""` | diff --git a/charts/charted/templates/NOTES.txt b/charts/charted/templates/NOTES.txt new file mode 100644 index 0000000..e69de29 diff --git a/charts/charted/templates/helpers.tpl b/charts/charted/templates/helpers.tpl new file mode 100644 index 0000000..e69de29 diff --git a/charts/charted/values.yaml b/charts/charted/values.yaml new file mode 100644 index 0000000..823387b --- /dev/null +++ b/charts/charted/values.yaml @@ -0,0 +1,87 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +## @section Global Parameters +## @descriptionStart +## Contains any global parameters that will affected all objects in the `youtrack` Helm chart. +## @descriptionEnd +## +## @param global.replicas Amount of replicas to spawn +## @param global.resources Resource list to apply to all containers. +## @param global.fullNameOverride String to fully override the Helm installation name for all objects +## @param global.nameOverride String to override the Helm installation name for all objects, will be in conjunction with a prefix of `-` +## @param global.clusterDomain Domain host that maps to the cluster +## @param global.nodeSelector Selector labels to apply to contraint the pods to specific nodes. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). +## @param global.tolerations List of all taints/tolerations to apply in conjunction with `global.affinity`. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) +## @param global.affinity Map of all the affinity to apply to the spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). +## @param global.annotations Map of annotations to append to on all objects that this Helm chart creates. +## @param global.extraEnvVars List of extra environment variables to append to all init/sidecar containers and normal containers. +## @param global.initContainers List of init containers to create. +## @param global.podSecurityContext Security context for all spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). +## @param global.containerSecurityContext Security context for all init, sidecar, and normal containers. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). +global: + replicas: 1 + fullNameOverride: "" + nameOverride: "" + clusterDomain: cluster.local + nodeSelector: {} + tolerations: [] + affinity: {} + annotations: {} + extraEnvVars: [] + initContainers: [] + podSecurityContext: {} + containerSecurityContext: {} + resources: + {} + ## Example: + ## limits: + ## memory: 2Gi + ## cpu: 1500m + ## requests: + ## memory: 512Mi + ## cpu: 150m + +## @section Docker Image Parameters +## @descriptionStart +## Parameters to modify the Docker image that is ran. +## @descriptionEnd +## +## @param image.pullPolicy [string] [Pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) when pulling the image. +## @param image.registry Registry URL to point to. For Docker Hub, use an empty string. +## @param image.image Image name. +## @param image.tag The tag of the image. Keep this as a empty string if you wish to use the default app's version. +## @param image.digest Digest in the form of `:`, this will replace the `image.tag` property if this is not empty. +image: + pullPolicy: IfNotPresent + registry: cr.noelware.cloud + image: charted/server + tag: "" # keep empty for the app version + digest: "" + +## @section Service Account Parameters +## @param serviceAccount.create Whether or not if the service account should be created for this Helm installation. +## @param serviceAccount.annotations Any additional annotations to append to this ServiceAccount +## @param serviceAccount.name The name of the service account, this will be the Helm installation name if this is empty. +serviceAccount: + create: true + annotations: {} + name: "" diff --git a/charts/emails/Chart.lock b/charts/emails/Chart.lock new file mode 100644 index 0000000..2336a47 --- /dev/null +++ b/charts/emails/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.14.1 +digest: sha256:c18e87191d35e805a40a45ba75edb912efc98d6e54bc2ff466294f93d0218382 +generated: "2024-02-02T10:20:49.337134114-08:00" diff --git a/charts/emails/Chart.yaml b/charts/emails/Chart.yaml new file mode 100644 index 0000000..5f4df1f --- /dev/null +++ b/charts/emails/Chart.yaml @@ -0,0 +1,57 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +kubeVersion: ">=1.26" +description: "📦 Free, open source, and reliable Helm Chart registry made in Rust" +apiVersion: v2 + +# renovate: datasource=github-tags version=charted-dev/emails +appVersion: 0.2.0 +version: 0.1.0 +type: application +home: https://charts.noelware.org +name: charted-emails +icon: https://cdn.noelware.org/branding/charted.svg +sources: + - https://github.com/charted-dev/emails + - https://github.com/charted-dev/helm-charts +keywords: + - email-service + - grpc +maintainers: + - name: Noelware, LLC. + email: team@noelware.org + url: https://noelware.org + - name: Noel Towa + email: cutie@floofy.dev + url: https://floofy.dev +annotations: + charts.noelware.org/licenses: Apache-2.0 + charts.noelware.org/categories: RpcService + charts.noelware.org/owners: |- + - user: noel + maintainer: Noel Towa + - organization: noelware + maintainer: Noelware, LLC. +dependencies: + - name: common + version: 2.14.1 + repository: oci://registry-1.docker.io/bitnamicharts diff --git a/charts/emails/README.md b/charts/emails/README.md new file mode 100644 index 0000000..7708a40 --- /dev/null +++ b/charts/emails/README.md @@ -0,0 +1,57 @@ +# 🐻‍❄️🪻 Helm Chart for `charted-emails` + +This is the Helm Chart to install [charted-emails](https://github.com/charted-dev/emails) on Kubernetes with Helm. + +## Requirements + +- Kubernetes v1.26 or higher +- Helm 3.12 or higher + +## Installation + +```shell +$ helm repo add charted https://charts.noelware.org/~/charted +$ helm install emails charted/emails --namespace charted --create-namespace +``` + +## Parameters + +### Global Parameters + +Contains any global parameters that will affected all objects in the `youtrack` Helm chart. + +| Name | Description | Value | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `global.replicas` | Amount of replicas to spawn | `1` | +| `global.resources` | Resource list to apply to all containers. | `{}` | +| `global.fullNameOverride` | String to fully override the Helm installation name for all objects | `""` | +| `global.nameOverride` | String to override the Helm installation name for all objects, will be in conjunction with a prefix of `-` | `""` | +| `global.clusterDomain` | Domain host that maps to the cluster | `cluster.local` | +| `global.nodeSelector` | Selector labels to apply to contraint the pods to specific nodes. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). | `{}` | +| `global.tolerations` | List of all taints/tolerations to apply in conjunction with `global.affinity`. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) | `[]` | +| `global.affinity` | Map of all the affinity to apply to the spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). | `{}` | +| `global.annotations` | Map of annotations to append to on all objects that this Helm chart creates. | `{}` | +| `global.extraEnvVars` | List of extra environment variables to append to all init/sidecar containers and normal containers. | `[]` | +| `global.initContainers` | List of init containers to create. | `[]` | +| `global.podSecurityContext` | Security context for all spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | `{}` | +| `global.containerSecurityContext` | Security context for all init, sidecar, and normal containers. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). | `{}` | + +### Docker Image Parameters + +Parameters to modify the Docker image that is ran. + +| Name | Description | Value | +| ------------------ | --------------------------------------------------------------------------------------------------------------- | ------------------- | +| `image.pullPolicy` | [Pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) when pulling the image. | `""` | +| `image.registry` | Registry URL to point to. For Docker Hub, use an empty string. | `cr.noelware.cloud` | +| `image.image` | Image name. | `charted/emails` | +| `image.tag` | The tag of the image. Keep this as a empty string if you wish to use the default app's version. | `""` | +| `image.digest` | Digest in the form of `:`, this will replace the `image.tag` property if this is not empty. | `""` | + +### Service Account Parameters + +| Name | Description | Value | +| ---------------------------- | ------------------------------------------------------------------------------------------ | ------ | +| `serviceAccount.create` | Whether or not if the service account should be created for this Helm installation. | `true` | +| `serviceAccount.annotations` | Any additional annotations to append to this ServiceAccount | `{}` | +| `serviceAccount.name` | The name of the service account, this will be the Helm installation name if this is empty. | `""` | diff --git a/charts/emails/templates/NOTES.txt b/charts/emails/templates/NOTES.txt new file mode 100644 index 0000000..e69de29 diff --git a/charts/emails/templates/helpers.tpl b/charts/emails/templates/helpers.tpl new file mode 100644 index 0000000..e69de29 diff --git a/charts/emails/values.yaml b/charts/emails/values.yaml new file mode 100644 index 0000000..79f85fa --- /dev/null +++ b/charts/emails/values.yaml @@ -0,0 +1,87 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +## @section Global Parameters +## @descriptionStart +## Contains any global parameters that will affected all objects in the `youtrack` Helm chart. +## @descriptionEnd +## +## @param global.replicas Amount of replicas to spawn +## @param global.resources Resource list to apply to all containers. +## @param global.fullNameOverride String to fully override the Helm installation name for all objects +## @param global.nameOverride String to override the Helm installation name for all objects, will be in conjunction with a prefix of `-` +## @param global.clusterDomain Domain host that maps to the cluster +## @param global.nodeSelector Selector labels to apply to contraint the pods to specific nodes. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). +## @param global.tolerations List of all taints/tolerations to apply in conjunction with `global.affinity`. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration) +## @param global.affinity Map of all the affinity to apply to the spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). +## @param global.annotations Map of annotations to append to on all objects that this Helm chart creates. +## @param global.extraEnvVars List of extra environment variables to append to all init/sidecar containers and normal containers. +## @param global.initContainers List of init containers to create. +## @param global.podSecurityContext Security context for all spawned Pods. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). +## @param global.containerSecurityContext Security context for all init, sidecar, and normal containers. Read more in the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). +global: + replicas: 1 + fullNameOverride: "" + nameOverride: "" + clusterDomain: cluster.local + nodeSelector: {} + tolerations: [] + affinity: {} + annotations: {} + extraEnvVars: [] + initContainers: [] + podSecurityContext: {} + containerSecurityContext: {} + resources: + {} + ## Example: + ## limits: + ## memory: 2Gi + ## cpu: 1500m + ## requests: + ## memory: 512Mi + ## cpu: 150m + +## @section Docker Image Parameters +## @descriptionStart +## Parameters to modify the Docker image that is ran. +## @descriptionEnd +## +## @param image.pullPolicy [string] [Pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) when pulling the image. +## @param image.registry Registry URL to point to. For Docker Hub, use an empty string. +## @param image.image Image name. +## @param image.tag The tag of the image. Keep this as a empty string if you wish to use the default app's version. +## @param image.digest Digest in the form of `:`, this will replace the `image.tag` property if this is not empty. +image: + pullPolicy: IfNotPresent + registry: cr.noelware.cloud + image: charted/emails + tag: "" # keep empty for the app version + digest: "" + +## @section Service Account Parameters +## @param serviceAccount.create Whether or not if the service account should be created for this Helm installation. +## @param serviceAccount.annotations Any additional annotations to append to this ServiceAccount +## @param serviceAccount.name The name of the service account, this will be the Helm installation name if this is empty. +serviceAccount: + create: true + annotations: {} + name: "" diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..0a2c8bc --- /dev/null +++ b/default.nix @@ -0,0 +1,28 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +let + lockfile = builtins.fromJSON (builtins.readFile ./flake.lock); + compat = builtins.fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lockfile.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = "${lockfile.nodes.flake-compat.locked.narHash}"; + }; +in + (import compat {src = ./.;}).defaultNix.default diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4d43e29 --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1706683685, + "narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a262066 --- /dev/null +++ b/flake.nix @@ -0,0 +1,49 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +{ + description = "🐻‍❄️🪻 Helm Charts available for Noelware's charted project"; + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixpkgs-unstable; + flake-utils.url = github:numtide/flake-utils; + flake-compat = { + url = github:edolstra/flake-compat; + flake = false; + }; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs {inherit system;}; + helm = pkgs.kubernetes-helm; + in { + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + helm + bun + ]; + }; + }); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5d0f733 --- /dev/null +++ b/package.json @@ -0,0 +1 @@ +{ "dependencies": { "@bitnami/readme-generator-for-helm": "/workspaces/Noelware/Products/charted/helm-charts/.cache/bitnami-helm-gen" } } \ No newline at end of file diff --git a/scripts/emit-values b/scripts/emit-values new file mode 100755 index 0000000..a39509a --- /dev/null +++ b/scripts/emit-values @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +while [ -L "$BASH_SRC" ]; do + target=$(readlink "$BASH_SRC") + if [[ $target == /* ]]; then + BASH_SRC=$target + else + dir=$(dirname "$BASH_SRC") + BASH_SRC=$dir/$target + fi +done + +DIR=$(cd -P "$(dirname "$BASH_SRC")" >/dev/null 2>&1 && pwd) + +if ! command -v bun >/dev/null; then + echo "[ERROR] ===> Missing \`bun\` in host machine, install it please!" + exit 1 +fi + +! [ -d "$DIR/.cache" ] && mkdir -p "$DIR/.cache" + +if ! [ -d "$DIR/.cache/bitnami-helm-gen" ]; then + echo "===> Missing $DIR/.cache/bitnami-helm-gen directory, installing..." + + git clone https://github.com/bitnami-labs/readme-generator-for-helm "$DIR/.cache/bitnami-helm-gen" + bun install "$DIR/.cache/bitnami-helm-gen" +fi + +# TODO(@auguwu): auto generate this list (if we need to) +charts=( + "$DIR/charts/charted" + "$DIR/charts/emails" +) + +for chart in "${charts[@]}"; do + rel="./$(realpath --relative-to="$DIR" "$chart")" + echo "Updating README.md with Helm values... [$rel]" + + if ! [ -f "$chart/values.yaml" ]; then + echo ".... Skipping due to no \`values.yaml\` in $rel" + continue + fi + + if ! [ -f "$chart/README.md" ]; then + echo ".... Skipping due to no \`README.md\` in $rel" + continue + fi + + echo ".... Generating..." + (cd "$DIR/.cache/bitnami-helm-gen" && bun --bun bin/index.js --values "$chart/values.yaml" --readme "$chart/README.md") + + if [ "$?" != "0" ]; then + echo ".... Failed to generate, view logs above" + exit 1 + fi +done diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..ec18fbb --- /dev/null +++ b/shell.nix @@ -0,0 +1,28 @@ +# 🐻‍❄️🪻 helm-charts: Helm Charts available for Noelware's charted project +# Copyright (c) 2023-2024 Noelware, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +let + lockfile = builtins.fromJSON (builtins.readFile ./flake.lock); + compat = builtins.fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/${lockfile.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = "${lockfile.nodes.flake-compat.locked.narHash}"; + }; +in + (import compat {src = ./.;}).shellNix.default