3223a5ced7
Stale package.json создавал ложное впечатление rollback'а: staging
показывал "v1.2.0" хотя последний tag — v1.2.2 (package.json не bump'ился
со времён v1.2.0 release).
Vote A — branch builds НЕ используют package.json как version label.
Vite определяет channel:
serverTag != none → что прод/staging RUNS
clientTag → что build'ил CI tag pipeline (CI_COMMIT_TAG set)
CI без tag → 'dev' literal (staging / branch CI build)
локально → 'local' literal (pnpm dev)
Detection через новый __APP_CI__ define из process.env.CI (GitLab сетает
CI=true). Local pnpm dev: CI undefined → channel='local'.
package.json.version всё ещё инжектится как __APP_VERSION__ и видна в
tooltip badge'а как 'floor vX.Y.Z' — не как primary label.
Files:
- vite.config.ts: + APP_CI from process.env.CI
- src/vite-env.d.ts: + __APP_CI__ declare
- src/components/version/useAppVersion.ts: + clientCI
- src/components/version/VersionBadge.tsx: channel logic вместо fallback
Verify all three modes:
local → 'local · {commit}'
CI branch → 'dev · {commit}'
CI tag v1.3.1 → 'v1.3.1 · {commit}'
Tests: 116 pass.
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import { useAppVersion } from './useAppVersion'
|
||
|
||
/**
|
||
* Subtle version indicator в header. Показывает client version + short commit.
|
||
*
|
||
* <p>Hover/title attribute exposes полную идентификацию (server tag, build time).
|
||
* Используется как secondary affordance для эксплуатационной диагностики
|
||
* (юзер скриншотит badge в bug report → ops знает точную сборку).
|
||
*
|
||
* <p>Если update available — badge подсвечивается dot indicator. Banner делает
|
||
* primary CTA, badge — passive signal.
|
||
*/
|
||
export function VersionBadge() {
|
||
const {
|
||
clientVersion,
|
||
clientTag,
|
||
clientCI,
|
||
clientCommit,
|
||
clientBuiltAt,
|
||
serverVersion,
|
||
serverCommit,
|
||
serverTag,
|
||
updateAvailable,
|
||
} = useAppVersion()
|
||
|
||
// Channel-based label per "Vote A" — НЕ показываем package.json fallback
|
||
// как версию когда tag'а нет. Stale package.json (e.g. 1.2.0 когда уже
|
||
// выпущен v1.2.2) создавал ложное впечатление rollback'а.
|
||
//
|
||
// Channels:
|
||
// serverTag real — что прод/staging RUNS (most authoritative)
|
||
// clientTag — что build'ил CI tag pipeline
|
||
// CI без tag — 'dev' (staging / branch CI build)
|
||
// no CI no tag — 'local' (pnpm dev на машине разработчика)
|
||
//
|
||
// package.json.version используется ТОЛЬКО в tooltip как build-time floor
|
||
// — пользователь не видит его если не наведёт.
|
||
const displayVersion =
|
||
serverTag && serverTag !== 'none'
|
||
? serverTag
|
||
: clientTag
|
||
? `v${clientTag}`
|
||
: clientCI
|
||
? 'dev'
|
||
: 'local'
|
||
|
||
const tooltip = [
|
||
`client: ${
|
||
clientTag ? `v${clientTag}` : clientCI ? `dev (floor v${clientVersion})` : `local (floor v${clientVersion})`
|
||
} (${clientCommit})`,
|
||
`server: ${serverTag || serverVersion} (${serverCommit ?? '...'})`,
|
||
`built: ${clientBuiltAt}`,
|
||
].join('\n')
|
||
|
||
return (
|
||
<span
|
||
className="inline-flex items-center gap-1.5 text-mono text-mute select-none"
|
||
title={tooltip}
|
||
>
|
||
{updateAvailable && (
|
||
<span
|
||
aria-label="Доступна новая версия"
|
||
className="inline-block w-1.5 h-1.5 rounded-full bg-accent animate-pulse"
|
||
/>
|
||
)}
|
||
<span>{displayVersion}</span>
|
||
<span className="text-mute/70">·</span>
|
||
<span>{(serverCommit || clientCommit).substring(0, 8)}</span>
|
||
</span>
|
||
)
|
||
}
|