Gerenciamento Centralizado de Versões de Pacotes NuGet com Directory.Build.props

No desenvolvimento de soluções .NET complexas, manter a consistência das versões dos pacotes NuGet entre múltiplos projetos pode ser desafiador. O arquivo Directory.Build.props oferece uma solução eficiente para definir variáveis globais de versão.

Este arquivo especial, localizado na raiz da solução ou em um diretório pai compartilhado, é automaticamente importado pelo MSBuild em todos os projetos. Para ambientes multi-produto, é recomendável colocar um arquivo Directory.Build.props no diretório raiz de cada produto para isolar suas dependências.

Uma boa prática é utilizar grupos de propriedades (PropertyGroup) para organizar as variáveis. A convenção de nomenclatura para as versões pode substituir pontos por sublinhados e adicionar um sufixo, como _Versao.

Exemplo de um arquivo Directory.Build.props básico:

<Project>
    <PropertyGroup>
        <LangVersion>latest</LangVersion>
        <NoWarn>$(NoWarn);NU1603;CS8618</NoWarn>
        <InformacaoProduto>Minha Aplicacao Corporativa</InformacaoProduto>
    </PropertyGroup>

    <PropertyGroup Label="VersoesExternas">
        <VersaoFrameworkAbp>8.1.0</VersaoFrameworkAbp>
        <Versao_BibliotecaX>4.5.*-*</Versao_BibliotecaX>
        <Versao_PacoteIdentityModel>6.2.0</Versao_PacoteIdentityModel>
    </PropertyGroup>

    <PropertyGroup Label="VersoesAspNetCore">
        <Versao_AspNetCore>7.0.10</Versao_AspNetCore>
        <Versao_AspNetCore_Rewriter>2.3.0</Versao_AspNetCore_Rewriter>
    </PropertyGroup>
</Project>

Para consumir essas variáveis em um projeto filho, utiliza-se a sintaxe de variáveis do MSBuild $(NomeDaVariavel) no atributo Version do pacote.

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Volo.Abp.Core" Version="$(VersaoFrameworkAbp)" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="$(Versao_AspNetCore)" />
        <PackageReference Include="Meu.Pacote.Interno.Core" Version="$(Versao_MeuPacote_Core)" />
    </ItemGroup>
</Project>

Em arquiteturas modulares, como as construídas com o framework ABP, é vantajoso isolar as versões de cada módulo em arquivos separados dentro de uma pasta, por exemplo, configuracoes-versoes.

<!-- Arquivo: configuracoes-versoes/VersoesModuloFinanceiro.props -->
<Project>
    <PropertyGroup>
        <Versao_ModuloFinanceiro>2024.1.250</Versao_ModuloFinanceiro>
    </PropertyGroup>
</Project>

O arquivo principal importa então todos esses módulos:

<!-- Directory.Build.props na raiz do produto -->
<Project>
    <Import Project="configuracoes-versoes/VersoesModuloFinanceiro.props" />
    <Import Project="configuracoes-versoes/VersoesModuloIdentidade.props" />
    <PropertyGroup>
        <VersaoFrameworkAbp>8.1.0</VersaoFrameworkAbp>
        <!-- Outras configurações comuns -->
    </PropertyGroup>
</Project>

Para automatizar a atualiazção dessas versões, pipelines de CI/CD, como o GitLab CI, podem ser configurados. Após etapas de compilação e teste, um job dedicado pode autalizar os arquivos de versão via SSH.

  atualizar_versoes_modulo:
    stage: deploy
    script:
      - ssh usuario@servidor "sed -i 's/<Versao_ModuloFinanceiro>.*<\/Versao_ModuloFinanceiro>/<Versao_ModuloFinanceiro>$NOVA_VERSAO<\/Versao_ModuloFinanceiro>/g' /caminho/para/configuracoes-versoes/VersoesModuloFinanceiro.props"

As equipes de desenvolvimento podem sincronizar suas versões locais usando um script simples que baixa os arquivos de um servidor de artefatos. Um exemplo de script em lote para Windows (sincronizar-versoes.bat):

@echo off
set "URL_BASE=https://artefatos.empresa.com/versoes/"
set "PASTA_DESTINO=%~dp0configuracoes-versoes"
mkdir "%PASTA_DESTINO%" 2>nul

for %%f in (VersoesModuloFinanceiro.props VersoesModuloIdentidade.props Directory.Build.props) do (
    curl -o "%PASTA_DESTINO%\%%f" "%URL_BASE%%%f"
)
echo Versoes sincronizadas.

Em ambientes de contêiner, o Dockerfile pode incluir a etapa de cópia dos arquivos de configuração de versão antes do restore e build:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

# Copiar arquivos de definição de versões
COPY ["Directory.Build.props", "."]
COPY ["configuracoes-versoes/", "configuracoes-versoes/"]

COPY ["Meu.Projeto.csproj", "."]
RUN dotnet restore "Meu.Projeto.csproj"
COPY . .
RUN dotnet publish "Meu.Projeto.csproj" -c Release -o /app/publish

Esta abordagem garante que todas as compilações, sejam locais, em CI ou em contêineres, utilizem exatamente as mesmas versões de pacotes, proporcionando reprodutibilidade e controle total sobre as dependências.

Tags: Directory.Build.props NuGet MSBuild ASP.NET Core Gerenciamento de Dependências

Publicado em 6-10 02:33 por Thomas