Eu sou Elton Minetto, desenvolvedor, professor e empresário

Melhores de 2013 - Back End

- - publicado em carreira | Comments

O portal iMasters lançou há algumas semanas o Melhores de 2013 uma lista com diversas categorias onde os profissionais podiam indicar e votar em outros desenvolvedores.

E eu tive a felicidade de ficar em segundo lugar na categoria “back end”. Só por estar nessa lista, junto com diversos profissionais que eu admiro me deixa muito orgulhoso.

Obrigado a quem votou em mim e parabéns a todos os profissionais da lista. E parabéns para o iMasters pela iniciativa.

A paciência ou a demência

- - publicado em ceo | Comments

Uma das coisas mais difíceis que aprendi nesses três anos de Coderockr foi que as coisas não dependem só de você.

Quando você é um programador e precisa desenvolver uma nova funcionalidade, ou corrigir um bug, quase tudo o que você faz impacta diretamente e rapidamente no resultado final da tarefa. Talvez você precise de ajuda de um colega no backend, ou no frontend, ou no banco de dados, ou no servidor, mas a complexidade destas interações é relativamente baixa.

Quando falamos em uma empresa tudo fica mais complexo. Agora as suas decisões envolvem clientes, fornecedores, colaboradores, governos, contador, bancos, advogados, etc. É muito frustrante para nós desenvolvedores, que estamos acostumados a termos mudanças rápidas de status nas nossas tarefas (Doing, Review, Done) termos que esperar por decisões simples que podem demorar muito tempo para serem feitas. E as vezes pressionar por uma decisão ou resposta pode tornar tudo pior.

Outro fator angustiante é a complexidade das coisas. Você quer que a sua empresa cresça e tenha mais rendimentos, mas para isso você precisa contratar mais pessoas, aumentando o custo e o risco. Precisa de mais pessoas para colocar mais projetos em desenvolvimento, mas precisa de mais dinheiro para manter os novos custos. É o típico caso do ovo e da galinha, o que deve vir primeiro?

São situações que tiram o sono, nos deixam malucos. Eu venho tentando exercitar algo que nunca foi meu forte: a paciência. Tentar separar os problemas da empresa da vida pessoal, para não ficar completamente maluco. E você? Essas situações também acontecem com você?

Novo desafio: CEO

- - publicado em ceo | Comments

Já devo ter escrito isso em algum post aqui no meu site, mas tem uma frase que ouvi de uma professora há alguns anos e que relembro de tempos em tempos: “na sua carreira, sempre que você tiver um desafio que realmente te assuste você precisa fazê-lo. Na pior das hipóteses você vai aprender muito e na melhor situação você vai crescer ainda mais”.

Pensei nisso no final de 2013, quando em uma reunião com meus sócios da Coderockr decidimos dividir melhor as responsabilidades, pois estávamos nos revezando entre diversas tarefas: programando, gerenciando projetos, gerenciando a equipe, prospectando novos clientes, fazendo orçamentos, etc. Essa dinâmica funciona bem por algum tempo, mas para a empresa crescer é necessário uma melhor divisão das tarefas. Então desde Janeiro de 2014 eu assumi um papel mais gerencial e me afastei bastante das tarefas de programação. Hoje sou responsável pela prospeção de novos negócios, orçamentos e tratamento direto com clientes e parceiros. Também gerencio o andamento dos projetos, mas a um nível menos técnico, deixando essa tarefa para os meus sócios.

E esse foi o desafio que me assustou. Por mais de 15 anos eu trabalhei com aspectos técnicos, praticamente todos os dias e a ideia de não fazer isso me deixou apreensivo. Mas novamente a minha professora acertou no conselho e eu realmente estou aprendendo muito. Eu estou me divertindo muito com as novas responsabilidades de CEO (siglas moderninhas…) e me sentindo muito motivado a melhorar a cada dia. Mas como velhos costumes são difíceis de se largar eu continuo programando nas horas vagas, para manter a mente afiada :)

Pretendo escrever alguns posts sobre minhas novas descobertas aqui no site, sempre com uma pitada de programação ou comparações nerds entre as ideias de negócios e gerenciamento. Se você passou ou passa pela mesma experiência, de migrar da área de desenvolvimento para a de negócios por favor compartilhe suas aventuras aqui nos comentários.

Startup Weekend Florianópolis

- - publicado em eventos | Comments

E 2014 já começa em grande estilo!

Fui convidado a ser um dos mentores do evento Startup Weekend Florianópolis que irá acontecer entre os dias 21 e 23 de Março.

(não podia perder a piada)

É uma grande oportunidade para acelerar uma ideia de negócio que você tenha ou mesmo para fazer um ótimo networking.

As inscrições estão abertas, então aproveite essa ótima chance!

