Showing posts with label build. Show all posts
Showing posts with label build. Show all posts

Thursday, June 16, 2016

Maven POST a zip through HTTPS using gmaven and HttpClient

What

Well in this blog post I put all necessary things to be able to post on a defined url a product.
This product could be provided by an assembly or (it's my case)  by a tycho repository build.

How

First of all we use maven and an integration chain. As I dont want to use a post script build in jenkins (it's external...)
So we have two main options :
  • build a Maven plugin
  • use something embed in the pom.
As we have very few site to push I target the second option and I use gmaven, that is allows to excute a groovy script so every thing is open.
To do the https post I use HttpClient from apache, this framework allow a good way to do post whith authentication, SSL and all those kind of things.

So the script :

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

class X509TM implements X509TrustManager {
 public X509Certificate[] getAcceptedIssuers(){
  return null;
  }

 public void checkClientTrusted(X509Certificate[] certs, String authType){}
 public void checkServerTrusted(X509Certificate[] certs, String authType){}
};

String url = pom.properties["http.url"];
if(url != null)  {
 log.info("Try to post site at url : " + url);
 FileInputStream fileInputStream = null;
 try {
  //TRUST ALL : bar but it should be a temporarly workaround
  X509TrustManager X509Tm = new X509TM();
  TrustManager[] trustAllCerts = [X509Tm] as TrustManager[] ;
  SSLContext sslcontext = SSLContexts.custom()
    .loadTrustMaterial(null, new TrustSelfSignedStrategy())
    .build();
  sslcontext.init(null, trustAllCerts, new SecureRandom());
  SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
  CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
 
  String outDir = pom.properties['outputdir'];
  String pname = pom.properties['pname'];
  String pversion = pom.properties['pversion'];
  HttpPost post = new HttpPost(url);
  File file = new File(outDir+"/"+pname+"-"+pversion+".zip");
  if(file.exists())  {
   log.info("multipart to post : " + file.getAbsolutePath());
   //create multi part
   MultipartEntityBuilder builder = MultipartEntityBuilder.create();
   builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
   builder.addBinaryBody("site", file, ContentType.MULTIPART_FORM_DATA, file.getName());
   HttpEntity multipart = builder.build();
   post.setEntity(multipart);
   //DO POST
   CloseableHttpResponse  response = httpclient.execute(post);
   HttpEntity entityRep = response.getEntity();
   if (entityRep != null) {
    String page = EntityUtils.toString(entityRep);
    log.info("PAGE :" + page);
   }
   EntityUtils.consume(entityRep);
  } else  {
   log.info("File "+file.getAbsolutePath() +" not found");
  }
  } catch (Exception e) {
  e.printStackTrace();
  if(fileInputStream != null )
   try {
    fileInputStream.close();
   } catch (IOException e1) {
    e1.printStackTrace();
   }
  }
} else {
 log.info("Post site is disabled (url is null)");
}


And finally the  pom. As you could see I set a maven profil activated on system property :

<project>
...
<profiles>
 <profile>
  <activation>
  <!--ACTIVATE through -Denvprops=Push-->
   <property>
    <name>envprops</name>
    <value>Push</value>
   </property>
  </activation>
  <properties>
   <http.url>${YOURURL}</http.url>
   <pname>${project.name}</pname>
   <pversion>${project.version}</pversion>
   <outputdir>${project.build.directory}</outputdir>
  </properties>
 </profile>
</profiles>

<build>
 <plugins>
  <plugin>
   <groupId>org.codehaus.gmaven</groupId>
   <artifactId>gmaven-plugin</artifactId>
   <version>1.5</version>
   <dependencies>
    <dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.2</version>
    </dependency>
    <dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpmime</artifactId>
     <version>4.5.2</version>
    </dependency>
   </dependencies>
   <executions>
    <execution>
     <!-- To be after Zip generation -->
     <phase>install</phase>
     <goals>
      <goal>execute</goal>
     </goals>
     <configuration>
      <source>${project.basedir}/post.groovy</source>
     </configuration>
    </execution>
   </executions>
  </plugin>
 </plugins>
</build>
</project>

Tuesday, February 10, 2015

Jenkins : duplicate jenkins enviromnent and apply SCM change on every job

Duplicate Continuous integration (Jenkins) enviromnent

Just a reminder to explain and speak about jenkins scripting console.

Our problem is :
  • we have many hundred maven projets
  • each project has its job in jenkins (project choice)
  • when preparing a new release we "branch" all sources in our SCM

question how can we duplicate jenkins environement ?

Cookbook

  • install a new jenkins instance 
  • install in this instance a plugin called Job import plugin
  • use this plugin and import all job from your initial instance
  • Then use the script console  ${host}/${Jenkins_inst_name}/script . This jenkins feature is very powerfull. It's allow to walk through all job and mofify them if needed. In our case we apply this groovy script (I start from this source wiki.jenkins-ci.org/display/JENKINS/Change+Version-Number+in+SVN-path)
import hudson.scm.*
hudsonInstance = hudson.model.Hudson.instance
overrideExistingValues = false
allItems = hudsonInstance.items
allItems.each { job-> println "Name : "+job.name;
if(!(job instanceof hudson.model.ExternalJob)) {
   if (job.scm instanceof SubversionSCM) {
     def newSvnPath = [][]
     println "SCM job : "+job.name;
     job.scm.locations.each{
       println "Scm location : "+it.remote;
       newRemote = it.remote
       newRemote = newRemote.replaceAll("franckys/svn/LOCAL/trunk",
        "franckys/svn/LOCAL/branches/preV2")
       newSvnPath.add(new hudson.scm.SubversionSCM.
        ModuleLocation(newRemote,it.local))
       println "Scm new location : "+newRemote;
     }
     newscm = new hudson.scm.SubversionSCM(newSvnPath,
        job.scm.workspaceUpdater, job.scm.browser,
     job.scm.excludedRegions, job.scm.excludedUsers, job.scm.excludedRevprop, 
        job.scm.excludedCommitMessages, job.scm.includedRegions)
     if (overrideExistingValues){
       job.scm = newscm;
     }
   }
 }
}
If you have interest in script you could have a look at : https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console