From 7eed1c8a01b469f74191a54c9d87711e9876014f Mon Sep 17 00:00:00 2001 From: Till Krullmann Date: Sun, 20 Jan 2019 14:07:31 +0100 Subject: [PATCH 1/5] Increment version to 0.3.0 --- gradle.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9fc6cfe4..2cba50dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ kotlinVersion=1.3.11 group=org.unbroken-dome.gradle-plugins.helm -version=0.2.3 +version=0.3.0 + From 910a728df694989a1a43b2bba390b8f3f179fabd Mon Sep 17 00:00:00 2001 From: Till Krullmann Date: Sun, 20 Jan 2019 13:45:35 +0100 Subject: [PATCH 2/5] Generate documentation --- build.gradle.kts | 22 +++++++++ docs/defining-charts.adoc | 75 +++++++++++++++++++++++++++++++ docs/filtering-chart-sources.adoc | 53 ++++++++++++++++++++++ docs/index.adoc | 12 +++++ docs/plugins.adoc | 50 +++++++++++++++++++++ 5 files changed, 212 insertions(+) create mode 100644 docs/defining-charts.adoc create mode 100644 docs/filtering-chart-sources.adoc create mode 100644 docs/index.adoc create mode 100644 docs/plugins.adoc diff --git a/build.gradle.kts b/build.gradle.kts index 4130e4d4..51c19313 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import org.asciidoctor.gradle.AsciidoctorTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -7,6 +8,7 @@ plugins { id("com.gradle.plugin-publish") version "0.10.0" id("org.jetbrains.dokka") version "0.9.17" id("maven-publish") + id("org.asciidoctor.convert") version "1.5.9.2" } @@ -104,3 +106,23 @@ pluginBundle { } } } + + +asciidoctorj { + version = "1.6.0" +} + +dependencies { + "asciidoctor"("com.bmuschko:asciidoctorj-tabbed-code-extension:0.2") +} + + +val asciidoctor: AsciidoctorTask by tasks.getting(AsciidoctorTask::class) { + sourceDir("docs") + options(mapOf( + "doctype" to "book" + )) + attributes(mapOf( + "project-version" to project.version + )) +} \ No newline at end of file diff --git a/docs/defining-charts.adoc b/docs/defining-charts.adoc new file mode 100644 index 00000000..37db7bf5 --- /dev/null +++ b/docs/defining-charts.adoc @@ -0,0 +1,75 @@ += Defining Charts + +With the `org.unbroken-dome.helm` plugin you can configure your Helm chart using a declarative DSL, and the corresponding Gradle tasks will be added automatically. + +.build.gradle +[source,groovy,subs="attributes"] +---- +plugins { + id 'org.unbroken-dome.helm' version '{project-version}' +} + +helm { + charts { + foo { + chartName = 'foo' + chartVersion = '1.2.3' + sourceDir = file('src/helm') + } + } +} +---- + +Note that the chart moniker used in the DSL and the actual chart name are not necessarily the same, unless you set them to the same value. + +From this chart definition, a number of tasks will be created automatically: + +* Task `helmFilterFooChartSources`: Resolve placeholders in the chart sources, and copy everything to a directory build/helm/foo (`helm package` requires the chart directory to have the same name as the chart). +* Task `helmBuildFooChartDependencies`: equivalent to the `helm dep build` CLI command. +* Task `helmLintFooChart`: equivalent to the `helm lint` CLI command. +* Task `helmPackageFooChart`: equivalent to the `helm package` CLI command. + +Also, the following configurations and artifacts will be created: + +* Configuration `helmFoo`: Contains a single artifact that has the chart directory as its output, and is built by the `helmBuildFooChartDependencies` task. +* Configuration `helmFooPackaged`: Contains a single artifact that has the packaged (tar.gz) chart file as its output, and is built by the `helmPackageFooChart` task. + +In addition, the plugin creates a task named `helmPackage` that will depend on all charts' package task, so it can be used to build all the project's charts. + +== Using the `main` chart + +If you don't define any charts in the `helm.charts` DSL block, then by convention a chart named `"main"` will be defined automatically, equivalent to the following: + +[source,groovy] +---- +helm.charts { + main { + chartName = project.name + chartVersion = project.version + sourceDir = file('src/main/helm') + } +} +---- + +NOTE: since Helm chart versions must be SemVer-compliant, you should either make sure that the project version is a valid SemVer, or set the main chart version to a different value. + +The `main` chart will not be instantiated if you define any other charts; however you can reference the `main` chart to modify some of its properties: + +[source,groovy] +---- +helm.charts.main.chartVersion = '1.0.0' +---- + +== Using Charts in a Multi-Project Build + +Of course, instead of defining multiple charts in one Gradle project, you can also have a multi-project build where each subproject defines a single `main` chart. That way, you can take advantage of the `main` chart convention in every project. + +However, note that the default values defined in the `helm` block are not automatically inherited by subprojects. If you want to define your Helm CLI options in one central place, you can add a `subprojects` clause in the root project: + +[source,groovy] +---- +subprojects { + helm.home = "${rootProject.buildDir}/helm/home +} +---- + diff --git a/docs/filtering-chart-sources.adoc b/docs/filtering-chart-sources.adoc new file mode 100644 index 00000000..52a82d94 --- /dev/null +++ b/docs/filtering-chart-sources.adoc @@ -0,0 +1,53 @@ += Filtering Chart Sources + +The plugin includes a _filtering_ step that will resolve placeholders in certain chart files before the chart is packaged. + +This is most useful to insert the name and version into the chart, because they will often correspond to the project version: + +.Chart.yaml +[source,yaml] +---- +name: ${chartName} +version: ${chartVersion} +---- + +The `chartName` and `chartVersion` placeholders are automatically available based on the corresponding properties of the chart in the DSL. You can also define additional placeholders and their values (see below). + +NOTE: Only the files _Chart.yaml_, _requirements.yaml_ and _values.yaml_ are filtered this way. The actual templates in the chart are not filtered; you should use Helm's templating constructs instead. + +== Configure the Filtering Step + +You can fine-tune the filtering process by modifying the `filtering` block, which is available both directly inside the `helm` block, as well as each chart. The chart-level filtering inherits from the global filtering but will override properties if they are defined in both places: + +[source,groovy] +---- +helm { + filtering { + // Set a custom pattern for placeholder delimiters. The default is '${' and '}'. + placeholderPrefix = '@[' + placeholderSuffix = ']' + } + + charts { + main { + filtering { + // add a custom value that can be resolved inside the YAML files. + values.put 'dockerImage', 'busybox' + } + } + } +} +---- + +The following properties are available in the `filtering` block: + +|=== +| Property | Type | Default Value | Description + +| enabled | `boolean` | `true` | Enables or disables the entire filtering step. +| placeholderPrefix | `String` | `${` | The string that marks the end of a resolvable placeholder inside the filtered YAML files. +| placeholderSuffix | `String` | `}` | The string that marks the end of a resolvable placeholder inside the filtered YAML files. +| values | `Map` | | The values to be resolved in placeholders. +|=== + +`values` is a special `MapProperty` which merges the values from different levels of `filtering` blocks. That means you can add some values in the global `helm.filtering` block, add some more inside the individual chart's `filtering` block, and they will all be available for the placeholder resolution. diff --git a/docs/index.adoc b/docs/index.adoc new file mode 100644 index 00000000..cfe10fdc --- /dev/null +++ b/docs/index.adoc @@ -0,0 +1,12 @@ += Gradle Helm Plugin +:revnumber: {project-version} +:doctype: book +:toc: left +:icons: font +:sectanchors: + + +include::defining-charts.adoc[leveloffset=1] + +include::filtering-chart-sources.adoc[leveloffset=1] + diff --git a/docs/plugins.adoc b/docs/plugins.adoc new file mode 100644 index 00000000..461bb7e8 --- /dev/null +++ b/docs/plugins.adoc @@ -0,0 +1,50 @@ += Plugins + +The _gradle-helm-plugin_ library actually consists of four different plugins, with different use cases for each: + +== `org.unbroken-dome.helm-commands` plugin + +This plugin does little more than add the plugin library to your build's classpath so you can define tasks for various Helm CLI commands. Use this if you want to use Helm CLI commands directly as tasks, without any of the declarative DSL that the `helm` plugin offers. + +The plugin installs a `helm` DSL extension on the project which can be used to define default values for all Helm tasks (like `home` or `kubeContext`). Apart from this, the plugin does not create any tasks or other project model objects automatically. + +Note that the `helm-commands` plugin is implied when using any of the other plugins like `org.unbroken-dome.helm` or `org.unbroken-dome.helm-publish`, so you only need to list it when using it on its own. + +=== Example + +.build.gradle +[source,groovy] +---- +import org.unbrokendome.gradle.plugins.helm.command.tasks.* + +plugins { + id 'org.unbroken-dome.helm-commands' version '' +} + +helm { + home = file("${project.buildDir}/helm/home") +} + +task helmInit(type: HelmInit) + +task installMariaDb(type: HelmInstall) { + dependsOn helmInit + chart = 'stable/mariadb' + version = '4.3.1' + releaseName = 'mariadb' +} +---- + +== `org.unbroken-dome.helm` plugin + +This is the main plugin of the suite. It enables a variety of extra DSL blocks inside `helm`, for example `charts` and `repositories`. + + +== `org.unbroken-dome.helm-publish` plugin + +Use this plugin _in addition to_ the `org.unbroken-dome.helm` plugin if you want to publish your charts to a remote repository like ChartMuseum. It enables the `helm.publishing` DSL block and adds publishing tasks for each chart. + + +== `org.unbroken-dome.helm-releases` plugin + +Use this plugin to manage releases (install/update/delete) on a remote Kubernetes cluster. You can declare your releases using Gradle DSL, referencing either Helm charts built using the other projects, or existing charts from a Helm repository. From 5a2dbd6391a4b2953046257b54d56b031f1fa59a Mon Sep 17 00:00:00 2001 From: Till Krullmann Date: Sun, 20 Jan 2019 23:22:27 +0100 Subject: [PATCH 3/5] Documentation --- build.gradle.kts | 9 +- docs/config-from-project-properties.adoc | 157 ++++++++++++++++++ docs/configure-helm.adoc | 92 +++++++++++ docs/defining-charts.adoc | 116 ++++++++++--- docs/defining-repositories.adoc | 111 +++++++++++++ docs/filtering-chart-sources.adoc | 51 ++++-- docs/index.adoc | 23 +++ docs/linting-charts.adoc | 157 ++++++++++++++++++ docs/managing-chart-dependencies.adoc | 143 ++++++++++++++++ docs/managing-releases.adoc | 199 +++++++++++++++++++++++ docs/plugins.adoc | 104 +++++++++--- docs/prerequisites.adoc | 19 +++ docs/publishing-charts.adoc | 155 ++++++++++++++++++ docs/quickstart.adoc | 36 ++++ docs/using-helm-commands.adoc | 39 +++++ 15 files changed, 1351 insertions(+), 60 deletions(-) create mode 100644 docs/config-from-project-properties.adoc create mode 100644 docs/configure-helm.adoc create mode 100644 docs/defining-repositories.adoc create mode 100644 docs/linting-charts.adoc create mode 100644 docs/managing-chart-dependencies.adoc create mode 100644 docs/managing-releases.adoc create mode 100644 docs/prerequisites.adoc create mode 100644 docs/publishing-charts.adoc create mode 100644 docs/quickstart.adoc create mode 100644 docs/using-helm-commands.adoc diff --git a/build.gradle.kts b/build.gradle.kts index 51c19313..bdc5cc23 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -117,12 +117,15 @@ dependencies { } -val asciidoctor: AsciidoctorTask by tasks.getting(AsciidoctorTask::class) { +tasks.named("asciidoctor", AsciidoctorTask::class) { sourceDir("docs") + sources(delegateClosureOf { include("index.adoc") }) + options(mapOf( "doctype" to "book" )) attributes(mapOf( - "project-version" to project.version + "project-version" to project.version, + "source-highlighter" to "prettify" )) -} \ No newline at end of file +} diff --git a/docs/config-from-project-properties.adoc b/docs/config-from-project-properties.adoc new file mode 100644 index 00000000..e16bc772 --- /dev/null +++ b/docs/config-from-project-properties.adoc @@ -0,0 +1,157 @@ += Configuration from Project Properties + +Many settings can be configured by Gradle +https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties[project properties] +instead of specifying them in the DSL. This has the advantage that you can pass them on the command line +(using `-P` switches) or a local `~/gradle.properties` file to account for different build environments. +In addition, such properties are automatically inherited by subprojects. + +Some of these properties allow evaluation as a Groovy `GString`, so that you can do things like +`-Phelm.home=$buildDir/helm/home` (but the dollar signs may need to be escaped so the shell does not +treat them as environment variables). + +In general, the name of the project property corresponds to the path of the property in the DSL, +e.g. `helm.home`. + +NOTE: Properties set explicitly in your Gradle script have precedence over properties from the command line +or `gradle.properties` file, so it may be better to put them in `gradle.properties` in the first place, to +allow for easier overriding. + +== Basic Helm Properties + +[cols="3,4,1"] +|=== +| Property | Description | GString + +| `helm.executable` +| Path to the Helm CLI executable. Defaults to `helm`. +| icon:check[] + +| `helm.debug` +| Enable verbose output from the Helm CLI. +| + +| `helm.home` +| Location of the Helm home directory. +| icon:check[] + +| `helm.host` +| Address of Tiller, in the format `host:port`. +| + +| `helm.kubeContext` +| Name of the kubeconfig context to use. +| + +| `helm.kubeConfig` +| Path to the Kubernetes configuration file. +| icon:check[] + +| `helm.timeoutSeconds` +| Timeout used for various Helm CLI commands. +| + +| `helm.outputDir` +| The base output directory for charts; defaults to `$buildDir/helm/charts`. +| icon:check[] +|=== + +== Tiller + +[cols="2*"] +|=== +| Property | Description + +| `helm.tiller.install` +| If `true`, install Tiller on the cluster. + +| `helm.tiller.namespace` +| Namespace of Tiller. + +| `helm.tiller.forceUpgrade` +| Force upgrade of Tiller to the current Helm version. + +| `helm.tiller.historyMax` +| Limit the maximum number of revisions saved per release. + +| `helm.tiller.replicas` +| Amount of Tiller instances to run on the cluster. + +| `helm.tiller.serviceAccount` +| Name of the service account to use for Tiller. + +| `helm.tiller.image` +| Override the Tiller image. + +| `helm.tiller.upgrade` +| Upgrade if Tiller is already installed. + +| `helm.tiller.wait` +| Block until Tiller is running and ready to receive requests (defaults to `true`) + +|=== + +== Repositories + +You can configure repositories entirely from Gradle properties -- just the presence of a set of +`helm.repositories..` properties will automatically create a corresponding repository. + +[cols="2*"] +|=== +| Property | Description + +| `helm.repository..url` +| The URL of the repository. + +| `helm.repository..credentials.username` +| Username for password-based authentication. + +| `helm.repository..credentials.password` +| Password for password-based authentication. + +| `helm.repository..credentials.certificateFile` +| Client certificate file for certificate authentication. + +| `helm.repository..credentials.keyFile` +| Private key file for certificate authentication. +|=== + +== Filtering + +[cols="2*"] +|=== +| Property | Description + +| `helm.filtering.enabled` +| Globally enable or disable filtering. Defaults to `true`. + +| `helm.filtering.placeholderPrefix` +| Prefix that demarcates a placeholder in filtered YAML files. Defaults to `${`. + +| `helm.filtering.placeholderSuffix` +| Suffix that demarcates a placeholder in filtered YAML files. Defaults to `}`. +|=== + +== Linting + +[cols="2*"] +|=== +| Property | Description + +| `helm.lint.enabled` +| Globally enable or disable linting. Defaults to `true`. + +| `helm.lint.strict` +| Globally enable strict mode for linting. Defaults to `false`. + +|=== + +== Releases + +[cols="2*"] +|=== +| Property | Description + +| `helm.dryRun` +| Only perform a dry run when installing or deleting releases. +|=== diff --git a/docs/configure-helm.adoc b/docs/configure-helm.adoc new file mode 100644 index 00000000..b6d3bb3e --- /dev/null +++ b/docs/configure-helm.adoc @@ -0,0 +1,92 @@ += Configuring the Helm Client + +The global flags for Helm can be configured directly in the `helm` DSL block. + +Most of these correspond to options that are passed to every Helm CLI command as a parameter +or an environment variable, or parameters that are passed to the initial `helm init` call that +sets up the local Helm environment. + +[TIP] +==== +As these settings can be dependent on the build environment, it is often useful to specify them in +`gradle.properties` or on the command line instead. +See <>. +==== + + +The following `helm.home` sets the Helm home directory to a path inside the Gradle build directory. + +[source,groovy,role="primary"] +.Groovy +---- +helm { + home = file("$buildDir/helm/home") +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + home.set(file("$buildDir/helm/home")) +} +---- + + +[TIP] +==== +Setting the Helm home directory to a path like this is actually a good practice, as it makes your +build less dependent on the local machine, and does not pollute the local Helm configuration. +==== + +The plugin splits what is usually done by `helm init` into two steps: + +Task `helmInitClient`:: +This will call `helm init --client-only`, skipping a remote Tiller installation. Since this sets up the +Helm client, most other Helm tasks will have a dependency on this. + +Task `helmInitServer`:: +This will call `helm init` which also installs Tiller in the remote cluster. Only tasks that actually +communicate with Tiller (like +link:dokka/gradle-helm-plugin/org.unbrokendome.gradle.plugins.helm.command.tasks/-helm-install/[`HelmInstall`] +or +link:dokka/gradle-helm-plugin/org.unbrokendome.gradle.plugins.helm.command.tasks/-helm-delete/[`HelmDelete`] +depend on this. + + +== Configuring Tiller + +Inside the `helm.tiller` block you can configure certain settings for the remote Tiller installation. +Most of these correspond to parameters of the `helm init` CLI command. + +[source,groovy,role="primary"] +.Groovy +---- +helm { + tiller { + // Install/expect Tiller in a different namespace than kube-system + namespace = "custom-namespace" + + // Set a service account for Tiller + serviceAccount = "tiller-service-account" + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + tiller { + // Install/expect Tiller in a different namespace than kube-system + namespace.set("custom-namespace") + + // Set a service account for Tiller + serviceAccount.set("tiller-service-account") + } +} +---- + +Please refer to the +link:dokka/gradle-helm-plugin/org.unbrokendome.gradle.plugins.helm.dsl/-tiller/[API Reference] for a +full list of configuration options. diff --git a/docs/defining-charts.adoc b/docs/defining-charts.adoc index 37db7bf5..c911f6b1 100644 --- a/docs/defining-charts.adoc +++ b/docs/defining-charts.adoc @@ -1,9 +1,9 @@ = Defining Charts -With the `org.unbroken-dome.helm` plugin you can configure your Helm chart using a declarative DSL, and the corresponding Gradle tasks will be added automatically. +With the `helm` plugin you can configure your Helm chart using a declarative DSL, and the corresponding Gradle tasks will be added automatically. .build.gradle -[source,groovy,subs="attributes"] +[source,groovy,subs="+attributes",role="primary"] ---- plugins { id 'org.unbroken-dome.helm' version '{project-version}' @@ -20,56 +20,130 @@ helm { } ---- -Note that the chart moniker used in the DSL and the actual chart name are not necessarily the same, unless you set them to the same value. +.build.gradle +[source,kotlin,subs="+attributes",role="secondary"] +---- +plugins { + id("org.unbroken-dome.helm") version "{project-version}" +} -From this chart definition, a number of tasks will be created automatically: +helm { + charts { + create("foo") { + chartName.set("foo") + chartVersion.set("1.2.3") + sourceDir.set(file("src/helm")) + } + } +} +---- + +Note that the chart moniker used in the DSL and the actual chart name are not necessarily the same, unless you set + them to the same value. + +From the above chart definition, a number of tasks will be created automatically: + +Task `helmFilterFooChartSources`:: +Resolves placeholders in the chart sources, and copies everything to a directory `build/helm/foo` (`helm package` +requires the chart directory to have the same name as the chart). + +Task `helmBuildFooChartDependencies`:: +Equivalent to the `helm dep build` CLI command. + +Task `helmLintFooChart`:: +Equivalent to the `helm lint` CLI command. + +Task `helmPackageFooChart`:: +Equivalent to the `helm package` CLI command. -* Task `helmFilterFooChartSources`: Resolve placeholders in the chart sources, and copy everything to a directory build/helm/foo (`helm package` requires the chart directory to have the same name as the chart). -* Task `helmBuildFooChartDependencies`: equivalent to the `helm dep build` CLI command. -* Task `helmLintFooChart`: equivalent to the `helm lint` CLI command. -* Task `helmPackageFooChart`: equivalent to the `helm package` CLI command. Also, the following configurations and artifacts will be created: -* Configuration `helmFoo`: Contains a single artifact that has the chart directory as its output, and is built by the `helmBuildFooChartDependencies` task. -* Configuration `helmFooPackaged`: Contains a single artifact that has the packaged (tar.gz) chart file as its output, and is built by the `helmPackageFooChart` task. +Configuration `helmFoo`:: +Contains a single artifact that has the chart directory as its output, and is built by the +`helmBuildFooChartDependencies` task. + +Configuration `helmFooPackaged`:: +Contains a single artifact that has the packaged (tar.gz) chart file as its output, and is built by the +`helmPackageFooChart` task. + + +In addition, the plugin creates a task named `helmPackage` that will depend on all charts' package task, so it can be +used to build all the project's charts. -In addition, the plugin creates a task named `helmPackage` that will depend on all charts' package task, so it can be used to build all the project's charts. == Using the `main` chart -If you don't define any charts in the `helm.charts` DSL block, then by convention a chart named `"main"` will be defined automatically, equivalent to the following: +If you don't define any charts in the `helm.charts` DSL block, then by convention a chart named `main` will be +defined automatically, equivalent to the following: -[source,groovy] +[source,groovy,role="primary"] +.Groovy ---- helm.charts { main { chartName = project.name - chartVersion = project.version + chartVersion = project.version.toString() sourceDir = file('src/main/helm') } } ---- -NOTE: since Helm chart versions must be SemVer-compliant, you should either make sure that the project version is a valid SemVer, or set the main chart version to a different value. +[source,kotlin,role="secondary"] +.Kotlin +---- +helm.charts { + create("main") { + chartName.set(project.name) + chartVersion.set(project.version.toString()) + sourceDir.set(file("src/main/helm")) + } +} +---- -The `main` chart will not be instantiated if you define any other charts; however you can reference the `main` chart to modify some of its properties: +WARNING: since Helm chart versions must be SemVer-compliant, you should either make sure that the project version is a +valid SemVer, or set the main chart version to a different value. -[source,groovy] +The `main` chart will not be instantiated if you define any other charts; however you can reference the `main` chart +to modify some of its properties: + +[source,groovy,role="primary"] +.Groovy ---- helm.charts.main.chartVersion = '1.0.0' ---- +[source,kotlin,role="secondary"] +.Kotlin +---- +helm.charts.named("main") { + chartVersion.set("1.0.0") +} +---- + + == Using Charts in a Multi-Project Build -Of course, instead of defining multiple charts in one Gradle project, you can also have a multi-project build where each subproject defines a single `main` chart. That way, you can take advantage of the `main` chart convention in every project. +Of course, instead of defining multiple charts in one Gradle project, you can also have a multi-project build where +each subproject defines a single `main` chart. That way, you can take advantage of the `main` chart convention in +every project. -However, note that the default values defined in the `helm` block are not automatically inherited by subprojects. If you want to define your Helm CLI options in one central place, you can add a `subprojects` clause in the root project: +However, note that the default values defined in the `helm` block are not automatically inherited by subprojects. +If you want to define your Helm CLI options in one central place, you can add a `subprojects` clause in the root +project: -[source,groovy] +[source,groovy,role="primary"] +.Groovy ---- subprojects { - helm.home = "${rootProject.buildDir}/helm/home + helm.home = "${rootProject.buildDir}/helm/home" } ---- +[source,kotlin,role="secondary"] +.Kotlin +---- +subprojects { + helm.home.set("${rootProject.buildDir}/helm/home") +} +---- diff --git a/docs/defining-repositories.adoc b/docs/defining-repositories.adoc new file mode 100644 index 00000000..d028d704 --- /dev/null +++ b/docs/defining-repositories.adoc @@ -0,0 +1,111 @@ += Defining Repositories + +Chart repositories are external storages of Helm charts. By default, a Helm client will know about the +`local` and `stable` repositories. You can use the `helm.repositories` block to define additional +repositories: + +[source,groovy,role="primary"] +.Groovy +---- +helm { + repositories { + example { + url = uri('http://helm-repo.example.com/') + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + repositories { + create("example") { + url.set(uri("http://helm-repo.example.com/") + } + } +} +---- + +Defining a repository will automatically add a task `helmAddRepository` (for example, +`helmAddExampleRepository`) that does the equivalent of `helm repo add`. + + +== Configuring Repository Credentials + +If a chart repository requires authentication, you can configure credentials using the `credentials` +block. It works very similarly to other places in Gradle where credentials are used. + +[source,groovy,role="primary"] +.Groovy +---- +helm { + repositories { + example { + url = uri('http://helm-repo.example.com/') + credentials { + username = 'user' + password = 'password' + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + repositories { + create("example") { + url.set(uri("http://helm-repo.example.com/") + credentials { + username.set("user") + password.set("password") + } + } + } +} +---- + +In addition to username/password credentials, certificate credentials based on PEM files +are also supported: + +[source,groovy,role="primary"] +.Groovy +---- +import org.unbrokendome.gradle.plugins.helm.dsl.credentials.CertificateCredentials + +helm { + repositories { + example { + url = uri('http://helm-repo.example.com/') + + credentials(CertificateCredentials) { + certificateFile = file('path/to/cert.pem') + keyFile = file('path/to/key.pem') + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +import org.unbrokendome.gradle.plugins.helm.dsl.credentials.CertificateCredentials + +helm { + repositories { + create("example") { + url.set(uri("http://helm-repo.example.com/") + + credentials(CertificateCredentials::class.java) { + certificateFile.set(file("path/to/cert.pem")) + keyFile.set(file("path/to/key.pem")) + } + } + } +} +---- diff --git a/docs/filtering-chart-sources.adoc b/docs/filtering-chart-sources.adoc index 52a82d94..b70a4453 100644 --- a/docs/filtering-chart-sources.adoc +++ b/docs/filtering-chart-sources.adoc @@ -1,8 +1,10 @@ = Filtering Chart Sources -The plugin includes a _filtering_ step that will resolve placeholders in certain chart files before the chart is packaged. +The plugin includes a _filtering_ step that will resolve placeholders in certain chart files before the chart +is packaged. -This is most useful to insert the name and version into the chart, because they will often correspond to the project version: +This is most useful to insert the name and version into the chart, because they will often correspond to the +Gradle project's name and version: .Chart.yaml [source,yaml] @@ -11,27 +13,32 @@ name: ${chartName} version: ${chartVersion} ---- -The `chartName` and `chartVersion` placeholders are automatically available based on the corresponding properties of the chart in the DSL. You can also define additional placeholders and their values (see below). +The `chartName` and `chartVersion` placeholders are automatically available based on the corresponding properties of +the chart in the DSL. You can also define additional placeholders and their values (see below). + +NOTE: Only the files _Chart.yaml_, _requirements.yaml_ and _values.yaml_ are filtered this way. The actual templates +in the chart are not filtered; you should use Helm's templating constructs instead. -NOTE: Only the files _Chart.yaml_, _requirements.yaml_ and _values.yaml_ are filtered this way. The actual templates in the chart are not filtered; you should use Helm's templating constructs instead. == Configure the Filtering Step -You can fine-tune the filtering process by modifying the `filtering` block, which is available both directly inside the `helm` block, as well as each chart. The chart-level filtering inherits from the global filtering but will override properties if they are defined in both places: +You can fine-tune the filtering process by modifying the `filtering` block, which is available both directly inside +the `helm` block, as well as each chart. The chart-level filtering inherits from the global filtering but will +override properties if they are defined in both places: -[source,groovy] +[source,groovy,role="primary"] +.Groovy ---- helm { filtering { - // Set a custom pattern for placeholder delimiters. The default is '${' and '}'. - placeholderPrefix = '@[' - placeholderSuffix = ']' + // This value will be resolvable in all charts' YAML files as ${authorName} + values.put 'authorName', 'A. U. Thor' } charts { main { filtering { - // add a custom value that can be resolved inside the YAML files. + // add a custom value that can be resolved only inside this chart's YAML files. values.put 'dockerImage', 'busybox' } } @@ -39,6 +46,26 @@ helm { } ---- +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + filtering { + // This value will be resolvable in all charts' YAML files as ${authorName} + values.put("authorName", "A. U. Thor") + } + + charts { + main { + filtering { + // add a custom value that can be resolved only inside this chart's YAML files. + values.put("dockerImage", "busybox") + } + } + } +} +---- + The following properties are available in the `filtering` block: |=== @@ -50,4 +77,6 @@ The following properties are available in the `filtering` block: | values | `Map` | | The values to be resolved in placeholders. |=== -`values` is a special `MapProperty` which merges the values from different levels of `filtering` blocks. That means you can add some values in the global `helm.filtering` block, add some more inside the individual chart's `filtering` block, and they will all be available for the placeholder resolution. +INFO: `values` is a `MapProperty` which merges the values from different levels of `filtering` blocks. That means +you can add some values in the global `helm.filtering` block, add some more inside the individual chart's `filtering` +block, and they will all be available for the placeholder resolution. diff --git a/docs/index.adoc b/docs/index.adoc index cfe10fdc..70913275 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -5,8 +5,31 @@ :icons: font :sectanchors: +This is a suite of plugins for packaging and publishing Helm Charts from Gradle, and managing Helm releases +on a Kubernetes cluster. + +include::prerequisites.adoc[leveloffset=1] + +include::quickstart.adoc[leveloffset=1] + +include::plugins.adoc[leveloffset=1] + +include::configure-helm.adoc[leveloffset=1] include::defining-charts.adoc[leveloffset=1] +include::defining-repositories.adoc[leveloffset=1] + include::filtering-chart-sources.adoc[leveloffset=1] +include::linting-charts.adoc[leveloffset=1] + +include::managing-chart-dependencies.adoc[leveloffset=1] + +include::publishing-charts.adoc[leveloffset=1] + +include::managing-releases.adoc[leveloffset=1] + +include::using-helm-commands.adoc[leveloffset=1] + +include::config-from-project-properties.adoc[leveloffset=1] diff --git a/docs/linting-charts.adoc b/docs/linting-charts.adoc new file mode 100644 index 00000000..2fca402d --- /dev/null +++ b/docs/linting-charts.adoc @@ -0,0 +1,157 @@ += Linting Charts + +The default workflow for building and packaging a Helm chart includes a lint step, which is +performs by the `HelmLint` task and maps to a `helm lint` CLI call. + +Both the global `helm` DSL block and each `chart` block provide a nested `lint` block, where you +can fine-tune linting on a global or chart level. Each chart will inherit the global configuration +and can selectively override certain aspects of it. + +[source,groovy,role="primary"] +.Groovy +---- +helm { + + // The global lint configuration applies to all charts + lint { + // treat linter warnings as errors (failing the build) + strict = true + } + + charts { + main { + // This configures linting only for the main chart + lint { + // disable strict linting only for this chart + strict = false + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + + // The global lint configuration applies to all charts + lint { + // treat linter warnings as errors (failing the build) + strict.set(true) + } + + (charts) { + "main" { + // This configures linting only for the main chart + lint { + // disable strict linting only for this chart + strict.set(false) + } + } + } +} +---- + + +== Passing Values to the Linter + +You can pass values to the linter using the `values` and `valueFiles`. + +This may be necessary if you use the `required` function in your Helm templates (see +https://github.com/helm/helm/issues/2347[Helm issue #2347]). Also, it can be useful if +you have conditional templates which would not be rendered when using the default values +from values.yaml. + +[TIP] +`helm lint` does not actually perform a syntactic analysis of your charts; instead it renders +the template internally (just as `helm install` would do) and checks the resulting YAML for +correctness. + +Values and value files defined in the global `lint` block are automatically inherited by +each chart; however a chart can add additional values or value files. + +[source,groovy,role="primary"] +.Groovy +---- +helm { + + lint { + valueFiles.from 'src/test/helm/helm-lint-global.yaml' + } + + charts { + main { + lint { + valueFiles.from 'src/test/helm/helm-lint-main.yaml' + values.put 'foo', 'bar' + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + + lint { + valueFiles.from("src/test/helm/helm-lint-global.yaml") + } + + (charts) { + "main" { + lint { + valueFiles.from("src/test/helm/helm-lint-main.yaml") + values.put("foo", "bar") + } + } + } +} +---- + + +== Disable the Lint Step + +You can disable the lint step altogether by setting the `lint.enabled` property to `false`. This +works on a global as well as on a chart level. (Again, the chart setting is inherited from the +global setting). + +[source,groovy,role="primary"] +.Groovy +---- +helm { + + lint { + // disable linting by default + enabled = false + } + + charts { + main { + // enable linting for the main chart + lint.enabled = true + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + + lint { + // disable linting by default + enabled.set(false) + } + + (charts) { + "main" { + // enable linting for the main chart + lint.enabled.set(true) + } + } +} +---- diff --git a/docs/managing-chart-dependencies.adoc b/docs/managing-chart-dependencies.adoc new file mode 100644 index 00000000..4887c810 --- /dev/null +++ b/docs/managing-chart-dependencies.adoc @@ -0,0 +1,143 @@ += Managing Chart Dependencies + +The `helm` plugin can manage your +https://docs.helm.sh/developing_charts/#chart-dependencies[chart's dependencies], modifying the +`requirements.yaml` file accordingly. + +This is especially useful if you have multiple charts in the same project (or in a multi-project build) +that depend on one another, because it will also add Gradle task dependencies to make sure that the charts +are packaged in the correct order. + +Note that you will still need a `requirements.yaml` file with `dependencies` entries; the plugin will not +create it automatically. For each dependency declared in the Gradle script, it will find the matching +dependency in `requirements.yaml` and modify its `repository` property. + + +== Declaring a Dependency + +To declare a dependency from one chart onto another, use the `dependencies` block inside a `chart`. + +The following example defines two charts `foo` and `bar`, and declares a dependency from `bar` onto `foo`: + +[source,groovy,role="primary"] +.Groovy +---- +helm.charts { + + foo { + chartVersion = '1.2.3' + sourceDir = file('src/helm/foo') + } + + bar { + chartVersion = '3.2.1' + sourceDir = file('src/helm/bar') + + dependencies { + foo chart: 'foo' + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm.charts { + + create("foo") { + chartVersion.set("1.2.3") + sourceDir.set(file("src/helm/foo")) + } + + create("bar") { + chartVersion = '3.2.1' + sourceDir.set(file("src/helm/bar")) + + dependencies { + "foo"(chart = "foo") + } + } +} +---- + +The "method" name inside `dependencies` is the name that the dependency will have in the `requirements.yaml`, +whereas the `chart` parameter specifies the name of the chart in the Gradle DSL. + +TIP: The `dependencies` entry in the YAML file will be matched either by its `name` or an `alias`. + +You can also use an alternative syntax using `dependencies.add` if you prefer so: + +[source,groovy,role="primary"] +.Groovy +---- +dependencies.add(name: 'foo', chart: 'foo') +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +dependencies.add(name = "foo", chart = "foo") +---- + + +The resulting `requirements.yaml` file for the `bar` chart will look as follows: + +[source,yaml] +.requirements.yaml +---- +dependencies: + - name: foo + repository: file://../foo +---- + +The URL in `repository` points to the local output directory of the `foo` chart, +relative to the output directory of the `bar` chart. + + +== Chart Dependencies in Multi-Project Builds + +If you have a Gradle multi-project builds, chart dependencies can also refer to charts built by +other projects. + +Use the `project` parameter when adding a dependency, in addition to the `chart` parameter: + +[source,groovy,role="primary"] +.Groovy +---- +dependencies { + // Assuming that the foo chart is defined in the foo project + foo project: ':foo', chart: 'foo' +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +dependencies { + // Assuming that the foo chart is defined in the foo project + "foo"(project = ":foo", chart = "foo") +} +---- + + +The `chart` parameter defaults to `"main"`, so if a dependency references another project's `main` +chart, the `chart` parameter can be omitted: + +[source,groovy,role="primary"] +.Groovy +---- +dependencies { + // Referencing the main chart in the foo project + foo project: ':foo' +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +dependencies { + // Referencing the main chart in the foo project + "foo"(project = ":foo") +} +---- diff --git a/docs/managing-releases.adoc b/docs/managing-releases.adoc new file mode 100644 index 00000000..23e64432 --- /dev/null +++ b/docs/managing-releases.adoc @@ -0,0 +1,199 @@ += Managing Releases + +With the `helm-release` plugin, you can manage Helm releases on a remote Kubernetes cluster. + +It allows you to define your releases in the Gradle DSL, in a declarative fashion. In this way, it can +be used as an alternative to tools like https://github.com/roboll/helmfile[Helmfile] or +https://github.com/Praqma/Helmsman[Helmsman], with the advantage of leveraging the full power of Gradle +instead of defining a custom file format. + +Define your releases using the `helm.repositories` block in your Gradle script: + +[source,groovy,role="primary"] +.Groovy +---- +helm { + releases { + mariadb { + from 'stable/mariadb' + version = '5.1.1' + + // pass values (like --set on the command line) + values = [ 'rootUser.password': 'secret' ] + + // pass value files (like -f on the command line) + valueFiles.from 'mariadb.yaml' + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + releases { + create("mariadb") { + from("stable/mariadb") + version.set("5.1.1") + + // pass values (like --set on the command line) + values.set(mapOf("rootUser.password" to "secret")) + + // pass value files (like -f on the command line) + valueFiles.from("mariadb.yaml") + } + } +} +---- + +There are quite a few properties you can set for a release; most of them correspond to a command line +option in `helm install`, `helm upgrade` or `helm delete`. + +The `from` method is quite powerful, as it accepts various sources for the chart from which the release +will be created. Besides a `String` (for specifying the chart directly), it can also be a `File`, +`RegularFile`, `Directory`, `URI` or also a Gradle `Provider` of any of these types. + +It is also possible to use a `FileCollection` (e.g. a Gradle `Configuration`), which should consist of +only one file. In that case, any +https://docs.gradle.org/current/javadoc/org/gradle/api/Buildable.html#getBuildDependencies--[build dependencies] +expressed by the `FileCollection` will be honored by the release. + +Of course you can also reference charts built by the `helm` plugin, by just passing the chart's DSL object +to `from`: + +[source,groovy,role="primary"] +.Groovy +---- +helm { + charts { + foo { + // configure the foo chart ... + } + } + + releases { + foo { + from charts.foo + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + charts { + create("foo") { + // configure the foo chart ... + } + } + + releases { + foo { + from charts["foo"] + } + } +} +---- + +You can also refer to a chart by name (and optionally project) by using the `chart` helper function: + +[source,groovy,role="primary"] +.Groovy +---- +// Chart in the same project, equivalent to charts.foo +from chart('foo') + +// foo chart in the foo project +from chart(project: ':foo', chart: 'foo') + +// main chart in the foo project +from chart(project: ':foo') +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +// Chart in the same project, equivalent to charts["foo"] +from(chart("foo")) + +// foo chart in the foo project +from(chart(project = ":foo", chart = "foo") + +// main chart in the foo project +from(chart(project = ":foo")) +---- + + +== Release Tasks + +For each release defined in the `releases` block, the following Gradle tasks will be generated: + +Task `helmInstall`:: +Installs the release named X. This task will also do upgrades; depending on the `replace` property +it will either call `helm upgrade --install` (by default) or `helm install --replace`. + +Task `helmDelete`:: +Deletes the release named X (by calling `helm delete`). + + +In addition, there will be the following tasks to manage _all_ releases in the project at once: + +Task `helmInstall`:: +Install or upgrade all releases. + +Task `helmDelete`:: +Delete all releases. + +TIP: If you use a chart built by the helm plugin for a release, the corresponding `helmInstall` +task will have a task dependency on the `helmPackage` task so that the chart is guaranteed to be +up to date before it is installed. + + +== Release Dependencies + +You can express dependencies between releases, to influence the order of installations/deletions +when using the `helmInstall` or `helmDelete` task. A release will always be installed after all +its dependencies, and deleted before its dependencies are deleted. + +Currently it is not possible to define dependencies on releases in another Gradle project. + +TIP: While a release dependency influences the order of `install` invocations, it does not guarantee +that the release will be up and running on the cluster when the installation of the dependent release +begins.. By default, `helm install` does not wait until the deployment is complete -- if this is what +you need, you can set `wait` to `true` in the release, so that the install/upgrade command is invoked +with the `--wait` flag. + +[source,groovy,role="primary"] +.Groovy +---- +helm.releases { + + postgres { + from 'stable/postgresql' + } + + myApp { + // ... + dependsOn 'postgres' + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm.releases { + + create("postgres") { + from("stable/postgresql") + } + + create("myApp") { + // ... + dependsOn("postgres") + } +} +---- diff --git a/docs/plugins.adoc b/docs/plugins.adoc index 461bb7e8..0460d1e2 100644 --- a/docs/plugins.adoc +++ b/docs/plugins.adoc @@ -1,50 +1,104 @@ = Plugins -The _gradle-helm-plugin_ library actually consists of four different plugins, with different use cases for each: +The _gradle-helm-plugin_ library provides several Gradle plugins, with different use cases for each. -== `org.unbroken-dome.helm-commands` plugin +All plugins IDs are prefixed the namespace `org.unbroken-dome`. -This plugin does little more than add the plugin library to your build's classpath so you can define tasks for various Helm CLI commands. Use this if you want to use Helm CLI commands directly as tasks, without any of the declarative DSL that the `helm` plugin offers. -The plugin installs a `helm` DSL extension on the project which can be used to define default values for all Helm tasks (like `home` or `kubeContext`). Apart from this, the plugin does not create any tasks or other project model objects automatically. +== `helm-commands` -Note that the `helm-commands` plugin is implied when using any of the other plugins like `org.unbroken-dome.helm` or `org.unbroken-dome.helm-publish`, so you only need to list it when using it on its own. +This plugin does little more than add the plugin library to your build's classpath so you can define tasks for + various Helm CLI commands. It creates the `helm` DSL block which you can use to configure common settings + for all tasks, like the Helm home path and the Kubecontext. Apart from this, it does not create any tasks + automatically. -=== Example +Use this if you want to use Helm CLI commands directly as tasks, without any of the declarative DSL that the `helm` + plugin offers. -.build.gradle -[source,groovy] +[source,groovy,role="primary",subs="+attributes"] +.Groovy ---- -import org.unbrokendome.gradle.plugins.helm.command.tasks.* - plugins { - id 'org.unbroken-dome.helm-commands' version '' + id 'org.unbroken-dome.helm-commands' version '{project-version}' } +---- -helm { - home = file("${project.buildDir}/helm/home") +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm-commands") version "{project-version}" } +---- + +All the other plugins imply `helm-commands`, so you don't need to apply this plugin if you use any of the others. + + + +== `helm` -task helmInit(type: HelmInit) +This is the main plugin of the suite. It enables a variety of extra DSL blocks inside `helm`, for example `charts` + and `repositories`. -task installMariaDb(type: HelmInstall) { - dependsOn helmInit - chart = 'stable/mariadb' - version = '4.3.1' - releaseName = 'mariadb' +[source,groovy,role="primary",subs="+attributes"] +.Groovy +---- +plugins { + id 'org.unbroken-dome.helm' version '{project-version}' } ---- -== `org.unbroken-dome.helm` plugin +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm") version "{project-version}" +} +---- + + +== `helm-publish` + +Use this plugin to publish charts to a remote chart repository like ChartMuseum. -This is the main plugin of the suite. It enables a variety of extra DSL blocks inside `helm`, for example `charts` and `repositories`. +It enables the `helm.publishing` DSL block and adds publishing tasks for each chart. +[source,groovy,role="primary",subs="+attributes"] +.Groovy +---- +plugins { + id 'org.unbroken-dome.helm-publish' version '{project-version}' +} +---- + +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm-publish") version "{project-version}" +} +---- -== `org.unbroken-dome.helm-publish` plugin -Use this plugin _in addition to_ the `org.unbroken-dome.helm` plugin if you want to publish your charts to a remote repository like ChartMuseum. It enables the `helm.publishing` DSL block and adds publishing tasks for each chart. +== `helm-releases` +Use this plugin to manage Helm releases (install/update/delete) on a remote Kubernetes cluster. -== `org.unbroken-dome.helm-releases` plugin +It enables the `helm.releases` DSL block, where you can declare your releases using Gradle DSL, referencing either + Helm charts built using the other projects, or existing charts from a Helm repository. -Use this plugin to manage releases (install/update/delete) on a remote Kubernetes cluster. You can declare your releases using Gradle DSL, referencing either Helm charts built using the other projects, or existing charts from a Helm repository. +[source,groovy,role="primary",subs="+attributes"] +.Groovy +---- +plugins { + id 'org.unbroken-dome.helm-releases' version '{project-version}' +} +---- + +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm-releases") version "{project-version}" +} +---- diff --git a/docs/prerequisites.adoc b/docs/prerequisites.adoc new file mode 100644 index 00000000..e476f8fe --- /dev/null +++ b/docs/prerequisites.adoc @@ -0,0 +1,19 @@ += Prerequisites + +You need at least the following: + +* Gradle 5.1 or higher ++ +Since the plugin makes extensive use of Gradle's provider/property API, including the new `MapProperty` added +in Gradle 5.1, earlier versions of Gradle are unfortunately not supported. + +* JDK 8 or higher (for running Gradle) + +* Helm CLI ++ +This plugin delegates all `helm` commands to a locally installed Helm CLI. See +https://docs.helm.sh/using_helm/#installing-helm[Installing Helm] in the Helm documentation for installation +instructions on various systems. ++ +INFO: Delegating to the Helm CLI decouples the plugin release cycle from the Helm release cycle, but it also +means that some features offered by the plugin may not be available in the CLI and vice versa. diff --git a/docs/publishing-charts.adoc b/docs/publishing-charts.adoc new file mode 100644 index 00000000..523652a0 --- /dev/null +++ b/docs/publishing-charts.adoc @@ -0,0 +1,155 @@ += Publishing Charts + +The `helm-publish` plugin allows you to publish your charts to remote repositories over HTTP. + +NOTE: There is currently no "official" API to publish Helm charts; Helm defines only how charts should be +served from a repository. Since https://chartmuseum.com/[ChartMuseum] is probably the most widespread +type of repository, the plugin assumes its API pattern by default, with some limited possibilities +for configuration. + +Apply the `helm-publish` plugin to your project: + +[source,groovy,role="primary",subs="+attributes"] +.Groovy +---- +plugins { + id 'org.unbroken-dome.helm-publish' version '{project-version}' +} +---- + +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm-publish") version "{project-version}" +} +---- + +The plugin adds another sub-extension `helm.publishing` that lets you define the repository or +repositories to publish to: + +[source,groovy,role="primary"] +.Groovy +---- +helm { + publishing { + repositories { + example { + url = uri('http://helm-repo.example.com/') + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + publishing { + repositories { + create("example") { + url.set(uri("http://helm-repo.example.com/") + } + } + } +} +---- + +This will automatically define some Gradle tasks in the project: + +Task `helmPublish`:: +Publishes all charts to all repositories. + +Task `helmPublishChart`:: +Publishes chart X to all repositories. + +Task `helmPublishChartToRepo`:: +Publishes chart X to repository Y, e.g. `helmPublishMainChartToExampleRepo`. + +[NOTE] +==== +There is no connection between the repositories in `helm.repositories` and +the publishing repositories in `helm.publishing.repositories`. The former are for retrieving +charts, the latter are for publishing them. + +If you want to download from and publish to +the same external repository, you would need to specify it both in `helm.repositories` and +`helm.publishing.repositories` (similar to Gradle's built-in publishing). +==== + + +== Specifying Credentials for Repositories + +Most likely, a chart repository will require some credentials for write access. You can configure +credentials in the same way as for `repositories`: + +[source,groovy,role="primary"] +.Groovy +---- +helm { + publishing { + repositories { + example { + url = uri('http://helm-repo.example.com/') + credentials { + username = 'user' + password = 'password' + } + } + } + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm { + publishing { + repositories { + create("example") { + url.set(uri("http://helm-repo.example.com/") + } + credentials { + username.set("user") + password.set("password") + } + } + } +} +---- + + + + +== Preventing a Chart from Being Published + +By default, all charts defined in the project will be published. You can prevent this for a specific +chart by setting its `publish` property to `false`: + +[source,groovy,role="primary"] +.Groovy +---- +helm.charts { + + // This chart will not be published + unpublishedChart { + // ... + publish = false + } +} +---- + +[source,kotlin,role="secondary"] +.Kotlin +---- +helm.charts { + + // This chart will not be published + create("unpublishedChart") { + // ... + publish = false + } +} +---- diff --git a/docs/quickstart.adoc b/docs/quickstart.adoc new file mode 100644 index 00000000..06dcee55 --- /dev/null +++ b/docs/quickstart.adoc @@ -0,0 +1,36 @@ += Quick Start + +Apply the `org.unbroken-dome.helm` plugin to your Gradle project: + +[source,groovy,role="primary",subs="+attributes"] +.Groovy +---- +plugins { + id 'org.unbroken-dome.helm' version '{project-version}' +} +---- + +[source,kotlin,role="secondary",subs="+attributes"] +.Kotlin +---- +plugins { + id("org.unbroken-dome.helm") version "{project-version}" +} +---- + + +Put your Helm chart sources into `src/main/helm`: + +---- +📂 (project root) + 📂 src + 📂 main + 📂 helm + 📂 templates + 📄 ... + 📄 Chart.yaml + 📄 requirements.yaml + 📄 values.yaml +---- + +Use the `helmPackage` task to build your chart. diff --git a/docs/using-helm-commands.adoc b/docs/using-helm-commands.adoc new file mode 100644 index 00000000..0b642290 --- /dev/null +++ b/docs/using-helm-commands.adoc @@ -0,0 +1,39 @@ += Using Helm Commands + +The plugin `org.unbroken-dome.helm-commands` allows you to use Helm commands directly, similar to what you would do +with the Helm CLI. `helm-commands` is also implied by all the other plugins in the suite. + +For most Helm CLI commands, there is a corresponding Gradle task type (except for commands that do not really make +sense for a build script, like `helm search` or `helm inspect`). + +NOTE: In most cases it is more convenient to use the high-level DSL provided by the other plugins to manage your +charts in a declarative way. + +Check the link:/dokka/gradle-helm-plugin/org.unbrokendome.gradle.plugins.helm.command.tasks/[API Reference] +for a full list of available tasks. + + +== Example + +.build.gradle +[source,groovy] +---- +import org.unbrokendome.gradle.plugins.helm.command.tasks.* + +plugins { + id 'org.unbroken-dome.helm-commands' version '' +} + +helm { + home = file("${project.buildDir}/helm/home") +} + +task helmInit(type: HelmInit) + +task installMariaDb(type: HelmInstall) { + dependsOn helmInit + chart = 'stable/mariadb' + version = '4.3.1' + releaseName = 'mariadb' +} +---- From fe33a83cdaa1b2fc70e05b3aef2b9b5cfe40946e Mon Sep 17 00:00:00 2001 From: Till Krullmann Date: Sun, 20 Jan 2019 23:22:51 +0100 Subject: [PATCH 4/5] Configure Dokka --- build.gradle.kts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index bdc5cc23..1c87b48e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,8 @@ import org.asciidoctor.gradle.AsciidoctorTask +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import java.net.URL plugins { @@ -108,6 +111,15 @@ pluginBundle { } +tasks.named("dokka", DokkaTask::class) { + outputFormat = "html" + externalDocumentationLink(delegateClosureOf { + url = URL("https://docs.gradle.org/current/javadoc/") + }) + reportUndocumented = false +} + + asciidoctorj { version = "1.6.0" } From 97bba780e9135a37a38f35eac5e49476d90f821c Mon Sep 17 00:00:00 2001 From: Till Krullmann Date: Sun, 20 Jan 2019 23:27:48 +0100 Subject: [PATCH 5/5] Updated readme --- README.adoc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.adoc b/README.adoc index 2917f27f..bff2deff 100644 --- a/README.adoc +++ b/README.adoc @@ -10,8 +10,6 @@ endif::[] This is a suite of Gradle plugins for building, publishing and managing https://www.helm.sh/[Helm] charts. -IMPORTANT: This is still work in progress! - == Features @@ -23,7 +21,7 @@ IMPORTANT: This is still work in progress! == Requirements -* Gradle 4.3 or higher +* Gradle 5.1 or higher * JDK 1.8 or higher (for running Gradle) * Helm command-line client @@ -36,7 +34,7 @@ Apply the `org.unbroken-dome.helm` plugin to your Gradle project: [source,groovy] ---- plugins { - id 'org.unbroken-dome.helm' version '0.2.3' + id 'org.unbroken-dome.helm' version '0.3.0' } ---- @@ -60,4 +58,5 @@ Use the `helmPackage` task to build your chart. == Further Documentation -Please refer to the https://github.com/unbroken-dome/gradle-helm-plugin/wiki[Wiki] for full documentation. +* https://unbroken-dome.github.io/projects/gradle-helm-plugin/[User Manual] +* https://unbroken-dome.github.io/projects/gradle-helm-plugin/dokka/gradle-helm-plugin/[API/DSL Documentation]