Gerenciando projetos com Github e ZenHub

- - publicado em projetos | Comments

Eu sempre gostei da “abordagem Unix”: pequenas ferramentas que fazem apenas uma coisa bem feita mas que podem ser usadas em conjunto com outras para criarmos um ambiente poderoso.

Venho usando essa abordagem para quase tudo, incluindo o gerenciamento de projetos na Coderockr. Usamos algumas ideias de Scrum e Kanban incluindo sprints, pontos de complexidade, quadro de tarefas, burndown chart, reuniões diárias, etc. Atualmente usamos uma série de aplicativos diferentes para cada uma das fases:

  • Trello para gerenciar o quadro de tarefas e sprints. Usamos uma extensão do Firefox/Chrome chamada Scrum for Trello para contabilizar os pontos de complexidade:

  • Github para armazenar os códigos
  • Google Docs para criar o burndown chart:

Tudo funciona bem mas percebi que alguns membros da equipe estavam criando issues do Github para cada tarefa criada no Trello porque assim eles conseguem vincular facilmente os commits de código com a tarefa, o que faz muito sentido. Observando isso cheguei a hipótese que o Trello não é necessário para gerenciarmos os nossos projetos de software e que podemos usar apenas o Github para este fim. Continuamos usando o Trello para gerenciarmos outros projetos que não são especificamente de software, como marketing ou mesmo as tarefas diárias da empresa (compras, idas ao banco, etc).

Para isso criei a seguinte lógica:

  • cada sprint do projeto torna-se um milestone no Github;
  • cada tarefa do backlog torna-se uma issue no Github;
  • cada ponto de complexidade (usando a escala de fibonacci) torna-se um label que é aplicado a cada issue;

O primeiro passo foi criar as labels equivalentes aos pontos de complexidade:

Podemos manter as outras labels e usá-las junto com estas novas.

Agora é preciso criar os milestones que irão representar os sprints do projeto:

Cada milestone pode ter uma data de vencimento, o que condiz bastante com o comportamento dos sprints, que geralmente são períodos de uma ou duas semanas. Nesta tela também é possível visualizarmos o andamento de cada sprint, pois o Github nos mostra o percentual de trabalho já realizado (issues fechadas).

Podemos agora criar as nossas issues, anexar as devidas labels representando os pontos de complexidade e alocá-las para cada sprint.

Uma característica interessante do Trello é a facilidade de acompanharmos o andamento das tarefas de uma forma bem visual, mostrando-as em um quadro com divisões para cada fase. Podemos suprir essa característica usando o ZenHub. Trata-se de um complemento para o Chrome (com uma versão para Firefox já prometida) que adiciona mais funcionalidades ao Github, entre elas um quadro bem parecido com o fornecido pelo Trello.

Após instalar o complemento, acessar a página do repositório pela primeira vez e clicar na opção “Board” o ZenHub mostra uma tela sugerindo uma organização de quadros, ou permitindo que você crie a sua própria:

Eu criei a seguinte organização para nossos projetos:

Com isso podemos facilmente mover as issues entre as fases e acompanhar o andamento do projeto.

Outra vantagem em usarmos o Github para gerenciar os projetos é que podemos usar a sua API para criarmos relatórios, inclusive um burndown chart. Criei um pequeno script para testes, usando a php-github-api:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
require_once 'vendor/autoload.php';

if ($argc < 2) {
    echo "Usage: php index.php ProjectName\n";
    exit;
}
$projectName = $argv[1];

$client = new \Github\Client(
    new \Github\HttpClient\CachedHttpClient(array('cache_dir' => '/tmp/github-api-cache'))
);

$client->authenticate('username', 'password', \Github\Client::AUTH_HTTP_PASSWORD);

//get sprints
$sprints = array();
$milestones = $client->api('issue')->milestones()->all('coderockr', $projectName, array('direction' => 'asc'));
foreach ($milestones as $m) {
    $sprints[$m['id']] = array(
        'name' => $m['title'],
        'open_issues' => $m['open_issues'],
        'closed_issues' => $m['closed_issues'],
        'state' => $m['state'],
        'due_on' => $m['due_on'],
        'open_points' => 0,
        'closed_points' => 0,
    );
}
//get issues
$issues = array_merge(
    $client->api('issue')->all('coderockr', $projectName, array('state' => 'open')),
    $client->api('issue')->all('coderockr', $projectName, array('state' => 'closed'))
);
//update sprint points
foreach ($issues as $i) {
    $milestone = $i['milestone'];
    switch ($i['state']) {
        case 'open':
            $open_points = $sprints[$milestone['id']]['open_points'];
            foreach ($i['labels'] as $l) {
                $open_points += (float) $l['name'];
            }
            $sprints[$milestone['id']]['open_points'] = $open_points;
            break;
        case 'closed':
            $closed_points = $sprints[$milestone['id']]['closed_points'];
            foreach ($i['labels'] as $l) {
                $closed_points += (float) $l['name'];
            }
            $sprints[$milestone['id']]['closed_points'] = $closed_points;
            break;
    }

}
//show sprint's details
$total_open_points = 0;
$total_closed_points = 0;
foreach ($sprints as $s) {
    $sprint_points = $s['open_points'] + $s['closed_points'];
    $sprint_issues = $s['open_issues'] + $s['closed_issues'];
    echo "{$s['name']} due on {$s['due_on']} has {$s['closed_issues']} closed of {$sprint_issues} issues and {$s['closed_points']} closed of {$sprint_points} points\n";
    $total_open_points += $s['open_points'];
    $total_closed_points += $s['closed_points'];
}
//show project's details
$project_points = $total_open_points + $total_closed_points;
echo "Project have {$total_closed_points} closed of {$project_points} points \n";

