diff --git a/.ci/scripts/compute-release.mjs b/.ci/scripts/compute-release.mjs index 85729cd..686e313 100644 --- a/.ci/scripts/compute-release.mjs +++ b/.ci/scripts/compute-release.mjs @@ -86,16 +86,50 @@ function parseCommit(subject, body = "") { return { type, scope, description, bump } } -function getLatestTag() { +function getAllTags() { try { - const tags = git("tag", "--list", "v*.*.*", "--sort=-v:refname") - const first = tags.split("\n").map((line) => line.trim()).find(Boolean) - return first ?? null + return git("tag", "--list", "v*.*.*", "--sort=-v:refname") + .split("\n") + .map((line) => line.trim()) + .filter(Boolean) + } catch { + return [] + } +} + +function getPreviousTag(tag) { + const tags = getAllTags() + const index = tags.indexOf(tag) + return index >= 0 && index + 1 < tags.length ? tags[index + 1] : null +} + +function getTagPublishedAt(tag) { + try { + return git("log", "-1", "--format=%aI", tag) } catch { return null } } +function toManifestCommits(commits) { + return commits.map((commit) => ({ + sha: commit.sha, + shortSha: commit.shortSha, + subject: commit.subject, + author: commit.author, + type: commit.type, + })) +} + +function writeManifest(manifest) { + mkdirSync(outputDir, { recursive: true }) + writeFileSync(join(outputDir, "release-manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`, "utf8") +} + +function getLatestTag() { + return getAllTags()[0] ?? null +} + function getCommitsSince(tag) { const range = tag ? `${tag}..HEAD` : "HEAD" const raw = git( @@ -174,28 +208,25 @@ function main() { const commits = getCommitsSince(latestTag) if (commits.length === 0) { + const deployTag = latestTag ?? `v${baseFromTag}` + const deployVersion = baseFromTag + const displayCommits = latestTag ? getCommitsSince(getPreviousTag(latestTag)) : [] + const publishedAt = latestTag ? getTagPublishedAt(latestTag) : null + mkdirSync(outputDir, { recursive: true }) writeFileSync(join(outputDir, "release_notes.md"), "", "utf8") - writeFileSync( - join(outputDir, "release-manifest.json"), - `${JSON.stringify( - { - version: baseFromTag, - tag: latestTag ?? `v${baseFromTag}`, - publishedAt: null, - releaseUrl: latestTag ? buildReleaseUrl(latestTag) : "", - commits: [], - }, - null, - 2, - )}\n`, - "utf8", - ) + writeManifest({ + version: deployVersion, + tag: deployTag, + publishedAt, + releaseUrl: latestTag ? buildReleaseUrl(latestTag) : "", + commits: toManifestCommits(displayCommits), + }) writeGithubOutput({ should_release: "false", - version: baseFromTag, - tag: latestTag ?? `v${baseFromTag}`, + version: deployVersion, + tag: deployTag, bump: "none", release_url: latestTag ? buildReleaseUrl(latestTag) : "", }) @@ -213,18 +244,12 @@ function main() { tag, publishedAt, releaseUrl, - commits: commits.map((commit) => ({ - sha: commit.sha, - shortSha: commit.shortSha, - subject: commit.subject, - author: commit.author, - type: commit.type, - })), + commits: toManifestCommits(commits), } mkdirSync(outputDir, { recursive: true }) writeFileSync(join(outputDir, "release_notes.md"), releaseNotes, "utf8") - writeFileSync(join(outputDir, "release-manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`, "utf8") + writeManifest(manifest) writeGithubOutput({ should_release: "true", diff --git a/Dockerfile.frontend b/Dockerfile.frontend index 860e462..66bcc50 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -27,7 +27,7 @@ COPY components components COPY lib lib COPY shared shared COPY entities entities -RUN mkdir -p public +COPY public public COPY hooks hooks ENV NEXT_TELEMETRY_DISABLED=1 RUN npm run build -w @mmapp/contracts \ diff --git a/app/(main)/releases/page.tsx b/app/(main)/releases/page.tsx index 451fb68..86bd37c 100644 --- a/app/(main)/releases/page.tsx +++ b/app/(main)/releases/page.tsx @@ -7,17 +7,22 @@ import { readReleaseManifest } from "@/lib/release-manifest" import { cn } from "@/lib/utils" import { ExternalLinkIcon } from "lucide-react" -function formatPublishedAt(value: string | null): string { - if (!value) return "Локальная сборка" - return new Intl.DateTimeFormat("ru-RU", { - dateStyle: "long", - timeStyle: "short", - }).format(new Date(value)) +export const dynamic = "force-dynamic" + +function formatPublishedAt(value: string | null, isProdBuild: boolean): string { + if (value) { + return new Intl.DateTimeFormat("ru-RU", { + dateStyle: "long", + timeStyle: "short", + }).format(new Date(value)) + } + return isProdBuild ? "Прод-сборка" : "Локальная сборка" } export default function ReleasesPage() { const manifest = readReleaseManifest() const version = getAppVersion() + const isProdBuild = !version.endsWith("-dev") const releaseUrl = getReleaseUrl() || manifest.releaseUrl || null const commits = manifest.commits @@ -50,7 +55,7 @@ export default function ReleasesPage() {
{formatAppVersionLabel(version)} - {formatPublishedAt(manifest.publishedAt)} + {formatPublishedAt(manifest.publishedAt, isProdBuild)}

Версия формируется автоматически от базы v1.0.0 по Conventional Commits.