Wednesday, November 16, 2011

How to display Static HTML Pages from Grails

They must be an easy way to do this but after a lot of Googling and some failures I used the following approach.

Store the HTML file in the web-app/WEB-INF folder of your grails application in a suitable subdirectory.

Where you wish to provide a link in a GSP page add the following, changing the file and dir strings as required:

 <g:link controller="ServeStatic" action="index"
params="[file:'disclaimer.html',dir:'/WEB-INF/FutureLetters/legal/']" >
Our WebSite Disclaimer</g:link>

Create the Grails Controller to render the file:

package com.yourdomain

import org.codehaus.groovy.grails.commons.ApplicationHolder

class ServeStaticController {

        def index(  ) {
       
        def file = params.file
        def dir = params.dir
       
        File layoutFolder = ApplicationHolder.application.parentContext.getResource("${dir}").file
       
        def absolutePath = layoutFolder.absolutePath
        def fileName = "${absolutePath}/${file}"
       
        File newLayoutFile = new File(fileName)
        def is = newLayoutFile.newInputStream()

        def String exportTemplate = is.text
       
        render exportTemplate
    }
}

Tuesday, September 13, 2011

A 101 on how to set-up CI for a Grails applications using Cloudbees

Synopsis: In this article I explain how I was able to set-up a Git repository on GitHub.com, populate it with a sample Grails application and then set-up Jenkins on Cloadbees.com to poll the GitHub repository for changes, build the application and deploy the application to the Cloud on Cloudbees. After reading this article you should be able to repeat the process in less  than 30 minutes yourself.


Prerequisites: I assume that you have:
  • Downloaded Grails and have a JVM installed from http://grails.org/
  • Are comfortable using a Unix like terminal shell (I am using Mac Os. I could have used Windows but at home I prefer to use my macbook)
Feedback
Whilst I will endeavour to correctly describe all of the steps required, I am very human so please feel free to submit any corrections. I was motivated to write this as the information I managed to find on the Internet was fairly patchy and didn't quite work for me. I have run this through using new Github and Cloudbees Ids in an attempt to QA my own work.

The Steps to Follow: 

1. Setup Master Git Repository 
  • If you haven't already register for an account on http://github.com/
  •  Click on the Set up Git tab and download and install git for your machine if not already present. This page explains how to get up your Github user name and email address in your local git global configuration file and how to set-up and store your ssh key.
  • You will create a local ssh key for GitHub access as follows:

  • Follow the instruction on how to configure git to be able to access your newly created GitHub repository as follows:

  • Next create a repository on GitHub. I called my first one grailstest so this can later be accessed using the access string: git@github.com:<your-github-id>/<your_repo_name>.git (you can see my name on Github is seahope1 and the access string is shown clearly.


  • Next from your Github Account Settings tab access the SSH Public Keys tab and store your local ssh public key for your machine which you need to create as explained on the Set up Git tab. The default public key to store on GitHub will be stored locally in ~/.ssh/id_rsa.pub


  • You will also need to add the Cloudbees public key which you can find within the Jenkins job which you will create later. I will come back to this.

2. Create a local working git repository
  • In a local terminal window follow the instruction you get when you click on your empty repository on Github. I have added the 'grails add first' command to create a basic grails application to provide files to add to the repository:
git init
grails create-app first
git add first 
git commit -m 'first commit'
git remote add origin git@github.com:<your-github-id>/grailstest.git
git push -u origin master
  • This will upload the default Grails application to your GitHub.com repository. You will be asked for your GitHub usename (not email address) and password when use use git push.
 3. Set-up Cloudbees.com for Continuous Integration
  • If you haven't already, sign-up for an acount at http://cloudbees.com/
  • Make sure you subscribe for DEV@cloud & RUN@cloud services. I selected the free options.

  • From the Jenkins page select Manage Jenkins -> Manage Plugins and enable the Git plugin. Ensure you select Install when you will be asked to restart Jenkins.
  • You also need to enable grails and github support are listed under the Available tab.

  • Again, you will need to restart Jenkins for these changes to take effect, which make take a few minutes.
  • From the Home screen -> Applications -> Add new application and call it: first grails

  • From Jenkins screen create a New Job & select Build a free-style software project and name the job first. 

  • Setup the following fields as follows:
    • Project name: first
    • GitHub project: git@github.com:<your-github-id>/<your-repo>.git
    •  Source Code management -> Git repositories selected. URL of repository: git@github.com:<your-github-id>/<your-repo>.git
    • Branches to build Branch Specifier: **



    • A while ago I mentioned the Cloudbees Public Key. This is located under the heading Cloudbees DEV@CLOUD Authorization (towards the top of the screen). This is the key that needs to be entered in GitHub as described above as another SSH Public key. Once this key is added to GitHub for your account Jenkins will be authorised to access  the repository to get the source to build.
    • Build Triggers ->  select Poll SCM and enter the pattern: * * * * *
    • Build Add Build Step and select Grails



    • Build -> Build with Grails -> Grails Installation: Grails 1.3.7 (or your version)
    • Targets: "war target/first.war"
    • Project base directory: first


    • Post-build actions -> Archive the artifacts Files to archive: first/target/first.war
    • Deploy to Cloudbees selected, Cloudbees site:<your-Cloudbees-id> (auto-populated)
    • Application Id: <your-Cloudbees-id>/firstgrails
    • Filename pattern: first/target/first.war



    • You can safely ignore the error message as it is just telling you that the grails target has not been created through a build yet.
    • Save the job and select Build Now to test the job. 
    • At this point you will be asked to validate your account by clicking on a URL. The page displayed will ask for a telephone number where the automated call back service will provide a pin number which you need to enter to complete the validation process.
    • Once you have successfully validated you will be able to run the job.



    • The Build History window will show progress.  If you click on the build number (hopefully with a blue sucessful icon showing) you can use Console Output [raw] to check to see what happened and if successful you can run the deployed application by clicking the link: http://firstgrails.<your-cloudbees-id>.cloudbees.net to access the running sample application. You can find the link from the Application screen:



    4. Make a change to the application and prove CI & CD works
  • In the Grails application change change the file: grailstest/first/grails-app/view/index.gsp e.g. change the text "Welcome to Grails" to "Welcome you to Grails" in both places. Then execute the commands:
    git add index.gsp 
    git commit -m 'simple change to index.gsp'
    git push -u origin master
  • You will notice on the Cloudbees Jenkins dashboard that after about one minute another build will be executed and once it completes successfully the application deployed will show the change.
    Next Steps
    You will notice that I haven’t tried to run the Grails tests and this step would have to be added before the application is deployed.
    I have not had a chance to explore using the Cloudbees SQL database.
    I have not explored how Grails plug-ins work with Grails on Cloudbees

    Acknowledgements
    1. An interesting blog on how to get up continuous delivery for Grails using Cloudbees