What happened
Both releases today shipped a migration that could half-land, and the second one did.
v0.3.0 renamed the values a caller reads. simplycubed/corp#66 upgraded the caller to match, passed its own CI, and merged — while SIMPLYCUBED_AZURE_OPENAI_API_KEY did not yet exist at organisation scope. From that moment corp could not run: every command would have resolved an empty key. It was broken for about an hour, and nothing anywhere said so.
With one install that is an inconvenience. With adopters it is an outage, caused by merging a pull request that looked entirely healthy.
Why nothing caught it
preflight checks the four values, and #115 made it name the section a missing one belongs in. But it only runs inside a job that already has them injected, which is after the merge that needs them. The window between "caller now reads the new names" and "the new names exist" is invisible to every check we have.
The values are also readable by name without reading them:
$ gh variable list --org simplycubed
$ gh secret list -R simplycubed/corp
So the check is possible. It just does not exist.
Suggested shape
A mode of preflight that asks GitHub what the repository can actually see, rather than reading its own environment. Something like:
$ simplycubed preflight --remote
SIMPLYCUBED_GH_APP_CLIENT_ID variable ok (org)
SIMPLYCUBED_GH_APP_PRIVATE_KEY secret ok (org)
SIMPLYCUBED_AZURE_OPENAI_ENDPOINT variable ok (org)
SIMPLYCUBED_AZURE_OPENAI_API_KEY secret MISSING
Names only. It must never read a secret's value, and it does not need to: the failure being guarded against is absence.
Resolution has to consider both scopes, and the org/repo distinction is exactly where today's confusion sat: the key was set on simplycubed/code at repository scope and looked done, while corp could not see it. A check that says where a value resolved from would have made that obvious in one line.
Open question
Where should this run so it actually blocks?
- as a step in the adopter's own CI, so a caller upgrade cannot merge green while its values are missing
- as a step
init --workflow writes, so every install gets it
- manually before merging, which is what documentation alone amounts to
The first is the only one that makes the ordering enforceable rather than remembered. It needs a token that can list variables and secrets, which the App's own installation token cannot do, so this needs thinking through rather than assuming.
Acceptance
What happened
Both releases today shipped a migration that could half-land, and the second one did.
v0.3.0 renamed the values a caller reads.
simplycubed/corp#66upgraded the caller to match, passed its own CI, and merged — whileSIMPLYCUBED_AZURE_OPENAI_API_KEYdid not yet exist at organisation scope. From that momentcorpcould not run: every command would have resolved an empty key. It was broken for about an hour, and nothing anywhere said so.With one install that is an inconvenience. With adopters it is an outage, caused by merging a pull request that looked entirely healthy.
Why nothing caught it
preflightchecks the four values, and #115 made it name the section a missing one belongs in. But it only runs inside a job that already has them injected, which is after the merge that needs them. The window between "caller now reads the new names" and "the new names exist" is invisible to every check we have.The values are also readable by name without reading them:
So the check is possible. It just does not exist.
Suggested shape
A mode of
preflightthat asks GitHub what the repository can actually see, rather than reading its own environment. Something like:Names only. It must never read a secret's value, and it does not need to: the failure being guarded against is absence.
Resolution has to consider both scopes, and the org/repo distinction is exactly where today's confusion sat: the key was set on
simplycubed/codeat repository scope and looked done, whilecorpcould not see it. A check that says where a value resolved from would have made that obvious in one line.Open question
Where should this run so it actually blocks?
init --workflowwrites, so every install gets itThe first is the only one that makes the ordering enforceable rather than remembered. It needs a token that can list variables and secrets, which the App's own installation token cannot do, so this needs thinking through rather than assuming.
Acceptance
docs/setup.mdsays which values a public repository must hold itself, because a public repo cannot read private-visibility organisation secrets andsimplycubed/codeis the standing example