Merge pull request #54 from claude-hdb/feat/source-commit-notice
feat(resolve): warn that apply cannot enable "Include Source Commit in Build" (#46)
This commit is contained in:
commit
7c6092dd87
3 changed files with 107 additions and 0 deletions
|
|
@ -638,6 +638,33 @@ one used — verified against a live private clone.
|
|||
Coolify 4.1.2 services — configure hostnames manually in the Coolify UI`)
|
||||
once per run for every service that declared any. Set service hostnames
|
||||
in the Coolify UI by hand.
|
||||
- **"Include Source Commit in Build" cannot be enabled via the API in Coolify
|
||||
4.1.2 — `apply` warns instead.** A dockercompose application whose build
|
||||
consumes `SOURCE_COMMIT` as a **build arg** only receives it if the
|
||||
per-application setting *Include Source Commit in Build* is on; Coolify
|
||||
withholds it by default to preserve build cache. That setting
|
||||
(`ApplicationSetting.include_source_commit_in_build`, default `false`) has no
|
||||
API surface in 4.1.2: it appears in **zero** API controllers, and both the
|
||||
create and PATCH allowlists in `ApplicationsController.php` (l.914, l.2368)
|
||||
reject unrecognized keys outright (`"This field is not allowed."`), so cast
|
||||
cannot smuggle it through — sending it would fail the whole request. Its only
|
||||
writer is the Livewire *Advanced* tab
|
||||
(`app/Livewire/Project/Application/Advanced.php:128`), i.e. a human in the UI.
|
||||
Contrast `connect_to_docker_network`, which *is* in both allowlists and which
|
||||
`apply` therefore does set on create. So `desiredFromManifest` **warns** once
|
||||
per dockercompose application (`application <name> builds with dockercompose,
|
||||
but apply cannot enable "Include Source Commit in Build" on Coolify 4.1.2 …`)
|
||||
rather than pretending it is desired state. Enable it in the Coolify UI and
|
||||
redeploy if your image bakes the SHA in at build time.
|
||||
|
||||
**This toggle gates the build-time arg only.** Coolify's **runtime** injection
|
||||
of `SOURCE_COMMIT` is unconditional with respect to it
|
||||
(`ApplicationDeploymentJob.php:2949` — `if (! $forBuildTime || …)`
|
||||
short-circuits true at runtime), so a service that reads
|
||||
`process.env.SOURCE_COMMIT` per request does **not** need the toggle at all.
|
||||
What silently suppresses *that* value is an application-level env var of the
|
||||
same name (`ApplicationDeploymentJob.php:2950`) — a distinct trap, and the
|
||||
actual cause of a live box reporting `{"sha":"unknown"}`.
|
||||
- **The redis default image is an unverified extrapolation.** Coolify's
|
||||
"New Resource" wizard drives PostgreSQL version selection through a
|
||||
verified `postgres:<version>-alpine` image string; Redis has no version
|
||||
|
|
|
|||
|
|
@ -345,6 +345,34 @@ export function desiredFromManifest(
|
|||
return env;
|
||||
};
|
||||
for (const [name, app] of Object.entries(envSpec.applications)) {
|
||||
if (app.build.pack === "dockercompose") {
|
||||
// Coolify gates the SOURCE_COMMIT *build arg* behind a per-application
|
||||
// setting — `ApplicationSetting.include_source_commit_in_build`, default
|
||||
// false — and in 4.1.2 that setting has NO API surface. Verified against
|
||||
// the v4.1.2 source: it appears in zero API controllers, and both the
|
||||
// create and the PATCH allowlists in ApplicationsController.php (l.914,
|
||||
// l.2368) reject unrecognized keys outright ("This field is not
|
||||
// allowed."), so sending it would fail the whole request rather than be
|
||||
// quietly ignored. Its only writer is the Livewire Advanced tab
|
||||
// (app/Livewire/Project/Application/Advanced.php:128) — i.e. a human, in
|
||||
// the UI. Do NOT add it to `fields` below expecting apply to set it the
|
||||
// way it sets `connect_to_docker_network` (which *is* in the allowlist,
|
||||
// which is why that one works): apply would 422 on every run. Warning is
|
||||
// the only honest move — a manual step the tool knows about and does not
|
||||
// mention is one that gets forgotten, and this one fails green.
|
||||
//
|
||||
// Scope: the toggle gates the BUILD-time arg only. Coolify's *runtime*
|
||||
// injection of SOURCE_COMMIT is unconditional with respect to it
|
||||
// (ApplicationDeploymentJob.php:2949 — `if (! $forBuildTime || ...)`,
|
||||
// which short-circuits true at runtime), so a service that reads
|
||||
// process.env.SOURCE_COMMIT per request does not need this toggle at all.
|
||||
// What *does* silently suppress that runtime value is an application-level
|
||||
// env var of the same name (ApplicationDeploymentJob.php:2950) — a
|
||||
// different bug, tracked separately.
|
||||
console.warn(
|
||||
`application ${name} builds with dockercompose, but apply cannot enable "Include Source Commit in Build" on Coolify 4.1.2 — the setting is absent from the API's field allowlist. If the build consumes SOURCE_COMMIT as a build arg, enable it in the Coolify UI and redeploy; Coolify injects SOURCE_COMMIT at runtime regardless.`,
|
||||
);
|
||||
}
|
||||
desired.push({
|
||||
kind: "application",
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -305,7 +305,9 @@ environments:
|
|||
join(dir, ".infra", "env", "core.prod.env.template"),
|
||||
"PORT=3000\n",
|
||||
);
|
||||
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const { desired } = desiredFromManifest(dir, "prod", {});
|
||||
warn.mockRestore();
|
||||
expect(desired).toHaveLength(1);
|
||||
expect(desired[0]).toMatchObject({
|
||||
kind: "application",
|
||||
|
|
@ -325,6 +327,56 @@ environments:
|
|||
expect(desired[0].fields).not.toHaveProperty("healthcheck");
|
||||
expect(desired[0].fields).not.toHaveProperty("domains");
|
||||
});
|
||||
it('warns that apply cannot enable "Include Source Commit in Build" on a dockercompose app (unsettable via the Coolify 4.1.2 API)', () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "infra-co-"));
|
||||
mkdirSync(join(dir, ".infra"), { recursive: true });
|
||||
writeFileSync(
|
||||
join(dir, ".infra", "manifest.yaml"),
|
||||
`project: widget
|
||||
environments:
|
||||
prod:
|
||||
applications:
|
||||
core:
|
||||
source: { repo: acme/widget, branch: main }
|
||||
build: { pack: dockercompose, base_directory: /, compose_file: docker-compose.yaml }
|
||||
service_domains:
|
||||
api: ["https://api.widget.example.com"]
|
||||
`,
|
||||
);
|
||||
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const { desired } = desiredFromManifest(dir, "prod", {});
|
||||
expect(warn).toHaveBeenCalledTimes(1);
|
||||
expect(warn.mock.calls[0][0]).toMatch(/application core/);
|
||||
expect(warn.mock.calls[0][0]).toMatch(/Include Source Commit in Build/);
|
||||
expect(warn.mock.calls[0][0]).toMatch(/Coolify UI/);
|
||||
warn.mockRestore();
|
||||
// The setting is absent from Coolify 4.1.2's create/PATCH allowlists, which
|
||||
// reject unknown keys outright — so it must never reach `fields`, or apply
|
||||
// would 422 on every run. Guards the fix a future reader would reach for.
|
||||
expect(desired[0].fields).not.toHaveProperty(
|
||||
"include_source_commit_in_build",
|
||||
);
|
||||
});
|
||||
it("does not warn about the source-commit toggle for a non-dockercompose app (the build arg is a compose concern)", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "infra-co-"));
|
||||
mkdirSync(join(dir, ".infra"), { recursive: true });
|
||||
writeFileSync(
|
||||
join(dir, ".infra", "manifest.yaml"),
|
||||
`project: widget
|
||||
environments:
|
||||
prod:
|
||||
applications:
|
||||
site:
|
||||
source: { repo: acme/widget, branch: main }
|
||||
build: { pack: nixpacks, base_directory: / }
|
||||
domains: ["https://widget.example.com"]
|
||||
`,
|
||||
);
|
||||
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
desiredFromManifest(dir, "prod", {});
|
||||
expect(warn).not.toHaveBeenCalled();
|
||||
warn.mockRestore();
|
||||
});
|
||||
it("throws when the env is missing from the manifest", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "infra-co-"));
|
||||
mkdirSync(join(dir, ".infra"), { recursive: true });
|
||||
|
|
|
|||
Loading…
Reference in a new issue