Executando na linha de comando:

eminetto@MacBook-Pro-de-Elton ~/Documents/Projects/GitHubPM: php index.php ProjectTemplate
Sprint 1 due on 2014-01-09T08:00:00Z has 1 closed of 3 issues and 2 closed of 28 points
Sprint 2 due on 2014-01-16T08:00:00Z has 1 closed of 2 issues and 3 closed of 11 points
Sprint 3 due on 2014-01-23T08:00:00Z has 0 closed of 2 issues and 0 closed of 3.5 points
Sprint 4 due on 2014-01-30T08:00:00Z has 0 closed of 1 issues and 0 closed of 3 points
Project have 5 closed of 45.5 points
eminetto@MacBook-Pro-de-Elton ~/Documents/Projects/GitHubPM:

É somente um exemplo mas brincando um pouco com a API do Github é possível fazermos controles bem avançados, gráficos, aplicativos móveis, etc.

Ainda vamos testar essa abordagem em alguns projetos e algumas coisas podem mudar, assim como o ZenHub e o próprio Github podem criar novas funcionalidades num futuro próximo, então esse post deve receber atualizações. Se você tiver sugestões ou experiências parecidas por favor compartilhe nos comentários.

Deploy estilo Heroku usando Git

- - publicado em devops | Comments

Venho estudando bastante sobre DevOps recentemente, inclusive vou apresentar uma das keynotes do PHP Conference Brasil 2013 no final de Novembro.

E um dos pontos importantes de todo o processo de desenvolvimento é o deploy. Na Coderockr estamos usando o seguinte ambiente:

  • Vagrant para facilitar a configuração das máquinas dos desenvolvedores
  • Github para armazenar os repositórios de códigos
  • Amazon AWS (e começamos a usar Azure recentemente) para os servidores

A ideia da cultura DevOps e suas ferramentas é diminuir a barreira entre o desenvolvimento e o deploy, deixando a vida mais fácil tanto para desenvolvedores quanto gerentes de rede/servidores/operações.

Então pensamos em uma forma de unificar este nosso ambiente e tornar o deploy das aplicações mais rápido. Com o plugin vagrant-aws basta um simples comando (vagrant up –provider=aws) para que uma máquina seja criada na Amazon, com o ambiente configurado, exatamente igual ao ambiente que usamos para desenvolver a aplicação.

O próximo passo é facilitar o deploy das novas versões e correções do software. Sempre achei muito interessante a abordagem que o Heroku (e outras plataformas de PaaS) vem usando, de permitir o deploy apenas com um git push. Então fiz algumas pesquisas para tentar emular este funcionamento na nossa arquitetura.

O primeiro requisito é que você possa fazer login via ssh no seu servidor, preferencialmente sem senha usando chaves privadas. Neste post você pode ver como configurar isto no seu servidor.

O próximo passo é conectar no servidor e configurar o repositório remoto e o diretório do seu aplicativo. Neste exemplo estou usando um Ubuntu Server com uma aplicação PHP, mas isto deve funcionar para qualquer ambiente/linguagem de programação.

ssh ubuntu@ip_do_servidor
mkdir -p repositorios/minha_app
cd repositorios/minha_app
git init --bare

Este diretório vai conter apenas a estrutura que o git vai usar para receber os arquivos da aplicação. Vamos criar um diretório para a aplicação, neste caso no /var/www onde o servidor Apache está configurado para procurar a nossa aplicação PHP. Também vamos dar permissão de escrita neste diretório para o usuário ubuntu:

sudo mkdir /var/www/minha_app
sudo chown -R ubuntu:ubuntu /var/www/minha_app

Vamos agora configurar o gatilho (ou gancho se você for traduzir a palavra hook literalmente) que o git vai executar após receber o push. Para isso vamos criar o arquivo

