Skip revoked GitHub tokens and queue one Satis build per release - #543
Merged
Merged
Conversation
The token resolver handed out stored tokens without checking them, so a revoked installation or user token failed everything it was passed to, including the Satis build. It now tries each one against the plugin's repo and moves on after a 401 or 404. PluginSyncService drops its own copy of the resolver and uses the shared one. Both webhook handlers now only act on the "published" release action, and the first delivery of a release claims it, so the per-repo webhook and the GitHub App webhook no longer queue a build each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes two problems in how plugin releases reach the Satis server.
The token resolver handed out whatever token it had stored without trying it. An installation token stops working when the app is uninstalled or loses access to a repo. A user can also revoke our access. We don't always hear about either, and a revoked token fails everything it's passed to. For a paid plugin that includes the Satis build. Satis then can't archive the package, and the version's dist is left pointing at the GitHub zipball, which our users can't download from a private repo.
The resolver now calls
GET /repos/{owner}/{repo}with the installation token, then the owner's token, and moves on to the next one if GitHub answers 401 or 404. Any other failure, like a rate limit or GitHub being down, doesn't count against a token because it says nothing about the token itself. The platform token is the last resort, so it isn't tried.PluginSyncServicehad its own copy of the resolver and now uses the shared one.SyncPluginReleasesused to resolve a token twice and now builds with the one it fetched releases with.Since the move to the GitHub App, release events can arrive twice: once through the old per-repo webhook and once through the App webhook. GitHub also sends
created,publishedandreleasedfor a single publish, and neither handler checked the action, so one publish could queue up to six identical builds. Nightwatch issues 1 and 6 on the plugins app show builds have already overlapped in the shared build directory. Both handlers now go throughPlugin::claimReleaseEvent(). It only letspublishedthrough, and the first delivery claims the release in the cache for an hour, so the second webhook's copy is ignored.The per-repo handler never read the payload before, so it worked whatever content type the webhook used. GitHub's add-webhook form defaults to form data and our instructions to switch it to JSON are easy to miss, so the handler now reads the payload either way.
Things to watch for:
latest_versioncatches up on the next push.buildAll()still sends one build per plugin back to back. That needsWithoutOverlappingon the satis jobs in the plugins repo.New tests are in
SatisBuildTokenTest,PluginWebhookTest,GitHubAppRepositoryEventsTestandPluginSyncServiceTest. The eight that cover the new behaviour fail against the old code, and the full suite passes.🤖 Generated with Claude Code