Задача
Helm мощный и гибкий инструмент управления ресурсами в Kubernetes.
А что если одним Helm Chart пользуются несколько команд для развертывания своих приложений в Kubernetes? Как гарантировать, что Helm Chart как минимум рендериться после внесения изменений, прежде чем публиковать Helm Chart в репозиторий артефактов? Как гарантировать, что новая версия Helm Chart не "сломает" установку приложения в Kubernetes в критический момент(например во время релиза целевого продукта)?
Этими вопросами задался и я при разработке подобного Helm Chart.
Дополнительные требования к задаче
Надо отметить, что в моем случае, в качестве хранилища артефактов используется JFrog Artifactory внутри организации.
Для репозиториев есть явное деление на группы, в которые разрешено публиковать артефакты. В большинстве случаев под группой понимается groupId из pom.xml файла проекта/модуля. 
Аналогичное правило работает и для репозиториев хранения Helm Charts.
Выбор инструмента
В моих проектах используется Apache Maven как инструмент сборки, запуска тестов, упаковки и публикации артефактов.
Под артефактом понимается все то, что создается при сборке проекта: JAR/WAR/EAR-файлы, Docker образы, сопутствующие файлы конфигурации, и тп.
Ок, я умею в Maven.
Ок, я умею в Helm Charts.
Почему бы не совместить эти два инструмента?
Что предлагает сообщество, с точки зрения плагинов для Apache Maven, которые можно использовать для работы с таким зверем как Helm Charts?
Сообщество предлагает два плагина:
Первый позволяет:
- довольно гибко настроить подготовку Helm Chart как артефакта 
- позволяет сделать как минимум прогнать Helm Chart через встроенный в Helm линтер 
- позволяет опубликовать Helm Chart в репозиторий таким образом, что Helm Chart будет использоваться только лишь в том случае, если при выполнении - helm upgradeдобавить аргумент- --devel, в данном случае будет использоваться пред-релизная(или developement) версия Helm Chart
Второй - не удовлетворял некоторым моим требованиям, поэтому решил идти в бой с первым!
Настройка
Создадим простой проект типа maven, со следующей структурой каталогов/файлов:
./pom.xml
./src/helm/Chart.yaml
./src/helm/templates/config-map.yamlСодержимое ./src/helm/Chart.yaml:
apiVersion: v2
name: sample-helm-chart
version: 0.0.0Тут важно отметить значения поля
version- в исходном коде оно всегда будет равно0.0.0
Содержимое ./src/helm/templates/config-map.yaml :
apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-config-map
data:
  foo: barТо есть Helm Chart создает объект типа ConfigMap с одним ключом foo и значением bar
А теперь самое интересное, содержимое pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>sample-helm-chart</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>helm</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>io.kokuwa.maven</groupId>
                <artifactId>helm-maven-plugin</artifactId>
                <version>6.3.0</version>
                <extensions>true</extensions>
                <configuration>
                    <chartDirectory>${project.basedir}/src/helm</chartDirectory>
                    <chartVersion>${project.version}</chartVersion>
                    <timestampOnSnapshot>true</timestampOnSnapshot>
                    <addDefaultRepo>false</addDefaultRepo>
                    <uploadRepoStable>
                        <name>central</name>
                        <url>https://example.org/artfactory/hlm-all</url>
                        <type>ARTIFACTORY</type>
                        <useGroupId>true</useGroupId>
                    </uploadRepoStable>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>Давайте пройдемся по конфигурации плагина в секции <build>:
- chartDirectory- указывает на корневой каталог, содержащий код Helm Chart
- chartVersion- связываем версию Helm Chart и версию проекта/модуля
- timestampOnSnapshot- в случае, если при сборке версия проекта/модуля имеет суффикс- -SNAPSHOT- то суффикс будет заменен на текущее время в формате- yyyyMMddHHmmss(формат по умолчанию)
- addDefaultRepo- нам не нужен репозиторий по умолчанию, так как Helm Chart будет публиковаться в хранилище артефактов внутри организации.
- uploadRepoStable/name- имя/идентификатор сервера из- settings.xml. Необходимо в том числе для аутентификации в хранилище артефактов. В- settings.xmlдолжны быть заданы значения полей- usernameи- passwordдля сервера указанного в данном поле.
- uploadRepoStable/url- Адрес хранилища артефактов и базовый путь публикации артефакта.
- uploadRepoStable/type- Тип репозитория. Плагин поддерживает три типа репозиториев.
- uploadRepoStable/usegGroudId- согласно дополнительным требованиям к задаче, необходимо публиковать артефакты в свои группы. В случае если- usegGroudIdравен- true, тогда, после публикации нашего Helm Chart в хранилище артефактов, Helm Chart из нашего примера можно будет скачать по адресу- https://example.org/artfactory/hlm-all/org/example/0.0.1-SNAPSHOT/sample-helm-chart-0.0.1-20220701142516.tgz
Используя дополнительные плагины для Apache Maven, можно настроить автоматический инкремент версии, чтобы можно было выпускать релизные версии Helm Chart.
Пожалуй, самый важный параметр timestampOnSnapshot - зачем он нужен и как он помогает отделить мух от ... в достижении цели?
Как было описано в описании параметров конфигурации плагина:
в случае, если при сборке версия проекта/модуля имеет суффикс
-SNAPSHOT- то суффикс будет заменен на текущее время в форматеyyyyMMddHHmmss(формат по умолчанию)
Что это дает?
Обратимся к справке по SemVer2:
A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.–.
То есть, если в значении версии, помимо главных атрибутов <MAJOR>.<MINOR>.<PATCH>, есть некий суффикс(в нашем случае текущее время), то это считается пред-релизной версией, или с точки зрения Helm - development версией, а значит, когда выполняется команда helm upgrade будет использоваться только релизная версия Helm Chart, если таковая имеется в репозитории.
Если есть необходимость использовать пред-релизную(или development) версию Helm Chart - надо явно "сказать" Helm'у  с помощью аргумента: helm upgrade --devel .
Заключение
Перед тем как имплементировать решение внутри организации, используемый плагин не поддерживал ряд функциональности, которая вытекала из Дополнительных требований к задаче, а так как у меня есть небольшой опыт написания плагинов для Apache Maven - я добавил недостающую функциональность в плагин.
Но самое сложное было то, что плагин давно не выпускался и пришлось не мало "побегать" за владельцами плагина. Благо ребята оказались отзывчивые и мы дружно вдохнули новую жизнь в плагин!
Как вы считаете нужен ли релизный цикл для таких вещей как Helm Charts?
 
           
 
Terranz
Очень полезно, спасибо. Мы деплоим не из мавена в хелмы, но тоже может пригодится.