feat: update Dockerfile and release management scripts
Docker images / prepare-release (push) Successful in 6s
Docker images / backend-image (push) Successful in 1m45s
Docker images / frontend-image (push) Successful in 1m37s
Docker images / updater-image (push) Successful in 37s
Docker images / notify-webhook (push) Has been skipped
Docker images / publish-release (push) Successful in 6s

- Replaced the public directory creation step with a direct copy in the Dockerfile for improved build efficiency.
- Enhanced the compute-release script to retrieve all tags and manage release manifests more effectively, including better handling of published timestamps and commit details.
- Updated the ReleasesPage component to conditionally format the published date based on the build type, improving user clarity on release status.
This commit is contained in:
Denozordec
2026-05-12 17:39:50 +07:00
parent 7207d1b749
commit 35876fcd6f
3 changed files with 67 additions and 37 deletions
+53 -28
View File
@@ -86,16 +86,50 @@ function parseCommit(subject, body = "") {
return { type, scope, description, bump } return { type, scope, description, bump }
} }
function getLatestTag() { function getAllTags() {
try { try {
const tags = git("tag", "--list", "v*.*.*", "--sort=-v:refname") return git("tag", "--list", "v*.*.*", "--sort=-v:refname")
const first = tags.split("\n").map((line) => line.trim()).find(Boolean) .split("\n")
return first ?? null .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 { } catch {
return null 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) { function getCommitsSince(tag) {
const range = tag ? `${tag}..HEAD` : "HEAD" const range = tag ? `${tag}..HEAD` : "HEAD"
const raw = git( const raw = git(
@@ -174,28 +208,25 @@ function main() {
const commits = getCommitsSince(latestTag) const commits = getCommitsSince(latestTag)
if (commits.length === 0) { 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 }) mkdirSync(outputDir, { recursive: true })
writeFileSync(join(outputDir, "release_notes.md"), "", "utf8") writeFileSync(join(outputDir, "release_notes.md"), "", "utf8")
writeFileSync( writeManifest({
join(outputDir, "release-manifest.json"), version: deployVersion,
`${JSON.stringify( tag: deployTag,
{ publishedAt,
version: baseFromTag,
tag: latestTag ?? `v${baseFromTag}`,
publishedAt: null,
releaseUrl: latestTag ? buildReleaseUrl(latestTag) : "", releaseUrl: latestTag ? buildReleaseUrl(latestTag) : "",
commits: [], commits: toManifestCommits(displayCommits),
}, })
null,
2,
)}\n`,
"utf8",
)
writeGithubOutput({ writeGithubOutput({
should_release: "false", should_release: "false",
version: baseFromTag, version: deployVersion,
tag: latestTag ?? `v${baseFromTag}`, tag: deployTag,
bump: "none", bump: "none",
release_url: latestTag ? buildReleaseUrl(latestTag) : "", release_url: latestTag ? buildReleaseUrl(latestTag) : "",
}) })
@@ -213,18 +244,12 @@ function main() {
tag, tag,
publishedAt, publishedAt,
releaseUrl, releaseUrl,
commits: commits.map((commit) => ({ commits: toManifestCommits(commits),
sha: commit.sha,
shortSha: commit.shortSha,
subject: commit.subject,
author: commit.author,
type: commit.type,
})),
} }
mkdirSync(outputDir, { recursive: true }) mkdirSync(outputDir, { recursive: true })
writeFileSync(join(outputDir, "release_notes.md"), releaseNotes, "utf8") writeFileSync(join(outputDir, "release_notes.md"), releaseNotes, "utf8")
writeFileSync(join(outputDir, "release-manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`, "utf8") writeManifest(manifest)
writeGithubOutput({ writeGithubOutput({
should_release: "true", should_release: "true",
+1 -1
View File
@@ -27,7 +27,7 @@ COPY components components
COPY lib lib COPY lib lib
COPY shared shared COPY shared shared
COPY entities entities COPY entities entities
RUN mkdir -p public COPY public public
COPY hooks hooks COPY hooks hooks
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build -w @mmapp/contracts \ RUN npm run build -w @mmapp/contracts \
+8 -3
View File
@@ -7,17 +7,22 @@ import { readReleaseManifest } from "@/lib/release-manifest"
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils"
import { ExternalLinkIcon } from "lucide-react" import { ExternalLinkIcon } from "lucide-react"
function formatPublishedAt(value: string | null): string { export const dynamic = "force-dynamic"
if (!value) return "Локальная сборка"
function formatPublishedAt(value: string | null, isProdBuild: boolean): string {
if (value) {
return new Intl.DateTimeFormat("ru-RU", { return new Intl.DateTimeFormat("ru-RU", {
dateStyle: "long", dateStyle: "long",
timeStyle: "short", timeStyle: "short",
}).format(new Date(value)) }).format(new Date(value))
} }
return isProdBuild ? "Прод-сборка" : "Локальная сборка"
}
export default function ReleasesPage() { export default function ReleasesPage() {
const manifest = readReleaseManifest() const manifest = readReleaseManifest()
const version = getAppVersion() const version = getAppVersion()
const isProdBuild = !version.endsWith("-dev")
const releaseUrl = getReleaseUrl() || manifest.releaseUrl || null const releaseUrl = getReleaseUrl() || manifest.releaseUrl || null
const commits = manifest.commits const commits = manifest.commits
@@ -50,7 +55,7 @@ export default function ReleasesPage() {
<CardContent className="space-y-3"> <CardContent className="space-y-3">
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<span className="text-2xl font-semibold tracking-tight">{formatAppVersionLabel(version)}</span> <span className="text-2xl font-semibold tracking-tight">{formatAppVersionLabel(version)}</span>
<span className="text-sm text-muted-foreground">{formatPublishedAt(manifest.publishedAt)}</span> <span className="text-sm text-muted-foreground">{formatPublishedAt(manifest.publishedAt, isProdBuild)}</span>
</div> </div>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
Версия формируется автоматически от базы <span className="font-mono">v1.0.0</span> по Conventional Commits. Версия формируется автоматически от базы <span className="font-mono">v1.0.0</span> по Conventional Commits.