Se você seguir minhas recomendações abaixo (eu faço há anos), você será capaz de:
- coloque cada projeto em qualquer lugar no controle de origem, desde que você preserve a estrutura do diretório raiz do projeto para baixo
- construir cada projeto em qualquer lugar em qualquer máquina, com risco mínimo e preparação mínima
- construir cada projeto completamente autônomo, contanto que você tenha acesso às suas dependências binárias (diretórios "biblioteca" e "saída" locais)
- construir e trabalhar com qualquer combinação de projetos, uma vez que são independentes
- construir e trabalhar com várias cópias / versões de um único projeto, uma vez que são independentes
- evite sobrecarregar seu repositório de controle de origem com arquivos ou bibliotecas gerados
Eu recomendo (aqui está a carne):
Defina cada projeto para produzir um único produto primário, como .DLL, .EXE ou .JAR (padrão com Visual Studio).
Estruture cada projeto como uma árvore de diretórios com uma única raiz.
Crie um script de construção automatizado para cada projeto em seu diretório raiz que o construirá do zero, sem dependências em um IDE (mas não evite que seja construído no IDE, se possível).
Considere projetos nAnt para .NET no Windows ou algo semelhante com base em seu sistema operacional, plataforma de destino, etc.
Faça com que cada script de construção de projeto referencie suas dependências externas (de terceiros) de um único diretório de "biblioteca" local compartilhado, com cada binário TOTALMENTE identificado pela versão: %DirLibraryRoot%\ComponentA-1.2.3.4.dll
, %DirLibraryRoot%\ComponentB-5.6.7.8.dll
.
Faça com que cada script de construção de projeto publique a entrega primária em um único diretório de "saída" compartilhado local: %DirOutputRoot%\ProjectA-9.10.11.12.dll
, %DirOutputRoot%\ProjectB-13.14.15.16.exe
.
Faça com que cada script de construção de projeto referencie suas dependências por meio de caminhos absolutos configuráveis e com versão completa (veja acima) nos diretórios "library" e "output", E NENHUM ONDE MAIS.
NUNCA deixe um projeto referenciar diretamente outro projeto ou qualquer um de seus conteúdos - permita apenas referências aos produtos primários no diretório "output" (veja acima).
Faça com que cada script de construção de projeto referencie suas ferramentas de construção necessárias por meio de um caminho absoluto configurável e com versão completa: %DirToolRoot%\ToolA\1.2.3.4
, %DirToolRoot%\ToolB\5.6.7.8
.
Faça cada projeto script de construção de conteúdo fonte de referência por um caminho absoluto relativo ao diretório raiz do projeto: ${project.base.dir}/src
, ${project.base.dir}/tst
(sintaxe varia de acordo com ferramenta de construção).
SEMPRE exija um script de construção de projeto para fazer referência a CADA arquivo ou diretório por meio de um caminho absoluto e configurável (com raiz em um diretório especificado por uma variável configurável): ${project.base.dir}/some/dirs
ou ${env.Variable}/other/dir
.
NUNCA permita que um script de construção de projeto faça referência a QUALQUER COISA com um caminho relativo como .\some\dirs\here
ou ..\some\more\dirs
, SEMPRE use caminhos absolutos.
NUNCA permita que um script de construção de projeto faça referência a QUALQUER COISA usando um caminho absoluto que não tenha um diretório raiz configurável, como C:\some\dirs\here
ou \\server\share\more\stuff\there
.
Para cada diretório raiz configurável referenciado por um script de construção de projeto, defina uma variável de ambiente que será usada para essas referências.
Tente minimizar o número de variáveis de ambiente que você deve criar para configurar cada máquina.
Em cada máquina, crie um script de shell que define as variáveis de ambiente necessárias, que é específico para ESSA máquina (e possivelmente específico para aquele usuário, se relevante).
NÃO coloque o script de shell de configuração específico da máquina no controle de origem; em vez disso, para cada projeto, envie uma cópia do script no diretório raiz do projeto como um modelo.
REQUIRE cada script de construção de projeto para verificar cada uma de suas variáveis de ambiente e aborte com uma mensagem significativa se não estiverem definidas.
REQUIRE cada script de construção de projeto para verificar cada um de seus executáveis de ferramenta de construção dependentes, arquivos de biblioteca externa e arquivos de entrega de projeto dependentes, e aborte com uma mensagem significativa se esses arquivos não existirem.
RESISTA à tentação de comprometer QUALQUER arquivo gerado no controle de origem - sem entregas do projeto, sem origem gerada, sem documentos gerados, etc.
Se você usar um IDE, gere todos os arquivos de controle de projeto que puder e não os envie para o controle de origem (isso inclui arquivos de projeto do Visual Studio).
Estabeleça um servidor com uma cópia oficial de todas as bibliotecas e ferramentas externas, para ser copiado / instalado nas estações de trabalho do desenvolvedor e nas máquinas de construção. Faça backup dele, junto com seu repositório de controle de origem.
Estabeleça um servidor de integração contínua (máquina de construção) SEM qualquer ferramenta de desenvolvimento.
Considere uma ferramenta para gerenciar suas bibliotecas externas e produtos, como Ivy (usado com Ant).
NÃO use o Maven - ele inicialmente o deixará feliz e, eventualmente, o fará chorar.
Observe que nada disso é específico do Subversion, e a maioria é genérico para projetos direcionados a qualquer sistema operacional, hardware, plataforma, linguagem, etc. Eu usei um pouco de sintaxe específica do sistema operacional e da ferramenta, mas apenas para ilustração- -Eu confio que você traduzirá para o seu sistema operacional ou ferramenta de escolha.
Observação adicional sobre as soluções do Visual Studio: não as coloque no controle de origem! Com essa abordagem, você não precisa deles ou pode gerá-los (assim como os arquivos de projeto do Visual Studio). No entanto, acho melhor deixar os arquivos da solução para desenvolvedores individuais criarem / usarem como acharem adequado (mas não registrados no controle de origem). Eu mantenho um Rob.sln
arquivo em minha estação de trabalho do qual faço referência aos meus projetos atuais. Como meus projetos são independentes, posso adicionar / remover projetos à vontade (isso significa que não há referências de dependência baseadas em projeto).
Por favor, não use recursos externos do Subversion (ou similares em outras ferramentas), eles são um antipadrão e, portanto, desnecessários.
Quando você implementa a integração contínua, ou mesmo quando deseja apenas automatizar o processo de liberação, crie um script para ela. Faça um único script de shell que: pegue os parâmetros do nome do projeto (conforme listado no repositório) e nome da tag, crie um diretório temporário dentro de um diretório raiz configurável, verifique a fonte para o nome do projeto e nome da tag fornecidos (construindo o URL apropriada no caso do Subversion) para aquele diretório temporário, executa uma compilação limpa que executa testes e empacota a entrega. Este script de shell deve funcionar em qualquer projeto e deve ser verificado no controle de origem como parte de seu projeto de "ferramentas de construção". Seu servidor de integração contínua pode usar esse script como sua base para a construção de projetos ou pode até fornecê-lo (mas você ainda pode querer o seu próprio).
@VonC: Você NÃO deseja trabalhar o tempo todo com "ant.jar" ao invés de "ant-abcdjar" depois de ser queimado quando seu script de construção quebra porque você, sem saber, o executou com uma versão incompatível do Ant. Isso é particularmente comum entre Ant 1.6.5 e 1.7.0. Generalizando, você SEMPRE deseja saber qual versão específica de CADA componente está sendo usada, incluindo sua plataforma (Java ABCD) e sua ferramenta de construção (Ant EFGH). Caso contrário, você eventualmente encontrará um bug e seu primeiro GRANDE problema será rastrear quais versões de seus vários componentes estão envolvidas. É simplesmente melhor resolver esse problema antecipadamente.