Семантическое управление версиями dotnet в среде непрерывного развертывания - PullRequest
3 голосов
/ 09 апреля 2019

Я настраиваю семантическое управление версиями с помощью GitLab для своих основных приложений dotnet и пакетов netstandard 2.0.

Прочитав довольно много мнений, некоторые из которых противоречивы, это то, что мне ясно. Семантическая версия должна быть что-то вроде M.m.P.B-abc123 где

  • M является основной версией
  • m является минорной версией
  • P - это версия патча
  • B - версия сборки (необязательно)
  • -abc123 - суффикс (необязательно), если я использую предварительные версии. Должен начинаться с буквы

Таким образом, следующие версии пакета будут действительны:

  • 1.0.0
  • 1.0.1.20190301123
  • 1.0.1.20190301123-beta
  • 1.0.1-rc1

У меня есть следующий скрипт gitlab для управления версиями

#Stages
stages:
  - ci
  - pack

#Global variables
variables:
  GITLAB_RUNNER_DOTNET_CORE: mcr.microsoft.com/dotnet/core/sdk:2.2
  NUGET_REPOSITORY: $NEXUS_NUGET_REPOSITORY
  NUGET_API_KEY: $NEXUS_API_KEY
  NUGET_FOLDER_NAME: nupkgs

#Docker image
image: $GITLAB_RUNNER_DOTNET_CORE

#Jobs
ci:
  stage: ci
  script:
    - dotnet restore --no-cache --force
    - dotnet build --configuration Release
    - dotnet vstest *Tests/bin/Release/**/*Tests.dll

pack-beta-nuget:
  stage: pack
  script:
    - export VERSION_SUFFIX=beta$CI_PIPELINE_ID
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME --version-suffix $VERSION_SUFFIX --include-symbols
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  except:
    - master

pack-nuget:
  stage: pack
  script:
    - dotnet restore
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  only:
    - master

Это создает пакеты, такие как: 1.0.0 для основной ветви (стабильная или готовая к производству) и 1.0.0-beta1234567 для любой другой ветви.

Проблема с моим подходом состоит в том, что у меня есть VS решения с несколькими проектами, каждый проект будет представлять собой пакет nuget, и у каждого будет своя собственная версия. Иногда я изменяю один проект, но не другой, поэтому теоретически мне не нужно создавать новый артефакт проекта, которого я не касался, и, конечно же, новую версию.

Прямо сейчас мой репозиторий nuget предотвращает перезапись пакетов, поэтому, если есть XXX.YYY 1.0.0, и я сгенерирую еще один XXX.YYY 1.0.0 и отправлю его в репозиторий, он выдаст ошибку, и конвейер завершится ошибкой.

Я подумал, что, возможно, неплохо создавать новый пакет каждый раз, когда я запускаю конвейер CI / CD, поэтому я подумал ввести номер сборки и получить что-то вроде XXX.YYY 1.0.0.12345 и, даже если я не буду ' Не трогайте ничего там, в следующий раз будет произведена новая упаковка XXX.YYY 1.0.0.123499.

Это правильный подход в сценарии непрерывного развертывания? или я должен искать способ сделать свой скрипт умнее, а не создавать новый артефакт, если в моем репозитории nuget уже есть такой с такой же версией?

Предполагая, что можно использовать номера сборки всегда, как мне убедиться, что из конвейера извлекается только номер сборки, но номера версий M.m.P остаются в моем csproj, как показано ниже?

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <Description>Whatever</Description>
    <VersionPrefix>1.0.1</VersionPrefix>
  </PropertyGroup>
</Project>

Мне нужно что-то вроде: dotnet pack *.sln --configuration Release -p:PackageVersion=$FIXED_VERSION.$CI_PIPELINE_ID --output nupkg

но я не знаю, как извлечь содержимое <VersionPrefix> из csproj через CLI.

Какой-нибудь совет, хорошее чтение или решение для моего подхода, если он верен?

Спасибо

1 Ответ

1 голос
/ 20 апреля 2019

Проблема с моим подходом заключается в том, что у меня есть VS решения с несколькими проектами, каждый проект будет представлять собой пакет nuget, и у каждого будет своя собственная версия. Иногда я изменяю один проект, но не другой, поэтому теоретически мне не нужно создавать новый артефакт проекта, которого я не касался, и, разумеется, новую версию.

Поскольку конвейер непрерывной интеграции не может определить, должен ли ваш код быть новой вспомогательной или основной версией, вам всегда нужно будет определить, какую семантическую версию должен получить ваш пакет. Это делает весь процесс намного проще.

Ребята из сервисов команды Visual Studio говорят об этом:

Неизменность и уникальные номера версий В NuGet конкретный пакет идентифицируется по его имени и номеру версии. После того, как вы опубликуете пакет с определенной версией, вы никогда не сможете изменить его содержимое. Но когда вы создаете CI-пакет, вы не можете знать, будет ли это версия 1.2.3 или просто шаг по пути к 1.2.3. Вы не хотите записывать номер версии 1.2.3 в пакете, который все еще нуждается в нескольких исправлениях ошибок.

Семер на помощь! В дополнение к Major.Minor.Patch в SemVer предусмотрена предварительная метка. Предварительные метки - это «-», за которыми следуют любые буквы и цифры. Версии 1.0.0-alpha, 1.0.0-beta и 1.0.0-foo12345 являются предварительными версиями 1.0.0. Более того, SemVer указывает, что при сортировке по номеру версии эти предварительные версии соответствуют именно тому, что вы ожидаете: 0.99.999 <1.0.0-alpha <1.0.0 <1.0.1-beta. </p>

В блоге Ксавьера описывается «угон» пререлизного тега для использования в CI. Однако мы не думаем, что это угон. Это именно то, что мы делаем в Visual Studio Team Services для создания наших пакетов CI. Мы преодолеем парадокс, выбрав номер версии, а затем выпуская пререлизы этой версии. Имеет ли значение, что мы оставляем предварительный тег в номере версии? Для большинства случаев использования не совсем. Если вы прикрепляете к определенному номеру версии зависимого пакета, это не повлияет, и если вы используете плавающие диапазоны версий с project.json, это будет означать небольшое изменение указанного вами диапазона версий. Источник: https://devblogs.microsoft.com/devops/versioning-nuget-packages-cd-1/

Как указывалось вначале, вам все равно нужно самостоятельно выбрать версию для нового пакета. Для процесса, предшествующего фактической публикации окончательного пакета (основной ветки в вашем случае), вы можете использовать тег предварительной версии, чтобы включить номер сборки в качестве тега предварительной версии.

Не делая ничего умного, он будет публиковать новый пакет для каждого запускаемого конвейера. Сотрудники службы визуальной студии, и я не думаю, что это плохо, но это будет по вкусу каждого

...