Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Code } from '@astrojs/starlight/components';
import { UPGRADE_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import type { Products } from '~/models/site.models';

interface Props {
Expand Down Expand Up @@ -56,8 +56,8 @@ function repoLink(ver: string): string | null {
{versions.map((v) => {
const newer = isNewerVersionScheme(v.version);
const needsCompat = needsCompatibilityCheck(v.version);
const heading = v.patch && v.baseVersion !== v.displayVersion
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to latest ${v.baseVersion} (${v.displayVersion})`
const heading = v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion}`;
const prevLabel = v.x ? v.upgradableFrom : v.upgradableFrom;
const prevDisplayLabel = isPE ? `${prevLabel} PE` : prevLabel;
Expand Down Expand Up @@ -117,7 +117,7 @@ function repoLink(ver: string): string | null {
{prevHref ? (
<a href={prevHref}>{prevDisplayLabel}</a>
) : prevDisplayLabel}
{v.patch && <>{' '}or any {v.baseVersion} patch</>}.{' '}
{v.patch && <>{' '}or any {v.patchableFrom ?? v.baseVersion} patch</>}.{' '}
In order to upgrade to <strong>{isPE ? `${v.displayVersion}PE` : v.displayVersion}</strong> you need to{' '}
{prevHref ? (
<><a href={prevHref}><strong>upgrade to {prevDisplayLabel} first</strong></a>.</>
Expand Down Expand Up @@ -161,7 +161,7 @@ function repoLink(ver: string): string | null {
<p class="starlight-aside__title" aria-hidden="true">Caution</p>
<div class="starlight-aside__content">
{v.patch ? (
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {`${v.baseVersion}.x`}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {v.patchableFrom ?? v.baseVersion + '.x'}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
) : (
<p>If you are upgrading from version {v.upgradableFrom}, you must run the script below.</p>
)}
Expand Down
12 changes: 6 additions & 6 deletions src/components/upgrade-instructions/DockerUpgradeSteps.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Code } from '@astrojs/starlight/components';
import { UPGRADE_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import type { Products } from '~/models/site.models';

interface Props {
Expand Down Expand Up @@ -34,8 +34,8 @@ function versionTag(ver: string): string {
{versions.map((v) => {
const newer = isNewerVersionScheme(v.version);
const needsCompat = needsCompatibilityCheck(v.version);
const heading = v.patch && v.baseVersion !== v.displayVersion
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to latest ${v.baseVersion} (${v.displayVersion})`
const heading = v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion}`;
const prevLabel = v.x ? v.upgradableFrom : v.upgradableFrom;
const prevDisplayLabel = isPE ? `${prevLabel} PE` : prevLabel;
Expand Down Expand Up @@ -94,7 +94,7 @@ function versionTag(ver: string): string {
{prevHref ? (
<a href={prevHref}>{prevDisplayLabel}</a>
) : prevDisplayLabel}
{v.patch && <>{' '}or any {v.baseVersion} patch</>}.{' '}
{v.patch && <>{' '}or any {v.patchableFrom ?? v.baseVersion} patch</>}.{' '}
In order to upgrade to <strong>{isPE ? `${v.displayVersion}PE` : v.displayVersion}</strong> you need to{' '}
{prevHref ? (
<><a href={prevHref}><strong>upgrade to {prevDisplayLabel} first</strong></a>.</>
Expand Down Expand Up @@ -122,7 +122,7 @@ function versionTag(ver: string): string {
<p class="starlight-aside__title" aria-hidden="true">Caution</p>
<div class="starlight-aside__content">
{v.patch ? (
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {`${v.baseVersion}.x`}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {v.patchableFrom ?? v.baseVersion + '.x'}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
) : (
<p>If you are upgrading from version {v.upgradableFrom}, you must run the script below.</p>
)}
Expand All @@ -144,7 +144,7 @@ function versionTag(ver: string): string {
<p class="starlight-aside__title" aria-hidden="true">Caution</p>
<div class="starlight-aside__content">
{v.patch ? (
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {`${v.baseVersion}.x`}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {v.patchableFrom ?? v.baseVersion + '.x'}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
) : (
<p>If you are upgrading from version {v.upgradableFrom}, you must run the script below.</p>
)}
Expand Down
10 changes: 5 additions & 5 deletions src/components/upgrade-instructions/LinuxUpgradeSteps.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Code } from '@astrojs/starlight/components';
import { UPGRADE_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import type { Products } from '~/models/site.models';
import PrepareSection from './PrepareSection.astro';

Expand Down Expand Up @@ -58,8 +58,8 @@ function needsCompatibilityCheck(version: string): boolean {
{versions.map((v) => {
const newer = isNewerVersionScheme(v.version);
const needsCompat = needsCompatibilityCheck(v.version);
const heading = v.patch && v.baseVersion !== v.displayVersion
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to latest ${v.baseVersion} (${v.displayVersion})`
const heading = v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion}`;
const prevLabel = v.x ? v.upgradableFrom : v.upgradableFrom;
const prevDisplayLabel = isPE ? `${prevLabel} PE` : prevLabel;
Expand Down Expand Up @@ -125,7 +125,7 @@ function needsCompatibilityCheck(version: string): boolean {
<a href={prevHref}>{prevDisplayLabel}</a>
) : (
prevDisplayLabel
)}{v.patch ? <>{' '}or any {v.baseVersion} patch</> : ''}.{' '}
)}{v.patch ? <>{' '}or any {v.patchableFrom ?? v.baseVersion} patch</> : ''}.{' '}
In order to upgrade to <strong>{isPE ? `${v.displayVersion}PE` : v.displayVersion}</strong> you need to{' '}
{prevHref ? (
<><a href={prevHref}><strong>upgrade to {prevDisplayLabel} first</strong></a>.</>
Expand Down Expand Up @@ -199,7 +199,7 @@ function needsCompatibilityCheck(version: string): boolean {
<p class="starlight-aside__title" aria-hidden="true">Caution</p>
<div class="starlight-aside__content">
{v.patch ? (
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {`${v.baseVersion}.x`}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {v.patchableFrom ?? v.baseVersion + '.x'}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
) : (
<p>If you are upgrading from version {v.upgradableFrom}, you must run the script below.</p>
)}
Expand Down
10 changes: 5 additions & 5 deletions src/components/upgrade-instructions/WindowsUpgradeSteps.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Code } from '@astrojs/starlight/components';
import { UPGRADE_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import type { Products } from '~/models/site.models';

interface Props {
Expand Down Expand Up @@ -47,8 +47,8 @@ function needsCompatibilityCheck(version: string): boolean {
{versions.map((v) => {
const newer = isNewerVersionScheme(v.version);
const needsCompat = needsCompatibilityCheck(v.version);
const heading = v.patch && v.baseVersion !== v.displayVersion
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to latest ${v.baseVersion} (${v.displayVersion})`
const heading = v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard${isPE ? ' PE' : ''} to ${v.displayVersion}`;
const prevLabel = v.x ? v.upgradableFrom : v.upgradableFrom;
const prevDisplayLabel = isPE ? `${prevLabel} PE` : prevLabel;
Expand Down Expand Up @@ -114,7 +114,7 @@ function needsCompatibilityCheck(version: string): boolean {
{prevHref ? (
<a href={prevHref}>{prevDisplayLabel}</a>
) : prevDisplayLabel}
{v.patch && <>{' '}or any {v.baseVersion} patch</>}.{' '}
{v.patch && <>{' '}or any {v.patchableFrom ?? v.baseVersion} patch</>}.{' '}
In order to upgrade to <strong>{isPE ? `${v.displayVersion}PE` : v.displayVersion}</strong> you need to{' '}
{prevHref ? (
<><a href={prevHref}><strong>upgrade to {prevDisplayLabel} first</strong></a>.</>
Expand Down Expand Up @@ -183,7 +183,7 @@ function needsCompatibilityCheck(version: string): boolean {
<p class="starlight-aside__title" aria-hidden="true">Caution</p>
<div class="starlight-aside__content">
{v.patch ? (
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {`${v.baseVersion}.x`}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
<p>If you are upgrading from {v.upgradableFrom}, you <strong>must</strong> run the script below. However, if you are upgrading from version {v.patchableFrom ?? v.baseVersion + '.x'}, <strong>DO NOT</strong> run the upgrade script; proceed directly to starting the service.</p>
) : (
<p>If you are upgrading from version {v.upgradableFrom}, you must run the script below.</p>
)}
Expand Down
34 changes: 34 additions & 0 deletions src/models/upgrade-instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface UpgradeVersion {
releaseDatePe?: string;
/** "upgradable-from" value, e.g. "4.2.1.x" or "4.1.0" */
upgradableFrom: string;
/** Optional override for the in-family patch label used in "or any X patch" text and the "from version X" upgrade-script note. When unset, templates fall back to baseVersion (and baseVersion.x for the script note). */
patchableFrom?: string;
/** Anchor of the upgradable-from version on the same platform page */
prevVersionAnchor?: string;
lts: boolean;
Expand All @@ -39,6 +41,17 @@ export function getFamilySlug(family: string): string {
return 'v' + family.replace(/\./g, '-') + '-x';
}

/**
* All upgrade-eligible versions, newest-first.
*
* ORDERING IS LOAD-BEARING — keep entries in descending version order, and within
* a baseVersion group list the newest patch first. Consumers rely on array position:
* - UPGRADE_FAMILIES dedups by position to derive family order
* - UpgradeTable / *UpgradeSteps render rows in array order
* - LATEST_PATCH_VERSIONS treats the first entry per baseVersion as the latest
* An out-of-order insert silently mislabels "(latest patch)" and visibly reorders
* the upgrade table and steps.
*/
export const UPGRADE_VERSIONS: UpgradeVersion[] = [
{
version: '4.3.1.2',
Expand All @@ -47,6 +60,7 @@ export const UPGRADE_VERSIONS: UpgradeVersion[] = [
baseVersion: '4.3.1',
releaseDate: 'May 28 2026',
upgradableFrom: '4.2.1.x',
patchableFrom: '4.3.x',

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.

Worth confirming this against the release policy before it ships. Per src/content/_includes/docs/releases/release-policy.mdx, the scheme is MAJOR.MINOR.MAINTENANCE.PATCH and the "no upgrade script" guarantee is PATCH-level only — i.e. within the same MAINTENANCE number. Here baseVersion is exactly the MAINTENANCE level, so 4.3.0 and 4.3.1 are two distinct maintenance releases.

Setting patchableFrom: '4.3.x' broadens the caution note ("if you are upgrading from version 4.3.x, DO NOT run the upgrade script") to cover users on 4.3.0.x moving to 4.3.1.x — which crosses a maintenance boundary. The policy says maintenance bumps "may require upgrade scripts" and should be done in a maintenance window (its example: 4.2.0.x → 4.2.1.0). The original 4.3.1.x scope (the baseVersion fallback) matched the policy exactly.

Caveat that cuts the other way: 4.3.1 is the Angular-20 maintenance release (release notes #14944), i.e. the 4.3 analog of 4.2.2.0, which the policy explicitly calls out as "no DB scripts required." So the broadening might be intentional and correct. But then it's inconsistent — this same PR leaves 4.2.2.x at 4.2.2.x scope (no patchableFrom). Either both Angular-maintenance lines should be broadened, or neither.

Could you confirm whether upgrade.sh has an incremental 4.3.0 → 4.3.1 step, or only the step from the 4.2.1.x LTS base? If the former, this should stay 4.3.1.x. (Same patchableFrom: '4.3.x' is set on all three 4.3.1.x entries — lines 52, 69, 87.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Could you confirm whether upgrade.sh has an incremental 4.3.0 → 4.3.1 step, or only the step from the 4.2.1.x LTS base? If the former, this should stay 4.3.1.x. (Same patchableFrom: '4.3.x' is set on all three 4.3.1.x entries — lines 52, 69, 87.)

yep, upgrade script is not needed, and that was actually the main focus of these changes.
current upgrade notes say "do not run starting from 4.3.1.x" - user upgrading from 4.3.0.x may misinterpret that script is required, run upgrade.sh, see "cannot upgrade this version" and wonder how to proceed.
actually - there were real customer portal tickets with questions on such confusions.

Caveat that cuts the other way: 4.3.1 is the Angular-20 maintenance release (release notes #14944), i.e. the 4.3 analog of 4.2.2.0, which the policy explicitly calls out as "no DB scripts required."
...
But then it's inconsistent — this same PR leaves 4.2.2.x at 4.2.2.x scope (no patchableFrom). Either both Angular-maintenance lines should be broadened, or neither.

a) separate Angular note exists, warning the user about this breaking change - also, 'patchableFrom' is strictly about "should you run upgrade.sh or not"
b) 4.2.x upgrades were consciously untouched since current cautions/notes are valid; additionally, these changes to upgrade pages were done with defaults and fallbacks to ensure they work in the same way as before in case 'patchableFrom' wasnt provided

prevVersionAnchor: 'v4-3-0-1',
lts: true,
patch: true,
Expand All @@ -63,6 +77,7 @@ export const UPGRADE_VERSIONS: UpgradeVersion[] = [
baseVersion: '4.3.1',
releaseDate: 'Mar 31 2026',
upgradableFrom: '4.2.1.x',
patchableFrom: '4.3.x',
prevVersionAnchor: 'v4-3-0-1',
lts: true,
patch: true,
Expand All @@ -80,6 +95,7 @@ export const UPGRADE_VERSIONS: UpgradeVersion[] = [
baseVersion: '4.3.1',
releaseDate: 'Mar 10 2026',
upgradableFrom: '4.2.1.x',
patchableFrom: '4.3.x',
prevVersionAnchor: 'v4-3-0-1',
lts: true,
patch: true,
Expand Down Expand Up @@ -708,3 +724,21 @@ export const UPGRADE_VERSIONS: UpgradeVersion[] = [

/** Unique version families in order, e.g. ["4.3", "4.2", "4.1", ...] */
export const UPGRADE_FAMILIES: string[] = [...new Set(UPGRADE_VERSIONS.map((v) => v.family))];

/**
* Version strings that are the newest patch within their baseVersion family.
* Relies on UPGRADE_VERSIONS being newest-first per baseVersion (see note there) —
* the first entry seen for each baseVersion is taken as the latest.
*/
export const LATEST_PATCH_VERSIONS: Set<string> = (() => {
const seen = new Set<string>();
const latest = new Set<string>();
for (const v of UPGRADE_VERSIONS) {

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.

This silently depends on UPGRADE_VERSIONS being ordered newest-patch-first within each baseVersion group — the first entry seen for a given baseVersion is taken as "latest." That invariant holds today (and UPGRADE_FAMILIES above relies on the same ordering), but nothing enforces it: if a future edit inserts an older patch above a newer one for the same base, the wrong version silently gets the "(latest X patch)" label with no error. Worth a one-line comment noting the newest-first requirement, or deriving "latest" via an actual version comparison rather than positional order.

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.

Concrete suggestion for the ordering dependency flagged earlier — derive "latest" by comparing version components rather than relying on array position, so an out-of-order insert can't silently mislabel the newest patch:

function cmpVersion(a: string, b: string): number {
	const pa = a.split('.').map(Number);
	const pb = b.split('.').map(Number);
	for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
		const d = (pa[i] ?? 0) - (pb[i] ?? 0);
		if (d) return d;
	}
	return 0;
}

export const LATEST_PATCH_VERSIONS: Set<string> = (() => {
	const byBase = new Map<string, string>(); // baseVersion → newest version
	for (const v of UPGRADE_VERSIONS) {
		if (!v.patch || !v.baseVersion) continue;
		const cur = byBase.get(v.baseVersion);
		if (!cur || cmpVersion(v.version, cur) > 0) byBase.set(v.baseVersion, v.version);
	}
	return new Set(byBase.values());
})();

If you'd rather keep the positional approach, at least add a one-line comment stating the "newest patch listed first within each baseVersion" invariant, since nothing currently enforces it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

imho, the concern is overblown: the upgrade instructions should be already ordered, since adding out-of-order version on top of the file is not something that could happen (new release = version number increments) or should happen (you logically never "upgrade" to older version, and the document is also always logically read bottom-to-top).
apart from that the "silent error" is factually incorrect: even if an out-of-order entry did slip in, UPGRADE_FAMILIES dedups by position, while table components render UPGRADE_VERSIONS in array order - so misorder would surface directly in the rendered table and get caught immediately, not silently.

i had Claude trace the consumers to confirm - the newest-first order is already relied on by UPGRADE_FAMILIES and every table/step component; so ordering is already load-bearing across all the UPGRADE_VERSIONS consumers, not just this Set.

since that is such a corner case and ordering - although already logical - is not enforced, i think adding comment will suffice - will commit it asap

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done: 5de6f49

if (!v.patch || !v.baseVersion) continue;
if (!seen.has(v.baseVersion)) {
seen.add(v.baseVersion);
latest.add(v.version);
}
}
return latest;
})();
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import { UPGRADE_VERSIONS, UPGRADE_FAMILIES, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, UPGRADE_FAMILIES, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { Products } from '~/models/site.models';
import LinuxUpgradeSteps from '~/components/upgrade-instructions/LinuxUpgradeSteps.astro';
import WindowsUpgradeSteps from '~/components/upgrade-instructions/WindowsUpgradeSteps.astro';
Expand Down Expand Up @@ -42,8 +42,8 @@ const familyVersions = UPGRADE_VERSIONS.filter((v) => v.family === family);
const headings = familyVersions.map((v) => ({
depth: 2,
slug: v.anchor,
text: v.patch
? `Upgrading ThingsBoard to latest ${v.baseVersion} (${v.displayVersion})`
text: v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard to ${v.displayVersion}`,
}));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
import { UPGRADE_VERSIONS, UPGRADE_FAMILIES, getFamilySlug } from '~/models/upgrade-instructions';
import { UPGRADE_VERSIONS, UPGRADE_FAMILIES, LATEST_PATCH_VERSIONS, getFamilySlug } from '~/models/upgrade-instructions';
import { Products } from '~/models/site.models';
import LinuxUpgradeSteps from '~/components/upgrade-instructions/LinuxUpgradeSteps.astro';
import WindowsUpgradeSteps from '~/components/upgrade-instructions/WindowsUpgradeSteps.astro';
Expand Down Expand Up @@ -42,8 +42,8 @@ const familyVersions = UPGRADE_VERSIONS.filter((v) => v.family === family);
const headings = familyVersions.map((v) => ({
depth: 2,
slug: v.anchor,
text: v.patch
? `Upgrading ThingsBoard PE to latest ${v.baseVersion} (${v.displayVersion})`
text: v.patch && v.baseVersion !== v.displayVersion && LATEST_PATCH_VERSIONS.has(v.version)
? `Upgrading ThingsBoard PE to ${v.displayVersion} (latest ${v.baseVersion} patch)`
: `Upgrading ThingsBoard PE to ${v.displayVersion}`,
}));

Expand Down