Fail fast on missing psa-systems org secrets, and stop shipping the old org's update URL (LC-594) #564
Loading…
Reference in a new issue
No description provided.
Delete branch "chore/lc594-psa-systems-ci-secrets"
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?
Closes LC-594.
What the ticket asked for was already half done
The
A8N_TOOLS_*->PSA_SYSTEMS_*rename landed yesterday in770f3cb, and it works. I verified it empirically rather than by reading: the OCI build and both desktop builds have run green onmainsince the move (runs 26948/26949/26950), soPSA_SYSTEMS_PRIVATE_PACKAGE_OWNER,PSA_SYSTEMS_PRIVATE_PACKAGE_PATandRUNS_ON_OPENSUSE_BASE_LATESTall resolve in the new org. No workflow references ana8nname any more except one historical comment.What was left is the release path, which has never run in psa-systems.
create-release.ymlhas fired once ever (2026-06-24, pre-move) andpublish-release.ymlonce, where it failed. Everything they need is org-level, and org values do not follow a repo across orgs.Fail fast instead of failing deep
publish-release.ymlonly fires on av*tag, so a missing org value surfaces twenty-odd minutes into a release rather than in CI. One of them would not have surfaced at all:DESKTOP_UPDATE_PUBLIC_KEYis passed as a build-arg with an empty default, and an empty key makes the updater returnNotConfiguredand refuse every update. An unset variable therefore ships binaries with a permanently dead self-updater, discoverable only by users, and unfixable for those users precisely because self-update is the thing that broke.The new preflight step checks all four values before any build work and names every missing one in a single line. The existing late guard on the signing key stays as defence in depth.
create-release.ymlgets the same treatment forFORGEJO_PAT, so a missing token reports its own name instead of a 401 from a malformedAuthorizationheader.The stale org that was still compiled into the product
DEFAULT_UPDATE_URLindesktop/src/update.rsstill read.../api/packages/a8n-tools/generic/lets-chat. Shipped binaries would have polled an owner CI no longer publishes under.Rather than swap one hardcoded org for another, the publish workflow now derives the URL from the same
PACKAGE_OWNERit uploads to and injects it viaoption_env!, mirroring howLETS_CHAT_UPDATE_PUBLIC_KEYalready works. The upload destination and the compiled-in default now come from one value and cannot drift on the next org move. The in-source literal remains as the fallback for builds that inject nothing.Verification
Both build-time arms were checked directly, not assumed: with a distinct value injected the injected value wins, and with an empty one it falls back. My first attempt at this check was vacuous (I injected a value identical to the fallback, so all three cases printed the same string) and I redid it.
The preflight nu script was executed locally on nu 0.112.2 in both the all-present and partially-missing cases, and every nu step in both workflows parses under
nu --ide-check. The regression test asserts the absence of the stale owner rather than a fixed URL, since a release build legitimately compiles in a different string; it fails against the old constant.just checkand the fulljust testsuite are green.Needs you, not code
I could not read the org variables directly: my token lacks
read:organizationandread:package, so presence of the release-only values is inferred, not confirmed. Worth a look in the psa-systems org settings before the next release:DESKTOP_UPDATE_SIGNING_KEYandDESKTOP_UPDATE_PUBLIC_KEYare lets-chat-specific, no sibling repo uses them, and they are not repo-level here (repo secrets are empty, and the only repo variable isLETS_CHAT_UPDATE_URL). If they lived in the a8n-tools org they are gone, and the key pair has to be the same pair as before or already-shipped clients will reject the new manifest.FORGEJO_PATneedswrite:repository.The preflight turns any of these being absent into an immediate, named failure rather than a broken release, so this is no longer urgent, only worth doing before you cut a tag.
🤖 Generated with Claude Code
https://claude.ai/code/session_01BE9k4nWNUhPrjte9BcvASg
Follow-up after reading the org directly with a scoped token, which resolves the "needs you, not code" section of the description. Two corrections and one confirmation.
Corrected: the package owner is
psa-systems-private, notpsa-systems. The org variable resolves to the former, and that is where thelets-chatgeneric package and container images actually live;psa-systemsholds the mokosh and vervain packages. The fallback literal in the first commit named the wrong one and is fixed in0abe6bb. Release builds were correct either way, since they derive the URL from the same variable they upload with, which is precisely why deriving it was worth doing.Confirmed:
DESKTOP_UPDATE_SIGNING_KEYandDESKTOP_UPDATE_PUBLIC_KEYare absent at org level, with no repo-level secrets to fall back on. The nextv*tag would have shipped desktop binaries with a permanently dead self-updater and no failure anywhere in CI. The preflight in this PR stops that release instead, which is the whole point of it.FORGEJO_PATandPSA_SYSTEMS_PRIVATE_PACKAGE_PATare both present.Out of scope, filed as LC-607: the update channel is already broken end to end, independent of this PR. The packages owner is a private org, so an anonymous manifest fetch is 401 and no end user can reach it; and the
latestpackage version holds the six binaries but nolatest.jsonorlatest.json.sig, so even an authenticated fetch 404s. Recovering the signing pair is also not merely "create a secret": the public key is compiled into already-distributed binaries, so the restored pair must be the same pair or those clients reject every future manifest.This PR remains what it was: fail fast instead of failing deep, and stop compiling a stale org into the product. It does not fix distribution, and shouldn't.