martedì 20 ottobre 2015

Using git push to deploy

Using git push to deploy

Git is extremely useful as a versioning system, but it could be used to simplify deploy process: you can configure a repository to execute operations on push received. This way, when you push you commits, you can also trigger a deploy operation!
Here it is a short how-to guide.

Create a directory to use as a git remote repository

Go on your production machine. Create a directory that will be used as a remote repository, the one that will receive you push. Append .git to your directory name to mantain a usual name-convention. We decide to deploy an application called "mountain":

cd /home/myuser/
mkdir mountain.git
cd mountain.git

Initialize a bare repository

There is a very interesting and quick to be read article which explains what is a bare repository and what is a standard repository, but to say it even quicker, a standard repository is a "working" repository (where you can perform common versioning operations) while a bare repository is a repository that works as a remote origin and is used only to be read from other repositories. We need to create a bare repository to receive push, so:

git init --bare

This command will create a non-common git structure.

A note about this repository: we could have created a standard repository and then initing it as a bare repository, but then we should have added a special configuration. This article explains pros and contros

Create a new git repository where a new working copy will be checked out on every push (the deploy directory)

Now create a directory where the project will be checked out any time a push will occur. This will be the deploy directory. So, create the directory, cd in and git clone the previously created repository:

cd /home/myuser/
mkdir mountain
cd mountain
git clone myuser@localhost:/home/myuser/mountain.git

Modify hook to execute commands on push

Now we will go back to our mountain.git repository and add a hook to execute commands when we receive push. After a push (on post-received) we will checkout the master branch to the deploy folder and can executa any command, such starting nodejs (this is an example where we restart a nodejs server application invoking a script but you can do whatever you want to do):

cd /home/myuser/mountain.git
cd hooks
touch post-receive
chmod +x post-receive
vi post-receive

and now we insert this commands:

#!/bin/sh
GIT_WORK_TREE=/home/myuser/mountain git checkout -f
cd /home/myuser
./nodejsStarter.sh

GIT_WORK_TREE is a command!!! I didn't know it and had to dig a lot to understand it! But this is the magic command that executes a checkout after the push.

Add the new remote to your working copy project

In your working copy, you must add the newly created remote so you will be able to push to it. So, go inside your working copy directory (where you develop the project) and add the remote reference. Here it is and example where we add the "production" remote to our repository :

git remote add production myuser@192.123.123.123:/home/myuser/mountain.git

If you do something wrong, use "git remote rm production" to remove remote reference and "git remote" to check references

The end!

Now everything should work well: when you git push to the "production" reference, the deploy dir containing a repository is updated by the post-receive hook.

Now that you have read my article, i would like to show you another thing: i've developed an app to help increase customers registration and customers conversion.

You can find it at appromocodes.com

sabato 23 maggio 2015

Grails and Groovy xml marshalling and unmarshalling

Grails and Groovy xml marshalling and unmarshalling

Converting JSON to a map object is a very simple task to perform in Groovy. But what if you need to marshal and unmarshal xml?
I will show a simple way on how to do it.
Suppose we have a reservation xml we want to marshal:

<ns2:roomReservation xmlns:ns2="http://an.address.com/">
    <customerId locale="en_US">F3F0C7</customer>
    <itineraryId>205216012</itineraryId>
    <rooms>
      <room>301</room>
      <room>302</room>
    </rooms>
    <info>
      <start>2015-05-23</start>
      <end>2015-05-26</end>
    </info>
</ns2:roomReservation>

Ok now we must define classes to marshal xml to. Let's define a RoomReservation groovy class which must implements Serializable

package com.test.a
import javax.xml.bind.annotation.*

@XmlRootElement(name="roomReservation", namespace="http://an.address.com/")
@XmlAccessorType(XmlAccessType.FIELD)
class RoomReservation implements Serializable {

@XmlElement String customerId
@XmlAttribute String locale
@XmlElement long itineraryId
@XmlElement(name="rooms") List<Room> roomList
@XmlElement(name="info") Info info
}

Let's have a look at this class: this class bind roomReservation tag to this class and maps all the fields within.
Any attribute is mapped by @XmlAttribute annotation and the rooms tag is mapped as a List (roomList groovy property).
Pay attention!!! Any time you define a non simple Object or type property, you must use (name="xmltag") to map it to your specific class such as for Info class and List.

Now let's have a look at our Info class:

package com.test.a
import javax.xml.bind.annotation.*

@XmlRootElement(name="info")
@XmlAccessorType(XmlAccessType.FIELD)
class Info implements Serializable {

@XmlElement String start
@XmlElement String end
}

Now that we have mapped our structures, we can unmarshal xml this way:

String xml
...
... //we omit how to get xml but it will be stored in xml variable
def jaxbContext= JAXBContext.newInstance(RoomReservation.class)
def unmarshaller = jaxbContext.createUnmarshaller()
RoomReservation roomReservation = unmarshaller.unmarshal(new StringReader(xml))

or marshal this way (using the RoomReservation already defined and populated):

def jaxbContext = JAXBContext.newInstance(RoomReservation.class)
def marshaller = jaxbContext.createMarshaller()
StringWriter writer = new StringWriter();
marshaller.marshal(roomReservation, writer)
String xml = writer.toString()

So this is a very simple way to marshal and unmarshal xml to Groovy objects.

Now that you have read my article, i would like to show you another thing: i've developed an app to help increase customers registration and customers conversion.

You can find it at appromocodes.com