How to clean a particular directory before each build starts in jenkins? - continuous-integration

I am using jenkins with hudson cli through java. I want clean a particular directory before each build. Any idea ? I have provided the maven command clean package which clean target folder for each build. What i want is i want to clean some other directory before each build. How to do this ?
In jenkins i specified URL of maven project , Which ll download files to workspace when building. When i give clean package command, it clears target folder every time when building. There is another folder parallel to target folder. i want to clear that folder which is inside maven project.

If you are running version 1.433 or higher, use the Pre Steps / Post Steps in the project configuration section, located above and below the Build section, respectively.
Otherwise, install the M2 Extra Steps Plugin.
You can configure the maven-clean-plugin to handle the cleaning.
If you can't modify your pom.xml, as stated below, you can also use this plugin.

You can use the Workspace Cleanup Plugin to do exactly that.

You can add a JOB to clean the directory you want before each build. I have used ANT for this, no idea about MAVEN. This will not be machine dependent as well.

I'm not sure if I understand the question correctly, but if you are using repository to poll for changes and before each new build you do pull all files project from repo you could just use one of the options called: "Emulate clean checkout by first deleting..." This way all folders should be deleted before each build.
If that is not the case the most simple answer that comes into my mind is simply to write a CMD script which does simply DEL command on unwanted files/directories and run it as a pre step or post step as windows batch command.

