apply resolves a GitHub App unconditionally — a databases-only manifest cannot apply without one #103

Closed
opened 2026-07-19 12:10:03 +00:00 by dan-claude-bot · 0 comments
dan-claude-bot commented 2026-07-19 12:10:03 +00:00 (Migrated from github.com)

Found by the 2026-07-19 release drill (two live Coolify 4.1.2 instances).

What happened

A manifest declaring only databases (applications: {}) against a fresh instance:

2 change(s), 0 orphan(s)
no GitHub App bound for dan-claude-bot/drill-widget

  looked for:  github_apps["dan-claude-bot/drill-widget"], then github_apps["drill-widget"]

The plan renders, then preflight dies. src/cli.ts:1277-1280 resolves the server and the GitHub App before building the executor:

const serverUuid = await ctx.client.serverUuid(ctx.binding.server);
const githubAppUuid = await ctx.client.githubAppUuid(
  githubAppNameFor(ctx.bindings, orgRepo),
);

githubAppNameFor throws when the repo has no github_apps binding — regardless of whether the manifest declares any applications. A GitHub App only matters for POST /applications/private-github-app; databases and services never touch it.

In the drill this blocked the entire A→B promotion until we seeded a placeholder GithubApp row on both instances and bound a name that is never used — pure ceremony.

Why it matters

Infra-only projects (a project that carries the databases/services other projects share) are a real shape, and the first cast apply a new adopter runs is very likely databases-first. Requiring a registered GitHub App — which today involves the browser-manifest registration flow — to create a Redis is a hard onboarding wall.

Suggested fix

Resolve the GitHub App lazily: only when desired contains at least one application (mirroring how s3DestinationUuid is already optional). The refusal for application-bearing manifests stays exactly as is.

Related observation from the same run: manifest.yaml requires applications: to be present per environment (empty {} accepted) — if that stays required, the error for an omitted block might point at applications: {} as the empty form.

🤖 Filed from the release-drill session.

Found by the 2026-07-19 release drill (two live Coolify 4.1.2 instances). ## What happened A manifest declaring only databases (`applications: {}`) against a fresh instance: ``` 2 change(s), 0 orphan(s) no GitHub App bound for dan-claude-bot/drill-widget looked for: github_apps["dan-claude-bot/drill-widget"], then github_apps["drill-widget"] ``` The plan renders, then preflight dies. `src/cli.ts:1277-1280` resolves the server **and** the GitHub App before building the executor: ```ts const serverUuid = await ctx.client.serverUuid(ctx.binding.server); const githubAppUuid = await ctx.client.githubAppUuid( githubAppNameFor(ctx.bindings, orgRepo), ); ``` `githubAppNameFor` throws when the repo has no `github_apps` binding — regardless of whether the manifest declares any applications. A GitHub App only matters for `POST /applications/private-github-app`; databases and services never touch it. In the drill this blocked the entire A→B promotion until we seeded a placeholder `GithubApp` row on both instances and bound a name that is never used — pure ceremony. ## Why it matters Infra-only projects (a project that carries the databases/services other projects share) are a real shape, and the first `cast apply` a new adopter runs is very likely databases-first. Requiring a registered GitHub App — which today involves the browser-manifest registration flow — to create a Redis is a hard onboarding wall. ## Suggested fix Resolve the GitHub App lazily: only when `desired` contains at least one application (mirroring how `s3DestinationUuid` is already optional). The refusal for application-bearing manifests stays exactly as is. Related observation from the same run: `manifest.yaml` requires `applications:` to be present per environment (empty `{}` accepted) — if that stays required, the error for an omitted block might point at `applications: {}` as the empty form. 🤖 Filed from the release-drill session.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/cast#103
No description provided.