diff --git a/README.md b/README.md
index 879586cd..ffdfcac7 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@
- [Setting the build name and build number](#setting-the-build-name-and-the-build-number)
- [Using multiple JFrog Platform instances](#using-multiple-jfrog-platform-instances)
- [Publishing and accessing the build-info](#publishing-and-accessing-the-build-info)
+ - [Capturing the output of JFrog CLI commands](#capturing-the-output-of-jfrog-cli-commands)
- [Using HTTP/s proxy](#using-https-proxy)
- [Jenkins Configuration as Code](#jenkins-configuration-as-code)
- [Examples](#examples)
@@ -180,6 +181,28 @@ stage('Publish build info') {
When the job publishes the build-info to Artifactory, you can access it by clicking on the build-info icon, next to the
job run.
+### Capturing the output of JFrog CLI commands
+
+The JFrog CLI commands output is returned as a string.
+To capture the output of JFrog CLI commands, wrap the JFrog CLI command in a `script` block:
+
+```groovy
+script {
+ String version = jf '-v'
+ echo "JFrog CLI version output: $version"
+}
+```
+
+
+ Scripted Pipeline
+
+```groovy
+String version = jf '-v'
+echo "JFrog CLI version output: $version"
+```
+
+
+
![build-info.png](images/readme/build-info.png)
## Using HTTP/S proxy
diff --git a/src/main/java/io/jenkins/plugins/jfrog/JfStep.java b/src/main/java/io/jenkins/plugins/jfrog/JfStep.java
index 9a721ee1..5d2b022f 100644
--- a/src/main/java/io/jenkins/plugins/jfrog/JfStep.java
+++ b/src/main/java/io/jenkins/plugins/jfrog/JfStep.java
@@ -2,17 +2,10 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import edu.umd.cs.findbugs.annotations.NonNull;
-import hudson.EnvVars;
-import hudson.Extension;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.AbstractProject;
+import hudson.*;
import hudson.model.Job;
import hudson.model.Run;
import hudson.model.TaskListener;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.Builder;
import hudson.util.ArgumentListBuilder;
import io.jenkins.plugins.jfrog.actions.BuildInfoBuildBadgeAction;
import io.jenkins.plugins.jfrog.actions.JFrogCliConfigEncryption;
@@ -21,11 +14,11 @@
import io.jenkins.plugins.jfrog.configuration.JFrogPlatformInstance;
import io.jenkins.plugins.jfrog.models.BuildInfoOutputModel;
import io.jenkins.plugins.jfrog.plugins.PluginsUtils;
-import jenkins.tasks.SimpleBuildStep;
+import lombok.Getter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.plaincredentials.StringCredentials;
+import org.jenkinsci.plugins.workflow.steps.*;
import org.jfrog.build.api.util.Log;
import org.kohsuke.stapler.DataBoundConstructor;
@@ -35,6 +28,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.List;
+import java.util.Set;
import static io.jenkins.plugins.jfrog.JfrogInstallation.JFROG_BINARY_PATH;
import static org.apache.commons.lang3.StringUtils.*;
@@ -43,10 +37,10 @@
/**
* @author gail
*/
+@Getter
@SuppressWarnings("unused")
-public class JfStep extends Builder implements SimpleBuildStep {
- private final ObjectMapper mapper = createMapper();
- static final String STEP_NAME = "jf";
+public class JfStep extends Step {
+ private static final ObjectMapper mapper = createMapper();
protected String[] args;
@DataBoundConstructor
@@ -59,180 +53,188 @@ public JfStep(Object args) {
this.args = split(args.toString());
}
- public String[] getArgs() {
- return args;
+ @Override
+ public StepExecution start(StepContext context) {
+ return new Execution(args, context);
}
- /**
- * Build and run a 'jf' command.
- *
- * @param run running as a part of a specific build
- * @param workspace a workspace to use for any file operations
- * @param env environment variables applicable to this step
- * @param launcher a way to start processes
- * @param listener a place to send output
- * @throws InterruptedException if the step is interrupted
- * @throws IOException in case of any I/O error, or we failed to run the 'jf' command
- */
- @Override
- public void perform(@NonNull Run, ?> run, @NonNull FilePath workspace, @NonNull EnvVars env, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException {
- workspace.mkdirs();
- // Build the 'jf' command
- ArgumentListBuilder builder = new ArgumentListBuilder();
- boolean isWindows = !launcher.isUnix();
- String jfrogBinaryPath = getJFrogCLIPath(env, isWindows);
+ public static class Execution extends SynchronousNonBlockingStepExecution {
+ private final String[] args;
- builder.add(jfrogBinaryPath).add(args);
- if (isWindows) {
- builder = builder.toWindowsCommand();
+ protected Execution(String[] args, @Nonnull StepContext context) {
+ super(context);
+ this.args = args;
}
- try (ByteArrayOutputStream taskOutputStream = new ByteArrayOutputStream()) {
- JfTaskListener jfTaskListener = new JfTaskListener(listener, taskOutputStream);
- Launcher.ProcStarter jfLauncher = setupJFrogEnvironment(run, env, launcher, jfTaskListener, workspace, jfrogBinaryPath, isWindows);
- // Running the 'jf' command
- int exitValue = jfLauncher.cmds(builder).join();
- if (exitValue != 0) {
- throw new RuntimeException("Running 'jf' command failed with exit code " + exitValue);
- }
- addBuildInfoActionIfNeeded(new JenkinsBuildInfoLog(listener), run, taskOutputStream);
- } catch (Exception e) {
- String errorMessage = "Couldn't execute 'jf' command. " + ExceptionUtils.getRootCauseMessage(e);
- throw new RuntimeException(errorMessage, e);
- }
- }
+ @Override
+ protected String run() throws Exception {
+ // Get the step context
+ Launcher launcher = getContext().get(Launcher.class);
+ FilePath workspace = getContext().get(FilePath.class);
+ TaskListener listener = getContext().get(TaskListener.class);
+ EnvVars env = getContext().get(EnvVars.class);
+ Run, ?> run = getContext().get(Run.class);
- /**
- * Get JFrog CLI path in agent, according to the JFROG_BINARY_PATH environment variable.
- * The JFROG_BINARY_PATH also can be set implicitly in Declarative Pipeline by choosing the JFrog CLI tool or
- * explicitly in Scripted Pipeline.
- *
- * @param env - Job's environment variables
- * @param isWindows - True if the agent's OS is windows
- * @return JFrog CLI path in agent.
- */
- static String getJFrogCLIPath(EnvVars env, boolean isWindows) {
- // JFROG_BINARY_PATH is set according to the master OS. If not configured, the value of jfrogBinaryPath will
- // eventually be 'jf' or 'jf.exe'. In that case, the JFrog CLI from the system path is used.
- String jfrogBinaryPath = Paths.get(env.get(JFROG_BINARY_PATH, ""), Utils.getJfrogCliBinaryName(isWindows)).toString();
+ workspace.mkdirs();
+ // Build the 'jf' command
+ ArgumentListBuilder builder = new ArgumentListBuilder();
+ boolean isWindows = !launcher.isUnix();
+ String jfrogBinaryPath = getJFrogCLIPath(env, isWindows);
- // Modify jfrogBinaryPath according to the agent's OS
- return isWindows ?
- FilenameUtils.separatorsToWindows(jfrogBinaryPath) :
- FilenameUtils.separatorsToUnix(jfrogBinaryPath);
- }
+ builder.add(jfrogBinaryPath).add(args);
+ if (isWindows) {
+ builder = builder.toWindowsCommand();
+ }
- /**
- * Log if the JFrog CLI binary path doesn't exist in job's environment variable.
- * This environment variable exists in one of the following scenarios:
- * 1. Declarative Pipeline: A 'jfrog' tool was set
- * 2. Scripted Pipeline: Using the "withEnv(["JFROG_BINARY_PATH=${tool 'jfrog-cli'}"])" syntax
- *
- * @param env - Job's environment variables
- * @param listener - Job's logger
- */
- private void logIfNoToolProvided(EnvVars env, TaskListener listener) {
- if (env.containsKey(JFROG_BINARY_PATH)) {
- return;
+ String output;
+ try (ByteArrayOutputStream taskOutputStream = new ByteArrayOutputStream()) {
+ JfTaskListener jfTaskListener = new JfTaskListener(listener, taskOutputStream);
+ Launcher.ProcStarter jfLauncher = setupJFrogEnvironment(run, env, launcher, jfTaskListener, workspace, jfrogBinaryPath, isWindows);
+ // Running the 'jf' command
+ int exitValue = jfLauncher.cmds(builder).join();
+ output = taskOutputStream.toString(StandardCharsets.UTF_8);
+ if (exitValue != 0) {
+ throw new RuntimeException("Running 'jf' command failed with exit code " + exitValue);
+ }
+ addBuildInfoActionIfNeeded(args, new JenkinsBuildInfoLog(listener), run, taskOutputStream);
+ } catch (Exception e) {
+ String errorMessage = "Couldn't execute 'jf' command. " + ExceptionUtils.getRootCauseMessage(e);
+ throw new RuntimeException(errorMessage, e);
+ }
+ return output;
}
- JenkinsBuildInfoLog buildInfoLog = new JenkinsBuildInfoLog(listener);
- buildInfoLog.info("A 'jfrog' tool was not set. Using JFrog CLI from the system path.");
- }
- /**
- * Configure all JFrog relevant environment variables and all servers (if they haven't been configured yet).
- *
- * @param run running as part of a specific build
- * @param env environment variables applicable to this step
- * @param launcher a way to start processes
- * @param listener a place to send output
- * @param workspace a workspace to use for any file operations
- * @param jfrogBinaryPath path to jfrog cli binary on the filesystem
- * @param isWindows is Windows the applicable OS
- * @return launcher applicable to this step.
- * @throws InterruptedException if the step is interrupted
- * @throws IOException in case of any I/O error, or we failed to run the 'jf' command
- */
- public Launcher.ProcStarter setupJFrogEnvironment(Run, ?> run, EnvVars env, Launcher launcher, TaskListener listener, FilePath workspace, String jfrogBinaryPath, boolean isWindows) throws IOException, InterruptedException {
- JFrogCliConfigEncryption jfrogCliConfigEncryption = run.getAction(JFrogCliConfigEncryption.class);
- if (jfrogCliConfigEncryption == null) {
- // Set up the config encryption action to allow encrypting the JFrog CLI configuration and make sure we only create one key
- jfrogCliConfigEncryption = new JFrogCliConfigEncryption(env);
- run.addAction(jfrogCliConfigEncryption);
+ /**
+ * Get JFrog CLI path in agent, according to the JFROG_BINARY_PATH environment variable.
+ * The JFROG_BINARY_PATH also can be set implicitly in Declarative Pipeline by choosing the JFrog CLI tool or
+ * explicitly in Scripted Pipeline.
+ *
+ * @param env - Job's environment variables
+ * @param isWindows - True if the agent's OS is windows
+ * @return JFrog CLI path in agent.
+ */
+ static String getJFrogCLIPath(EnvVars env, boolean isWindows) {
+ // JFROG_BINARY_PATH is set according to the master OS. If not configured, the value of jfrogBinaryPath will
+ // eventually be 'jf' or 'jf.exe'. In that case, the JFrog CLI from the system path is used.
+ String jfrogBinaryPath = Paths.get(env.get(JFROG_BINARY_PATH, ""), Utils.getJfrogCliBinaryName(isWindows)).toString();
+
+ // Modify jfrogBinaryPath according to the agent's OS
+ return isWindows ?
+ FilenameUtils.separatorsToWindows(jfrogBinaryPath) :
+ FilenameUtils.separatorsToUnix(jfrogBinaryPath);
}
- FilePath jfrogHomeTempDir = Utils.createAndGetJfrogCliHomeTempDir(workspace, String.valueOf(run.getNumber()));
- CliEnvConfigurator.configureCliEnv(env, jfrogHomeTempDir.getRemote(), jfrogCliConfigEncryption);
- Launcher.ProcStarter jfLauncher = launcher.launch().envs(env).pwd(workspace).stdout(listener);
- // Configure all servers, skip if all server ids have already been configured.
- if (shouldConfig(jfrogHomeTempDir)) {
- logIfNoToolProvided(env, listener);
- configAllServers(jfLauncher, jfrogBinaryPath, isWindows, run.getParent());
+
+ /**
+ * Log if the JFrog CLI binary path doesn't exist in job's environment variable.
+ * This environment variable exists in one of the following scenarios:
+ * 1. Declarative Pipeline: A 'jfrog' tool was set
+ * 2. Scripted Pipeline: Using the "withEnv(["JFROG_BINARY_PATH=${tool 'jfrog-cli'}"])" syntax
+ *
+ * @param env - Job's environment variables
+ * @param listener - Job's logger
+ */
+ private void logIfNoToolProvided(EnvVars env, TaskListener listener) {
+ if (env.containsKey(JFROG_BINARY_PATH)) {
+ return;
+ }
+ JenkinsBuildInfoLog buildInfoLog = new JenkinsBuildInfoLog(listener);
+ buildInfoLog.info("A 'jfrog' tool was not set. Using JFrog CLI from the system path.");
}
- return jfLauncher;
- }
- /**
- * Before we run a 'jf' command for the first time, we want to configure all servers first.
- * We know that all servers have already been configured if there is a "jfrog-cli.conf" file in the ".jfrog" home directory.
- *
- * @param jfrogHomeTempDir - The temp ".jfrog" directory path.
- */
- private boolean shouldConfig(FilePath jfrogHomeTempDir) throws IOException, InterruptedException {
- List filesList = jfrogHomeTempDir.list();
- for (FilePath file : filesList) {
- if (file.getName().contains("jfrog-cli.conf")) {
- return false;
+ /**
+ * Configure all JFrog relevant environment variables and all servers (if they haven't been configured yet).
+ *
+ * @param run running as part of a specific build
+ * @param env environment variables applicable to this step
+ * @param launcher a way to start processes
+ * @param listener a place to send output
+ * @param workspace a workspace to use for any file operations
+ * @param jfrogBinaryPath path to jfrog cli binary on the filesystem
+ * @param isWindows is Windows the applicable OS
+ * @return launcher applicable to this step.
+ * @throws InterruptedException if the step is interrupted
+ * @throws IOException in case of any I/O error, or we failed to run the 'jf' command
+ */
+ public Launcher.ProcStarter setupJFrogEnvironment(Run, ?> run, EnvVars env, Launcher launcher, TaskListener listener, FilePath workspace, String jfrogBinaryPath, boolean isWindows) throws IOException, InterruptedException {
+ JFrogCliConfigEncryption jfrogCliConfigEncryption = run.getAction(JFrogCliConfigEncryption.class);
+ if (jfrogCliConfigEncryption == null) {
+ // Set up the config encryption action to allow encrypting the JFrog CLI configuration and make sure we only create one key
+ jfrogCliConfigEncryption = new JFrogCliConfigEncryption(env);
+ run.addAction(jfrogCliConfigEncryption);
}
+ FilePath jfrogHomeTempDir = Utils.createAndGetJfrogCliHomeTempDir(workspace, String.valueOf(run.getNumber()));
+ CliEnvConfigurator.configureCliEnv(env, jfrogHomeTempDir.getRemote(), jfrogCliConfigEncryption);
+ Launcher.ProcStarter jfLauncher = launcher.launch().envs(env).pwd(workspace).stdout(listener);
+ // Configure all servers, skip if all server ids have already been configured.
+ if (shouldConfig(jfrogHomeTempDir)) {
+ logIfNoToolProvided(env, listener);
+ configAllServers(jfLauncher, jfrogBinaryPath, isWindows, run.getParent());
+ }
+ return jfLauncher;
}
- return true;
- }
- /**
- * Locally configure all servers that was configured in the Jenkins UI.
- */
- private void configAllServers(Launcher.ProcStarter launcher, String jfrogBinaryPath, boolean isWindows, Job, ?> job) throws IOException, InterruptedException {
- // Config all servers using the 'jf c add' command.
- List jfrogInstances = JFrogPlatformBuilder.getJFrogPlatformInstances();
- if (jfrogInstances != null && jfrogInstances.size() > 0) {
- for (JFrogPlatformInstance jfrogPlatformInstance : jfrogInstances) {
- // Build 'jf' command
- ArgumentListBuilder builder = new ArgumentListBuilder();
- addConfigArguments(builder, jfrogPlatformInstance, jfrogBinaryPath, job);
- if (isWindows) {
- builder = builder.toWindowsCommand();
- }
- // Running 'jf' command
- int exitValue = launcher.cmds(builder).join();
- if (exitValue != 0) {
- throw new RuntimeException("Running 'jf' command failed with exit code " + exitValue);
+ /**
+ * Before we run a 'jf' command for the first time, we want to configure all servers first.
+ * We know that all servers have already been configured if there is a "jfrog-cli.conf" file in the ".jfrog" home directory.
+ *
+ * @param jfrogHomeTempDir - The temp ".jfrog" directory path.
+ */
+ private boolean shouldConfig(FilePath jfrogHomeTempDir) throws IOException, InterruptedException {
+ List filesList = jfrogHomeTempDir.list();
+ for (FilePath file : filesList) {
+ if (file.getName().contains("jfrog-cli.conf")) {
+ return false;
}
}
+ return true;
}
- }
- private void addConfigArguments(ArgumentListBuilder builder, JFrogPlatformInstance jfrogPlatformInstance, String jfrogBinaryPath, Job, ?> job) {
- String credentialsId = jfrogPlatformInstance.getCredentialsConfig().getCredentialsId();
- builder.add(jfrogBinaryPath).add("c").add("add").add(jfrogPlatformInstance.getId());
- // Add credentials
- StringCredentials accessTokenCredentials = PluginsUtils.accessTokenCredentialsLookup(credentialsId, job);
- if (accessTokenCredentials != null) {
- builder.addMasked("--access-token=" + accessTokenCredentials.getSecret().getPlainText());
- } else {
- Credentials credentials = PluginsUtils.credentialsLookup(credentialsId, job);
- builder.add("--user=" + credentials.getUsername());
- builder.addMasked("--password=" + credentials.getPassword());
+ /**
+ * Locally configure all servers that was configured in the Jenkins UI.
+ */
+ private void configAllServers(Launcher.ProcStarter launcher, String jfrogBinaryPath, boolean isWindows, Job, ?> job) throws IOException, InterruptedException {
+ // Config all servers using the 'jf c add' command.
+ List jfrogInstances = JFrogPlatformBuilder.getJFrogPlatformInstances();
+ if (jfrogInstances != null && !jfrogInstances.isEmpty()) {
+ for (JFrogPlatformInstance jfrogPlatformInstance : jfrogInstances) {
+ // Build 'jf' command
+ ArgumentListBuilder builder = new ArgumentListBuilder();
+ addConfigArguments(builder, jfrogPlatformInstance, jfrogBinaryPath, job);
+ if (isWindows) {
+ builder = builder.toWindowsCommand();
+ }
+ // Running 'jf' command
+ int exitValue = launcher.cmds(builder).join();
+ if (exitValue != 0) {
+ throw new RuntimeException("Running 'jf' command failed with exit code " + exitValue);
+ }
+ }
+ }
}
- // Add URLs
- builder.add("--url=" + jfrogPlatformInstance.getUrl());
- builder.add("--artifactory-url=" + jfrogPlatformInstance.inferArtifactoryUrl());
- builder.add("--distribution-url=" + jfrogPlatformInstance.inferDistributionUrl());
- builder.add("--xray-url=" + jfrogPlatformInstance.inferXrayUrl());
- builder.add("--interactive=false");
- // The installation process takes place more than once per build, so we will configure the same server ID several times.
- builder.add("--overwrite=true");
- }
+ private void addConfigArguments(ArgumentListBuilder builder, JFrogPlatformInstance jfrogPlatformInstance, String jfrogBinaryPath, Job, ?> job) {
+ String credentialsId = jfrogPlatformInstance.getCredentialsConfig().getCredentialsId();
+ builder.add(jfrogBinaryPath).add("c").add("add").add(jfrogPlatformInstance.getId());
+ // Add credentials
+ StringCredentials accessTokenCredentials = PluginsUtils.accessTokenCredentialsLookup(credentialsId, job);
+ if (accessTokenCredentials != null) {
+ builder.addMasked("--access-token=" + accessTokenCredentials.getSecret().getPlainText());
+ } else {
+ Credentials credentials = PluginsUtils.credentialsLookup(credentialsId, job);
+ builder.add("--user=" + credentials.getUsername());
+ builder.addMasked("--password=" + credentials.getPassword());
+ }
+ // Add URLs
+ builder.add("--url=" + jfrogPlatformInstance.getUrl());
+ builder.add("--artifactory-url=" + jfrogPlatformInstance.inferArtifactoryUrl());
+ builder.add("--distribution-url=" + jfrogPlatformInstance.inferDistributionUrl());
+ builder.add("--xray-url=" + jfrogPlatformInstance.inferXrayUrl());
+ builder.add("--interactive=false");
+ // The installation process takes place more than once per build, so we will configure the same server ID several times.
+ builder.add("--overwrite=true");
+ }
+ }
/**
* Add build-info Action if the command is 'jf rt bp' or 'jf rt build-publish'.
*
@@ -240,7 +242,7 @@ private void addConfigArguments(ArgumentListBuilder builder, JFrogPlatformInstan
* @param run - The Jenkins project
* @param taskOutputStream - Task's output stream
*/
- void addBuildInfoActionIfNeeded(Log log, Run, ?> run, ByteArrayOutputStream taskOutputStream) {
+ static void addBuildInfoActionIfNeeded(String[] args, Log log, Run, ?> run, ByteArrayOutputStream taskOutputStream) {
if (args.length < 2 ||
!args[0].equals("rt") ||
!equalsAny(args[1], "bp", "build-publish")) {
@@ -276,13 +278,17 @@ void addBuildInfoActionIfNeeded(Log log, Run, ?> run, ByteArrayOutputStream ta
}
}
- private void logIllegalBuildPublishOutput(Log log, ByteArrayOutputStream taskOutputStream) {
+ private static void logIllegalBuildPublishOutput(Log log, ByteArrayOutputStream taskOutputStream) {
log.warn("Illegal build-publish output: " + taskOutputStream.toString(StandardCharsets.UTF_8));
}
- @Symbol("jf")
@Extension
- public static final class DescriptorImpl extends BuildStepDescriptor {
+ public static final class DescriptorImpl extends StepDescriptor {
+ @Override
+ public String getFunctionName() {
+ return "jf";
+ }
+
@Nonnull
@Override
public String getDisplayName() {
@@ -290,8 +296,8 @@ public String getDisplayName() {
}
@Override
- public boolean isApplicable(Class extends AbstractProject> jobType) {
- return true;
+ public Set extends Class>> getRequiredContext() {
+ return Set.of(Launcher.class, FilePath.class, TaskListener.class, EnvVars.class);
}
}
}
diff --git a/src/test/java/io/jenkins/plugins/jfrog/AddBuildInfoActionTest.java b/src/test/java/io/jenkins/plugins/jfrog/AddBuildInfoActionTest.java
index 8d41d977..b480d59f 100644
--- a/src/test/java/io/jenkins/plugins/jfrog/AddBuildInfoActionTest.java
+++ b/src/test/java/io/jenkins/plugins/jfrog/AddBuildInfoActionTest.java
@@ -83,7 +83,8 @@ public void addBuildInfoActionNegativeTest(String command, String output) throws
private void runCliCommand(String command, String output) throws IOException {
try (ByteArrayOutputStream taskOutputStream = new ByteArrayOutputStream()) {
taskOutputStream.writeBytes(output.getBytes(StandardCharsets.UTF_8));
- new JfStep(command).addBuildInfoActionIfNeeded(new NullLog(), run, taskOutputStream);
+ JfStep jfStep = new JfStep(command);
+ JfStep.addBuildInfoActionIfNeeded(jfStep.getArgs(), new NullLog(), run, taskOutputStream);
}
}
}
diff --git a/src/test/java/io/jenkins/plugins/jfrog/JfStepTest.java b/src/test/java/io/jenkins/plugins/jfrog/JfStepTest.java
index afa4025f..2c9e858f 100644
--- a/src/test/java/io/jenkins/plugins/jfrog/JfStepTest.java
+++ b/src/test/java/io/jenkins/plugins/jfrog/JfStepTest.java
@@ -8,7 +8,7 @@
import java.util.stream.Stream;
-import static io.jenkins.plugins.jfrog.JfStep.getJFrogCLIPath;
+import static io.jenkins.plugins.jfrog.JfStep.Execution.getJFrogCLIPath;
import static io.jenkins.plugins.jfrog.JfrogInstallation.JFROG_BINARY_PATH;
/**
diff --git a/src/test/java/io/jenkins/plugins/jfrog/integration/JFrogInstallationITest.java b/src/test/java/io/jenkins/plugins/jfrog/integration/JFrogInstallationITest.java
index 79138eac..0dbdfa1d 100644
--- a/src/test/java/io/jenkins/plugins/jfrog/integration/JFrogInstallationITest.java
+++ b/src/test/java/io/jenkins/plugins/jfrog/integration/JFrogInstallationITest.java
@@ -226,4 +226,15 @@ public void testConfigurationAsCode(JenkinsRule jenkins) throws Exception {
assertTrue(StringUtils.containsIgnoreCase(output, "jfrog:"));
}
}
+
+ @Test
+ public void testOutput(JenkinsRule jenkins) throws Exception {
+ setupJenkins(jenkins);
+
+ // Download the latest CLI version from releases.jfrog.io.
+ configureJfrogCliFromReleases(StringUtils.EMPTY, false);
+
+ // Run pipeline that asserts the output is correct
+ runPipeline(jenkins, "version_output");
+ }
}
diff --git a/src/test/resources/integration/pipelines/version_output.pipeline b/src/test/resources/integration/pipelines/version_output.pipeline
new file mode 100644
index 00000000..14adb51e
--- /dev/null
+++ b/src/test/resources/integration/pipelines/version_output.pipeline
@@ -0,0 +1,21 @@
+pipeline {
+ agent any
+ tools {
+ jfrog '${JFROG_CLI_TOOL_NAME_1}'
+ }
+ stages {
+ stage ('Testing') {
+ steps {
+ script {
+ // Run 'jf -v' with string args to show the installed version of JFrog CLI and check the output.
+ String version = jf '-v'
+ assert version.startsWith('jf version')
+
+ // Run 'jf -v' with commands array to show the installed version of JFrog CLI and check the output.
+ version = jf(['-v'])
+ assert version.startsWith('jf version')
+ }
+ }
+ }
+ }
+}
\ No newline at end of file