repositorios/minha_app/hooks/post-receive

E neste arquivo podemos colocar qualquer script que precise ser executado após o deploy. As primeiras linhas do script devem ter algo como:

#!/bin/bash
export GIT_WORK_TREE=/var/www/minha_app
git checkout -f

A primeira linha indica que é um shell script bash. A segunda é importante pois indica ao git que todos os comandos a serem executados devem ser feitos neste caminho. A terceira linha é opcional pois neste exemplo ela vai descartar qualquer alteração que tenha sido feita nos arquivos deste diretório e usar os novos arquivos sendo enviados via push (cuidado com esta linha, pois se o seu aplicativo criou algum arquivo neste diretório ele será descartado).

Abaixo um exemplo de script de uma aplicação que desenvolvemos na Coderockr, usando Silex e Doctrine:

#!/bin/bash
export GIT_WORK_TREE=/var/www/minha_app
git checkout -f
cd /var/www/minha_app
php composer.phar install
./vendor/bin/doctrine orm:schema-tool:update --force
sudo service apache2 reload

O script atualiza os pacotes usando o Composer e faz a atualização das entidade do Doctrine, além de fazer um reload no Apache.

Não esqueça de dar permissão de execução para o script executando o comando:

chmod +x repositorios/minha_app/hooks/post-receive

O último passo é adicionar o repositório na sua aplicação (na sua máquina de desenvolvimento):

git remote add production ssh://ubuntu@ip_do_servidor/home/ubuntu/repositorios/minha_app

Depois basta fazer push para este novo repositório remoto e a mágica é executada:

git push production master

Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 431 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: Loading composer repositories with package information
remote: Installing dependencies (including require-dev) from lock file
remote:   - Installing symfony/event-dispatcher (2.3.x-dev 2d8ece3)
remote:     Cloning 2d8ece3c610726a73d0c95c885134efea182610e
remote:
remote:   - Installing guzzle/guzzle (dev-master 4363c95)
remote:     Cloning 4363c95b584dcafc8ff386c27116283ad53d738d
remote:
remote:   - Installing aws/aws-sdk-php (dev-master 80ec29d)
remote:     Cloning 80ec29d00a23471553005e6948609304aeb4e899
remote:
remote:   - Installing symfony/routing (2.3.x-dev 7d41463)
remote:     Cloning 7d41463094752e87a0fae60316d236abecb8a034
.....
remote:  * Reloading web server apache2
remote:  *

Este é só um exemplo das facilidades que algumas ferramentas podem fornecer ao nosso dia a dia de desenvolvedores. Se estiver em São Paulo no final de Novembro e puder participar do PHP Conference Brasil 2013 eu vou estar por lá para trocarmos ideias sobre PHP e sobre DevOps ;)

Frameworks PHP e analogias

- - | Comments

Venho palestrando sobre Frameworks PHP desde a primeira PHP Conference Brasil, em 2006. Todos os anos eu renovo a palestra porque continuo recebendo convites para palestrar sobre o assunto, que eu gosto bastante.

Na versão 2013 da palestra eu coloquei alguns novos frameworks, removi alguns e mudei um pouco a abordagem, colocando slides com pouco texto. Por isso resolvi fazer este post, para explicar alguns slides e principalmente a analogia que usei para a apresentação.

Lean publish do Doctrine na prática

- - | Comments

Como eu comentei em outro post quando eu escrevi o Zend Framework 2 na prática eu usei uma ferramenta muito interessante chamada Leanpub que me ajudou bastante na construção do e-book.

Recentemente comecei a escrever um novo e-book, o “Doctrine na prática” sobre o mais famoso e importante ORM para PHP e novamente estou usando o ótimo Leanpub. Mas desta vez quero usar todo o conceito de “lean” da ferramenta o que significa que as pessoas podem comprar o livro mesmo ele não estando 100% pronto.

No momento a versão PDF já conta com 82 páginas, o que eu considero algo próximo de 75% do resultado final. Nesta primeira versão eu estou escrevendo toda a parte de códigos e deixando o texto e explicações para a revisão final. Se você tiver interesse, ou curiosidade, de acompanhar o andamento do texto você pode comprá-lo agora e ir recebendo as atualizações até a versão final.

A ferramenta só permite a compra por cartão de créditos e PayPal, mas na versão final eu vou disponibilizar em um algum site que permita uso do Pagseguro (boletos!) e no site da Amazon, bem como uma versão impressa no Clube de Autores, como o Zend Framework 2 na prática. Durante essa fase de “beta” o livro vai ser um pouco mais barato do que a versão final, que deve ficar em torno de R$35 a R$40.

Quando a versão final estiver pronta eu faço outro post contando como foi a experiência com o “lean publish” deste livro, caso algum outro autor também queira fazer o mesmo.