mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-18 22:55:08 +08:00
00664404c0
# Description The `preview-pack` stage of the Azure DevOps pipeline fails with nine `NU5033` errors, which fails the whole build: ``` NuGet.Build.Tasks.Pack.targets(222,5): error NU5033: Invalid metadata. Cannot specify both a PackageLicenseExpression and a PackageLicenseFile. [src\Opc.Ua.Robotics\Opc.Ua.Robotics.csproj] ``` `common.props` gives every package the shared `LICENSE.txt` as its `<PackageLicenseFile>`, but **19** packages also declared `<PackageLicenseExpression>MIT</PackageLicenseExpression>`. Nine of them hit `NU5033`; the other ten only avoided it by carrying an empty `<PackageLicenseFile></PackageLicenseFile>` workaround. That declaration was wrong on two counts. **It advertised the wrong license.** `LICENSE.txt` is the **OPC Foundation MIT License 1.00**, which carries the OPC Foundation copyright and preamble — it is a different text than the plain SPDX `MIT` license. The affected packages therefore published `<license type="expression">MIT</license>` plus a `licenses.nuget.org/MIT` URL on nuget.org, instead of the OPC Foundation text that every other package in the stack ships. **It also broke the build,** because NuGet refuses to pack a project carrying both a license expression and a license file, failing `pack` solution-wide rather than just for the offending projects. ## Changes The expression is dropped from all 19 packages so every one uses the shared OPC Foundation license file uniformly, like the rest of the stack: * `src/Opc.Ua.OpenUsd`, `.Client`, `.Server` * `src/Opc.Ua.OpenUsdScene`, `.Server` * `src/Opc.Ua.Robotics`, `.Client`, `.Server` * `src/Opc.Ua.Positioning`, `.Client`, `.Server` * `src/Opc.Ua.Di`, `src/Opc.Ua.ISA95`, `src/Opc.Ua.WotCon`, `src/Opc.Ua.Gds.Common` * `tools/Opc.Ua.OpenUsd.Connector.Viewer`, `tools/Opc.Ua.SourceGeneration.Core` * `tools/Opc.Ua.SourceGeneration.Pack`, `tools/Opc.Ua.SourceGeneration.Stack.Pack` — these two set the license not in their own `.csproj` but in the shared `tools/SourceGeneratorPack.targets`, so they were only caught once the new guard ran in CI. The eight per-project empty `<PackageLicenseFile></PackageLicenseFile>` workarounds go away with it. To stop the whole class of failure from recurring, `Directory.Build.targets` now *enforces* the rule rather than papering over it. Silently clearing the inherited license file would have fixed the build while still publishing the wrong license metadata, so instead a violation fails fast with an actionable error naming the project: ``` error OPCUA0001: Opc.Ua.Foo sets PackageLicenseExpression=MIT. Every package must ship the OPC Foundation MIT License 1.00 via the shared LICENSE.txt that common.props sets as PackageLicenseFile, which the SPDX expression neither matches nor is allowed to coexist with (NU5033). Remove the PackageLicenseExpression property. ``` `common.props` cannot catch this itself: it is imported from `Directory.Build.props`, i.e. **before** the project body, so it never observes a project-level license expression. `Directory.Build.targets` is imported **after** the project body and is the earliest place that can. The `common.props` comment that previously hinted the expression was an option now points at this rule. ### Verification * Every packable project evaluates to `PackageLicenseFile=LICENSE.txt` with an empty `PackageLicenseExpression`; file-licensed packages such as `Opc.Ua.Client` are unchanged. * `dotnet pack -c Release` succeeds for `Opc.Ua.Robotics` (previously failing) and `Opc.Ua.SourceGeneration.Core` (previously relying on the removed workaround). * Replicated the CI build commands locally — `dotnet build` of `UA.slnx` (net48/Debug), `tools/SourceGeneration.slnx` (net472/Release) and `tools/MigrationAnalyzer.slnx` (net48/Debug) all succeed with 0 errors. * Inspected the produced `.nupkg`: now `<license type="file">LICENSE.txt</license>` with the license text at the package root, matching the rest of the stack (it was `<license type="expression">MIT</license>` before). * Confirmed the guard fires on a simulated violation (`-p:PackageLicenseExpression=MIT`) and is inert otherwise. ## Related Issues No tracking issue — this fixes the `NU5033` failure in the OPC Foundation Azure DevOps pipeline (build 16247, `preview-pack` stage) and corrects the license metadata published for the affected packages. No product code or public API changes. ## Checklist _Put an `x` in the boxes that apply. You can complete these step by step after opening the PR._ - [x] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. _(Build-infrastructure change with no code surface. Validated by `dotnet pack` of the affected projects, by inspecting the resulting package metadata, and by confirming the new `OPCUA0001` guard fires on a simulated violation. The pipeline `preview-pack` stage is the regression test.)_ - [x] I have added all necessary documentation. _(The rule is documented in place, on the new `Directory.Build.targets` guard and at the `PackageLicenseFile` definition in `common.props`.)_ - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received.
144 lines
7.1 KiB
XML
144 lines
7.1 KiB
XML
<Project>
|
|
<PropertyGroup>
|
|
<Product>OPC UA .NET Standard Library</Product>
|
|
<RepositoryUrl>https://github.com/OPCFoundation/UA-.NETStandard</RepositoryUrl>
|
|
<VersionPrefix>2.0</VersionPrefix>
|
|
<VersionSuffix>preview-$([System.DateTime]::Now.ToString("yyyyMMdd"))</VersionSuffix>
|
|
<Copyright>Copyright © 2004-2025 OPC Foundation, Inc</Copyright>
|
|
<PackagePrefix>OPCFoundation.NetStandard</PackagePrefix>
|
|
<AssemblyPrefix>Opc.Ua</AssemblyPrefix>
|
|
<Company>OPC Foundation</Company>
|
|
<Authors>OPC Foundation</Authors>
|
|
<NeutralLanguage>en-US</NeutralLanguage>
|
|
<HighEntropyVA>true</HighEntropyVA>
|
|
<IsPackable>false</IsPackable>
|
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
|
<LangVersion>14.0</LangVersion>
|
|
<!-- to enable package validation, uncomment here -->
|
|
<!--<EnablePackageValidation>true</EnablePackageValidation>-->
|
|
<!-- to check the package validation on a release build, uncomment here -->
|
|
<!--<PackageValidationBaselineVersion>1.5.374.27</PackageValidationBaselineVersion>-->
|
|
<!-- to regenerate the compatibility suppression file, uncomment here -->
|
|
<!--<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>-->
|
|
<NuGetAuditMode>all</NuGetAuditMode>
|
|
<NuGetAudit>true</NuGetAudit>
|
|
</PropertyGroup>
|
|
<PropertyGroup>
|
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
|
<EnableNETAnalyzers>true</EnableNETAnalyzers>
|
|
<RunAnalyzersDuringBuild Condition="'$(RunAnalyzersDuringBuild)' == ''">true</RunAnalyzersDuringBuild>
|
|
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
|
|
<AnalysisLevel>preview</AnalysisLevel>
|
|
<AnalysisMode>all</AnalysisMode>
|
|
<AnalysisModeStyle>default</AnalysisModeStyle>
|
|
</PropertyGroup>
|
|
<PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
|
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
|
</PropertyGroup>
|
|
<ItemGroup Condition="'$(NoRoslynatorAnalzers)' == ''">
|
|
<PackageReference Include="Roslynator.Analyzers" PrivateAssets="All" />
|
|
<PackageReference Include="Roslynator.Formatting.Analyzers" PrivateAssets="All" />
|
|
</ItemGroup>
|
|
<PropertyGroup>
|
|
<NoWarn>$(NoWarn);NU1510</NoWarn>
|
|
<PackageIcon>images/logo.jpg</PackageIcon>
|
|
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
|
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
|
<!--
|
|
Every package ships the OPC Foundation MIT License 1.00 as a license
|
|
file. Do NOT replace this with
|
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>: the SPDX `MIT`
|
|
license is a different text than the OPC Foundation one, and NuGet
|
|
rejects a project that carries both an expression and a license file
|
|
(NU5033). `Directory.Build.targets` enforces this.
|
|
-->
|
|
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
|
|
<PackageReleaseNotes>$(RepositoryUrl)/releases</PackageReleaseNotes>
|
|
<!--
|
|
Every package ships its own package-local README (`NugetREADME.md`
|
|
next to the csproj, or the established `McpREADME.md` for the
|
|
command-line tool package). Per-package READMEs are wired in each
|
|
csproj via <PackageReadmeFile> + a matching <None Include=...
|
|
Pack="true">. A generic shared README at this `common.props`
|
|
level was deliberately removed in favor of per-package READMEs
|
|
because it was misleading on nuget.org (every package described
|
|
itself identically).
|
|
-->
|
|
<PackageTags>OPCFoundation OPC UA ios linux dotnet net netcore</PackageTags>
|
|
</PropertyGroup>
|
|
<PropertyGroup Condition="'$(SignAssembly)' == 'true'">
|
|
<!-- OPC Foundation public key -->
|
|
<PublicKey>0024000004800000940000000602000000240000</PublicKey>
|
|
<PublicKey>$(PublicKey)525341310004000001000100d987b12f068b3580</PublicKey>
|
|
<PublicKey>$(PublicKey)429f3dde01397508880fc7e62621397618456ca1</PublicKey>
|
|
<PublicKey>$(PublicKey)549aeacfbdb90c62adfe918f05ce3677b390f783</PublicKey>
|
|
<PublicKey>$(PublicKey)57b8745cb6e1334655afce1a9527ac92fc829ff5</PublicKey>
|
|
<PublicKey>$(PublicKey)85ea79f007e52ba0f83ead627e3edda40bec5ae5</PublicKey>
|
|
<PublicKey>$(PublicKey)74128fc9342cb57cb8285aa4e5b589c0ebef3be5</PublicKey>
|
|
<PublicKey>$(PublicKey)71b5c8f2ab1067f7c880e8f8882a73c80a12a1ef</PublicKey>
|
|
</PropertyGroup>
|
|
<Choose>
|
|
<When Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net5.0'))">
|
|
<PropertyGroup>
|
|
<!-- Disable strongname warning as that's not been enforced since .net 5.-->
|
|
<NoWarn>$(NoWarn);CS8002</NoWarn>
|
|
</PropertyGroup>
|
|
</When>
|
|
<Otherwise>
|
|
<PropertyGroup>
|
|
<!-- Disable nullable warning as it is not as meaningful on .net framework as on .net -->
|
|
<NoWarn>$(NoWarn);nullable</NoWarn>
|
|
</PropertyGroup>
|
|
</Otherwise>
|
|
</Choose>
|
|
<PropertyGroup Condition="'$(TargetFramework)' == 'net472' OR '$(TargetFramework)' == 'net48'">
|
|
<!--
|
|
The Microsoft.Extensions.* graph used across the stack (Http.Resilience and
|
|
its transitive Telemetry / AmbientMetadata / Diagnostics packages) ships
|
|
net462 assets that build and run on .NET Framework, but their buildTransitive
|
|
support targets still emit "doesn't support net48/net472" warnings. These are
|
|
benign on net462-compatible TFMs, so suppress them once here for all projects
|
|
instead of scattering per-project SuppressTfmSupportBuildWarnings blocks.
|
|
TODO: remove when the library matrix drops .NET Framework or the packages stop warning.
|
|
-->
|
|
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
|
</PropertyGroup>
|
|
<ItemGroup Condition="'$(IsPackable)' != 'false'">
|
|
<None
|
|
Include="$(MSBuildThisFileDirectory)/LICENSE.txt"
|
|
Pack="true"
|
|
PackagePath="$(PackageLicenseFile)"
|
|
/>
|
|
<None
|
|
Include="$(MSBuildThisFileDirectory)/nuget/logo.jpg"
|
|
Pack="true"
|
|
PackagePath="$(PackageIcon)"
|
|
/>
|
|
<!--
|
|
Each NuGet package owns its own package-local README -
|
|
`NugetREADME.md` next to the csproj, or the established
|
|
`McpREADME.md` for the command-line tool package. Each csproj
|
|
wires its README via <PackageReadmeFile> and packs the file at
|
|
the package root with
|
|
<None Include="..." Pack="true" PackagePath="\" />.
|
|
A generic shared README would be misleading on nuget.org because
|
|
every package would describe itself identically.
|
|
-->
|
|
</ItemGroup>
|
|
<ItemGroup Condition="'$(NBGV_PublicRelease)' != ''">
|
|
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
|
|
</ItemGroup>
|
|
<!-- Deterministic build is currently not supported for code coverage tests. -->
|
|
<PropertyGroup Condition="'$(CollectCoverage)' != 'true' AND ('$(TF_BUILD)' == 'true' OR '$(GITHUB_ACTIONS)' == 'true')">
|
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
|
</PropertyGroup>
|
|
<PropertyGroup>
|
|
<IncludeSymbols>true</IncludeSymbols>
|
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
|
</PropertyGroup>
|
|
</Project>
|