This document discusses continuous integration (CI) using Jenkins and Java EE. It defines CI as applying quality control through frequent small changes. The history and key principles of CI are described. Features of CI like automated builds, testing, and deployment are covered. The document then focuses on Jenkins, an open source CI server, its features, plugins, and how to set up CI pipelines using Jenkins with source control from Git and builds from Maven.
4. What is CI
● In software engineering, continuous integration
(CI) implements continuous processes of applying
quality control - small pieces of effort, applied
frequently.
● Continuous integration aims to improve the quality
of software, and to reduce the time taken to deliver
it, by replacing the traditional practice of applying
quality control after completing all development.
5. History
• Continuous Integration emerged in the Extreme
Programming (XP) community, and XP advocates
Martin Fowler and Kent Beck first wrote about
Continuous Integration circa 1999.
6. Martin Fowler
● Continuous Integration is a software development
practice where members of a team integrate their
work frequently, usually each person integrates at
least daily - leading to multiple integrations per
day.
● Each integration is verified by an automated build
(including test) to detect integration errors as
quickly as possible.
20. CI Benefit
●Project Management
Detect system development problems earlier
Reduce risks of cost, schedule, and budget
●Code Quality
Measurable and visible code quality
Continuous automatic regression unit test
32. Jenkins
1. An open source CI server
2. More then 85000 installations
3. Plug-in extensibility (Over 900 plugins)
4. MIT license
33.
34. Jenkins Features
● Trigger a build
● Get source code from repository
● Automatically build and test
● Generate report & notify
● Deploy
● Distributed Build
35. Jenkins Requirement
● Web Server (Tomcat, WebLogic, …)
● Build tool (Maven, Ant)
● SCM (Git, Svn, Cvs, …)
37. Build Trigger
● Manually click build button
● Build periodically
● Build whenever a SNAPSHOT dependency is built
● Build after other projects are built
● Poll SCM
● IRC, Jabber, …
57. JBoss Wildfly
● Previously named JBoss Application Server
● Named change to better differentiate Community from Supported product
● Support Java EE 7
● Fast, Lightweight, Manageable
● Developer Friendly
● Open Source
DIRE!!!
Scarico il codice sorgente
● Faccio le mie modifiche
● Eseguo i test
● Decido di fare commit
● Peccato che qualcuno ha fatto commit sulle stesse classi
● Cerco di gestire tutti i conflitti
● Non posso! Sono troppi!
● Ri-scarico il codice e ricomincio da capo :-(
POSSO ANCHE NON DIRE!!!
Mantieni un repository del codice sorgente
● Automatizza il build
● Rendi il build auto-testante
● Tutti eseguono una commit alla baseline tutti i giorni
● Ogni commit fa partire una build
● Fai in modo che la build sia veloce
● Esegui i test in un clone dell'ambiente di produzione
● Prendere le ultime versioni dei pacchetti deve essere facile
● Ognuno può vedere quello che sta succedendo
● Automatizza il dispiegamento
Basta usare un software per il controllo della versione
● Scegliere tra lock or merge o sistema distribuito
● Stanno prendendo piede i sistemi di controllo di versione distribuito come Git e Mercurial
● Sono ancora molto usati quelli a lock ottimistico come Subversion e CVS
Per build intendiamo il processo che porta dal codice sorgente all'artefatto che può girare sul server o direttamente sul computer client
● Per buildare basterebbe solo Eclipse, anche se la configurazione in questo caso sarebbe molto complicata da gestire
● Opzione più diffusa è Maven, che permette anche di gestire le dipendenze da librerie open source
● Progetti legacy: Ant
● Altre opzioni possibili sono Gradle, Ivy e Buildr
Abbiamo sia i test unitari che i test di integrazione
● Solitamente i test unitari sono parecchio più veloci dei test di integrazione
● Se si è deciso di usare Maven come sistema di build, basterà mettere i test unitari nella sottocartella /src/test/java
● Per i test di integrazione ci sono varie librerie, tra cui Selenium, SoapUI, Jmeter, Arquillian
È importante per limitare i conflitti e quindi l'inferno dell'integrazione
● Difficile convincere gli sviluppatori a fare commit tutti i giorni
● Ancora più difficile convincerli a testare il codice prima di committarlo
Far partire unicamente i test unitari, postporre i test di integrazione a quando è possibile, comunque almeno una volta al giorno
● Ogni singolo commit potrebbe creare errori o fare fallire i test
● È importante che un eventuale commit che porta nuovi bug venga individuato immediatamente e vi sia posto rimedio
● Questo principio si basa sul principio “fail fast“
Se ogni commit fa partire una build, la build deve essere la più veloce possibile
● Suddividere build in due fasi
● Prima fase: compilazione e test unitari
● Seconda fase: test di integrazione
● La seconda fase gira quando possibile
Anche la più piccola delle differenze tra l'ambiente di test e quello di produzione può rendere estremamente difficile riprodurre un bug
● Stesso sistema operativo
● Stessa base dati
● Stessa JVM
● Stesso application / web server
● Stessi browser
Per le persone è più facile vedere ed eseguire le versioni intermedie del software e dire che cosa è che non va
● Fai in modo che ci sia un posto in cui tutte le persone possano prendere l'eseguibile e testarlo
● Sopratutto le persone che devono far girare delle demo dei prodotti per far vedere a potenziali clienti il funzionamento del software hanno bisogno di sapere dove trovare i pacchetti
Lo stato del progetto deve essere visibile e trasparente a tutte le parti coinvolte
● Questo permette di stabilire scadenze realistiche e allocare tempo per la risoluzione dei problemi attuali
● Inoltre, problemi di usabilità possono essere individuati più velocemente se è possibile vedere e testare facilmente l'applicativo
● È possibile stabilire un rapporto di fiducia con tutte le parti coinvolte nel processo di sviluppo
Per dispiegamento si intende il trasferimento degli artefatti sull'ambiente di destinazione e l'esecuzione di script di allineamento
● Per fare continous integration bisogna avere diversi ambienti che devono essere allineati più volte al giorno
● Per fare questo è buona norma avere dei meccanismi che permettano il rilascio dei risultati delle build sui vari ambienti, compreso quello di produzione
● Dopo il build è possibile trasferire il risultato del build in una cartella di un ambiente e far girare degli script di allineamento
CD is an attitude
L’obiettivo finale della metodologia di sviluppo software è quella di ridurre il tempo che intercorre tra l’attuale rilascio e il feedback dei clienti, da anni a ore…anche perché cambiano i requisiti funzionali continuamente.
In CD, ciascun commit può essere rilasciato al cliente in qualsiasi momento.
Tutto questo richiede un’organizzazione massiva.
Continuous Integration - is an automation to build and test application whenever new commits are pushed into the branch.
Continuous Delivery - is Continuous Integration + Deploy application to production by "clicking on a button" (Release to customers is often, but on demand).
Continuous Deployment - is Continuous Delivery but without human intervention (Release to customers is on-going).
each commit is a potential release
PACKAGE AND DEPLOY: we reuse the same binaries
ACCEPTANCE TESTS: automated tests give us confidence in our build
DEV, QA, PROD: automated, repeatable deployments
WILDFLY CLUSTER… LOAD BALANCING
● Estensibile tramite plugin
Web application che gira in un servlet container
● Permette di lanciare delle build
● Permette di vedere i risultati dei test
● Si integra con gli strumenti di controllo delle versioni e con gli strumenti di automazione dei build
● È in grado di scaricare autonomamente Maven e Ant
● Non ha bisogno di basi dati per funzionare: salva le configurazioni in file XML
Il plugin per il DSL permette la creazione programmatica di progetti. Usando uno script per pushare un job permette di automatizzare e standardizzare l’installazione di Jenkins, al contrario di quanto possibile finora.
Progetto free-style è l’aspetto fondamentale di Jenkins, perché mi permette di buildare il mio progetto, combinarlo con qualsiasi sistema di versionamento del codice, e usarlo eventualmente con altre caratteristiche che non siano build.
Jenkins utilizza Groovy come linguaggio di scripting per scrivere job, che presenta caratteristiche simili a quelle di Python, Ruby, Perl, e Smalltalk.
Groovy usa una sintassi simile a quella di Java, basata su parentesi graffe, viene compilato dinamicamente in bytecode per la Java Virtual Machine, ed interagisce in modo trasparente con altro codice Java e con le librerie esistenti. Il compilatore di Groovy può essere usato per generare bytecode Java standard che può quindi essere usato da qualsiasi progetto Java.
Posso usare anche shell scripting come curl o wget.
Risolvere le dipendenze e il download prima di mandare in running il job.
Un tipico job orientato alla CI, prende in input una stringa con il nome di un tag o di un branch e recupera i sorgenti corrispondenti copiandoli nella cartella del job dentro
il workspace di Jenkins. Esegue poi l’invocazione di maven in quell’ambiente, con le opzioni e i goal predisposti.
Le fasi di un job di tipo Maven sono:
● Lettura dei parametri di input,
● Gestione del codice sorgente,
● Pre-build Steps,
● Maven build,
● Post-build Steps,
● Azioni dopo la build
Per la gestione centralizzata dell'intera fase di costruzione, reporting e documentazione dei vari moduli, Maven, uno strumento di gestione di progetti software basato sul concetto di modello a oggetti di progetto (POM).
COMPILE E UNIT TEST: mvn test
INTEGRATION TEST: mvn verify
DEPLOY TO REPOSITORY: mvn deploy
MINIMIZE BUILD JOBS FOR THE MAIN BUILD: mvn install
escludere integration tests dalla fase di test
run solo integration tests in the integration-test phase
developer always work on a snapshot version
the number of snapshot is pretty arbitrary
We add this Wildfly plugin to our project’s pom.xml under the build >> plugins section and the plugin is pointed at the Wildfly master instance.
To make an application distributable in a cluster, you have to edit its web.xml to have the <distributable> tag for session replication. This allows us to have the master act as domain controller and host and the slave under control of the master. The domain controller then deploys the web project to both master and slave.
definire quale sorgente di SCM Jenkins dovrà prendere in input, Git o SVN come detto in precedenza, e definire il goal con il quale Maven interfacciandosi con il wildfly-maven-plugin permetterà di eseguire il deploy automatico del war su Wildfly.
Per fare questo, bisogna ricordarsi di configurare nel pom.xml l’utente Jenkins, in modo che sia ammesso a comunicare con wildfly.
Per effettuare l’undeploy del war dal server, sarà sufficiente cambiare il Maven Goal, nello specifico mvn wildfly:undeploy.
Essendo Groovy interpretato dalla JVM, posso andare ad inserire ulteriori parametri nel Maven Goal, ad esempio l’hostname, qualora ci fossero problemi nella comunicazione tra Jenkins e Wildfly mediante il wildfly-maven-plugin.
Git is installed in Jenkins as a default plugin. If not installed, it can be installed using option - manage Jenkins -> manage plugin ->
Click ‘available’ tab -> search & select Git plugin -> click ‘download now & install after restart’- submit button. This will install Git in your Jenkins.
A project is created in Jenkins with Git as SCM using option – new item -> update project name as new item name -> select freestyle or maven project -> press ok ->
Select Git in ‘Source Control Management’ section -> update your Git repository URL in repository URL field -> press apply & save button.
github is installed in Jenkins as default plugin
If not installed, it can be installed using option - manage Jenkins -> manage plugin
Click ‘available’ tab -> search & select Github plugin -> click ‘download now & install after restart’- submit button. This will configure Github in your Jenkins.
A project is created in Jenkins with Github as SCM using option – new item -> update project name as new item name -> select freestyle or maven project -> press ok -> update Github project URL under general - Github project – project URL ->
Select Git in ‘Source Control Management’ section -> update your Github repository URL in repository URL field -> press apply & save button.
Maven is not available as default plugin in Jenkins. Maven is installed in Jenkins using option - manage Jenkins -> manage plugin -> Click ‘available’ tab -> search & select Maven integration plugin -> click ‘download now & install after restart’ submit button.
Then, manage Jenkins -> global tool configuration -> under JDK section update JDK version in JDK name -> update jdk location of your server in JDK_HOME -> Under Maven update Maven version in Maven name -> update maven location of your server in Maven_HOME. This will configure Maven in your Jenkins.
A maven & Github project is created in Jenkins using option – new item -> update project name as new item name -> select maven project -> press ok -> update Github project URL in project URL field under general & Github project -> Select Git in ‘Source Control Management’ section -> update your Github repository URL in ‘repository URL’ field -> check ‘resolve dependencies during POM parsing’ under build section -> press apply & save button ->
Create POM xml with required instruction and save the POM xml file in the Github repository.