fix(version): resolve git metadata from env/SOURCE_COMMIT for Coolify builds
Coolify strips .git from the build context, so git CLI calls in generate:version-info fail during Docker builds. The script now resolves metadata in priority order: GIT_* env overrides, then SOURCE_COMMIT (Coolify's injected build arg, shortened to 7 chars), then git CLI fallback for local builds. Dockerfile passes the ARGs through as ENV before the build; DEPLOYMENT.md documents the required 'Include Source Commit in Build' setting.
This commit is contained in:
parent
8fe7276ba3
commit
10560c1446
3 changed files with 57 additions and 10 deletions
|
|
@ -205,6 +205,8 @@ Recommended flow:
|
|||
4. Coolify waits for `/api/health` to come back 200, then routes traffic.
|
||||
5. If a new migration shipped with that deploy, run it via `docker exec` or a Scheduled Task (Sec. 7).
|
||||
|
||||
> **Version metadata in builds.** The image build embeds git info into `src/generated/versionInfo.json` (shown in the admin VersionOverlay and on `/api/version`). Coolify **deletes `.git`** from the build context, so the build reads the commit SHA from the `SOURCE_COMMIT` build arg instead of `git` (see the Dockerfile's `ARG SOURCE_COMMIT` block). For that to work, enable **"Include Source Commit in Build"** under the application's *Advanced* settings (and leave "Inject Build Args to Dockerfile" on, which is the default) — otherwise the version overlay falls back to `version` only. Tags, commit date, and commit subject have no Coolify equivalent and stay null on Coolify builds; local builds (`docker build`, `bun run dev`) still use real `git`.
|
||||
|
||||
No SSH, no `rsync`, no `systemctl`. The legacy `build/deploy.sh` (gitignored, the old SSH+systemd flow to `jmf-usrv-2404`) is **no longer used** — exclude it from future deploys. `bun run deploy` (the npm script) will still try to run it (it calls `postversion → bash ./build/deploy.sh`); don't run it from your local machine anymore, or remove that script entry from `package.json` once you've moved onto Coolify for good.
|
||||
|
||||
---
|
||||
|
|
|
|||
29
Dockerfile
29
Dockerfile
|
|
@ -62,9 +62,11 @@ RUN for i in 1 2 3; do \
|
|||
# Full install (incl. devDeps) + Next.js standalone build.
|
||||
FROM base AS builder
|
||||
# `git` is needed only at build time so `generate:version-info` can populate
|
||||
# commitHash / gitDescribe / commitDate in src/generated/versionInfo.json
|
||||
# (the script gracefully no-ops without it, but we want the metadata in the
|
||||
# admin VersionOverlay). Not carried into the runner image.
|
||||
# commitHash / gitDescribe / commitDate in src/generated/versionInfo.json. It
|
||||
# is the LOCAL-build fallback: Coolify strips `.git` from the build context,
|
||||
# so there the script reads the commit SHA from the SOURCE_COMMIT build arg
|
||||
# instead (see the ARG/ENV block above `RUN bun run build`). Not carried into
|
||||
# the runner image.
|
||||
RUN apk add --no-cache git
|
||||
WORKDIR /app
|
||||
COPY package.json bun.lock ./
|
||||
|
|
@ -101,6 +103,27 @@ ARG EMAIL_PORT_BUILD=587
|
|||
ENV PAYLOAD_SECRET=$PAYLOAD_SECRET_BUILD \
|
||||
EMAIL_HOST=$EMAIL_HOST_BUILD \
|
||||
EMAIL_PORT=$EMAIL_PORT_BUILD
|
||||
# Git metadata passthrough for `generate:version-info` (the script reads env
|
||||
# vars first). Coolify strips `.git` from the build context, so builds there
|
||||
# must get the commit SHA via build args: Coolify injects `ARG
|
||||
# SOURCE_COMMIT=<sha>` into the Dockerfile after each FROM only when "Include
|
||||
# Source Commit in Build" is enabled (application settings → Advanced) and
|
||||
# "Inject Build Args to Dockerfile" is on (default). The bare `ARG`
|
||||
# declarations below preserve that injected value (no `=default` reset), and
|
||||
# the `ENV` forwards it to `bun run build`. The GIT_* args are optional
|
||||
# overrides for other build environments; none of this ships to runtime.
|
||||
ARG SOURCE_COMMIT
|
||||
ARG GIT_TAG
|
||||
ARG GIT_DESCRIBE
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_COMMIT_DATE
|
||||
ARG GIT_COMMIT_SUBJECT
|
||||
ENV SOURCE_COMMIT=$SOURCE_COMMIT \
|
||||
GIT_TAG=$GIT_TAG \
|
||||
GIT_DESCRIBE=$GIT_DESCRIBE \
|
||||
GIT_COMMIT_HASH=$GIT_COMMIT_HASH \
|
||||
GIT_COMMIT_DATE=$GIT_COMMIT_DATE \
|
||||
GIT_COMMIT_SUBJECT=$GIT_COMMIT_SUBJECT
|
||||
RUN bun run build
|
||||
|
||||
# ─────────────────────────── runner ──────────────────────────────
|
||||
|
|
|
|||
|
|
@ -4,8 +4,20 @@
|
|||
* VersionOverlay via GET /api/version (the file is read at runtime so a fresh
|
||||
* post-bump regeneration rsync'd to the server shows up without a rebuild).
|
||||
*
|
||||
* Gracefully no-ops on missing git metadata (no .git, no tags) so the JSON
|
||||
* always exists with whatever fields are resolvable.
|
||||
* Git metadata resolution order (first non-empty wins):
|
||||
* 1. Environment variables — explicit overrides for CI systems that inject
|
||||
* metadata as env vars:
|
||||
* GIT_TAG, GIT_DESCRIBE, GIT_COMMIT_HASH, GIT_COMMIT_DATE, GIT_COMMIT_SUBJECT
|
||||
* 2. SOURCE_COMMIT — the commit SHA Coolify injects as a build arg when
|
||||
* "Include Source Commit in Build" is enabled (application settings →
|
||||
* Advanced). Coolify strips `.git` from the build context, so `git` is
|
||||
* unavailable there. Only the SHA is provided — tags, date, and subject
|
||||
* have no Coolify equivalent and stay null in that case.
|
||||
* 3. `git` from the project root — the local-dev path (and any build context
|
||||
* that still contains .git, e.g. a local `docker build`).
|
||||
*
|
||||
* Gracefully no-ops on missing git metadata (no .git, no tags, no env) so the
|
||||
* JSON always exists with whatever fields are resolvable.
|
||||
*/
|
||||
import { execSync } from "node:child_process";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
|
|
@ -25,6 +37,15 @@ function git(args: string): string | null {
|
|||
}
|
||||
}
|
||||
|
||||
function envVar(name: string): string | null {
|
||||
const value = process.env[name];
|
||||
return typeof value === "string" && value.length > 0 ? value : null;
|
||||
}
|
||||
|
||||
function shortCommit(sha: string): string {
|
||||
return sha.length > 7 ? sha.slice(0, 7) : sha;
|
||||
}
|
||||
|
||||
function readPackageVersion(): string | null {
|
||||
try {
|
||||
const pkg = JSON.parse(readFileSync(path.join(projectRoot, "package.json"), "utf8"));
|
||||
|
|
@ -36,11 +57,12 @@ function readPackageVersion(): string | null {
|
|||
|
||||
function main(): void {
|
||||
const version = readPackageVersion();
|
||||
const tag = git("describe --tags --always --abbrev=0");
|
||||
const gitDescribe = git("describe --tags --always --abbrev=7");
|
||||
const commitHash = git("rev-parse --short HEAD");
|
||||
const commitDate = git("log -1 --format=%cI");
|
||||
const commitSubject = git("log -1 --format=%s");
|
||||
const tag = envVar("GIT_TAG") ?? git("describe --tags --always --abbrev=0");
|
||||
const gitDescribe = envVar("GIT_DESCRIBE") ?? git("describe --tags --always --abbrev=7");
|
||||
const rawCommit = envVar("GIT_COMMIT_HASH") ?? envVar("SOURCE_COMMIT");
|
||||
const commitHash = rawCommit ? shortCommit(rawCommit) : git("rev-parse --short HEAD");
|
||||
const commitDate = envVar("GIT_COMMIT_DATE") ?? git("log -1 --format=%cI");
|
||||
const commitSubject = envVar("GIT_COMMIT_SUBJECT") ?? git("log -1 --format=%s");
|
||||
const buildTime = new Date().toISOString();
|
||||
|
||||
const info = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue