Создание детерминированных пакетов

Начиная с .NET 11 пакеты NuGet являются детерминированными (или воспроизводимыми) по умолчанию.

Это означает, что повторная сборка того же пакета должна приводить к созданию идентичного файла .nupkg.

Одним из известных предостережением является время изменения файлов. Пакеты NuGet содержат различные файлы. Метка времени изменения файла на этих файлах основана на метке времени исходных файлов на диске, что может измениться из-за нескольких причин, даже если содержимое файла в противном случае идентично.

Чтобы создать побитово идентичные пакеты NuGet, можно задать свойству DeterministicTimestamp известное или фиксированное значение. Чтобы воспроизвести существующий пакет, можно найти значение DeterministicTimestamp, используемое этой сборкой, и передать его в новую сборку, которую вы хотите сделать.

Общеизвестная переменная SOURCE_DATE_EPOCH среды может быть задана для активации того же поведения, что и параметр DeterministicTimestamp.

Создание детерминированных пакетов

Начиная с версии .NET 11, по умолчанию используется сборка в детерминированном режиме.

  • Использование командной строки:

    dotnet pack
    

Если вы хотите установить время на основе времени последнего коммита Git, можно использовать что-то вроде этого:

export DeterministicTimestamp=$(git log -1 --pretty=%ct)
echo $DeterministicTimestamp
dotnet pack

Это установит переменной среды с именем DeterministicTimestamp значение временной метки коммита Git, которое MSBuild будет использовать автоматически. Воспроизведение пакета — это вопрос повторного выполнения того же набора команд.

Воспроизведение пакета

Если вы хотите воспроизвести пакет, идентичный на битовом уровне, узнайте значение DeterministicTimestamp, использованное в первой сборке, а затем снова используйте его:

dotnet pack -p:DeterministicTimestamp=<value from previous build>

Отключение фиксированных меток времени

Если вы хотите сохранить метки времени изменения исходного файла в пакетах NuGet, можно задать значение DeterministicTimestampfalse.

  • Использование командной строки:

    dotnet pack -p:DeterministicTimestamp=false
    
  • Использование файла .csproj:

    <PropertyGroup>
        <DeterministicTimestamp>false</DeterministicTimestamp>
    </PropertyGroup>