Skip to content

Move to Fluent UI Blazor 5.0.0 stable and drop the NU5104 suppression #280

Description

@phmatray

Problem / motivation

FormCraft.ForFluentUI (#260) depends on Microsoft.FluentUI.AspNetCore.Components 5.0.0-rc.5-26219.1
— a release candidate. v5 was chosen deliberately over the stable v4: v4 loses support in November
2026
and v5 renamed most of the input surface (FluentTextField → FluentTextInput,
FluentNumberField<T> → FluentNumberInput<T>, FluentDatePicker became generic), so a v4 adapter
would have shipped already-deprecated. But the RC leaves two things in the tree that must come out
together when 5.0.0 ships.

1. The prerelease pin in Directory.Packages.props.

2. A NU5104 suppression in FormCraft.ForFluentUI.csproj — and this one is a trap, because it
does not reproduce on an ordinary branch build:

<NoWarn>$(NoWarn);NU5104</NoWarn>

NU5104 is "a stable release of a package should not have a prerelease dependency". MinVer stamps
untagged commits as X.Y.Z-preview.N, and a prerelease package may depend on a prerelease, so the
warning never fires on a PR or a dev build. It fires only once MinVer produces a stable version
— i.e. on the release tag. With TreatWarningsAsErrors=true that is a hard build failure, in the
worst possible position: release-please creates the tag and the GitHub Release before the publish
job builds anything.

This was measured rather than assumed during #260:

$ dotnet pack FormCraft.ForFluentUI/FormCraft.ForFluentUI.csproj -c Release \
    -p:MinVerVersionOverride=3.2.0 -p:NoWarn='CS1591;CS8620'
error NU5104: Warning As Error: A stable release of a package should not have a prerelease
dependency. Either modify the version spec of dependency
"Microsoft.FluentUI.AspNetCore.Components [5.0.0-rc.5-26219.1, )" or update the version field
in the nuspec.

So the suppression is load-bearing today and becomes dead weight the moment the dependency goes
stable — and dead weight that hides a real future warning, since a later prerelease dependency added
by someone else would also be silently suppressed.

Proposed solution

When Microsoft.FluentUI.AspNetCore.Components 5.0.0 ships:

  1. Bump the pin in Directory.Packages.props from 5.0.0-rc.5-26219.1 to 5.0.0.
  2. Delete the <NoWarn>$(NoWarn);NU5104</NoWarn> line from FormCraft.ForFluentUI.csproj, along with
    the comment block explaining it.
  3. Delete the RC caveat from FormCraft.ForFluentUI/README.md and the root README.md.
  4. Verify with the same stable-version simulation that proved the suppression was needed —
    dotnet pack -p:MinVerVersionOverride=3.2.0 must now succeed without the NoWarn, which is the
    only check that actually distinguishes "no longer needed" from "still needed but untested".

Steps 1 and 2 must land together. Removing the pin without the suppression leaves dead config;
removing the suppression without the pin breaks the next release.

Alternatives considered

  • Let Renovate handle the bump. It will very likely open the version PR (renovate.json is
    configured, and dependencies is an active label) — but Renovate bumps the version and knows
    nothing about the NoWarn or the README caveats. The bump PR would go green, because NU5104 does
    not fire on a branch build. This issue exists precisely to catch the other three edits.
  • Remove the NoWarn now and pin an exact stable dependency range instead. Not possible: there is
    no stable 5.x to pin.
  • Keep the suppression permanently. Rejected: it would silently swallow a genuine NU5104 from any
    future prerelease dependency, which is the same silent-failure shape the suppression's own comment
    warns about.

Area

Build and packaging — Directory.Packages.props, FormCraft.ForFluentUI.csproj.

Related: #260, #198


🧠 Brainstorm

Problem & context

Two coupled edits and two documentation edits, gated on an external release. The coupling is the
whole difficulty: the failure they prevent is invisible on every build anyone normally runs.

The NU5104 mechanic in detail — MinVer derives the package version from git tags:

Build MinVer version NU5104?
PR / dev branch, untagged 3.1.1-preview.37 No — a prerelease may depend on a prerelease
Release tag v3.2.0 3.2.0 Yes — and TreatWarningsAsErrors makes it fatal

So CI is structurally incapable of catching this, and the first build that can is the release build,
which runs after release-please has already tagged and published the GitHub Release. That asymmetry is
why the removal needs a deliberate verification step rather than "CI is green".

Approaches

A. One PR doing all four edits, gated on 5.0.0 shipping. Small, coherent, verifiable in one place.
Recommended.

B. Let Renovate bump the version; do the rest as a follow-up. Realistic — Renovate is configured
and will open the version PR whether or not this issue exists. Rejected as the plan: the interval
between the two is exactly when the release breaks, and the Renovate PR looks green.

C. Remove the TreatWarningsAsErrors coupling instead (allow NU5104 repo-wide). Rejected outright:
it weakens a deliberate repo-wide setting that CLAUDE.md names as intentional, to work around one
temporary dependency.

Recommendation

Approach A, with one addition: if Renovate opens the version bump first, treat that PR as this
issue's implementation — add the other three edits to it rather than merging it and doing them after.
The whole point is that the four edits travel together.

Verification is the part worth insisting on. "The build is green" proves nothing here, because it is
green either way. The only meaningful check is -p:MinVerVersionOverride=3.2.0 without the
NoWarn — the same command that proved the suppression was needed in the first place.

📋 Spec

Goal

FormCraft.ForFluentUI depends on a stable Fluent UI Blazor 5.x, with the RC-era workarounds removed
together and verified by simulating a release build.

Scope

In: the version pin; the NU5104 suppression and its comment; the RC caveats in both READMEs; a
stable-version pack verification.

Non-goals: any code change (the v5 API surface is unchanged between RC and GA unless the bump
proves otherwise); Trusted Publishing (#198 owns that); other dependency bumps.

Trigger

Blocked on an external event: Microsoft.FluentUI.AspNetCore.Components 5.0.0 reaching stable on
nuget.org. Track via the Renovate dashboard (#4) or
https://www.nuget.org/packages/Microsoft.FluentUI.AspNetCore.Components.

The coupling

flowchart TD
    A["5.0.0 ships on nuget.org"] --> B["bump pin in Directory.Packages.props"]
    A --> C["delete NoWarn NU5104 + its comment"]
    B --> D["verify: dotnet pack -p:MinVerVersionOverride=3.2.0<br/>WITHOUT the NoWarn → must succeed"]
    C --> D
    D --> E["drop RC caveats from both READMEs"]
    F["⚠️ bump alone"] -.->|"leaves dead config"| G["suppression hides future NU5104"]
    H["⚠️ suppression removal alone"] -.->|"breaks the release build"| I["403-shaped failure after the tag exists"]

    style D fill:#cfe6ff,stroke:#2b6cb0
    style G fill:#ffd7d7,stroke:#b02a2a
    style I fill:#ffd7d7,stroke:#b02a2a
Loading

Acceptance

  1. Directory.Packages.props pins a stable 5.0.0 (or later stable), with the RC comment removed.
  2. FormCraft.ForFluentUI.csproj contains no NU5104 reference.
  3. dotnet pack -c Release -p:MinVerVersionOverride=3.2.0 succeeds — this is the check that matters.
  4. Full suite green; ./build.sh Pack still produces all three packages.
  5. Neither README mentions a prerelease dependency.

Assumptions

  • v5 GA is API-compatible with 5.0.0-rc.5. If not, the compile errors surface immediately on the
    bump and the fixes belong in this PR.
  • MinVer still honours MinVerVersionOverride (it does as of MinVer 7.0.0, which this repo pins).

🛠️ Implementation plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Move FormCraft.ForFluentUI onto a stable Fluent UI Blazor 5.x and remove the two RC-era
workarounds together, verified against a simulated release build.

Architecture: Configuration and documentation only — one version pin, one NoWarn, two READMEs.
No source changes expected.

Tech Stack: .NET 8 / .NET 10, central package management, MinVer, NUKE.

Global Constraints

  • Blocked until Microsoft.FluentUI.AspNetCore.Components 5.0.0 is stable on nuget.org. Do not
    start by relaxing the constraint — a 5.0.0-rc.6 is not the trigger.
  • All four edits land in one PR. A version bump merged without the NoWarn removal leaves dead
    config that suppresses future warnings.
  • TreatWarningsAsErrors=true stays as-is — it is deliberate and must not be relaxed to make this pass.
  • Central package management: the version lives in Directory.Packages.props only.
  • Never hand-edit CHANGELOG.md. dotnet test --filter is inert under MTP; use the full run.
  • Commit identity: git -c user.email=phmatray@gmail.com -c user.name="Philippe Matray".
  • Conventional Commits; scope deps.

Task 1: Bump to stable and remove the NU5104 suppression

Files: modify Directory.Packages.props (the Microsoft.FluentUI.AspNetCore.Components
PackageVersion and its comment) and FormCraft.ForFluentUI/FormCraft.ForFluentUI.csproj (the
<NoWarn> line and its comment block).

Interfaces: none — configuration only.

  • Step 1: Confirm the trigger: curl -s https://api.nuget.org/v3-flatcontainer/microsoft.fluentui.aspnetcore.components/index.json | python3 -c "import sys,json; print([v for v in json.load(sys.stdin)['versions'] if '-' not in v][-3:])" lists a stable 5.x. If it does not, stop — the issue is still blocked.
  • Step 2: Reproduce the failure the suppression prevents, so the removal is verified against a real signal rather than an assumption: dotnet pack FormCraft.ForFluentUI/FormCraft.ForFluentUI.csproj -c Release -o /tmp/nu5104-before -p:MinVerVersionOverride=3.2.0 -p:NoWarn='CS1591;CS8620' → expect error NU5104 naming the prerelease dependency.
  • Step 3: Bump the pin in Directory.Packages.props to the stable version and delete the RC explanation comment above it.
  • Step 4: Delete the <NoWarn>$(NoWarn);NU5104</NoWarn> line and its whole comment block from FormCraft.ForFluentUI.csproj.
  • Step 5: Re-run the Step 2 command unchanged. It must now succeed — that is the acceptance check, and the only one that distinguishes "no longer needed" from "still needed but no longer reported".
  • Step 6: Run dotnet build -c Release → PASS with 0 warnings. If the GA release renamed anything, fix the call sites here.
  • Step 7: Run dotnet test -c Release → PASS (all suites).
  • Step 8: Run ./build.sh Pack --configuration Release → three .nupkg files, including FormCraft.ForFluentUI.
  • Step 9: Commit: deps(fluentui): move to Fluent UI Blazor 5.0.0 stable and drop the NU5104 suppression.

Task 2: Drop the RC caveats from the documentation

Files: modify FormCraft.ForFluentUI/README.md and README.md.

Interfaces: none.

  • Step 1: Remove the "Fluent UI Blazor v5 is still an RC, so this package depends on a prerelease" sentence from the ## 🎉 Unreleased entry in the root README.md.
  • Step 2: Remove the equivalent caveat from FormCraft.ForFluentUI/README.md.
  • Step 3: Add a ## 🎉 Unreleased bullet recording the bump — this is a union hot-spot, so keep the edit additive rather than rewriting neighbouring entries.
  • Step 4: Grep for stragglers: grep -rn "rc\.5\|prerelease\|NU5104" README.md FormCraft.ForFluentUI/ --include=*.md --include=*.csproj → no hits outside CHANGELOG.md (which release-please owns and must not be hand-edited).
  • Step 5: Run dotnet build -c Release && dotnet test -c Release → PASS.
  • Step 6: Commit: docs(fluentui): drop the prerelease caveats now the dependency is stable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:lowNice to havestatus:blockedBlocked by external dependencytype:choreMaintenance, dependencies, tooling

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions