CircleCI cannot find maven settings when supplied on CLI - maven

[ERROR] Error executing Maven.
[ERROR] The specified user settings file does not exist: /home/circleci/project/ .folder/mvn-settings.xml
I have a script build-project.sh to build a mvn project.
This script takes the environment variable CUSTOM_MVN_OPTS, where I specify the path to the custom settings (e.g. private repo locations, etc.).
When I run the script in CircleCI or any CICD pipeline under docker env it's throwing above error.
#!/bin/sh
# build-project.sh
mvn ${CUSTOM_MVN_OPTS} package
What I expect? build-project.sh to build artifacts.
CUSTOM_MVN_OPTS="-s .folder/mvn-settings.xml" build-project.sh

After debugging found the solution.
Fix: hardcode the -s option within the script, you cannot pass this thru env variable.
#!/bin/sh
# build-project.sh
if [ -z "${CUSTOM_MVN_OPTS}" ]; then
mvn package
else
mvn -s ${CUSTOM_MVN_OPTS} package
fi

Related

Multiple maven install commands in Linux

I am running an azure pipeline for a maven project which has windows commands for maven installation, by calling multiple methods i.e.,
call mvn ... clean install
call mvn ... clean package (authentication)
call mvn ... clean package (restapi)
The build environment is linux Hence I am converting all the commands in the batch file to sh commands. For maven installation I initially added a maven installation task by mentioning the path and commands in the task. This failed.
So I am currently changing the windows commands to sh commands. The other commands except for maven installation have been converted using a batch to sh commands reference article.
Could some one guide me to convert the above mentioned installation commands to sh commands?
If the Apache Maven has been installed and added to the system path on the agent machine where your pipeline runs, you can just try directly calling the mvn command in the bash script, like you call it on Windows.
For example:
mvn ... clean install
mvn ... clean package (authentication)
mvn ... clean package (restapi)
Before you execute the bash script in the pipeline, you firstly should try and debug it on your local machine to make sure it can work as expected on the local machine. Then move the bash script to the pipeline on Azure DevOps.
If the bash script runs failed in the pipeline, for us to investigate this issue further, please share us with the complete debug logs of the failed pipeline run. To get the debug logs, you need to set the pipeline variable System.Debug to true, then trigger the pipeline.

Can Datomic dev-local be installed on windows?

