Promote scripts/register-github-app.sh to a proper subcommand: cast github-app register #5
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#5
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
The register script's env-var-pile interface produced three real footguns in one live provisioning run (incubator prod-migration, 2026-07-12):
APP_NAMEsilently decouples from state. The value must equalgithub_apps.<repo>inenvironments.yamlor every latercast applyfails to resolve the source — but the script takes it as a free-form env var and can't know it's wrong. The operator passed the GitHub App's display name instead of the state value; nothing caught it.CAST_STATE=.+ a relativePRIVATE_KEY_FILEmeans running from the wrong directory fails (or worse, half-works) depending on cwd. A typo'd script path (~/local/…vs~/.local/…) added a round of confusion the CLI itself would never have.WEBHOOK_SECRETis required even when the App's webhook is inactive — the correct configuration for a tailnet-only Coolify where deliveries can never arrive and deploys are CI-triggered. Operators must invent a placeholder (openssl rand -hex 16) to satisfy the check.Proposal
github_apps.<repo>inenvironments.yamlinstead of accepting a free-form name — the footgun disappears structurally.--client-secret-stdin(mirroringdocker login --password-stdin) keeps the secret out of shell history and process listings; the current script takes it as an env var on the command line.--webhook-secretoptional; when omitted, generate a random value and say so (webhook-inactive Apps are a legitimate, arguably preferable, configuration for clone-only use).Scope note
This stays a bootstrap-time, operator-run act — it doesn't blur the apply/diff reconciliation contract (semantics.md). It's the same one-time provisioning category as
cast server add, which already earned CLI status.🤖 Generated with Claude Code
Subsumed by #7. The register subcommand proposed here stays exactly as specced — #7 keeps it as
cast github-app register— but it lands as the floor thatcast github-app createfalls onto, rather than as a standalone wrapper around the env-var script.Worth noting why, since it reframes the three footguns above: they are symptoms of the tool transcribing values a human read off a web page. The App Manifest flow lets cast obtain those values instead (it is the only programmatic way to create a GitHub App — there is no REST endpoint, and
ghhas noappsubcommand). Footgun 1 dissolves because the Coolify-facing name is read from state rather than accepted as a flag; footgun 3 dissolves because the conversion response carries a realwebhook_secret, so nobody has to invent a placeholder.Leaving this open as the register-side spec; close it in favour of #7 if you'd rather track one issue.
Closing in favour of #7, taking up the invitation in the comment above ("close it in favour of #7 if you'd rather track one issue").
Nothing in this spec is dropped. #7 keeps the register subcommand exactly as specced here —
cast github-app register— as the floor thatcast github-app createfalls onto. The three footguns catalogued here are the motivation #7 inherits, and two of them dissolve structurally under the manifest flow rather than needing to be fixed by hand:APP_NAMEdecoupled from state) — the Coolify-facing name is read fromgithub_apps.<repo>instead of accepted as a flagWEBHOOK_SECRETrequired for a webhook-inactive App) — the conversion response carries a realwebhook_secret, so nobody invents a placeholderFootgun 2 (path/cwd fragility) stays a plain CLI-ergonomics item under #7.
The working path is unaffected meanwhile:
scripts/register-github-app.shstill does the job, with theAPP_NAME-must-match-state constraint documented in its header.