fix(github): use provided app for installation URLs

Generate GitHub App installation links and setup cache state from the
current app instance, and keep the Livewire app name in sync after
permission checks.
This commit is contained in:
Andras Bacsai
2026-06-03 10:07:57 +02:00
parent 858b1906ec
commit a047971bc1
3 changed files with 31 additions and 6 deletions
+1
View File
@@ -211,6 +211,7 @@ class Change extends Component
GithubAppPermissionJob::dispatchSync($this->github_app);
$this->github_app->refresh()->makeVisible('client_secret')->makeVisible('webhook_secret');
$this->syncData(false);
$this->name = str($this->github_app->name)->kebab();
$this->dispatch('success', 'Github App permissions updated.');
} catch (\Throwable $e) {
+5 -6
View File
@@ -119,18 +119,17 @@ function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $m
function getInstallationPath(GithubApp $source): string
{
$github = GithubApp::where('uuid', $source->uuid)->first();
$name = str(Str::kebab($github->name));
$installation_path = $github->html_url === 'https://github.com' ? 'apps' : 'github-apps';
$name = str(Str::kebab($source->name));
$installation_path = $source->html_url === 'https://github.com' ? 'apps' : 'github-apps';
$state = Str::random(64);
Cache::put('github-app-setup-state:'.hash('sha256', $state), [
'action' => 'install',
'github_app_id' => $github->id,
'team_id' => $github->team_id,
'github_app_id' => $source->id,
'team_id' => $source->team_id,
], now()->addMinutes(60));
return "$github->html_url/$installation_path/$name/installations/new?".http_build_query(['state' => $state]);
return "$source->html_url/$installation_path/$name/installations/new?".http_build_query(['state' => $state]);
}
function getPermissionsPath(GithubApp $source)
+25
View File
@@ -124,6 +124,29 @@ describe('GitHub Source Change Component', function () {
]);
});
test('installation path is generated from the provided github app instance', function () {
$githubApp = new GithubApp;
$githubApp->forceFill([
'id' => 123,
'name' => 'Provided GitHub App',
'html_url' => 'https://github.example.com',
'team_id' => 456,
]);
$installationUrl = getInstallationPath($githubApp);
parse_str(parse_url($installationUrl, PHP_URL_QUERY), $query);
$installState = $query['state'] ?? null;
expect($installationUrl)->toStartWith('https://github.example.com/github-apps/provided-git-hub-app/installations/new?')
->and($installState)->not->toBeEmpty()
->and(Cache::get('github-app-setup-state:'.hash('sha256', $installState)))
->toMatchArray([
'action' => 'install',
'github_app_id' => 123,
'team_id' => 456,
]);
});
test('defaults webhook endpoint to app url when it is the first available endpoint', function () {
config(['app.url' => 'http://localhost:8000']);
@@ -389,11 +412,13 @@ describe('GitHub Source Change Component', function () {
Livewire::withQueryParams(['github_app_uuid' => $githubApp->uuid])
->test(Change::class)
->assertSuccessful()
->assertSet('name', 'test-git-hub-app')
->assertSet('contents', null)
->assertSet('metadata', null)
->assertSet('pullRequests', null)
->call('checkPermissions')
->assertDispatched('success')
->assertSet('name', 'test-git-hub-app')
->assertSet('contents', 'read')
->assertSet('metadata', 'read')
->assertSet('pullRequests', 'write');