Skip to content

feat: exclude @vaadin packages from the minimum frontend package age - #25620

Open
totally-not-ai[bot] wants to merge 8 commits into
mainfrom
feat/exclude-vaadin-packages-from-the-minimum-release-age
Open

feat: exclude @vaadin packages from the minimum frontend package age#25620
totally-not-ai[bot] wants to merge 8 commits into
mainfrom
feat/exclude-vaadin-packages-from-the-minimum-release-age

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

The minimum frontend package age blocks packages that were published less than a day ago, so a build could fail right after a Vaadin release. Flow now tells npm and pnpm to skip that age check for the @vaadin/* packages, and warns you with a concrete fix when the package manager cannot do it.

What changed

Behavior change (all users of the minimum frontend package age): the install command now gets extra arguments, and the warning text changed.

  • npm 11.17.0 or newer gets --min-release-age-exclude=@vaadin/*; pnpm 10.17.0 or newer gets --config.minimum-release-age-exclude=@vaadin/*. This also happens when the age comes from the package manager's own configuration (.npmrc, pnpm-workspace.yaml) and Flow passes no age argument at all.
  • The pnpm argument is passed twice when there is only one pattern. pnpm reads the setting as a list only when the argument appears more than once, and pnpm 11 excludes every package when the value is a plain string — which would turn the age check off completely.
  • Exclusion patterns the package manager already resolves from its own configuration are passed along with @vaadin/*. Before, a command line value replaced them, so a project that excluded its own scope silently lost that exclusion.
  • Older npm and pnpm, and bun, cannot exclude packages from the command line. Those builds get a warning that an install during the first day after a Vaadin release may fail, plus the remedy for the package manager in use: upgrade npm to 11.17.0 (first shipped with Node.js 24.19.0), upgrade pnpm to 10.17.0, or, for bun, list the @vaadin packages one by one in minimumReleaseAgeExcludes in bunfig.toml, because bun matches exact names only. The warning no longer suggests turning the age check off.
  • With bun, Flow reads the project's bunfig.toml and stays quiet when that setting really lists a Vaadin package. A commented-out line or a mention elsewhere in the file is not enough.
  • Nothing is excluded and nothing is warned about when no age applies at all — including when the package manager itself is configured with an age of 0.
  • No public or protected API changed. The internal helper resolveMinimumFrontendPackageAgeArgument is now resolveMinimumFrontendPackageAge and returns whether an age applies together with the argument.

Use case

A team builds with bun and hits a failed frontend install on the morning after a Vaadin release. The build log now names the fix instead of telling them to disable the age check, so they add the Vaadin packages their app depends on to bunfig.toml:

[install]
minimumReleaseAgeExcludes = [
  "@vaadin/react-components",
  "@vaadin/bundles"
]

The next build installs the fresh Vaadin version, the warning goes away, and every other package is still held back for a day.

Test summary

# Status What the test verifies Why it matters
1 npm install gets --min-release-age-exclude=@vaadin/* Core fix; without it a build right after a release fails
2 pnpm gets --config.minimum-release-age-exclude=@vaadin/* twice, also in a real pnpm install command A single occurrence makes pnpm 11 exclude every package, silently disabling the age check
3 Exclusion patterns from the package manager configuration are kept and @vaadin/* is appended A project that excludes its own scope must not lose that exclusion
4 Too old npm: no argument, warning names 11.17.0 and Node.js 24.19.0 The user must be told what to upgrade, not left with a broken install
5 Too old pnpm: no argument, warning names 10.17.0 Same, for pnpm
6 bun: no argument, warning names minimumReleaseAgeExcludes and @vaadin/* bun's only remedy is manual, so the message must spell it out
7 A bunfig.toml that lists a @vaadin package as a value of the setting → no warning A project that already fixed this should not be nagged on every build
8 A bunfig.toml that only mentions @vaadin in a comment and excludes other packages → still warns A loose text match would hide a real problem
9 No age applies (min-release-age=0 in the configuration, or applies == false) → no argument and no warning Nothing is blocked, so an exclusion or warning would be noise
10 An age from .npmrc still produces the exclusion argument although no age argument is passed The most common real setup; the exclusion must not depend on Flow passing the age
11 getConfiguredSettingValues reads a JSON array and a comma separated string, and returns empty for a null or empty key Wrong parsing would drop or invent exclusion patterns
12 gap npmSupportsMinReleaseAgeExclude / pnpmSupportsMinimumReleaseAgeExclude version boundaries (11.16 vs 11.17, 10.16 vs 10.17, unknown version → false) A wrong boundary passes an argument an old tool rejects, or warns needlessly
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_npm_excludesVaadinPackages → 1
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_pnpm_excludesVaadinPackagesAsAList → 2
  • TaskRunPnpmInstallTest.runPnpmInstall_excludesVaadinPackagesFromTheMinimumAge → 2
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_configuredPatterns_areKept → 3
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_npmTooOld_warnsInsteadOfExcluding → 4
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_pnpmTooOld_warnsInsteadOfExcluding → 5
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_bun_warnsInsteadOfExcluding → 6
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_bunfigListsThePackages_noWarning → 7
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_bunfigListsOtherPackages_warns → 8
  • TaskRunNpmInstallTest.resolveMinimumFrontendPackageAge_npmrcValueOfZero_noAgeApplies → 9
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_noAgeApplies_noArgumentOrWarning → 9
  • TaskRunNpmInstallTest.minimumFrontendPackageAgeExclude_npmrcValue_isStillExcludedFrom → 10
  • FrontendToolsTest.getConfiguredSettingValues_listAndCommaSeparatedValue_areRead → 11
  • FrontendToolsTest.getConfiguredSettingValues_keyWithoutValue_isEmpty → 11

Left untested on purpose: the added Javadoc in Options, InitParameters, BuildFrontendMojo and BuildDevBundleMojo, and the unchanged behaviour of npmSupportsMinReleaseAge, which only moved into a shared helper. The version checks in row 12 run a real --version command, so they are exercised only indirectly by the mocked tests above.

The packages Vaadin publishes are pinned to the version of the platform in
use, so the minimum frontend package age blocks an installation that runs
during the first day after a Vaadin release: there is no older version to
fall back to and the build fails.

Specifies with tests how each package manager should be told to exempt those
packages, and that the build is warned when the package manager cannot do
it. The resolution itself is left unimplemented until the approach is
agreed on; the version checks that tell which package managers support
excluding are already in place.
Passes --min-release-age-exclude=@vaadin/* to npm 11.17 and newer, and
--config.minimum-release-age-exclude=@vaadin/* to pnpm 10.17 and newer, so
that a project can be built with a Vaadin version that was released a moment
ago. The argument is also passed when the age itself comes from the package
manager configuration.

bun accepts exclusions only as exact package names in a bunfig.toml, and
older npm and pnpm versions do not know the setting at all. Those builds are
warned that an installation started during the first day after a Vaadin
release may fail, and how to turn the age check off.
A command line value replaces the exclusions the package manager resolves
from its own configuration instead of adding to them, so a project that
excludes its own scope silently lost that exclusion. The configured patterns
are now passed along with '@vaadin/*'.

The pnpm argument is also passed twice when there is a single pattern: pnpm
reads the setting as a list only when the argument occurs more than once,
and pnpm 11 excludes every package when the value is a plain string, which
turned the age check off altogether.

Nothing is excluded and nothing is warned about when no age applies, which
now includes the package manager itself being configured with an age of 0.

@Artur- Artur- left a comment

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.

We might want to mention the node version that ships with a new enough npm also

}
if (options.isEnableBun()) {
warnAboutPackagesThatCannotBeExcluded(logger,
"bun accepts exclusions only as exact package names in the 'minimumReleaseAgeExcludes' setting of a bunfig.toml");

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.

Should this tell what you should add to match the npm/pnpm behavior?

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.

Yes — the warning now ends with the remedy for the package manager in use. For bun it says to list the @vaadin packages the project depends on one by one in the minimumReleaseAgeExcludes setting of a bunfig.toml, since bun matches exact names only (@vaadin/* does not match) and has no command line equivalent. pnpm and npm get their own line: upgrade to 10.17.0 and 11.17.0 respectively.

+ "minimum frontend package age, as {}. Installing a "
+ "Vaadin version during the first day after its "
+ "release may therefore fail. Upgrade the package "
+ "manager, or set the '{}' parameter to 0 to turn "

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.

We should not suggest turning off the age check

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.

Removed — the warning no longer mentions the age parameter at all. Instead of suggesting to turn the check off, it now names the upgrade that makes the exclusion work: npm 11.17.0 (first shipped with Node.js 24.19.0), pnpm 10.17.0, or the exact @vaadin package names in a bunfig.toml for bun.

The warning no longer suggests turning the age check off. It now ends with
the remedy for the package manager in use: upgrading npm to 11.17.0, which
Node.js 24.19.0 is the first release to ship, upgrading pnpm to 10.17.0, or,
for bun, listing the '@vaadin' packages one by one in the
'minimumReleaseAgeExcludes' setting of a bunfig.toml, as bun matches exact
names only. The parameter documentation names the Node.js version as well.
Only the npm remedy was asserted, so swapping the other two messages would
have gone unnoticed.
@totally-not-ai

Copy link
Copy Markdown
Contributor Author

@Artur- Added the Node.js version in both places: the npm warning now reads "Upgrade npm to 11.17.0 or newer, which Node.js 24.19.0 and newer ship with", and the same hint is in the minimumFrontendPackageAgeDays documentation of the Maven parameters, InitParameters and Options. Node.js 24.19.0 is the first release of the 24 line that bundles npm 11.17.0; the Node.js version Vaadin installs itself (v24.21.0, npm 11.19.0) is already new enough, so the warning only appears with an older globally installed npm.

* date npm falls back to is not a number and always blocks something.
*/
private static boolean blocksNothing(String packageManagerValue) {
try {

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.

Is this a method for comparing a string with "0" that is always used in an inverted manner !blocksNothing?

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.

It compared the age that npm or pnpm resolves for itself against zero, which is the one value that blocks nothing (before is a date, so it always blocks something). Turned around into blocksSomeVersion, so the call site reads without a negation.

}
if (options.isEnableBun()) {
warnAboutPackagesThatCannotBeExcluded(logger,
"bun accepts exclusions only as exact package names in the 'minimumReleaseAgeExcludes' setting of a bunfig.toml",

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.

If this is done by the user, will the warning still be printed?

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.

It was, on every build, with nothing the project could do about it. The bunfig.toml next to the package.json is now read, and the warning is skipped when it lists Vaadin packages in minimumReleaseAgeExcludes. The file is read as it is, since bun has no command for printing its resolved configuration, so a bunfig.toml outside the project (the one in the home directory) is still not seen.

}

@Test
void minimumFrontendPackageAgeExclude_pnpmTooOld_warnsInsteadOfExcluding() {

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.

Shouldn't pnpm tests be in the pnpm test class?

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.

These are unit tests of the argument resolution with a mocked FrontendTools, not tests of a pnpm install, and the class already holds the pnpm and bun variants of the neighbouring age tests (minimumFrontendPackageAge_pnpm_usesMinimumReleaseAgeInMinutes, resolveMinimumFrontendPackageAge_pnpmConfiguredValue_doesNotOverrideIt), so the whole npm/pnpm/bun matrix stays in one place. The test that runs a real pnpm install and checks the argument reaches the command is in TaskRunPnpmInstallTest. Happy to move the pnpm ones over if you prefer them separated.

A bun build could do nothing to stop the warning, as the exclusion it asks
for cannot be seen from the command line. The bunfig.toml of the project is
now read, and the warning is skipped when it lists Vaadin packages in
'minimumReleaseAgeExcludes'.

Also states the check of the age a package manager resolved for itself the
way it is used, instead of negating it at the call site.
Both strings were looked for anywhere in the bunfig.toml, so a commented out
setting or an unrelated mention of a Vaadin package was enough to lose the
warning. The package now has to be a value of the setting.
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Test Results

 1 440 files  ±0   1 524 suites  ±0   1h 41m 29s ⏱️ + 7m 17s
12 060 tests ±0  11 991 ✅  - 1  68 💤 ±0  0 ❌ ±0  1 🔥 +1 
12 378 runs  ±0  12 309 ✅  - 1  68 💤 ±0  0 ❌ ±0  1 🔥 +1 

For more details on these errors, see this check.

Results for commit efc02ca. ± Comparison against base commit 8365470.

♻️ This comment has been updated with latest results.

@Artur-
Artur- requested a review from caalador September 11, 2026 14:34
@sonarqubecloud

Copy link
Copy Markdown

@totally-not-ai

Copy link
Copy Markdown
Contributor Author

The failing it-tests (2, …) job is not caused by this branch. PostinstallIT.postinstallRanForProject in vite-basics errored with a NullPointerException because the main.postinstall resource was missing, while every frontend install in that job logged "Frontend dependencies resolved successfully" with the new arguments (--min-release-age=1 --min-release-age-exclude=@vaadin/* for npm, the duplicated --config.minimum-release-age-exclude=@vaadin/* for pnpm). The previous full validation run of this branch ran the very same install command and PostinstallIT passed; the only change since then is the merge of main. The WebComponentIT error in the same job passed on retry. So I re-ran the failed jobs instead of pushing a change.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant