Você é um desenvolvedor de software?

Muito se discute na comunidade sobre os atributos que um bom profissional que desenvolve software deve ter. Pode parecer balela, mas já sabemos dos vários problemas que o nosso mercado enfrenta, com relação a qualidade dos fornecedores, metodologias de gestão e com relação aos profissionais no nicho do desenvolvimento de software.

Ainda não chegamos em um consenso sobre o que é um software e qual a melhor maneira de se criar um. A discussão sobre o que um profissional de software deve ser também está longe de terminar. Tem muito profissional medíocre fazendo merda um trabalho medíocre.  Tenho uma opinião sobre isso baseada em minha experiência e no que conheço de outros profissionais que considero excepcionais.

Saber codificar

Tudo pode mudar no processo de criação de um software. Só uma coisa não muda: sempre haverá código. Não importa qual seja o processo de gestão ou metodologia, o produto é código.  Um software está longe de ser papelada ou mesmo post its em um quadro branco. Software é código e codificar não é fácil. É difícil pra uma pessoa que não codifica compreender as dificuldades que é programar. No entanto, não basta só programar, é preciso saber programar muito bem. Tem muito programador no mercado que não conhece conceitos básicos e que produz código imprestável.

Dominar a linha de comando

Entender comandos Unix é imprescindível para o desenvolvedor. Não por questões culturais, ou porque somos contra a microsoft ou porque quem usa windows é noob. Não é só por isso Não. Mas sim porque o Unix está muito presente, principalmente em servidores. A linha de comando é muito importante, também, para automação de tarefas do dia a dia. Não dominar a linha de comando o torna dependente e limitado. Nem sempre você terá o sysadmin para resolver os problemas pra você.

Entender a plataforma

Se você não possui conhecimentos sobre o sistema operacional que você utiliza, do servidor, de máquinas virtuais e configurações, você estará limitado sem uma visão macro das tecnologias que você usa. Isso pode lhe trazer problemas de produtividade. Outro perigo é você não saber bulhufas do que ocorre no background porque você só sabe mesmo é codificar e não entende nada de infraestrutura. Se você é desenvolvedor web, entenda pelo menos o básico do protocolo http. Com essas limitações, você nunca irá prestar uma consultoria completa.

Entender de design de interfaces

Conhecer usabilidade, user experience e desing é muito importante. Não que você vire um Leonardo Da Vinci, mas que seja suficiente para que você consiga projetar apps com interfaces agradáveis e fáceis de usar como foco sempre no usuário e não no seu gosto pessoal. É sempre bom saber css e  um pouco de teoria do design, simetria, cores, tipologia, imagens e heurísticas de nielsen.

Saber comunicar-se

A idéia do programador em sua báia já é ultrapassada já há alguns anos. É muito importante saber se comunicar e saber pedir ajuda  e ajudar quando necessário. Todo o problema em projetos de software é relacionado a comunicação.

Vá para as trincheiras. Converse com o cliente

Procure entender a visão do cliente e entender do negócio. Mesmo que haja especialistas no time, é importante o desenvolvedor entender o negócio. Se a pessoa que vai realmente desenvolver o software não entende porque aquele produto será criado, fica complicado. É preciso colaboração com o cliente. E não ter medo de dizer não a ele algumas vezes. Outra coisa importante, você precisa aprender a demitir seu cliente, mas isso já é outra história.

Participar de eventos

Não necessariamente o profissional é ruim porque não vai a eventos. Mas ir aos encontros tem muitas vantagens e oportunidades de melhoria contínua. Além de ser divertido e de conhecer pessoas novas. Organizar eventos também é muito bom. É complicado ficar preso em uma caixa sem que ninguém te conheça. Você teve muita ajuda no decorrer de sua carreira, chega o momento de retribuir.

Aprendizado Contínuo

Sair do trabalho, chegar em casa e dormir ou ir assistir televisão não é um comportamento de um desenvolvedor de software. Ele chega em casa e vai estudar, ou colaborar com algum projeto open source, ou planejar algum empreendimento, ou mesmo criar código pra se divertir. Desenvolvedor de software estuda todo o dia e normalmente dorme tarde. E ainda tem talento pra conciliar isso com a família.