I'm trying to install Datomic on a Windows 10 computer, following the official instructions.
I downloaded and unzipped the dev tools as instructed.
I cannot, however, run the install script because it is a bash script.
I opened the script and discovered it requires maven, so I installed maven and tried to run the commands manually.
echo 'Installing: com.cognitect/rebl {:mvn/version "0.9.242"}'
mvn -q org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file -Dfile=rebl-0.9.242/rebl-0.9.242.jar
echo 'Installing: com.datomic/dev-local {:mvn/version "0.9.232"}'
mvn -q org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file -Dfile=dev-local-0.9.232/dev-local-0.9.232.jar
At first this errored with
The goal you specified requires a project to execute but there is no POM in this directory
So I figured out how to create a maven pom.xml.
Then it errors
[ERROR] The specified file 'C:\workspaces\clj-recipe\rebl-0' not exists
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file (default-cli) on project clj-recipe: The specified file 'C:\workspaces\clj-recipe\rebl-0' not exists
Is dev-local not intended for windows?
Update
I did get the maven scripts to run. I created my own install.ps1 in the dev tool directory, which kept paths the same, and quoted the file paths.
# expects to be run from the project (pom.xml) directory, but in a script file in the same directory as the original install script
echo 'Installing: com.cognitect/rebl {:mvn/version "0.9.242"}'
mvn -q org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file -Dfile="rebl-0.9.242/rebl-0.9.242.jar"
echo 'Installing: com.datomic/dev-local {:mvn/version "0.9.232"}'
mvn -q org.apache.maven.plugins:maven-install-plugin:3.0.0-M1:install-file -Dfile="dev-local-0.9.232/dev-local-0.9.232.jar"
I still can't get dev-local to run though. There appears to be no changes to the pom.xml.
I start up a repl for the current lein project and run
(require '[datomic.client.api :as d])
(def client (d/client {:server-type :dev-local
:system "dev"}))
Getting the error No such namespace: d.
My guess is that I don't understand how deps.edn works... Right now I have a single deps.edn under C:/Users/[username here]/documents/.clojure/deps.edn
{
:mvn/repos {"cognitect-dev-tools"
{:url "https://dev-tools.cognitect.com/maven/releases/"}}
:deps
{com.datomic/dev-local {:mvn/version "0.9.225"}}
}
There were two key issues here
The install script is not necessary with leiningen (and is not written for windows)
If you want to use a maven-based approach, then use the install script. Be warned that you need maven installed.
The install script can be tweaked for windows by changing as shown above (quote paths, remove the cd, make it a ps1 file)
The deps.edn, maven, and leiningen paths are not compatible. I must configure the dependency using leiningen to use it in my lein-based project
Configuring for lein is fairly simple
add a repositories configuration section
add a package dependency
(defproject ;;...
:dependencies [
;;...
[com.datomic/dev-local "0.9.225"]
]
:repositories [
["cognitect-dev-tools" {:url "https://dev-tools.cognitect.com/maven/releases/"
:username :env/datomic_username
:password :env/datomic_password}]]
;;...
)
Note that the credentials have to be supplied to the lein project. This can be done with
environment variables as shown above (specify the name as :env/var-name-here)
or using an encrypted password field
or use a profile

mvn not found when executed via Jenkins shell script

I have set M2_HOME under Manage Jenkins -> configure system -> Environment variables and also under Manage Jenkins -> global tool configuration.
When I use maven project, it is working fine.
But when I use freestyle project and execute shell, it throws an error "mvn not found".
But when I give echo $M2_HOME in Execute shell, it shows the correct path.
Also, when I tried $M2_HOME/mvn compile, it worked fine.
I could not figure out the exact issue.
Error
[Compile]
$ /bin/sh -xe /tmp/jenkins1984982949384007169.sh
+ mvn --version
/tmp/jenkins1984982949384007169.sh: 2: /tmp/jenkins1984982949384007169.sh: mvn: not found
Build step 'Execute shell' marked build as failure
Finished: FAILURE
The shell which executes the mvn command doesn't know that the path for the script in in the M2_HOME variable. The shell will only look at commands listed in the $PATH variable.
So there are two solutions:
Always use "$M2_HOME/mvn" to execute Maven (or rather "$M2_HOME/bin/mvn" since M2_HOME should point to the folder which contains bin and lib and not to the script itself).
Change the path at the top of the script to make the shell search in the right place:
export PATH="$M2_HOME/bin:$PATH"
That probably only makes sense when you run Maven more than once in the script.

Jenkins "Invoke Maven 3" build step does not expose POM_* variables

I am using Jenkins as my CI server and Artifactory as my artifact repository. The Artifactory plugin works in free-style projects and can be used just by using Invoke Maven3 build step to both fetch the dependencies and deploy the artifacts. Furthermore, I have another build step for building a docker image and pushing it to my private docker registry using CloudBees Docker Build and Publish plugin.
The problem is that I want to use POM_* variables in CloudBees configurarion that should be exposed by Maven Plugin as mentioned here. But everytime I build the project, I got the following error:
ERROR: Unrecognized macro 'POM_VERSION' in '${POM_VERSION}'
org.jenkinsci.plugins.tokenmacro.MacroEvaluationException: Unrecognized macro 'POM_VERSION' in '${POM_VERSION}'
at org.jenkinsci.plugins.tokenmacro.TokenMacro.expand(TokenMacro.java:198)
at org.jenkinsci.plugins.tokenmacro.TokenMacro.expandAll(TokenMacro.java:233)
at org.jenkinsci.plugins.tokenmacro.TokenMacro.expandAll(TokenMacro.java:222)
at com.cloudbees.dockerpublish.DockerBuilder$Perform.expandAll(DockerBuilder.java:266)
at com.cloudbees.dockerpublish.DockerBuilder$Perform.getNameAndTag(DockerBuilder.java:277)
at com.cloudbees.dockerpublish.DockerBuilder$Perform.exec(DockerBuilder.java:247)
at com.cloudbees.dockerpublish.DockerBuilder$Perform.access$100(DockerBuilder.java:233)
at com.cloudbees.dockerpublish.DockerBuilder.perform(DockerBuilder.java:208)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779)
at hudson.model.Build$BuildExecution.build(Build.java:205)
at hudson.model.Build$BuildExecution.doRun(Build.java:162)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:537)
at hudson.model.Run.execute(Run.java:1744)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:98)
at hudson.model.Executor.run(Executor.java:374)
Build step 'Docker Build and Publish' marked build as failure
I do not know what exactly is the reason of this problem. Maybe the Invoke Maven3 build step is causing this problem by not exposing env variables. Another source of this could be CloudBees Plugin that does not utilize env variables. Any ideas?
The build step you mention, in a freestyle project, is not part of the Maven plugin. The environment variable described is only set for native Maven projects. From another project type, I suppose you would need to do something like
POM_VERSION=$(mvn help:evaluate -Dexpression=project.version | fgrep -v '[INFO]')
at the start of a script which continued to go on to use that variable.
Exposing the variable to subsequent non-shell build steps, such as from the CloudBees Docker Build and Publish plugin, is another matter; there may be some plugin that can do it, but I am not sure what offhand. (EnvInject perhaps.) It may be simpler to switch to a workflow job, using the CloudBees Docker Workflow plugin to drive Docker operations (depending on what exactly you are using from the Artifactory plugin):
node {
stage 'build'
git '…'
sh 'mvn package'
stage 'package'
sh 'mvn help:evaluate -Dexpression=project.version | fgrep -v '[INFO]' > .version'
def version = readFile '.version'
def image = docker.build("my-image:${version}")
stage 'publish'
docker.withRegistry(…) {
image.push()
}
}
By the way, you can add a shell build step just running
env | sort
if you are curious to see what environment variables are available.
Based on #Jesse Glick answer, searching around a little and struggling a bit with jenkins, I ended up with the following solution that works like a charm.
1-Add an "Execute Shell" build step containing following commands:
echo POM_VERSION=$(mvn help:evaluate -Dexpression=project.version | fgrep -v '[INFO]') > pom_file
echo POM_ARTIFACTID=$(mvn help:evaluate -Dexpression=project.groupId | fgrep -v '[INFO]') >> pom_file
echo POM_GROUPID=$(mvn help:evaluate -Dexpression=project.artifactId | fgrep -v '[INFO]') >> pom_file
2-Add an "Inject environment variables" build step (from EnvInject plugin) and enter "pom_file" as "Properties File Path"
3-Add a "Docker Build and Publish" build step and use POM_VERSION, POM_ARTIFACTID, POM_GROUPID in its configuration as you wish.

Executing maven compile commands from bash sequentially

I'm trying to build a project with Maven sequentially, with no success.
I tried put the following lines in a script file and called it from bash.
mvn -f ./cmroad-api/pom.xml clean install corona:package -Ddebug=false
mvn -f ./cmroad-impl/pom.xml clean install corona:package -Ddebug=false
The first command runs but the build does not call the second command. I tried putting the ; like:
mvn -f ./cmroad-api/pom.xml clean install corona:package -Ddebug=false; mvn -f ./cmroad-impl/pom.xml clean install corona:package -Ddebug=false.
The output was:
[ERROR] Unknown lifecycle phase "mvn". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>.
I would be most thankful for any help.
[ERROR] Unknown lifecycle phase "mvn".
This is the error you would get on typing mvn mvn; your script has two mvns on the same line, presumably because something is wrong with your line endings.
Start with a simple script:
#!/bin/sh
echo A
echo B
and get that working before moving on to Maven. The commands you specify should work when placed in a correctly prepared script. (Although, as khmarbaise says, your project is wrong if you need to build in this order.)

Resources