Context
Directory.Build.props currently only centralizes a handful of properties (Company, Copyright, RepositoryUrl, RepositoryType, Deterministic, NeutralLanguage, SatelliteResourceLanguages).
However, ReqIFSharp/ReqIFSharp.csproj and ReqIFSharp.Extensions/ReqIFSharp.Extensions.csproj still duplicate a number of properties that are identical (or nearly identical) across both packages:
LangVersion (12.0 in both)
PackageProjectUrl (https://reqifsharp.org in both)
PackageLicenseExpression (Apache-2.0 in both)
PackageTags (ReqIF mbse modeltopia in both)
GeneratePackageOnBuild (False in both)
RequireLicenseAcceptance (false in both)
IncludeSource / IncludeSymbols (true in both)
GenerateDocumentationFile (true in both)
GenerateSBOM (true in both)
PackageReadmeFile (README.md in both)
- The
<None Include="..\README.md" .../>, <None Include="..\LICENSE" .../>, <None Include="..\NOTICE" .../> pack-file item group (identical in both)
- The
Microsoft.Sbom.Targets PackageReference (present, identically configured, in both)
Duplicating these across csproj files means every package-wide change (e.g. bumping LangVersion, changing the SBOM/packaging policy) has to be applied twice and is easy to let drift.
Proposal
Move the properties/items above that are genuinely shared into Directory.Build.props, and optionally split out a Directory.Build.targets or a dedicated Directory.Packages.props-style packaging props file (e.g. Directory.Package.Common.props) imported from each packable project, so that:
ReqIFSharp.csproj and ReqIFSharp.Extensions.csproj only retain what's genuinely per-package: TargetFramework, Version, Title, Description, PackageId, PackageIcon, Authors, PackageReleaseNotes, and the icon None item.
- The
Microsoft.Sbom.Targets PackageReference and the README/LICENSE/NOTICE pack items are declared once and apply to any packable project (test/non-packable projects should not pick them up — e.g. guard with a condition on IsPackable).
Notes
- Test projects (
ReqIFSharp.Tests, ReqIFSharp.Extensions.Tests) target net10.0 and are not packed, so packaging-related props should not leak into them — use an IsPackable/$(MSBuildProjectName) condition or a separate props file imported only by the two library projects.
LangVersion is a good Directory.Build.props candidate since it's already documented as pinned to 12.0 repo-wide in CLAUDE.md.
Context
Directory.Build.propscurrently only centralizes a handful of properties (Company,Copyright,RepositoryUrl,RepositoryType,Deterministic,NeutralLanguage,SatelliteResourceLanguages).However,
ReqIFSharp/ReqIFSharp.csprojandReqIFSharp.Extensions/ReqIFSharp.Extensions.csprojstill duplicate a number of properties that are identical (or nearly identical) across both packages:LangVersion(12.0in both)PackageProjectUrl(https://reqifsharp.orgin both)PackageLicenseExpression(Apache-2.0in both)PackageTags(ReqIF mbse modeltopiain both)GeneratePackageOnBuild(Falsein both)RequireLicenseAcceptance(falsein both)IncludeSource/IncludeSymbols(truein both)GenerateDocumentationFile(truein both)GenerateSBOM(truein both)PackageReadmeFile(README.mdin both)<None Include="..\README.md" .../>,<None Include="..\LICENSE" .../>,<None Include="..\NOTICE" .../>pack-file item group (identical in both)Microsoft.Sbom.TargetsPackageReference(present, identically configured, in both)Duplicating these across csproj files means every package-wide change (e.g. bumping
LangVersion, changing the SBOM/packaging policy) has to be applied twice and is easy to let drift.Proposal
Move the properties/items above that are genuinely shared into
Directory.Build.props, and optionally split out aDirectory.Build.targetsor a dedicatedDirectory.Packages.props-style packaging props file (e.g.Directory.Package.Common.props) imported from each packable project, so that:ReqIFSharp.csprojandReqIFSharp.Extensions.csprojonly retain what's genuinely per-package:TargetFramework,Version,Title,Description,PackageId,PackageIcon,Authors,PackageReleaseNotes, and the iconNoneitem.Microsoft.Sbom.TargetsPackageReference and the README/LICENSE/NOTICE pack items are declared once and apply to any packable project (test/non-packable projects should not pick them up — e.g. guard with a condition onIsPackable).Notes
ReqIFSharp.Tests,ReqIFSharp.Extensions.Tests) targetnet10.0and are not packed, so packaging-related props should not leak into them — use anIsPackable/$(MSBuildProjectName)condition or a separate props file imported only by the two library projects.LangVersionis a good Directory.Build.props candidate since it's already documented as pinned to12.0repo-wide inCLAUDE.md.