Sair da matrix

Pra não ficar doente é sempre bom fazer outras coisas também. Um cinema, academia, um chopp, ler livros não técnicos. O bom desenvolvedor não é um sociopata.

Status quo

E acima de tudo, os bons profissionais não respeitam o status quo. Estão sempre inovando e procurando as melhores formas de se desenvolver software. Eles não conhecem receitas de bolo. Algumas vezes eles não são humildes. Mas a arrogância tem que ser merecida. ehehehhehe.

Especialistas ainda são necessários sim. Mas a idéia é do especialista que possua visão do todo. Se nós não conseguimos nem mesmo entender como trabalhar direito, como vamos vender isso aos clientes? De burocratas já estamos cheios, precisamos de desenvolvedores.

 

Scrum(to) para gerenciamento de projetos

Aviso: Este post é uma trolagem. Tudo tem exceção. Se você se ofender com as palavras ditas aqui, procure um médico.

Sempre que tenho a oportunidade dou uma cutucada no scrum, dou uma trolada. Desde que conheci esse método ágil, algumas coisas não me agradaram. Reuni aqui alguns argumentos e resolvi postar aqui. Espero não ser linchado quando sair na rua.

Realmente não sei exatamente como o scrum se tornou popular. Mas, quando isso aconteceu, patentiaram, embalaram e começaram a vender. E vendeu, parceiro. Muita gente comprou. Obviamente, as empresas estavam atrás de uma nova metodologia de gerenciamento de projetos, devido ao fracasso dos métodos tradicionais. Algumas, viram que o Scrum ta na moda e disseram: é essa mesma. Mas o que eu vi, e vi de perto algumas vezes, foi o fracasso novamente.

Novamente pelo fato de estar na moda, não sei, profissionais correm atrás da famigerada certificação. Um workshop de dois dias. Hoje tem que fazer uma prova no final. Esses profissionais vão atrás deste título para aumentar curriculo e nada mais. Imagina você ser chamado de SCRUM MASTER. O Mestre. Mas no final das contas, essa certificação não serve pra nada, ah não ser pra encher os bolsos de consultorias, assim como muitas outras que tem aí no mercado. Aprender por conta própria, algumas vezes agrega mais.

Os papéis

Eu não gosto dos papéis que o scrum prescreve. O tal do Scrum Master é um coach, um facilitador, um líder, um mimimimimim. Pra mim é uma figura que se impõe, o bam bam bam da parada.  Algumas vezes, mais atrapalha do que ajuda. Principalmente se for alguém com ego grande. Pra ser um bom Scrum Master, parceiro, é preciso muita maturidade, e isso ta faltando por aí. Ele não deixa lideres emergirem da equipe, não vai deixar, muitas vezes sem querer.

O Mestre

Product Owner. Agora foi na ferida. Esse é complicado. Nós passamos nossas vidas discutindo como melhorar a comunicação e que o analista de requisitos não serve pra nada (trollFace) e vem o Scrum e coloca esse papel pra fazer uma ponte entre o cliente e o time? Fala sério! PO é o analista de requisitos só que sem a documentação. São os mesmos problemas de antigamente. E ainda tem o fato de quando esse cara começa a se achar “o cara” porque sabe tudo do projeto. Ah não perái! Tem o Scrum Master pra dá um jeito nele. Putz!

O Dono do Produto

O Time

Reunião diária é outra coisa que não gosto. Sou obrigado a me reunir todo dia? E se eu não quiser? Me deixa trabalhar pow. Não tenho nada pra falar hoje, comecei a trabalhar ontem. Não sou retardado. Seu eu tiver alguma dificuldade vou gritar. Me esquece Scrum Master. Vai procurar o que fazer já que você não faz nada o dia todo.

Momento trolagem mode off