In pom.xml add the profile tag like below
<profiles>
<profile>
<id>ci</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-clean</id>
<phase>pre-clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
<configuration>
<filesets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fileset>
<directory>do_not_checkin/build</directory>
<includes>
<include>**/*</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
While executing commad just execute the maven command mvn -Pci clean.
Which uses the maven clean plugin to clear a particular directory, before each build starts.
We can package like mvn -Pci clean package.
After cleaning the directory , package phase is executed.

Related

Checkout file from another repo using maven-scm plugin

I have a java application that is in git repo RepoA and has a scm configuration set up for this repo for maven-release plugin etc.
I want to fetch one file from another RepoB (it is fine to checkout the whole repo also because there is only 1 file there) and use it as a part of build step.
How to do it with maven-scm plugin if scm section is already set up for RepoA?
Thanks.
You can use a separate maven profile for this task.
Here's profile part from pom.xml, assuming that you want to fetch file foo/bar.txt from github repo github-user/some-repo:
<profile>
<id>checkout-foo-bar</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.11.2</version>
<configuration>
<connectionUrl>scm:git:git#github.com:github-user/some-repo</connectionUrl>
<includes>foo/bar.txt</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Then run mvn scm:checkout -P checkout-foo-bar
Plugin first fetches all the files from repo and then removes ones that you don't need. This takes extra time, especially if the repo is huge.
I didn't find a way to setup output directory other than default target/checkout. But hopefully this working example can be a good starting point to solve a problem.

maven - generate sources is not working

please advise if possible on this
I am running mvn package source:jar and get a module.jar and module-sources.jar as expected in the target directory
However, I have 2 issues:
1) I when I do : mvn install source:jar I get a -source.jar in my "target" in
the local projects folder, HOWEVER, NOT in the "local-repository (under .m2
on my PC). Even though, I do get a module.jar with binaries installed.
EDIT: I have figured this item (1): It works if I place "source:jar" before "install". That is mvn source:jar install instead of mvn install source:jar
2) I want to NOT HAVE TO run source:jar in the command line to generate the sources. Because, when I use GO continuous integration tool, that I have no control over, they do not have a maven goal mvn source:jar there.
I know that with the configurations in the pom.xml it can be achieved, and I did see it occuring once or twice, but it stopped working (well, obviously I made a change,that I do not know that broke this)
My pom.xml has the following
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<outputDirectory>${source.directory}</outputDirectory>
<finalName>${project.jar.name}</finalName>
<fileNameMapping>no-version</fileNameMapping>
<classifier>${source.classifier}</classifier>
</configuration>
</execution>
</executions>
</plugin>
So, ultimately, when I run either mvn package or mvn install or I want to have sources generated as a jar file next to the regular project.jar (or in the specified folder, but it is not essential)

How to build EAR subproject and deploy it with Jenkins?

My Maven project has a bunch of subprojects like this:
proj/
projEAR/
projCommon/
How can I compile and build the EAR project + deploy it to my web server at the same time?
The way I do it now is:
proj$ mvn clean install
[... builds everything ... ]
proj$ cd projEAR
projEAR$ mvn weblogic:deploy
[... deploys the EAR file ... ]
I'd like to do this with one command. Something like
proj$ mvn clean install projEAR/pom.xml weblogic:deploy
This fails of course, but I hope you get the idea...
Update:
The reason for all this is that jenkins only accepts one pom-file and command. So the problem is really how to configure Jenkins to run Maven twice.
How about the weblogic-deployer-plugin of Jenkins. It will deploy your ear file to a weblogic instance. See WebLogic Deployer Plugin.
Quick and easy workaround
As a workaround, I can advise you to use some Jenkin's Plugins, like "M2 Extra Steps". It allow you to perform extra actions pre or post one. They are often use after a build to perform stuff like generating doc, or deploying something.
I know this is working well ... because I often use this trick :)
Suggestion, never tried
At this moment, I don't have a straight answer. I don't really know how to do it in only one maven command. What I would try is to attach weblogic deploy phase to install.
ear submodule --> pom.xml
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<configuration>
[...]
</configuration>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
<plugins>
[...]
<build>
It should work, but once again, I never tried it.
Don't hesitate to give feed back
I couldn't get it to work with Maven. But the way I solved it (in Jenkins) was
Create a pre-build step in Jenkins with the command mvn clean install using the parent pom: proj/pom.xml
Configure the main build as weblogic:deploy using projEAR/pom.xml.
This results in two commands being run: First mvn clean install followed by mvn weblogic:deploy.

Separate Jenkins-Project for deploying to JBoss

I have a Jenkins build which builds a maven project with -PmyProfile clean package. This works fine. Now I want the project be deployable but in a separate task (JBoss deployment) so it can be triggered explicitly via the jenkins GUI. For that, I have the following in my pom:
<profiles>
<profile>
<id>myProfile</id>
<properties>...</properties>
<build>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.0.0.Final</version>
<configuration>
<hostname>localhost</hostname>
<port>29999</port>
<username>admin</username>
<password>admin</password>
<filename>${project.build.finalName}.war</filename>
<name>my-webapp</name>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Now I only want to call that single deployment via mvn jboss-as:deploy separately. But how would I do that? If I create a second Jenkins project, everything needs to be built again, so that's pretty stupid. Building as a separate module does not work, either (some error with "building single modules not supported for maven 3").
Any ideas?
Thanks
It sucks a little, but you can always get stuff from another Jenkins workspace by using filesystem relative path like ../../SecondJob/workspace (or use symlink). I used to do this for the same case (deploying as separate job) for all my projects and it works, it's just not elegant, but I believe there's no built-in solution in Jenkins for that.
Alternatively, it seems there's Jenkins plugin for that, but I haven't used it and can't tell anything about it.
Possible trick:
Have only one project, but parameterize it with DEPLOY parameter set to FALSE by default. The build will contain your main build as well as an Invoke top-level Maven targets post-build step for deployment. The deployment step will be invoked only if DEPLOY is TRUE. To do that you use Conditional Build Step plugin.
There is a new deploy-only goal added in version 7.5.Final. You can grab the war from the first job with Copy Artifact Plugin.
References:
https://docs.jboss.org/jbossas/7/plugins/maven/latest/deploy-only-mojo.html
https://github.com/jbossas/jboss-as-maven-plugin/pull/56/commits

Maven Release Perform Commit Additional Files

I am using the preparationGoals configuration option of the Maven release plugin to transform additional files to reflect the version of the project being released. This works beautifully.
The problem is that when executing the commit, the plugin explicitly specifies that only the pom.xml files should be included thus leaving my other files uncommited:
[INFO] Executing: /bin/sh -c cd /Users/jw/dev/Test && git commit --verbose -F /var/folders/w0/hr1h_7h50f3_pwd_nrk9l808000195/T/maven-scm-114713951.commit pom.xml library/pom.xml sample/pom.xml
Is there any way for me to override this behavior and specify additional files or globs to include in the commit?
(I also need this behavior for the completionGoals as well which I have configured to do that same transformation)
I also need to commit some additional files (changed by Maven Replacer plugin). I did it in the following way:
First I configured Maven Release plugin to execute additional goals:
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<preparationGoals>-Prelease -DreplacerVersion="${releaseVersion}" clean replacer:replace scm:checkin verify</preparationGoals>
<completionGoals>-Prelease -DreplacerVersion="${developmentVersion}" clean replacer:replace scm:checkin verify</completionGoals>
</configuration>
</plugin>
release profile defines configuration of Maven SCM plugin
replacerVersion argument is used by Maven Replacer plugin to set correct version in some files
clean is a standard goal run by Maven Release plugin (default: clean verify)
replacer:replace goal is responsible for modifying files
scm:checkin does commit and push
verify is a standard goal run by Maven Release plugin (default: clean verify)
Next I configured Maven Replacer plugin:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<configuration>
<includes>
<include>${basedir}/file1.txt</include>
<include>${basedir}/file2.txt</include>
</includes>
<replacements>
<replacement>
<token><![CDATA[<pattern>.*</pattern>]]></token>
<value><![CDATA[<pattern>${replacerVersion}</pattern>]]></value>
</replacement>
</replacements>
</configuration>
</plugin>
${replacerVersion} allows to use the same configuration for changing from a development to a release and next from the release to a next development version.
Finally I defined which version of Maven SCM plugin I want to use:
<plugin>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.5</version>
</plugin>
and configuration it in the release profile (I defined it in the profile to prevent accidental commits during non-release build):
<profile>
<id>release</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-scm-plugin</artifactId>
<configuration>
<message>[maven-scm-plugin] set ${replacerVersion} version in files</message>
<includes>file1.txt, file2.txt</includes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Thanks to that after executing a command:
mvn release:prepare -DdevelopmentVersion=1.2.1-SNAPSHOT -DreleaseVersion=1.2.0 -Dtag=1.2.0
I see 4 commits:
[maven-scm-plugin] set 1.2.0 version in files
[maven-release-plugin] prepare release 1.2.0
[maven-scm-plugin] set 1.2.1-SNAPSHOT version in files
[maven-release-plugin] prepare for next development iteration
Could you use the maven-scm-plugin? Add a plugin execution running the scm:checkin goal to commit the files you want. Bind it to a phase that will execute when preparationGoals are run (if you specified one or more phases as the value for that element), or include the scm:checkin goal in preparationGoals directly.
It appears the failure to allow specification of additional tag files is actually a bug in Maven. On line 130 in the org.apache.maven.shared.release.phase.AbstractScmCommitPhase class of the Maven Release Plugin, there are references to a "commitByProject" flag first introduced in Maven 2.0-beta-7.
A branch is used to determine the mechanism by which files are added to the Maven release:prepare commit. The SCM plugin is loaded with files in advance of the commit using the SCMFileSet class. One of the branch instantiations of that class may have been trying to add all files in the base directory, but it doesn't work that way in SCM.
This is a point where a fix could be implemented to take a list of files or to add a directory of files to commit.
Bottom line, after deep-diving into a debug execution of the Maven Release Plugin, it is invoking SCM Plugin to add only the POMs from the repos. Changing the poorly documented "commitByProject" flag has zero impact on the results in respect to which files are added into the SCM commit.
Another workaround is to configure another plugin (e.g. Maven AntRun Plugin) to manually run git add ., and then execute that as part of preparationGoals as well. This just happens to work and the modified files are part of the "[maven-release-plugin] prepare release ..." commit. However, I am not sure if this behavior is guaranteed, so this might rely on implementation details of the Maven Release Plugin.
Example configuration using the Maven AntRun Plugin to run git add:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.0-M6</version>
<configuration>
<preparationGoals>
... other goals ...
antrun:run#git-add-changed
</preparationGoals>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>git-add-changed</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<exec executable="git" dir="${project.basedir}" failonerror="true">
<arg value="add" />
<arg value="." />
</exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
The main advantage of this compared to using the Maven SCM Plugin is that this does not require you to know in advance which files were modified and have to be committed. This can be useful when you replace a certain string in multiple files, e.g. #since NEXT in the Javadoc of all source files. With the scm:add goal of the Maven SCM Plugin the includes parameter seems to execute git add for all matching files separately, which will be slower and can cause issues when it matches by accident a file listed in .gitignore.

Resources