Setting build.timestamp when publishing from sbt - scala

Today, my team has a handful of projects which are frequently 'published' for production usage. We are using JFrog's hosted Artifactory solution to host our binaries, but are running into a problem when project publish both jars and assembly files.
From speaking to someone at JFrog, they said the following.
Artifactory expects the deployment to be in the following order (as done by Maven):
jar
pom
classifiers
I suspect that since you are deploying the files on a different order, Artifactory fails to calculate the unique snapshot.
However, there is a way to make it work:
For each artifact add the ‘build.timestamp’ HTTP matrix param with the current time in milliseconds. Note that all of the artifacts from the same build should have the same timestamp value.
For example:
http://myaccount.artifactoryonline.com/myaccunt/libs-snapshots-local/com/artifact-SNAPSHOT.jar;build.timestamp=1375140480339
Two questions out of this: is SBT really publishing in a different order and if so how do I change the publish url to include this build.timestamp?

sbt doesn't publish in a defined order. I don't think there is a way to put a timesamp in the published URL, so the best option is to implement an order in sbt itself.
Previous discussion: https://groups.google.com/d/topic/simple-build-tool/FZqTfpizI-k/discussion
The link there is now at: https://github.com/sbt/sbt/blob/0.13/ivy/src/main/scala/sbt/IvyActions.scala#L257

Related

SBT : Auto versioning of artifacts

We have a Scala project which we are building via CI tool (TeamCity/Jenkins). We are looking for an ability to set the build version of the artifact from the build job itself and not depend on the entry in build.sbt file. To give a reference, for java maven builds we can use goal set-version where the artifact version is set, irrespective of what we have in pom.xml. we are looking for something similar for a SBT build as well.
I'd reccoment to take a look at next sbt plugins:
https://github.com/dwijnand/sbt-dynver
https://github.com/sbt/sbt-git
Our team uses sbt-dynver to create version from Git, because it is easier. I'd recommend to build version on top of git tags information rather then using CI tool (TeamCity/Jenkins) information - like build number, because you can build same version twice for instance.
Also, consider using https://github.com/sbt/sbt-buildinfo - additionally, so to expose build version though API or print to output to quick identify currently deployed app version.
This isn't really the right forum for this kind of recommendation, but you could start by looking a sbt-git which will set version numbers based on GIT tags.
One option your have, is to add this to your build.sbt:
version := sys.env.getOrElse("ARTIFACT_VERSION", "0.0.0-SNAPSHOT")
Then setting the version you want at the environment variable ARTIFACT_VERSION.

Use another plugin in own hudson plugin?

I'm developing my own hudson plugin and can not find a really comprehensive documentation.
How can I connect to the artifactory plugin to get a list of artifacts? The artifactory plugin is installed in hudson but I don't know how to instance it/connect to it from my own plugin.
My plugin deploys a specific version to our webstart server. This includes downloading the artifact from artifactory over HTTP, creating version.xml and *.jnlp file and uploading these three files to the webserver using SCP. For the configuration of this plugin, I need a list of all versions of a specific project from artifactory.
Thanks in advance.
If you'd like to use model and utility classes of another plugin, then it's simply a process of depending on that plugin (compile-wise) and making sure that the dependent plugin is installed so you can reference these classes at runtime.
If you'd like to use entities like builders, actions or wrappers, you'll probably need to use Hudson's facilities; I'm not so sure as to which facilities it has, but Jenkins' hudson.model.AbstractBuild and hudson.model.AbstractProject (and other) objects have methods like:
hudson.model.Actionable#getActions
AbstractProject#getPublishersList
That'll return those entities (assuming they're configured on the project in question).
Apart from that approach, there are a number of ways to solve your issue using Artifactory's REST API:
If the artifacts are contained in Artifactory within one location that's known to you, you can execute a file list query to reveal the contents of that directory.
If you'd like to fetch the produced artifacts of a specific Hudson build, and assuming that you use the Hudson plugin to deploy Build Info, you can request the Build Info object using the Build Info resource; utilizing the checksums of the produced artifacts listed in this object, you can perform artifact checksum queries to find out if and where these artifacts exist in Artifactory.
If you don't know the specific build name and number or the location, you can use any of the search facilities to locate artifacts based on different details; The GAVC or XPath searchers are most likely to help in your situation.

Get a Hudson build with Maven