Agora falando sério. Tem muita coisa boa no Scrum que podemos usar para moldar, quem sabe a nossa própria metodologia. Usar o Scrum  só por usar é um grande erro, principalmente se não se conhece os princípios e valores do manifesto ágil. Não acredito no Scrum sendo um método de gerenciamento de projetos e na verdade ele não é. Eu o vejo como um processo de aprendizado. Um passo para se alcançar algo maior. E não um processo que sempre vai existir na empresa, mas sim algo passageiro. O Scrum Master seria um coach, logo não dá pra ser qualquer um nesse papel. Ele também é volátil, não está ali pra sempre.

A meu ver, Scrum não é para equipes auto-organizáveis. Se uma equipe é auto-organizável, me desculpe, mas ela não precisa que ninguém prescreva métodos de como ela deve agir, seja gerente ou metodologia. Ela já sabe o que tem que ser feito. O Scrum seria um passo para a auto-organização. O Scrum Master sairia de cena, o PO também. Agora sim. Obrigado Scrum e obrigado Scrum Master. Dessa vez você ajudou.

jqGrid com Vraptor

O jqGrid é um plugin do jquery para se criar um datatable rico. Ele roda sobre o jquery ui, uma api de plugins do jquery para rich interfaces. Confesso que levei um tempo pra fazê-lo funcionar bem com o vraptor. Costumava usá-lo bastante com php. Esse é um simples tutorial mostrando como usar o jQgrid com o vraptor no backend. Também se aplica para outros frameworks action-based como o spring mvc ou struts.

Eis o pom do projeto:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.com.studiosecret</groupId>
    <artifactId>demogrid</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>demogrid</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate</artifactId>
            <version>3.5.4-Final</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>br.com.caelum</groupId>
            <artifactId>vraptor</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.18</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.5.1-Final</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

A entidade User:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.studiosecret.demogrid.entidade;

import java.io.Serializable;
import java.util.Calendar;
import javax.persistence.*;

/**
 *
 * @author paulo
 */
@Entity
@Table(name="USER")
public class User implements Serializable {
    @Id
    @GeneratedValue
    private Long id;

    private String nome;

    private String email;

    private String idade;

    @Temporal(javax.persistence.TemporalType.DATE)
    private Calendar nascimento;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getIdade() {
        return idade;
    }

    public void setIdade(String idade) {
        this.idade = idade;
    }

    public Calendar getNascimento() {
        return nascimento;
    }

    public void setNascimento(Calendar nascimento) {
        this.nascimento = nascimento;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

}

O repositório injetando o entity manager através da DI do vraptor:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.studiosecret.demogrid.repositorio;

import br.com.caelum.vraptor.ioc.Component;
import java.util.Collection;
import javax.persistence.EntityManager;
import javax.persistence.Query;

/**
 *
 * @author paulo
 */
@Component
public class UserRepository {

    private EntityManager entityManager;

    public UserRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public Collection getAll() {
        Query query = this.entityManager
                .createQuery("SELECT u.id, u.nome, u.email, u.idade, DATE_FORMAT(u.nascimento, '%d/%m/%Y') FROM User as u");

        return query.getResultList();
    }
}

A classe abaixo foi criada para formatar dados para o jqGrid. Isso porque o plugin tem padrões pré-definidos. Perceba que é uma classe genérica. Isso é para atender a qualquer itpo de objetos e não somente a objetos users.

package br.com.studiosecret.demogrid.helpers;

import java.util.Collection;

/**
 *
 * @author paulo
 */
public class JQgrid<T> {

    private int page;

    private int total;

    private int records;

    private Collection<T> rows;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getRecords() {
        return records;
    }

    public void setRecords(int records) {
        this.records = records;
    }

    public Collection<T> getRows() {
        return rows;
    }

    public void setRows(Collection<T> rows) {
        this.rows = rows;
    }
}

 

A classe controladora:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.studiosecret.demogrid.controller;

import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.studiosecret.demogrid.entidade.User;
import br.com.studiosecret.demogrid.helpers.JQgrid;
import br.com.studiosecret.demogrid.repositorio.UserRepository;
import java.util.Collection;
import static br.com.caelum.vraptor.view.Results.json;

/**
 *
 * @author paulo
 */
@Resource
public class UserController {

