diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..4210158b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,33 @@
+**Is this a request for help?**:
+
+---
+
+**Is this a BUG REPORT or FEATURE REQUEST?** (choose one):
+
+
+
+**Environment (plugin version, maven version, OS, ...)**:
+
+
+**What happened**:
+
+
+**What you expected to happen**:
+
+
+**How to reproduce it** (as minimally and precisely as possible):
+
+
+**Anything else we need to know**:
\ No newline at end of file
diff --git a/README.md b/README.md
index 3195bc84..7839aad9 100644
--- a/README.md
+++ b/README.md
@@ -18,60 +18,89 @@ Currently (October 2017) there is no simple Maven plugin to package existing HEL
# How?
-The plugin downloads HELM in a specific version and runs the tool in the background.
+By default the plugin downloads HELM in a specific version. Next to that it is possible to specify a local HELM binary.
+In both cases HELM will be executed in the background.
Add following dependency to your pom.xml:
-```
+```xml
com.kiwigrid
helm-maven-plugin
- 3.4
+ 4.0
```
-Configure plugin with explicit credentials:
+## Configuration Examples
+
+### Usage with Downloaded Binary
+```xml
+
+
+ ...
+
+ com.kiwigrid
+ helm-maven-plugin
+ 4.0
+
+ ${project.basedir}
+ ${project.version}
+
+ https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz
+ ${project.basedir}/target/helm/home
+
+
+ ...
+
+
+```
+
+### Usage with Local Binary
+```xml
+
+
+ ...
+
+ com.kiwigrid
+ helm-maven-plugin
+ 4.0
+
+ ${project.basedir}
+ ${project.version}
+
+ true
+ /usr/local/bin
+
+
+ ...
+
+
```
-...
-
- https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz
-
-...
+
+### Configure Plugin to Use Credentials from settings.xml for Upload
+```xml
...
com.kiwigrid
helm-maven-plugin
- 3.4
+ 4.0
${project.basedir}
${project.version}
+
stable-repo
https://repo.example.com/artifactory/helm-stable
-
-
ARTIFACTORY
- foo
- bar
snapshot-repo
- https://my.chart.museum/api/charts
+ https://my.chart.museum:8080/api/charts
CHARTMUSEUM
- ${helm.download.url}
+ https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz
${project.basedir}/target/helm/home
- false
-
- ${project.basedir}/excluded
-
-
-
- incubator
- https://kubernetes-charts-incubator.storage.googleapis.com
-
-
...
@@ -79,35 +108,47 @@ Configure plugin with explicit credentials:
```
-Configure plugin using credentials from settings.xml:
-```
-...
-
- https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz
-
-...
+### More Complex Example
+```xml
...
com.kiwigrid
helm-maven-plugin
- 3.4
+ 4.0
${project.basedir}
${project.version}
stable-repo
https://repo.example.com/artifactory/helm-stable
+
+
ARTIFACTORY
+ foo
+ bar
snapshot-repo
- https://my.chart.museum:8080/api/charts
+ https://my.chart.museum/api/charts
CHARTMUSEUM
- ${helm.download.url}
+ https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz
${project.basedir}/target/helm/home
+
+ false
+
+
+ ${project.basedir}/excluded
+
+
+
+
+ kiwigrid
+ https://kiwigrid.github.io
+
+
...
@@ -122,7 +163,7 @@ Configure plugin using credentials from settings.xml:
- Recursive chart detection (subcharts)
- Helm does not need to be installed
- Upload to [ChartMuseum](https://github.com/kubernetes-helm/chartmuseum) or [Artifactory](https://jfrog.com/artifactory/)
-- Repository names are interpreted as server ids to retrieve basic authentication from server list in settings.xml.
+- Repository names are interpreted as server IDs to retrieve basic authentication from server list in settings.xml.
# Usage
@@ -144,8 +185,8 @@ Parameter | Type | User Property | Required | Description
`` | string | helm.appVersion | false | The version of the app. This needn't be SemVer.
`` | string | helm.downloadUrl | false | URL to download helm
`` | list of strings | helm.excludes | false | list of chart directories to exclude
+`` | boolean | helm.useLocalHelmBinary | false | Controls whether a local binary should be used instead of downloading it. If set to `true` path has to be set with property `executableDirectory`
`` | string | helm.executableDirectory | false | directory of your helm installation (default: `${project.build.directory}/helm`)
-`` | string | helm.executable | false | path to your helm executable (default: `${project.build.directory}/helm/linux-amd64/helm`)
`` | string | helm.outputDirectory | false | chart output directory (default: `${project.build.directory}/helm/repo`)
`` | string | helm.homeDirectory | false | path to helm home directory; useful for concurrent Jenkins builds! (default: `~/.helm`)
`` | list of [HelmRepository](./src/main/java/com/kiwigrid/helm/maven/plugin/HelmRepository.java) | helm.extraRepos | false | adds extra repositories while init
@@ -161,7 +202,7 @@ Parameter | Type | User Property | Required | Description
`` | boolean | helm.upload.skip | false | skip upload goal
`` | string | helm.security | false | path to your [settings-security.xml](https://maven.apache.org/guides/mini/guide-encryption.html) (default: `~/.m2/settings-security.xml`)
-## Packaging with the helm lifecycle
+## Packaging with the Helm Lifecycle
To keep your pom files small you can use 'helm' packaging. This binds `helm:init` to the initialize phase, `helm:lint` to the test phase, `helm:package` to the package phase and `helm:upload` to the deploy phase.
diff --git a/pom.xml b/pom.xml
index d46a4f44..e7798323 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,12 +3,12 @@
com.kiwigrid
helm-maven-plugin
- 3.5-SNAPSHOT
+ 4.0-SNAPSHOT
${project.groupId}:${project.artifactId}
A plugin for executing HELM (https://docs.helm.sh).
- HELM itself will be downloaded during build.
+ HELM itself will be downloaded during build or local binary can be provided.
https://github.com/kiwigrid/helm-maven-plugin
diff --git a/src/main/java/com/kiwigrid/helm/maven/plugin/AbstractHelmMojo.java b/src/main/java/com/kiwigrid/helm/maven/plugin/AbstractHelmMojo.java
index 55c78769..bbdf9786 100644
--- a/src/main/java/com/kiwigrid/helm/maven/plugin/AbstractHelmMojo.java
+++ b/src/main/java/com/kiwigrid/helm/maven/plugin/AbstractHelmMojo.java
@@ -35,15 +35,12 @@ public abstract class AbstractHelmMojo extends AbstractMojo {
@Component(role = org.sonatype.plexus.components.sec.dispatcher.SecDispatcher.class, hint = "default")
private SecDispatcher securityDispatcher;
+ @Parameter(property = "helm.useLocalHelmBinary", defaultValue = "false")
+ private boolean useLocalHelmBinary;
+
@Parameter(property = "helm.executableDirectory", defaultValue = "${project.build.directory}/helm")
private String helmExecutableDirectory;
- /**
- * If no executeable is set this plugin tries to determine helm executeable based on operation system.
- */
- @Parameter(property = "helm.executable")
- private String helmExecuteable;
-
@Parameter(property = "helm.outputDirectory", defaultValue = "${project.build.directory}/helm/repo")
private String outputDirectory;
@@ -87,12 +84,10 @@ public abstract class AbstractHelmMojo extends AbstractMojo {
private Settings settings;
Path getHelmExecuteablePath() throws MojoExecutionException {
- if (helmExecuteable == null) {
- helmExecuteable = SystemUtils.IS_OS_WINDOWS ? "helm.exe" : "helm";
- }
- Path path = Paths.get(helmExecutableDirectory, helmExecuteable).toAbsolutePath();
+ String helmExecutable = SystemUtils.IS_OS_WINDOWS ? "helm.exe" : "helm";
+ Path path = Paths.get(helmExecutableDirectory, helmExecutable).toAbsolutePath();
if (!path.toFile().exists()) {
- throw new MojoExecutionException("Helm executeable at " + path + " not found.");
+ throw new MojoExecutionException("Helm executable at " + path + " not found.");
}
return path;
}
@@ -248,14 +243,6 @@ protected SecDispatcher getSecDispatcher() {
return securityDispatcher;
}
- public String getHelmExecuteable() {
- return helmExecuteable;
- }
-
- public void setHelmExecuteable(String helmExecuteable) {
- this.helmExecuteable = helmExecuteable;
- }
-
public String getOutputDirectory() {
return outputDirectory;
}
@@ -355,4 +342,12 @@ public void setHelmSecurity(String helmSecurity) {
public Settings getSettings() {
return settings;
}
+
+ public boolean isUseLocalHelmBinary() {
+ return useLocalHelmBinary;
+ }
+
+ public void setUseLocalHelmBinary(boolean useLocalHelmBinary) {
+ this.useLocalHelmBinary = useLocalHelmBinary;
+ }
}
diff --git a/src/main/java/com/kiwigrid/helm/maven/plugin/InitMojo.java b/src/main/java/com/kiwigrid/helm/maven/plugin/InitMojo.java
index 93af7e1a..d670547a 100644
--- a/src/main/java/com/kiwigrid/helm/maven/plugin/InitMojo.java
+++ b/src/main/java/com/kiwigrid/helm/maven/plugin/InitMojo.java
@@ -35,6 +35,33 @@ public void execute()
getLog().info("Creating output directory...");
callCli("mkdir -p " + getOutputDirectory(), "Unable to create output directory at " + getOutputDirectory(),
false);
+
+ if(isUseLocalHelmBinary()) {
+ verifyLocalHelmBinary();
+ getLog().info("Using local HELM binary ["+ getHelmExecutableDirectory() +"]");
+ } else {
+ downloadAndUnpackHelm();
+ }
+
+ if (getHelmExtraRepos() != null) {
+ for (HelmRepository repository : getHelmExtraRepos()) {
+ getLog().info("Adding repo " + repository);
+ PasswordAuthentication auth = getAuthentication(repository);
+ callCli(getHelmExecutableDirectory()
+ + File.separator
+ + "helm repo add "
+ + repository.getName()
+ + " "
+ + repository.getUrl()
+ + (StringUtils.isNotEmpty(getHelmHomeDirectory()) ? " --home=" + getHelmHomeDirectory() : "")
+ + (auth != null ? " --username=" + auth.getUserName() + " --password=" + String.valueOf(auth.getPassword()) : ""),
+ "Unable add repo",
+ false);
+ }
+ }
+ }
+
+ protected void downloadAndUnpackHelm() throws MojoExecutionException {
getLog().info("Downloading Helm...");
callCli("wget -qO "
+ getHelmExecutableDirectory()
@@ -56,23 +83,10 @@ public void execute()
+ (StringUtils.isNotEmpty(getHelmHomeDirectory()) ? " --home=" + getHelmHomeDirectory() : ""),
"Unable to call helm init",
false);
+ }
- if (getHelmExtraRepos() != null) {
- for (HelmRepository repository : getHelmExtraRepos()) {
- getLog().info("Adding repo " + repository);
- PasswordAuthentication auth = getAuthentication(repository);
- callCli(getHelmExecutableDirectory()
- + File.separator
- + "helm repo add "
- + repository.getName()
- + " "
- + repository.getUrl()
- + (StringUtils.isNotEmpty(getHelmHomeDirectory()) ? " --home=" + getHelmHomeDirectory() : "")
- + (auth != null ? " --username=" + auth.getUserName() + " --password=" + String.valueOf(auth.getPassword()) : ""),
- "Unable add repo",
- false);
- }
- }
+ private void verifyLocalHelmBinary() throws MojoExecutionException {
+ callCli(getHelmExecuteablePath() + " version --client", "Unable to verify local HELM binary", false);
}
public boolean isSkipRefresh() {
diff --git a/src/test/java/com/kiwigrid/helm/maven/plugin/InitMojoTest.java b/src/test/java/com/kiwigrid/helm/maven/plugin/InitMojoTest.java
index 64732e54..863892f3 100644
--- a/src/test/java/com/kiwigrid/helm/maven/plugin/InitMojoTest.java
+++ b/src/test/java/com/kiwigrid/helm/maven/plugin/InitMojoTest.java
@@ -1,5 +1,7 @@
package com.kiwigrid.helm.maven.plugin;
+import java.io.File;
+import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -9,6 +11,7 @@
import com.kiwigrid.helm.maven.plugin.junit.MojoExtension;
import com.kiwigrid.helm.maven.plugin.junit.MojoProperty;
import com.kiwigrid.helm.maven.plugin.junit.SystemPropertyExtension;
+import org.apache.maven.plugin.MojoExecutionException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -29,26 +32,23 @@ public class InitMojoTest {
@DisplayName("Init helm with different download urls.")
@ParameterizedTest
@ValueSource(strings = { "darwin", "linux", "windows" })
- public void initMojoHappyPath(String os, InitMojo mojo) throws Exception {
+ public void initMojoHappyPathWhenDownloadHelm(String os, InitMojo mojo) throws Exception {
// prepare execution
-
doNothing().when(mojo).callCli(contains("helm "), anyString(), anyBoolean());
mojo.setHelmDownloadUrl("https://kubernetes-helm.storage.googleapis.com/helm-v2.9.1-" + os + "-amd64.tar.gz");
// run init
-
mojo.execute();
// check helm file
-
Path helm = Paths.get(mojo.getHelmExecutableDirectory(), "windows".equals(os) ? "helm.exe" : "helm")
.toAbsolutePath();
assertTrue(Files.exists(helm), "Helm executable not found at: " + helm);
}
@Test
- public void verifyDefaultInitCommand(InitMojo mojo) throws Exception {
+ public void verifyDefaultInitCommandWhenDownloadingHelm(InitMojo mojo) throws Exception {
// prepare execution
ArgumentCaptor helmCommandCaptor = ArgumentCaptor.forClass(String.class);
@@ -89,4 +89,25 @@ public void initMojoSkipRefreshIfConfigured(InitMojo mojo) throws Exception {
String helmInitCommand = helmCommands.get(0);
assertTrue(helmInitCommand.contains("--skip-refresh"), "Option 'skip-refresh' expected");
}
+
+ @Test
+ public void verifyLocalHelmBinaryUsage(InitMojo mojo) throws MojoExecutionException {
+
+ final URL resource = this.getClass().getResource("helm.tar.gz");
+ final String helmExecutableDir = new File(resource.getFile()).getParent();
+ mojo.callCli("tar -xf "
+ + helmExecutableDir
+ + File.separator
+ // flatten directory structure using --strip to get helm executeable on basedir, see https://www.systutorials.com/docs/linux/man/1-tar/#lbAS
+ + "helm.tar.gz --strip=1 --directory="
+ + helmExecutableDir, "Unable to unpack helm to " + helmExecutableDir, false);
+
+
+ // configure mojo
+ mojo.setUseLocalHelmBinary(true);
+ mojo.setHelmExecutableDirectory(helmExecutableDir);
+
+ // execute
+ mojo.execute();
+ }
}
\ No newline at end of file
diff --git a/src/test/resources/com/kiwigrid/helm/maven/plugin/helm.tar.gz b/src/test/resources/com/kiwigrid/helm/maven/plugin/helm.tar.gz
new file mode 100644
index 00000000..39f5b22f
Binary files /dev/null and b/src/test/resources/com/kiwigrid/helm/maven/plugin/helm.tar.gz differ