Four GitHub Apps were reachable under three different key suffixes
(_PRIVATE_KEY, _KEY_, _SECRET) and their ids sat half in secrets, half
in variables. Each app now reads <APP>_ID from variables and
<APP>_PRIVATE_KEY from secrets:
vars.APP_ID / secrets.APP_PRIVATE_KEY -> GHAPP_HEADERS_*
secrets.APP_{ID,KEY}_APPROVE_AND_MERGE -> GHAPP_MERGEBOT_*
vars.PUSH_MAIN_APP_ID / secrets.PUSH_MAIN_APP_SECRET -> GHAPP_SYNC_*
secrets.PB_BOT_APP_{ID,PRIVATE_KEY} -> GHAPP_PBBOT_*
Values that are not credentials become variables, so a failing run shows
what it talked to instead of ***:
secrets.POCKETBASE_URL -> vars.POCKETBASE_URL
secrets.POCKETBASE_COLLECTION -> vars.POCKETBASE_COLLECTION
secrets.FRONTEND_URL -> vars.FRONTEND_URL (also replaces vars.SITE_URL)
The frontend endpoints shared three secrets where two suffice. Cache
revalidation and screenshot import have the same blast radius and merge;
the advisory ingest keeps its own secret because it feeds the update
helper on user systems:
REVALIDATE_SECRET, SCREENSHOT_IMPORT_SECRET -> FRONTEND_INGEST_SECRET
BREAKING_CHANGE_INGEST_SECRET -> FRONTEND_ADVISORY_SECRET
PAT_MICHEL ties infrastructure to one person and existed at both org and
repo level, so the repo copy silently shadowed the org one; it becomes
GH_CROSS_REPO_TOKEN.
On a merged PR labelled "breaking change", POST the PR number to the site's
/api/breaking-changes/ingest endpoint so it can show a temporary advisory on
the affected scripts. Uses pull_request_target (secrets available for fork
PRs) and never checks out PR code — it only forwards the number after merge.
The `labeled` trigger also covers labelling a PR after it has merged.
Requires repo secret BREAKING_CHANGE_INGEST_SECRET (matching the site) and an
optional SITE_URL variable (defaults to https://community-scripts.org).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TFBuZEp142Ei2PAfWqbMXT