    private Result result;
    private UserRepository userRepository;

    public UserController(Result result, UserRepository userRepository){
        this.result = result;
        this.userRepository = userRepository;
    }

    public void grid(){
        result.include("users", userRepository.getAll());
    }

    @Path("/user/load-grid")
    public void loadGrid(Integer rows, Integer page, Integer sord){
        Collection<User> users = userRepository.getAll();

        JQgrid<User> JQgrid = new JQgrid<User>();

        JQgrid.setPage(page);
        JQgrid.setRecords(users.size());
        JQgrid.setTotal((int)Math.ceil((double)users.size() / (double)rows));
        JQgrid.setRows(users);

        result.use(json()).withoutRoot().from(JQgrid).include("rows").serialize();
    }
}

Na linha 36, os argumentos do método loadGrid são parametros da requisição que vem da view e são setados no javascript.Na linha 37 pegamos a coleção de usuários que vem do repositório. Na linha 39 instanciamos a nossa classe do grid. Nas linhas 41 à 43 setamos alguns dados necessários para o grid, como a página atual, o número total de registros da base de dados, o número total de páginas que para a paginação do grid(é feito através da razão entre o total de registros na base de dados e o total de registros que você quer que apareçam no grid), respectivamente. Na linha 44 setamos a coleção.

Na lina 46 é que acontece a mágica. O jqgrid aceita vários formatos de dados como array javascript, xml e json. Eu sempre que posso prefiro trabalhar com json. O vraptor consegue serializar objetos em xml ou json, logo, passamos para ele o nosso objeto JQGrid, que faz somente o papel de estrutura de dados, e o vraptor irá serializá-lo para o formato json.

{"page": 1,"total": 1,"records": 2,
"rows": [
[1,"Paulo Moura","paulociecomp@gmail.com","15","16/02/2012"],
[2,"Fulano de Tal","email@email.com","45","12/03/2012"]
]}

O jsp fica assim:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Demo JQGrid com Vraptor</title>
        <link rel="stylesheet" type="text/css"	href="${pageContext.servletContext.contextPath}/resources/css/themes/primefaces-glass-x/jquery.ui.all.css" />
        <link rel="stylesheet" type="text/css"	href="${pageContext.servletContext.contextPath}/resources/css/ui.jqgrid.css" />
    </head>
    <body>
        <table id="grid-user" ></table>
        <div id="pager-user"></div>
    </body>
    <script type="text/javascript" src="${pageContext.servletContext.contextPath}/resources/js/jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="${pageContext.servletContext.contextPath}/resources/js/jquery-ui-1.8.17.custom.min.js"></script>
    <script type="text/javascript" src="${pageContext.servletContext.contextPath}/resources/js/jqgrid/i18n/grid.locale-pt-br.js"></script>
    <script type="text/javascript" src="${pageContext.servletContext.contextPath}/resources/js/jqgrid/jquery.jqGrid.min.js"></script>
    <script type="text/javascript" src="${pageContext.servletContext.contextPath}/resources/js/user.js"></script>
</html>

Nele referenciamos dois arquivos css, um é o estilo do tema do jquery ui, o outro é o css do jqgrid. No corpo da página precisamos criar uma table e uma div que serão responsáveis por renderizar o grid e a paginação respectivamente. Logo abaixo referenciamos os arquivos javascript do jquery,  do jquery ui e do jqGrid. O arquivo users.js é onde fica nossa implementação do plugin.

$(function(){
    $("#grid-user").jqGrid({
        url : "/demogrid/user/load-grid",
        datatype : "json",
        colNames : [ 'Código', 'Nome', 'E-mail', 'Idade', 'Nascimento' ],
        colModel : [ {
            name : 'id',
            index : 'id',
            width : 80,
            align : 'center'
        },
        {
            name : 'nome',
            index : 'nome',
            width : 200
        },
        {
            name : 'email',
            index : 'email',
            width : 150
        },
        {
            name : 'idade',
            index : 'idade',
            width : 50
        },
        {
            name : 'nascimento',
            index : 'nascimento',
            width : 80
        }
        ],
        rowNum : 10,
        pager : '#pager-user',
        height : 220,
        viewrecords : true,
        sortorder : "desc",
        caption : "Lista de Usuários",
        jsonReader : {
            root: "rows",
            page: "page",
            total: "total",
            records: "records",
            cell: "",
            id: "0"
        }
    });
});

AS linhas 39 à 45 são importantes. Esse atributo jsonReader é opcional. No entanto, se não o setarmos, o plugin irá setar o formato json padrão em que ele é amarrado. Um formato parecido com esse:

{
  "total": "xxx",
  "page": "yyy",
  "records": "zzz",
  "rows" : [
    {"id" :"1", "cell" :["cell11", "cell12", "cell13"]},
    {"id" :"2", "cell":["cell21", "cell22", "cell23"]},
      ...
  ]
}

Para isso, nossa classe jQgrid ficaria um pouco mais complicada e talvez tivéssemos que criar mais classes e aumentar a complexidade da nossa implementação. Ao invés disso, podemos simplesmente setar o atributo jsonReader da maneira que está no exemplo.

Como resultado temos:

jqGrid

O projeto completo encontra-se em github.com/paulociecomp/demogrid.

Conhecendo um pouco sobre o Jenkins

Integrar para Entregar

É costume dos cascateiros seguir um processo linear de desenvolvimento e só no final integrar as funcionalidades. É de se esperar uma série de dores de cabeça com essa presepada. Um trabalho árduo e cansativo cheio de conflitos. Novos problemas podem surgir e podem ser de difícil resolução, além do magnífico retrabalho. É um processo com muitos riscos que leva a atrasos na entrega. No entanto, equipes com bom senso estão eliminando essa prática tão zero à esquerda. Sabe aquela equipe de QA que fica fazendo testes manuais? Você pode demitir e contratar desenvolvedores. :P

Integração Contínua

Integração Contínua é a pedra angular do desenvolvimento de software moderno. É uma mudança radical na maneira como as equipes pensam o processo de desenvolvimento. Ela traz uma série de melhorias no processo incremental, desde automatização até o deploy contínuo em produção.

Integração contínua é uma maneira de monitorar o repositório de controle de versão, para que, sempre que for detectada alguma alteração, a ferramenta compila automaticamente e executa os testes do projeto. Se algo der errado, a equipe é notificada imediatamente. Mas não é só isso. Integração Contínua pode fornecer métricas de qualidade e cobertura do código. Essa métricas são visíveis e podem ajudar os desenvolvedores a manter o padrão de qualidade. É uma excelente ferramenta de comunicação fornecendo um feedback rápido, além de ser um fator importante para agilizar a entrega.

Devemos atentar para a importância da automatização. Ganhamos velocidade no processo de build, execução de testes unitários e de aceitação e no deploy. O processo de deploy pode ocorrer em um ambiente de teste ou homologação, ou até mesmo diretamente em produção. O uso da Integração Contínua para se fazer um deploy em produção e conhecido como Continuos Deployment. É claro que isso depende do cliente. Algumas vezes ele faz questão de homologar e validar a entrega. Ou preferem um ciclo de lançamento mais previsível, até por questões comerciais.

Continuous Delivery é uma variação do Continuous Deployment. Com Continuous Delivery o build passa por todo um fluxo de testes e padrões de qualidade para ser implatado em produção através de um processo totalmente automatizado. Mas, claro que isso tem a ver com agregar valor ao usuário o mais rápido possível e quem decide isso é o negócio.

A Integração Contínua é mais uma mentalidade do que uma ferramenta e a equipe precisa adotar essa mentalidade. É preciso ter confiança e maturidade técnica. Não deve ter intervenção humana no processo. Ele deve ser automático, sem etapas manuais. Mas, além da confiança na equipe, é preciso confiança no seu servidor de Integração.

Jenkins. Hudson é você?

Jenkins é uma ferramenta de Integração Contínua open source escrita em java. É utilizada em projetos de variados tamanhos e em várias linguagens e plataformas como .NET, Ruby, PHP,  Groovy, entre outras.

É uma ferramenta fácil de usar e sua interface é intuitiva. Em alguns minutos você pode ter seu servidor de Integração Contínua em funcionamento. No entanto, Jenkins é bastante robusto e extremamente flexível e extensível. Possui centenas de plugins open source que podem ser instalados automaticamente. Plugins que cobrem ferramentas de controle de versão, de compilação, de testes, métricas de código e etc.

O Jenkins foi desenvolvido por Kohsuke Kawaguchi, inicialmente chamado de Hudson enquanto trabalhava na Sun. O Hudson evoluiu bastante no decorrer dos anos e foi adotado em inúmeros projetos pelo mundo todo. Em 2008, Kawaguchi começou a trabalhar exclusivamente no projeto do Hudson dentro da Sun( definitivamente acho que a Sun era uma boa empresa. É uma pena).   Em 2009, infelizmente, a Oracle comprou a Sun e começaram a surgir conflitos entre os desenvolvedores do Hudson e a Oracle. A equipe Hudson não concordava com o modo da Oracle de gerir o projeto. A Oracle
queria avançar para um processo de desenvolvimento mais estritamente controlado com uma programação de liberação mais lenta.

Em janeiro de 2011, a comunidade de desenvolvedores mudou o nome do projeto para Jenkins. A base do código, originalmente do Hudson, migrou para o github. A grande maioria dos desenvolvedores de plugins seguiram Kohsuke Kawaguchi e levaram junto 70% dos usuários do Hudson. No entanto a Oracle e a Sonatype (empresa por trás do Maven e Nexus) continuam mantendo o projeto do Hudson.

Metendo ficha

Jenkins é uma aplicação web e para executá-lo é preciso instalar a JRE.  Você pode verificar se o ambiente está instalado usando o comando java -version.

java - version

Se não estiver instalado você pode fazer o download diretamente no site da Oracle.

Download JRE

Vamos usar o git como controle de versão. Mas vale ressaltar que o Jenkins possui plugins para diversos outros scm.

Existem várias maneiras de instalar o Jenkins. Você pode até mesmo instalá-lo via apt-get se você usa alguma distribuição derivada do debian. Você pode instalá-lo, também, através do Java Web Start ou simplesmente fazendo download do arquivo war direto do site do Jenkins e inserindo o arquivo no seu web container preferido. Mais informações no site oficial do projeto. Estou executando o jenkins no Tomcat na porta 8080.

 

Jenkins

Depois de instalado, é preciso fazer umas pequenas configurações. Na página inicial iremos clicar em Gerenciar Jenkins.

 

Gerenciar Jenkins

Nesta tela temos opções de configurações globais do Jenkins, assim como instalação e upgrades de plugins, controle de carga, distribuições de servidores, entre outras coisas. Vamos configurá-lo para fazer o build de uma aplicação simples usando java, maven e git. Para isso precisamos dizer ao Jenkins onde está nossa instalação do java e do Maven. É claro que, primeiramente, precisaremos instalar o Maven. Mas o Maven foge do escopo deste tuto, então deixa pra próxima.

Na página de gerência do Jenkins, vamos clicar em “Configurar o sistema”.

Configurações

Vamos dizer a ele onde está instalado o jdk clicando em “Add JDK”.

E agora o maven.

Em “Notificação de E-mail”, precisaremos setar as configurações de smtp e os emails para notificação quando houver quebra de build. Existem também, plugins de sms e de mensagens através do twitter. Isso vai de acordo com o cultura de sua empresa ou projeto.

O Jenkins por padrão vem com o plugin do subversion, mas não queremos isso. Somos sofisticados e usamos git. Precisaremos instalar o plugin do git. Para isso, vamos novamente em “Gerenciar Jenkins” e “Gerenciar Plugins”.

Na aba “Disponíveis” vamos procurar pelo plugin do git (não confundir com o plugin do github).

Agora é só instalar e reiniciar o Jenkins. Pronto, o jenkins agora está preparado para o git. Vamos voltar à tela de configurações do sistema para configurar o scm.

Na mesma tela em que configuramos o jdk e o maven apareceu a opção de configurar o git.

Agora sim podemos criar uma job. Na página inicial do Jenkins vamos clicar em “Novo(a) job”.

Marcamos a opção Construir um projeto maven2/3 e damos ok.

Em Gerenciamento de Código Fonte, selecionamos git.

Inserimos o caminho do repositório. No meu caso, o repositório está na mesma máquina em que o Jenkins está instalado. Caso contrário, será preciso setar configurações de ssh no painel de configuração do Jenkins. No campo Branch Specifier, inserimos o branch que o Jenkins usará para fazer o build.

Em Pre Steps, podemos inserir comandos que serão executados antes do build. No nosso caso, quem é responsável pelo build é o maven, então, selecionamos a opção “Invocar alvo do maven de alto nível” e  inserimos o comando “clean package”.

Post Steps é similar, no entanto, setamos comandos que serão executados após o build. Podemos, por exemplo, executar algum plugin de deploy do maven. Em “Notificações de Construção”, iremos setar os e-mais dos indivíduos que receberão o feedback caso algo dê errado no processo de construção.

Após salvar as configurações, seremos direcionados à página do projeto.

Para realizar o build, Clicamos em “Construir agora”.

 

Pronto! Temos um servidor de integração contínua rodando. Neste caso o maven faz todo o trabalho pesado, cuidando do build e da execução dos testes. Se algo der errado, o maven “avisa” ao Jenkins que notifica a equipe através da melhor forma de feedback escolhido(e-mail, sms, twitter).

Mas ainda não está bom. Temos que clicar sempre que quisermos fazer o build? Não. A idéia é automatizar. Podemos fazer com que o git dispare um comando para executar o Jenkins.

No repositório do projeto existe um diretório chamado hooks. Nele encontramos um arquivo chamado “post-receive.sample”. Vamos renomear para post-receive e inserir o comando shell para executar o Jenkins. Usaremos o curl para executar a url responsável pela execução do projeto my-app no Jenkins.

Agora sempre que enviarmos qualquer alteração para o repositório do projeto, o Jenkins será executado e ocorrerá o buid automatizado do projeto.

Essa foi só uma apresentação rápida do que o Jenkins é capaz. Existe uma infinidade de plugins, inclusive plugins que mostram a foto do Chuck Norris se o build falhar. Realmente vale a pena Integração Contínua com o Jenkins. Ele vai lhe servir muito bem.

Quem quer viver no mundo real

Tradução por Fábio Akita: Who wants to live in The Real World?

O Mundo Real deve ser um lugar verdadeiramente deprimente de se viver. Aparentemente um lugar onde novas idéias, maneiras não-familiares, e conceitos estrangeiros sempre perdem. Me dizem que a única coisa que funciona no Mundo Real é que seus habitantes já sabem e já fazem. Não importa quão ruim ou ineficiente isso possa ser.

Define-se pessoas que vivem lá como vivendo uma Vida Real. Uma existência preenchida com pessimismo, desespero e todo gradiente de preto imaginável. E de forma estranha, essas pessoas vivendo Vidas Reais não parecem interessadas em sair. Eles não estão procurando por uma mudança no cenário do duro Mundo Real.

Em vez disso, eles na realidade estão recrutando! Em argumentos em todos os lugares, eles estão tentando convencer aqueles com comportamento mais ensolarado que eles devem se converter para o Mundo Real ou sofrer. Que resistir ao Mundo Real é fútil. Essa chamada persiste mesmo em face a experiências contrárias. Contos de pessoas que realmente fizeram as coisas de forma diferente e ainda vivem para ver o nascer do sol de manhã.

Por favor, não seja idiota, não existe nada nem remotamente atraente sobre o Mundo Real. É uma miragem miserável que serve somente como um lugar de comunhão para aqueles que perderam toda a esperança.

Page 1 of 6
1
2
3
4
5
...
Last »