I have moved to Maven recently, and since it works fine for resources up to date in some repositories, it's not obvious for non-maven ones.
I have something very simple to achieve (in the idea), but that I am unable to express so far:
I need to compile my code with a jar that can be found here:
https://hudson.eclipse.org/hudson/view/WTP/job/cbi-wtp-wst.xsl.psychopath/ws/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/target/
What do I have to put in my pom.xml to make Maven downloading the .jar + the java source + the javadoc, and eventually the other dependencies (actually IBM ICU, Xerces, JavaCup) that are mentionned in the supplied MANIFEST ?
I have read lots of documents, including those with a plugin called Tycho, but nothing helpfull for that simple task.
Thanks for your help.
Maven only works well if all artifacts needed for a build are contained in the local or a configured remote repository. So you have to do the following jobs:
Find out if eclipse plugins are deployed in a Maven2-style repository, and what the URL of that repository is.
Then find out which version of that plugin (artifact) you need.
Maven allows you to configure what will be copied locally: jar file, sources and api doc if you want to.
Maven should then be responsible to download as well all needed artifacts for the plugin you want to use.
After looking at the contents of the URL you gave us (especially the file p2content.xml), it looks like there should be a repository. I searched for the maven repository for org.eclipse.wst.xml.xpath2 and found the URL http://maven.eclipse.org/nexus/content/repositories/testing/org/eclipse/wst/org.eclipse.wst.xml.xpath2/1.1.0/org.eclipse.wst.xml.xpath2-1.1.0.pom
So the repository you are searching for is located at http://maven.eclipse.org/nexus. Just open it, search for example for xpath2, and Nexus, the repository software used there will you show the available artifacts. Depending on what was deployed to that repository, it may contain only the library, or have even sources and JavaDoc bundled with it. For the example above (xpath2), there seems to be only the POM itself and the library (the jar). If you take as example junit, you will find all versions and variants, even with sources.jar and javadoc.jar.
After you have found the needed artifact, you can include it in the dependency section of your POM. And you have to add http://maven.eclipse.org/nexus as a remote repository in the configuration of your Maven installation.
The question and its answer Get source JARs from Maven repository explain how to fetch sources and JavaDoc (if they are available).
You need a maven repository which contains this artifacts (i don't know, if Eclipse hosts a repository for their projects). You can also deploy manually the artifacts to a local repository on your computer.

Maven: Prevent upload of default-jar - only upload jar-with-dependencies

I'm evaluating Maven 3 at work. For several example projects I have to deploy them to a server (no repository), but that's not the problem.
In my current example-project I'm trying to upload only the "jar-with-dependencies".
and exactly that's my problem.
It all works fine, except that the main-artifact AND the jar-with-dependencies (created by the assembly-plugin) are uploaded.
How do I prevent Maven or rather the deploy-phase from uploading the main-jar and only upload a given or specified file (in this case, the assembly-file "jar-with-dependencies")?
Referring to the question Only create executable jar-with-dependencies in Maven, I can't just alter the packaging-setting to pom, because it will also prevent the assembly-plugin from adding my classes to the JAR file. It only creates a JAR file with the files of the dependencies.
I hope I'm clear about my problem, and you can help me ;)
if you just looking how to add a file to be deployed you can take a look here:
http://mojo.codehaus.org/build-helper-maven-plugin/attach-artifact-mojo.html
May be this helps. If not express your needs more in detail.
There seems to be no way to configure the deploy plugin to filter out some of the artifacts from a project and selectively deploy the others. Faced with a similar problem, we solved this with the ease-maven-plugin. It fit well into our release process but might not be the right choice for everyone as it mandates a two-step approach. During the build you would make a list of all artifacts and filter out those that you want deployed. In a second step, you then run mvn deploy on a separate project (or separate profile) in which the list of artifacts is attached to the project as the only artifacts which then get deployed. See the examples in the source code of the ease maven plugin to better understand how it works.
The original version is not able to filter out specific artifacts of a project. I have forked the project and added patches that add this.

How to deal with Maven projects containing several internal artifacts?

I'm about to start working on a web-application and I'll be using Maven. I want the web-application to be an individual artifact. The web-application will end up depending on a couple of self written libraries (for example text-formatting), and each of these libraries should be an individual artifact.
What's the recommended way of achieving this separation while making it simple to code for both artifacts? I was thinking of creating one project for each artifact and import them one by one in Eclipse. However, if the pom for web-application has a dependency pointing at the self written library, I'll end up having to deploy a snapshot every time I want to see if the change I made stopped the web-application from crashing (in example).
I hope you understand what I am getting at. I'll be working with a couple more developers, and we're using Nexus to maintain our shared artifact repository.
I was thinking of creating one project for each artifact and import them one by one in Eclipse.
Yes, that's the recommended way.
However, if the pom for web-application has a dependency pointing at the self written library, I'll end up having to deploy a snapshot every time I want to see if the change I made stopped the web-application from crashing
During development, you can use "workspace resolution" i.e. configure Eclipse to resolve dependencies from the workspace. This way changes are immediately visible from the webapp. This is possible whether you are using m2eclipse or the maven eclipse plugin (and is actually the default behavior for both).
Below, an illustration for m2eclipse:
A good maven plugin for eclipse is capable of "workspace resolution", i.e. it will recognize if the dependency is also present in the workspace, and refer to the other project directly rather than adding a JAR to the build path.