Skip to content

Выбирать TargetFramework для восточных библиотек по выбранной конфигурации цемента#27

Merged
kungasc merged 3 commits intovostok:masterfrom
east1k:target-framework-from-cement-configuration
Oct 13, 2022
Merged

Выбирать TargetFramework для восточных библиотек по выбранной конфигурации цемента#27
kungasc merged 3 commits intovostok:masterfrom
east1k:target-framework-from-cement-configuration

Conversation

@east1k
Copy link
Copy Markdown
Contributor

@east1k east1k commented Oct 13, 2022

Проблема

Сейчас через модуль vostok.devtools для всех восточных библиотек устанавливается свойство TargetFramework для сборки.
Это упрощает команде базовой инфраструктуры предоставлять разные TargetFramework для пользователей.
Сейчас пользователи могут выбрать под какие TargetFramework собирать, выбрав определенную ветку этого репозитория:

  • master - netstandard2.0
  • only-net6.0 - net6.0
  • with-net6.0 - netstandard2.0;net6.0

Но у этого есть недостатки:

  1. если у пользователя какие-то его цементные зависимости захотят этот репозиторий в разных явных ветках, получится конфликт и сломается сборка, потому как цемент не сможет решить какую в итоге ветку переключиться.
    Сейчас это незаметно из-за того, что в основном все пользуются неявной веткой master и явной with-net6.0, и такое цемент может разрулить.
    Но если появятся использования only-net6.0 или появятся новые ветки (например с net7.0), то проблема выстрелит во всей красе, особенно сейчас многие начинают завязываться на with-net6.0 ради некоторых фич, которые там доступны.
  2. при сборке разных конечных проектов в одной цементной папке, которые резолвятся в разные ветки этого репозитория (например, старый проект резолвит vostok.devtools, а новый проект vostok.devtools@with-net6.0), будет сбрасываться кеш цемента (ведь ветка поменялась) и пересобираться вся цементная папка (так как будут пересобираться все восточные модули, а от них зависит практически все).
    Это уже сейчас больно как локально у пользователя, так и на агентах CI.
  3. команде инфраструктуры надо поддерживать все эти ветки в актуальном состоянии и не забывать подливать в них изменения, так как этот модуль используется не только для определения TargetFramework

Концепт

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

Собственно я хочу сделать выбор TargetFramework на основе выбранной конфигурации цементного модуля.
Будут следующие конфигурации:

  • netstandard2.0 - netstandard2.0 (по-умолчанию)
  • only-net6.0 - net6.0
  • with-net6.0 - netstandard2.0;net6.0 (включает конфигурации netstandard2.0 и only-net6.0)
  • full-build - netstandard2.0;net6.0 (включает конфигурацию with-net6.0)

И теперь:

  1. если при сборке конечного модуля разные зависимости попросят разные конфигурации, то будет собрана общая конфигурация (например, netstandard2.0 и only-net6.0 => with-net6.0)
  2. теперь сборка одного конечного модуля может переиспользовать сборку зависимостей другого конечного модуля, если раньше была собрана более широкая конфигурация
  3. можно отказаться от нескольких актуальных веток в пользу мастера

Но есть минус:
Если при сборке одного конечного модуля, которому нужна небольная конфигурацию (например netstandard2.0), другой модуль уже собирал в этой цементной папке часть восточных зависимостей с большей конфигурацией (with-net6.0), то все остальные еще не собранные восточные зависимости будут собраны под большую конфигурацию, хотя хватило бы меньшей, что влияет на время сборки.
Но мне кажется это лучше, чем пересобирать цементную папку каждый раз.
Тем более есть вероятность собирать какой-то третий модуль, которому нужны были бы зависимости второго модуля в большей конфигурации, и тут он их уже получит бесплатно.

Также в решение будет учтено:

  • обратная совместимость - не сломается старый механизм с ветками
  • обратная совместимость - если каким-то образом будет пропущена сборка модуля, то без сборки будет подставлена старая дефолтная конфигурация
  • обратная совместимость - кроссплатформенность

Обсуждение

https://kontur.slack.com/archives/C08DRHZTP/p1665407872789439

Решение

Вытащим из Main-Project.props установку TargetFramework, вместо этого в Main-Project.props будет импортить Main-TargetFramework.props, в котором будет задаваться это свойство.
Изначально файла Main-TargetFramework.props нет, он будет появляется в результате цементной сборки.
Цементная сборка будет состоять просто из копирования одного из заготовленных файлов в Main-TargetFramework.props:

  • Main-TargetFramework-netstandard2.0.props
  • Main-TargetFramework-only-net6.0.props
  • Main-TargetFramework-with-net6.0.props
    Чтобы было кросплатформенно, решил копировать через утилиту dotnet, а не скриптом, для этого пришлось завести Resolve-Main-TargetFramework.csproj, в котором указана логика копирования.
    Чтобы, на всякий случай для обратной совместимости, работало без сборки, указал импорт Main-TargetFramework-netstandard2.0.props, если Main-TargetFramework.props не существует.

Проблема:
При влитии в другие актуальные ветки (only-net6.0, with-net6.0) будет конфликт, который надо порешать и указать другой дефолтный файл.
Если не торопиться со влитием в эти ветку, будет проблема того, что при переключении с мастера на эти ветку будет ругаться на незакоммиченный файл Main-TargetFramework.props (так как игнор его также лежит в .gitignore мастера).
Но МР-ки с решением этих конфликтов можно подготовить заранее.

Comment thread library-common-props/Main-TargetFramework-with-net6.0.props
Comment thread library-common-props/Main-Project.props Outdated
Comment thread library-common-props/Resolve-Main-TargetFramework.csproj Outdated
Comment thread module.yaml
build:
- tool: dotnet
parameters: build
target: library-common-props/Resolve-Main-TargetFramework.csproj -p:PropsFile=Main-TargetFramework-netstandard2.0.props
Copy link
Copy Markdown
Member

@kungasc kungasc Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а зачем тут вообще что-то билдить?

нельзя ли только в остальных конфигах это делать?

тогда текущее поведение останется без изменений

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я подумал, что будет неявно, а тут сразу понятно какая конфигурация что делает.
И условный импорт я добавил не как основной способ задания, а больше как fallback для обратной совместимости, и на деле сейчас не знаю сценария, когда сработает fallback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

просто как-то не понятно, в csproj есть if под случай когда файла нету, а ситуации такой быть не должно

хочется как-то однообразно, либо файл всегда генерится и есть, либо же наоборот

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

мне больше нравиться убрать fallback и везде собирать, это однообразно.
но я знаю только сценарии использования модуля вместе с цементом, вдруг есть еще какие, которые я не знаю, а вы в курсе.
либо убрать, а если сценарий найдется, то только тогда добавить.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай уберем, будет сразу падать если что

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

убрал, изменения в Main-Project.props

@kungasc kungasc merged commit 8d12cf5 into vostok:master Oct 13, 2022
kungasc added a commit that referenced this pull request Oct 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants